MCP server for the Funraise nonprofit fundraising API. Exposes tools to read and write supporters, donations, recurring subscriptions, campaign sites, forms, households, addresses, and supporter interactions.
Strong foundation with 30 well-named tools following verb_noun convention (list_, get_, create_, update_, delete_). All tools have descriptions (avg 180 chars, within 10-1024 baseline). Input schemas present with typed parameters. However, critical gaps: (1) Object-type parameters (supporter, transaction, subscription, interaction) lack internal field documentation, LLMs cannot infer required vs optional fields or valid nested structures; (2) No output schemas documented, agents don't know what fields to expect from responses; (3) Enum constraints missing (e.g., interaction_type, subscription status, payment methods); (4) No pagination metadata (total_count, next_cursor) specified in list tool descriptions; (5) Error handling descriptions generic, no recovery guidance (e.g., 'If 401, regenerate API key' in health_check is good, but missing from create/update tools).
Cancel a recurring subscription. The subscription is marked as cancelled; the supporter's transaction history is preserved.
Create a new supporter interaction record (call, email, meeting, or note). ``interaction`` follows the documented JSON shape. At minimum: ``supporterId``, ``type`` (call/email/meeting/note), and ``date``. Optional: ``notes``, ``duration``, ``outcome``. Use when: "log this call with the major donor".
Create a recurring donation subscription. ``subscription`` follows the documented JSON shape. At minimum: ``supporterId``, ``amount``, ``frequency`` (e.g. ``monthly``), and ``startDate``. Optional: ``endDate``, ``allocation`` (fund split), ``paymentMethod``. Use when: "set up a $50/month pledge for this donor".
Create a new supporter (donor / contact) record in Funraise. ``supporter`` follows the documented JSON shape. At minimum you need a way to identify the donor: ``email`` or phone, plus a name (first/last). Optional fields include tags, address, household membership, and custom questions. Use when: "log this new donor from our event".
Object-type parameters (supporter, transaction, subscription, interaction) lack field-level documentation. LLMs cannot determine which nested fields are required, optional, or valid. E.g., create_supporter accepts {supporter: object} but no schema shows required fields (email|phone, first_name, last_name) or optional ones (tags, address).
No output schemas documented for any tool. Agents don't know what fields to expect from get_supporter, list_transactions, etc. This forces LLMs to guess field names for downstream tool calls, increasing errors.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | <=2025-11-25 | v2 |
Create a one-time donation record (manual entry / cash / check). ``transaction`` follows the documented JSON shape. At minimum: ``supporterId``, ``amount``, and ``date``. Optional: ``paymentMethod``, ``allocation`` (fund split), ``memo``, ``dedication``. Use when: "log this $500 check from the gala".
Soft-delete an interaction record (Funraise keeps the record for audit). Use sparingly - prefer fixing via ``update_interaction`` when possible.
Soft-delete a supporter (Funraise keeps the record for audit). Use sparingly - prefer fixing the record via ``update_supporter`` when possible. A delete here does NOT remove the donor's transaction history.
Soft-delete a transaction (Funraise keeps the record for audit). Use sparingly - prefer fixing via ``update_transaction`` when possible.
Fetch a single address record by id. Returns the full record including street, city, state, zip, and country.
Fetch a single campaign site record by UUID. Returns the full record including name, description, goal, and current total.
Fetch a single form record by id. Returns the full record including name, description, and configuration.
Fetch a single household record by id. Returns the full record including address and all members.
Fetch a single interaction record by id. Returns the full record including type, date, notes, and associated supporter.
Fetch a single subscription record by id. Returns the full record including the supporter, amount, frequency, and payment details.
Fetch a single supporter record by id. Use when: "show me everything we have on supporter <id>". Returns the full record including tags, household, and any custom field values.
Fetch a single donation transaction by id. Returns the full record including the supporter, allocation, payment details, and any dedication / memo text.
Verify credentials work by listing one supporter. If this fails with 401, the API key is missing or invalid. The 1-row supporter list is the lightest possible read - safe to call any time without worrying about rate limits.
List addresses in the nonprofit's database. Use when: "show me all addresses", "find addresses in a city". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List fundraising campaign sites (peer-to-peer, event, etc.). Use when: "show me all active campaigns", "what campaign sites exist?". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List donation forms (online giving pages, event registration, etc.). Use when: "show me all forms", "what forms are active?". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List households (address-level groupings of supporters). Use when: "show me all households", "find households with multiple supporters". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List supporter interactions (calls, emails, meetings, notes). Use when: "show me all interactions with this donor", "what calls have we logged?". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List recurring donation subscriptions (NOT one-time transactions). Use when: "show me all active recurring gifts", "what subscriptions did this campaign site create?", "what is donor <id> pledging monthly?". Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
List supporters (donors) in the nonprofit's Funraise account. Use when: "show me the donor database", "find donors named Patel", "look up by email". Filters combine with AND - leave them all empty to scan the whole list (paginated). Pagination: ``limit`` up to 100 per page, ``offset`` is 0-indexed.
List one-time donation transactions (NOT recurring gifts). Use when: "show me all donations from last month", "what did this campaign site bring in?", "what has donor <id> given this year?". Date filters take ISO 8601 (``2026-01-01T00:00:00Z``). Pagination: ``limit`` up to 100, ``offset`` 0-indexed.
Email the supporter a yearly giving summary. Use when: "send <donor name> their 2025 giving summary". The Funraise server enqueues the email; the response confirms the request was accepted.
Update an existing interaction record (PATCH). ``interaction`` is the partial record - omit any field you don't want to change. Use this to add notes, correct the date, or update the outcome.
Update an existing subscription (PATCH). ``subscription`` is the partial record - omit any field you don't want to change. Use this to change the amount, frequency, or end date.
Update an existing supporter (PATCH - only the fields you send). ``supporter`` is the partial record - omit any field you don't want to change. Use this to fix typos, add tags, change household assignment, or update contact info.
Update an existing transaction (PATCH). ``transaction`` is the partial record - omit any field you don't want to change. Use this to correct the amount, date, memo, or allocation after manual entry.
Enum constraints missing for categorical parameters. interaction_type accepts 'call|email|meeting|note' but not declared as enum. subscription status values not enumerated. payment_method options not specified. Free-form strings invite hallucinated values.
Pagination metadata not documented. list_* tools accept limit/offset but descriptions don't specify: does the response include total_count? next_cursor? Are results guaranteed sorted? Without this, agents cannot reliably iterate through large datasets.
Error handling descriptions generic. create_supporter, update_transaction, etc. don't explain what to do if validation fails (e.g., 'Invalid email format, must be [email protected]'). health_check is an exception with good 401 guidance, but pattern not replicated.