Virtuous MCP by usefulapi
by usefulapi.io · remote · no sign-in to list tools · v1.16.3 · published by io.usefulapi
Search donors and contacts, giving history, notes and projects, and log notes, tags and gifts.
20 tools: 4 can delete or cancel things, 1 change things and 15 only read.
Scanned Oct 21, 2026
- Deletes or cancels4Claude Code: deny: see these tools
- Can't be undone0Claude Code: ask
- Changes things1Claude Code: ask: see these tools
- Only reads15Claude Code: allow: see these tools
1 check matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http virtuous-crm https://virtuous-crm.usefulapi.io/mcpFindings
Matches of fixed checks, with the text they matched.
- Warnvirtuous_query
The server marks "virtuous_query" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "virtuous_query" says "query": a word for reading.
Tools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
20 tools
Deletes or cancels 4Claude Code: deny
virtuous_add_contact_tagApply an existing tag to a contact (find the tagId with virtuous_list_tags).No findings
Why it is in this group
- The name "virtuous_add_contact_tag" says "add": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Apply an existing tag to a contact (find the tagId with virtuous_list_tags). Virtuous: POST /api/ContactTag.
Annotations the server declares
- title: Tag a contact
- destructiveHint: true
virtuous_create_contact_noteAdd a note to a contact's timeline — a call, meeting, visit or other touchpoint.No findings
Why it is in this group
- The name "virtuous_create_contact_note" says "create": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Add a note to a contact's timeline — a call, meeting, visit or other touchpoint. Writes to the donor record. Virtuous: POST /api/ContactNote.
Annotations the server declares
- title: Log a note on a contact
- destructiveHint: true
virtuous_create_contact_transactionSubmit a new or updated contact through Virtuous's import pipeline (the recommended way to add contacts).No findings
Why it is in this group
- The name "virtuous_create_contact_transaction" says "create": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Submit a new or updated contact through Virtuous's import pipeline (the recommended way to add contacts). It is matched against existing contacts by name, email, phone, address and reference, bundled into an import at midnight, and only committed when a user reviews the import and clicks Run — so nothing is created in real time and no duplicates are forced. Virtuous: POST /api/Contact/Transaction.
Annotations the server declares
- title: Submit a contact for import
- destructiveHint: true
virtuous_create_gift_transactionRecord a gift (donation already received) through Virtuous's gift import pipeline — the method Virtuous recommends.No findings
Why it is in this group
- The name "virtuous_create_gift_transaction" says "create": a word for a change.
- The input carries an amount (input.amount) and a currency, so it moves money.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Record a gift (donation already received) through Virtuous's gift import pipeline — the method Virtuous recommends. The gift is matched to a contact, recurring gift or pledge, held until the nightly import, and only created when a user reviews the import and clicks Run. This records a gift; it does NOT charge anyone. Identify the donor with contact.id, contact.referenceId, or name/email details. Virtuous: POST /api/v2/Gift/Transaction.
Annotations the server declares
- title: Submit a gift for import
- destructiveHint: true
Changes things 1Claude Code: ask
virtuous_queryRun a Virtuous query-builder query against one record type (contacts, gifts, campaigns, projects, tasks, grants, pledges, recurring gifts, events ...).1 finding
Why it is in this group
- The name "virtuous_query" says "query": a word for reading.
- The description's first verb is "run": a word for a change.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Findings
- Warn
The server marks "virtuous_query" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true}; The name "virtuous_query" says "query": a word for reading.
Description, as the server wrote it Run a Virtuous query-builder query against one record type (contacts, gifts, campaigns, projects, tasks, grants, pledges, recurring gifts, events ...). Conditions use parameter/operator names from virtuous_get_query_options. Returns { list, total }. For Contact and Gift, full_details returns full records instead of the abbreviated view. Virtuous: POST /api/<Resource>/Query.
Annotations the server declares
- title: Query records
- readOnlyHint: true
Only reads 15Claude Code: allow
virtuous_find_contactLook up a single contact by email address, or by an external reference (reference source + id, e.g.No findings
Why it is in this group
- The name "virtuous_find_contact" says "find": a word for reading.
Description, as the server wrote it Look up a single contact by email address, or by an external reference (reference source + id, e.g. Stripe customer id). Give either email, or both reference_source and reference_id; if both are given Virtuous prioritises the reference. Virtuous: GET /api/Contact/Find.
Annotations the server declares
- title: Find a contact by email or reference
- readOnlyHint: true
virtuous_get_contactFetch one contact (household, organization, foundation ...) with its address, giving summary (life-to-date, year-to-date, last gift), individuals and their contact methods, and cus…No findings
Why it is in this group
- The name "virtuous_get_contact" says "get": a word for reading.
Description, as the server wrote it Fetch one contact (household, organization, foundation ...) with its address, giving summary (life-to-date, year-to-date, last gift), individuals and their contact methods, and custom fields. Virtuous: GET /api/Contact/{contactId}.
Annotations the server declares
- title: Get a contact
- readOnlyHint: true
virtuous_get_current_organizationFetch the Virtuous organization this API key acts in — its name, time zone and culture, and whether the key's user is an administrator.No findings
Why it is in this group
- The name "virtuous_get_current_organization" says "get": a word for reading.
Description, as the server wrote it Fetch the Virtuous organization this API key acts in — its name, time zone and culture, and whether the key's user is an administrator. A cheap way to confirm the key works. Virtuous: GET /api/Organization/Current.
Annotations the server declares
- title: Get the current organization
- readOnlyHint: true
virtuous_get_giftFetch one gift in full: contact, type, date, amount and currency, batch, segment, grant, tribute, receipt date, designations to projects, premiums and custom fields.No findings
Why it is in this group
- The name "virtuous_get_gift" says "get": a word for reading.
Description, as the server wrote it Fetch one gift in full: contact, type, date, amount and currency, batch, segment, grant, tribute, receipt date, designations to projects, premiums and custom fields. Virtuous: GET /api/Gift/{giftId}.
Annotations the server declares
- title: Get a gift
- readOnlyHint: true
virtuous_get_projectFetch one project: code, type, status, balances, financial need, date range, life-to-date and calendar-year giving and gift/giver counts.No findings
Why it is in this group
- The name "virtuous_get_project" says "get": a word for reading.
Description, as the server wrote it Fetch one project: code, type, status, balances, financial need, date range, life-to-date and calendar-year giving and gift/giver counts. Virtuous: GET /api/Project/{projectId}.
Annotations the server declares
- title: Get a project
- readOnlyHint: true
virtuous_get_query_optionsList the parameters, their types, allowed operators and value options that virtuous_query accepts for one record type.No findings
Why it is in this group
- The name "virtuous_get_query_options" says "get": a word for reading.
Description, as the server wrote it List the parameters, their types, allowed operators and value options that virtuous_query accepts for one record type. Call this BEFORE building a query. Virtuous: GET /api/<Resource>/QueryOptions.
Annotations the server declares
- title: Get query options
- readOnlyHint: true
virtuous_list_contact_giftsList a contact's giving history: gift id, type, date, amount, segment and batch.No findings
Why it is in this group
- The name "virtuous_list_contact_gifts" says "list": a word for reading.
Description, as the server wrote it List a contact's giving history: gift id, type, date, amount, segment and batch. Use virtuous_get_gift for designations and full detail. Virtuous: GET /api/Gift/ByContact/{contactId}.
Annotations the server declares
- title: List a contact's gifts
- readOnlyHint: true
virtuous_list_contact_individualsList the individuals (people) that belong to a contact/household, with names, birth dates, and their emails and phones (contact methods).No findings
Why it is in this group
- The name "virtuous_list_contact_individuals" says "list": a word for reading.
Description, as the server wrote it List the individuals (people) that belong to a contact/household, with names, birth dates, and their emails and phones (contact methods). Virtuous: GET /api/ContactIndividual/ByContact/{contactId}.
Annotations the server declares
- title: List a contact's individuals
- readOnlyHint: true
virtuous_list_contact_notesList the notes logged on a contact — calls, meetings, emails and other touchpoints — with type, date, text and author.No findings
Why it is in this group
- The name "virtuous_list_contact_notes" says "list": a word for reading.
Description, as the server wrote it List the notes logged on a contact — calls, meetings, emails and other touchpoints — with type, date, text and author. Virtuous: GET /api/ContactNote/ByContact/{contactId}.
Annotations the server declares
- title: List a contact's notes
- readOnlyHint: true
virtuous_list_contact_tagsList the tags applied to a contact (contactTagId, tagId, name).No findings
Why it is in this group
- The name "virtuous_list_contact_tags" says "list": a word for reading.
Description, as the server wrote it List the tags applied to a contact (contactTagId, tagId, name). Virtuous: GET /api/ContactTag/ByContact/{contactId}.
Annotations the server declares
- title: List a contact's tags
- readOnlyHint: true
virtuous_list_eventsList the organization's events: name, type, location, start/end, invite and RSVP counts, attendance and total giving.No findings
Why it is in this group
- The name "virtuous_list_events" says "list": a word for reading.
Description, as the server wrote it List the organization's events: name, type, location, start/end, invite and RSVP counts, attendance and total giving. Virtuous: GET /api/Event.
Annotations the server declares
- title: List events
- readOnlyHint: true
virtuous_list_tagsList the organization's tags (id, name, tag group).No findings
Why it is in this group
- The name "virtuous_list_tags" says "list": a word for reading.
Description, as the server wrote it List the organization's tags (id, name, tag group). Use this to find a tagId before virtuous_add_contact_tag. Virtuous: GET /api/Tag.
Annotations the server declares
- title: List tags
- readOnlyHint: true
virtuous_searchFull-text search across contacts, individuals and entities (campaigns, projects, segments, tags) — the same search as the Virtuous search bar.No findings
Why it is in this group
- The name "virtuous_search" says "search": a word for reading.
Description, as the server wrote it Full-text search across contacts, individuals and entities (campaigns, projects, segments, tags) — the same search as the Virtuous search bar. Returns hits with highlights, grouped by kind. Virtuous: POST /api/Search.
Annotations the server declares
- title: Global search
- readOnlyHint: true
virtuous_search_contactsFind contacts whose name, email, phone or address fully or partially matches a search string.No findings
Why it is in this group
- The name "virtuous_search_contacts" says "search": a word for reading.
Description, as the server wrote it Find contacts whose name, email, phone or address fully or partially matches a search string. Returns id, name, contact type, email, phone and address per match. Virtuous: POST /api/Contact/Search.
Annotations the server declares
- title: Search contacts
- readOnlyHint: true
virtuous_search_projectsFind projects (funds / designations gifts are given to) by name or code, with their balances, financial need and life-to-date giving.No findings
Why it is in this group
- The name "virtuous_search_projects" says "search": a word for reading.
Description, as the server wrote it Find projects (funds / designations gifts are given to) by name or code, with their balances, financial need and life-to-date giving. Virtuous: POST /api/Project/Search.
Annotations the server declares
- title: Search projects
- readOnlyHint: true
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 1.16.3. Values in angle brackets are yours to fill in.
claude mcp add --transport http virtuous-crm https://virtuous-crm.usefulapi.io/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__virtuous-crm__virtuous_get_current_organization",
"mcp__virtuous-crm__virtuous_search",
"mcp__virtuous-crm__virtuous_search_contacts",
"mcp__virtuous-crm__virtuous_get_contact",
"mcp__virtuous-crm__virtuous_find_contact",
"mcp__virtuous-crm__virtuous_list_contact_individuals",
"mcp__virtuous-crm__virtuous_list_contact_notes",
"mcp__virtuous-crm__virtuous_list_contact_tags",
"mcp__virtuous-crm__virtuous_list_contact_gifts",
"mcp__virtuous-crm__virtuous_get_gift",
"mcp__virtuous-crm__virtuous_list_tags",
"mcp__virtuous-crm__virtuous_search_projects",
"mcp__virtuous-crm__virtuous_get_project",
"mcp__virtuous-crm__virtuous_list_events",
"mcp__virtuous-crm__virtuous_get_query_options"
],
"ask": [
"mcp__virtuous-crm__virtuous_query"
],
"deny": [
"mcp__virtuous-crm__virtuous_create_contact_note",
"mcp__virtuous-crm__virtuous_add_contact_tag",
"mcp__virtuous-crm__virtuous_create_contact_transaction",
"mcp__virtuous-crm__virtuous_create_gift_transaction"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as virtuous-crm. Review it before you use it.