Connectors · CRM & sales
Virtuous CRM MCP server for AI agents.
actionlake is an MCP gateway: one remote MCP server that connects Claude and other MCP clients to Virtuous CRM and the rest of your systems. It gives your agent 290 Virtuous CRM actions (174 reads, 92 writes and 24 that wait for a confirmation) and holds the Virtuous CRM credential itself, so the agent never does. It paces Virtuous CRM's limits and records every call.
100,000 free calls a month. No card, no email, no password: press Start a free sandbox on the next screen and keep the key it shows you.
claude mcp add --transport http actionlake https://connect.actionlake.com/mcpdo { action: "virtuous.events.list", intent: "check which Virtuous CRM account is connected"}# Get Events · read · 1 upstream call- 290actionsin one signed file
- 174readlook, never change
- 92writecreate and update
- 24wait for a yesdestructive, confirmed first
Set up
Connect Virtuous CRM in three steps.
- 01
Add actionlake to Claude.
Run the command once in Claude Code; its consent page can create a free sandbox: 100,000 calls a month, no card. In the Claude app, add a custom connector with the URL below and paste your key on the consent page. Creating a new sandbox from the Claude app is not yet tested by us.
https://connect.actionlake.com/mcp - 02
Connect Virtuous CRM.
Bearer token. No consent screen: your agent can connect it for you, but the key then passes through your chat. To keep it out of the model's context, paste it in the console instead. actionlake stores what you paste write-only, sealed under your tenant's key.
access_tokenVirtuous API key: in Virtuous, Settings > Connectivity > API Keys > Create a Key (choose a permission group)
account { op: "connections.requirements", service: "virtuous" } # free: exactly what to paste, and what is found for you - 03
Make the first call. Check before a write.
Ask in plain words; Claude picks the action. Before anything changes,
checkvalidates the call and prices it, for free.do { action: "virtuous.events.list" }# get events · read · 1 upstream callcheck { action: "virtuous.events.create", input: { … } }# free: inputs, permissions, cost and confirmations, nothing sent
Virtuous CRM at a glance
- Sign-in
- Bearer token. No consent screen: your agent can connect it for you, but the key then passes through your chat. To keep it out of the model's context, paste it in the console instead.
- You provide
access_token- Limits we pace to
- 1,500 calls an hour, per connection
- API covered
- Virtuous REST API (Postman reference collection, latest)
api.virtuoussoftware.com - Built from
- Virtuous CRM's documentation, read 23 October 2026docs.virtuoussoftware.comdocs.virtuoussoftware.com
- Service file
- Version 1.0.0, signed (Ed25519)
- Cached reads
- 174 of 174 reads, for up to 5 minutes; a write clears what it affects
- Shared entities
- 5, so ask can line Virtuous CRM up with your other systems
- Data
- Processed and stored in Sydney, Australia. No US region yet
Capabilities
What an AI agent can do in Virtuous CRM.
290 actions in 45 areas. Every one carries its effect, so a key can allow the reads and hold the rest.
- 174readlook, never change
- 92writecreate and update
- 24destructivewait for a confirmation
Contacts
2215 read · 7 write · 0 destructive
Create a Contact · Get a Contact · Query Contacts with Abbreviated Details · Update a Contact
Gifts
1810 read · 7 write · 1 destructive
Create a Gift · Query Gifts with Abbreviated Details · Get a Gift · Update a Gift
Reminders
169 read · 7 write · 0 destructive
Create Manual Reminder · Create Milestone Reminder · Create Recurring Reminder · Gets Reminder Frequency Types
Projects
127 read · 5 write · 0 destructive
Create a Project · Get Project · Update a Project · Query Projects
Contact notes
117 read · 3 write · 1 destructive
Create a Note for a Contact · Get a Note · Update a Note · Query Contact Notes
Individuals
118 read · 2 write · 1 destructive
Create an Individual · Query Individuals · Get an Individual · Update an Individual
Events
107 read · 2 write · 1 destructive
Get Events · Create an Event · Get an Event · Update an Event
Grants
107 read · 2 write · 1 destructive
Create a Grant · Query Grants · Get Grant · Update a Grant
37 more areas · 180 actions
- Premiums 10
- Contact methods 8
- Event attendees 8
- Gift asks 8
- Planned gifts 8
- Pledges 8
- Recurring gifts 8
- Volunteer opportunities 8
- Communications 7
- Contact addresses 7
- Project roles 7
- Volunteers 7
- Organization groups 6
- Project notes 6
- Segments 6
- Project expenses 5
- Relationships 5
- Volunteer attendance 5
- Webhooks 5
- Campaigns 4
- Contact collections 4
- Event contacts 4
- Individual collections 4
- Tasks 4
- Volunteer organizers 4
- Contact tags 3
- Organizations 3
- Tributes 3
- Contact receipts 2
- Contact references 2
- Email lists 2
- Emails 2
- Gift designations 2
- Tags 2
- Permissions 1
- Recurring gift payments 1
- Search 1
Top actions
The Virtuous CRM API, shaped for agents.
The ids your agent types, what each does, and the one name it shares with other systems. 56 of Virtuous CRM's 57 action names are shared with at least one other connector, so an agent learns them once.
| Action | What it does | Effect | Same name in |
|---|---|---|---|
virtuous.events.listGet Events | Get Events. | read | comm.event.list61 connectors |
virtuous.tags.listGet all Tags | Get all Tags. | read | crm.tag.list65 connectors |
virtuous.events.createCreate an Event | Create an Event. | write | comm.event.create52 connectors |
virtuous.contacts.createCreate a Contact | Create a Contact. | write | crm.contact.create161 connectors |
virtuous.contacts.getGet a Contact | Get a Contact. | read | crm.contact.get176 connectors |
virtuous.contact_notes.createCreate a Note for a Contact | Create a Note for a Contact. | write | crm.contact_note.create28 connectors |
virtuous.projects.createCreate a Project | Create a Project. | write | work.project.create102 connectors |
virtuous.projects.getGet Project | Get Project. | read | work.project.get106 connectors |
virtuous.contact_notes.getGet a Note | Get a Note. | read | crm.contact_note.get21 connectors |
virtuous.events.deleteDelete an Event | Delete an Event. | destructive | comm.event.delete45 connectors |
virtuous.segments.createCreate a Segment | Create a Segment. | write | comm.audience_segment.create16 connectors |
virtuous.campaigns.getGet Campaign | Get Campaign. | read | comm.campaign.get39 connectors |
Try it
Prompts to paste into Claude.
Each one names the Virtuous CRM actions it will call, so you know what it reads and what it changes before you send it.
- Readread
Give me a one-line status for every active Virtuous CRM project.
calls
virtuous.projects.query - Writewrite
Create an Event in Virtuous CRM. Show me exactly what you will send before you save it.
calls
virtuous.events.create - Across systemsread
Which contacts are in both Virtuous CRM and HaloPSA, and how many are in only one of them?
calls
virtuous.contacts.queryhalopsa.users.list
Across your systems
Virtuous CRM, joined to the rest of your business.
One ask fetches from Virtuous CRM and another system, joins the rows on the same customer on our side, and hands your agent the answer, not every row.
Which contacts are in both Virtuous CRM and HaloPSA, and how many are in only one of them?
virtuous.contacts.query+halopsa.users.list, oncrm.contact· HaloPSAWhich contacts are in both Virtuous CRM and NetSuite, and how many are in only one of them?
virtuous.contacts.query+netsuite.views.contacts, oncrm.contact· NetSuite
crm.contact 192work.project 116comm.event 47crm.tag 47crm.contact_note 9ask { intent: "which contacts are in both Virtuous CRM and HaloPSA, and how many are in only one of them", steps: [ { action: "virtuous.contacts.query", as: "people", input: {}, limit: 100, max_pages: 5 }, { action: "halopsa.users.list", as: "people2", input: {}, limit: 100, max_pages: 5 }, { join: { left: "people", right: "people2", on: "crm.contact", group_by: "people.email", select: ["people.email", "count(people2.id) as in_halopsa"] } } ]}Governance for Virtuous CRM
Destructive actions wait for a yes.
24 Virtuous CRM actions are destructive. These are all of them:
- Delete an Event
virtuous.events.delete - Delete a Note
virtuous.contact_notes.delete - Delete an Event Attendee
virtuous.event_attendees.delete - Delete a Webhook
virtuous.webhooks.delete - Delete a Contact Tag
virtuous.contact_tags.delete - Delete a Project Note
virtuous.project_notes.delete - Delete a Gift
virtuous.gifts.delete - Delete a Grant
virtuous.grants.delete - Write-off the Pledge
virtuous.pledges.write_off - Delete a Volunteer
virtuous.volunteers.delete - Delete an Individual
virtuous.individuals.delete - Delete a Project Role
virtuous.project_roles.delete - Delete a Relationship
virtuous.relationships.delete - Delete an Event Contact
virtuous.event_contacts.delete - Delete a Contact Method
virtuous.contact_methods.delete - Delete a Contact Address
virtuous.contact_addresses.delete - Delete a Contact Reference
virtuous.contact_references.delete - Delete Collection for a Contact
virtuous.contact_collections.delete - Delete a Volunteer Attendance
virtuous.volunteer_attendance.delete - Delete a Volunteer Organizer
virtuous.volunteer_organizers.delete - Delete Collection for an Individual
virtuous.individual_collections.delete - Delete a Volunteer Opportunity
virtuous.volunteer_opportunities.delete - Remove a Contact from an Organization Group
virtuous.organization_groups.remove_contact - Cancel a Recurring Gift
virtuous.recurring_gifts.cancel
A destructive action runs only with confirm: true. Under the human policy the agent cannot confirm for itself: the run stops until a named person approves, in the console or from a signed link in an email. The cap on a key is refused before the call is sent, never after.
Delete an Event?
intent: the user asked me to delete an Event
account { op: "keys.create", name: "virtuous-agent", allowed_actions: ["virtuous.*"], cap_calls: 2000, confirm_policy: "human_for_writes", approval_rules: [ { match: "virtuous.events.delete", approver: "[email protected]" }, { match: "virtuous.contact_notes.delete", approver: "[email protected]" }, { match: "virtuous.event_attendees.delete", approver: "[email protected]" } ]}Cost
What Virtuous CRM costs on actionlake.
Every Virtuous CRM action is one upstream call, the only thing actionlake bills. Searching, check, cost, account and any call Virtuous CRM refused with 401, 403, 429 or a 5xx are free. Paid plans start at US$49 a month for 250,000 calls, with overage from US$0.30 down to US$0.18 per 1,000.
- 1upstream call per actionall 290 Virtuous CRM actions
- 290actions pageeach page of a long list is one call
- 174reads can be cacheda cache hit costs nothing
- 100,000calls a month, freepaid plans from US$49 a month for 250,000
Action index
Every Virtuous CRM action.
290 actions by area: the id your agent calls, what it does, and its effect.
Contacts22
virtuous.contacts.archiveArchive a Contactwritevirtuous.contacts.createCreate a Contactwritevirtuous.contacts.create_import_batchCreate a Contact Import that will be processed for changes and duplicateswritevirtuous.contacts.create_transactionCreate a Contact that will go through the import processwritevirtuous.contacts.custom_fieldsGet Contact Custom Fields Availablereadvirtuous.contacts.findFind a Contact by Email Address or Reference Source and IDreadvirtuous.contacts.getGet a Contactreadvirtuous.contacts.get_by_referenceGet a Contact by Reference IDreadvirtuous.contacts.get_by_reference_sourceGet a Contact by Reference Source and IDreadvirtuous.contacts.list_by_tagGet Contacts by Tag IDreadvirtuous.contacts.list_followingGet the Contacts the current user is followingreadvirtuous.contacts.list_following_activityGet the Activity for the Contacts the current user is followingreadvirtuous.contacts.prefixesGet Contact Name Prefixes and Titlesreadvirtuous.contacts.proximityFind all Contacts within a given proximity of a geocoordinatereadvirtuous.contacts.queryQuery Contacts with Abbreviated Detailsreadvirtuous.contacts.query_full_contactQuery Contacts with Full Detailsreadvirtuous.contacts.query_optionsGet Contact Query Optionsreadvirtuous.contacts.searchFind all Contacts that match, fully or partially, the given search parametersreadvirtuous.contacts.toggle_followFollow or Unfollow a Contact for the current userwritevirtuous.contacts.typesGet Contact Typesreadvirtuous.contacts.unarchiveUnarchive a Contactwritevirtuous.contacts.updateUpdate a Contactwrite
Gifts18
virtuous.gifts.createCreate a Giftwritevirtuous.gifts.create_manyCreate many Giftswritevirtuous.gifts.create_reversing_transactionCreate a Reversing Transactionwritevirtuous.gifts.create_transactionCreate a Gift Transactionwritevirtuous.gifts.create_transactionsCreate a Batch of Gift Transactionswritevirtuous.gifts.custom_fieldsGet Gift Custom Fields Availablereadvirtuous.gifts.deleteDelete a Giftdestructivevirtuous.gifts.getGet a Giftreadvirtuous.gifts.get_by_transactionGet a Gift by Transaction Source and IDreadvirtuous.gifts.list_by_contactGet Gifts for a Contactreadvirtuous.gifts.list_by_referenceGet Gifts for a Contact by Reference IDreadvirtuous.gifts.list_passthrough_by_contactGet Passthrough Gifts for a Contactreadvirtuous.gifts.non_cash_gift_typesGet Non-Cash Gift Types Availablereadvirtuous.gifts.queryQuery Gifts with Abbreviated Detailsreadvirtuous.gifts.query_full_giftQuery Gifts with Full Detailsreadvirtuous.gifts.query_optionsGet Gift Query Optionsreadvirtuous.gifts.updateUpdate a Giftwritevirtuous.gifts.update_manyUpdate many Giftswrite
Reminders16
virtuous.reminders.completeComplete Reminderwritevirtuous.reminders.createCreate Manual Reminderwritevirtuous.reminders.create_milestoneCreate Milestone Reminderwritevirtuous.reminders.create_recurringCreate Recurring Reminderwritevirtuous.reminders.dismissDismiss Reminderwritevirtuous.reminders.frequency_typesGets Reminder Frequency Typesreadvirtuous.reminders.list_activeGet Active Reminders (for current user)readvirtuous.reminders.list_active_by_contactGet Active Manual Reminders by Contactreadvirtuous.reminders.list_inactive_by_contactGet Inactive Manual Reminders by Contactreadvirtuous.reminders.list_savedGet Saved Reminders (for current user)readvirtuous.reminders.list_unresolved_by_contactGet Unresolved Manual Reminders by Contactreadvirtuous.reminders.milestone_typesGets Milestone Typesreadvirtuous.reminders.reminder_typesGet Reminder Typesreadvirtuous.reminders.source_typesGet Reminder Source Typesreadvirtuous.reminders.update_milestoneUpdate Milestone Reminderwritevirtuous.reminders.update_recurringUpdate Recurring Reminderwrite
Projects12
virtuous.projects.createCreate a Projectwritevirtuous.projects.custom_fieldsGet Project Custom Fields Availablereadvirtuous.projects.getGet Projectreadvirtuous.projects.get_by_codeGet a Project using a unique Codereadvirtuous.projects.queryQuery Projectsreadvirtuous.projects.query_optionsGet Project Query Optionsreadvirtuous.projects.searchFind Projectsreadvirtuous.projects.set_inventory_statusTemporarily Change Project Inventory Statuswritevirtuous.projects.typesGet Project Typesreadvirtuous.projects.updateUpdate a Projectwritevirtuous.projects.update_balanceUpdate Project Balancewritevirtuous.projects.update_manyUpdate many Projectswrite
Contact notes11
virtuous.contact_notes.createCreate a Note for a Contactwritevirtuous.contact_notes.create_from_emailCreate a Note using an Emailwritevirtuous.contact_notes.custom_fieldsGets the custom fields for contact notereadvirtuous.contact_notes.deleteDelete a Notedestructivevirtuous.contact_notes.getGet a Notereadvirtuous.contact_notes.list_by_contactGet the Notes for a Contactreadvirtuous.contact_notes.list_important_by_contactGet the Important Notes for a Contactreadvirtuous.contact_notes.queryQuery Contact Notesreadvirtuous.contact_notes.query_optionsGet Contact Note Query Optionsreadvirtuous.contact_notes.typesGet Contact Note Typesreadvirtuous.contact_notes.updateUpdate a Notewrite
Individuals11
virtuous.individuals.createCreate an Individualwritevirtuous.individuals.custom_fieldsGets the custom fields for contact individualsreadvirtuous.individuals.deleteDelete an Individualdestructivevirtuous.individuals.findFind an individual by email addressreadvirtuous.individuals.getGet an Individualreadvirtuous.individuals.get_avatarGets the avatar for a specified contact individualreadvirtuous.individuals.list_by_contactGet Individuals for a Contactreadvirtuous.individuals.list_email_listsGet Email Lists for an Individualreadvirtuous.individuals.queryQuery Individualsreadvirtuous.individuals.query_optionsGet Individual Query Optionsreadvirtuous.individuals.updateUpdate an Individualwrite
Events10
virtuous.events.createCreate an Eventwritevirtuous.events.custom_fieldsGet Event Custom Fields Availablereadvirtuous.events.deleteDelete an Eventdestructivevirtuous.events.findFind an Eventreadvirtuous.events.getGet an Eventreadvirtuous.events.listGet Eventsreadvirtuous.events.queryQuery Eventsreadvirtuous.events.query_optionsGet Event Query Optionsreadvirtuous.events.typesGet the Event Typesreadvirtuous.events.updateUpdate an Eventwrite
Grants10
virtuous.grants.createCreate a Grantwritevirtuous.grants.custom_fieldsGet Grant Custom Fields Availablereadvirtuous.grants.deleteDelete a Grantdestructivevirtuous.grants.getGet Grantreadvirtuous.grants.get_by_referenceGet a Grant by Reference IDreadvirtuous.grants.list_by_contactGet Grants for a Contactreadvirtuous.grants.list_giftsGet the Gifts applied to a Grantreadvirtuous.grants.queryQuery Grantsreadvirtuous.grants.query_optionsGet Grant Query Optionsreadvirtuous.grants.updateUpdate a Grantwrite
Premiums10
virtuous.premiums.createCreate a Premiumwritevirtuous.premiums.custom_fieldsGet Premium Custom Fields Availablereadvirtuous.premiums.decrement_inventoryDecrement the inventory countwritevirtuous.premiums.getGet Premiumreadvirtuous.premiums.get_by_codeGet Premium using a unique Codereadvirtuous.premiums.increment_inventoryIncrement the inventory countwritevirtuous.premiums.queryQuery Premiumsreadvirtuous.premiums.query_optionsGet Premium Query Optionsreadvirtuous.premiums.searchFind Premiumsreadvirtuous.premiums.updateUpdate a Premiumwrite
Contact methods8
virtuous.contact_methods.archiveArchive a Contact Methodwritevirtuous.contact_methods.createCreate a Contact Method for an Individualwritevirtuous.contact_methods.deleteDelete a Contact Methoddestructivevirtuous.contact_methods.getGet a Contact Methodreadvirtuous.contact_methods.related_typesGet Contact Methods Types related to the Base Typereadvirtuous.contact_methods.typesGet Contact Method Typesreadvirtuous.contact_methods.unarchiveUnarchive a Contact Methodwritevirtuous.contact_methods.updateUpdate a Contact Methodwrite
Event attendees8
virtuous.event_attendees.createCreate an Event Attendeewritevirtuous.event_attendees.custom_fieldsGet Event Attendee Custom Fields Availablereadvirtuous.event_attendees.deleteDelete an Event Attendeedestructivevirtuous.event_attendees.getGet an Event Attendeereadvirtuous.event_attendees.listGet Event Attendees for an Eventreadvirtuous.event_attendees.queryQuery Event Attendeesreadvirtuous.event_attendees.query_optionsGet Event Attendee Query Optionsreadvirtuous.event_attendees.updateUpdate an Event Attendeewrite
Gift asks8
virtuous.gift_asks.createCreate a Gift Askwritevirtuous.gift_asks.custom_fieldsGet Gift Ask Custom Fields Availablereadvirtuous.gift_asks.getGet a Gift Askreadvirtuous.gift_asks.list_by_contactGet Gift Asks for a Contactreadvirtuous.gift_asks.list_giftsGet the Gifts applied to a Gift Askreadvirtuous.gift_asks.queryQuery Gift Asksreadvirtuous.gift_asks.query_optionsGet Gift Ask Query Optionsreadvirtuous.gift_asks.updateUpdate a Gift Askwrite
Planned gifts8
virtuous.planned_gifts.createCreate a Planned Giftwritevirtuous.planned_gifts.custom_fieldsGet Planned Gift Custom Fields Availablereadvirtuous.planned_gifts.getGet Planned Giftreadvirtuous.planned_gifts.list_by_contactGet Planned Gifts for a Contactreadvirtuous.planned_gifts.list_giftsGet Gifts Applied to a Planned Giftreadvirtuous.planned_gifts.queryQuery Planned Giftsreadvirtuous.planned_gifts.query_optionsGet Planned Gift Query Optionsreadvirtuous.planned_gifts.updateUpdate a Planned Giftwrite
Pledges8
virtuous.pledges.createCreate a Pledgewritevirtuous.pledges.custom_fieldsGet Pledge Custom Fields Availablereadvirtuous.pledges.getGet Pledgereadvirtuous.pledges.list_by_contactGet Pledges for a Contactreadvirtuous.pledges.queryQuery Pledgesreadvirtuous.pledges.query_optionsGet Pledge Query Optionsreadvirtuous.pledges.updateUpdate a Pledgewritevirtuous.pledges.write_offWrite-off the Pledgedestructive
Recurring gifts8
virtuous.recurring_gifts.cancelCancel a Recurring Giftdestructivevirtuous.recurring_gifts.createCreate a Recurring Giftwritevirtuous.recurring_gifts.custom_fieldsGet Recurring Gift Custom Fields Availablereadvirtuous.recurring_gifts.getGet a Recurring Giftreadvirtuous.recurring_gifts.list_by_contactGet Recurring Gifts for a Contactreadvirtuous.recurring_gifts.queryQuery Recurring Giftsreadvirtuous.recurring_gifts.query_optionsGet Recurring Gift Query Optionsreadvirtuous.recurring_gifts.updateUpdate a Recurring Giftwrite
Volunteer opportunities8
virtuous.volunteer_opportunities.createCreate a Volunteer Opportunitywritevirtuous.volunteer_opportunities.custom_fieldsGet Custom Fields Availablereadvirtuous.volunteer_opportunities.deleteDelete a Volunteer Opportunitydestructivevirtuous.volunteer_opportunities.getGet Volunteer Opportunityreadvirtuous.volunteer_opportunities.listGet Volunteer Opportunitiesreadvirtuous.volunteer_opportunities.queryQueries Volunteer Opportunitiesreadvirtuous.volunteer_opportunities.query_optionsGet Query Optionsreadvirtuous.volunteer_opportunities.updateUpdate a Volunteer Opportunitywrite
Communications7
virtuous.communications.channel_typesGet Channel Typesreadvirtuous.communications.communication_typesGet Communication Typesreadvirtuous.communications.createCreate Communicationwritevirtuous.communications.getGet Communicationreadvirtuous.communications.list_by_campaignGet Communications for a Campaignreadvirtuous.communications.queryQuery Communicationsreadvirtuous.communications.query_optionsCommunication Query Optionsread
Contact addresses7
virtuous.contact_addresses.archiveArchive a Contact Addresswritevirtuous.contact_addresses.createCreate a Contact Addresswritevirtuous.contact_addresses.deleteDelete a Contact Addressdestructivevirtuous.contact_addresses.getGet a Contact Addressreadvirtuous.contact_addresses.list_by_contactGet the Contact Addresses for a Contactreadvirtuous.contact_addresses.unarchiveUnarchive a Contact Addresswritevirtuous.contact_addresses.updateUpdate a Contact Addresswrite
Project roles7
virtuous.project_roles.createCreate a Project Rolewritevirtuous.project_roles.deleteDelete a Project Roledestructivevirtuous.project_roles.getGet Project Rolereadvirtuous.project_roles.list_by_contactGet Project Roles for a Contactreadvirtuous.project_roles.list_by_projectGet Project Roles for a Projectreadvirtuous.project_roles.typesGet Project Role Typesreadvirtuous.project_roles.updateUpdate a Project Rolewrite
Volunteers7
virtuous.volunteers.createCreate a Volunteerwritevirtuous.volunteers.deleteDelete a Volunteerdestructivevirtuous.volunteers.getGet Volunteerreadvirtuous.volunteers.listGet Volunteers for a Volunteer Opportunityreadvirtuous.volunteers.queryQuery Volunteersreadvirtuous.volunteers.query_optionsGet Query Optionsreadvirtuous.volunteers.searchSearch for Volunteersread
Organization groups6
virtuous.organization_groups.add_contactAssign a Contact to an Organization Groupwritevirtuous.organization_groups.getGet an Organization Groupreadvirtuous.organization_groups.listGet all Organization Groupsreadvirtuous.organization_groups.list_by_contactGet Organization Groups for a Contactreadvirtuous.organization_groups.list_contactsGet the Contacts in an Organization Groupreadvirtuous.organization_groups.remove_contactRemove a Contact from an Organization Groupdestructive
Project notes6
virtuous.project_notes.createCreate a Project Notewritevirtuous.project_notes.deleteDelete a Project Notedestructivevirtuous.project_notes.getGet Project Notereadvirtuous.project_notes.list_by_projectGet Notes for a Projectreadvirtuous.project_notes.typesGet Project Note Typesreadvirtuous.project_notes.updateUpdate a Project Notewrite
Segments6
virtuous.segments.createCreate a Segmentwritevirtuous.segments.getGet a Segmentreadvirtuous.segments.get_by_codeGet a Segment using a unique Codereadvirtuous.segments.list_by_contactGet the Segments for a Contactreadvirtuous.segments.searchFind Segmentsreadvirtuous.segments.updateUpdate a Segmentwrite
Project expenses5
virtuous.project_expenses.createCreate a Project Expensewritevirtuous.project_expenses.create_manyCreate many Project Expenseswritevirtuous.project_expenses.getGet Project Expensereadvirtuous.project_expenses.listGet Project Expenses for a Projectreadvirtuous.project_expenses.updateUpdate a Project Expensewrite
Relationships5
virtuous.relationships.createCreate a Relationshipwritevirtuous.relationships.deleteDelete a Relationshipdestructivevirtuous.relationships.list_by_contactGet Relationships for a Contactreadvirtuous.relationships.typesGet Relationship Typesreadvirtuous.relationships.updateUpdate a Relationshipwrite
Volunteer attendance5
virtuous.volunteer_attendance.createCreate a Volunteer Attendancewritevirtuous.volunteer_attendance.deleteDelete a Volunteer Attendancedestructivevirtuous.volunteer_attendance.getGet Volunteer Attendancereadvirtuous.volunteer_attendance.listGet Volunteer Attendance for a Volunteerreadvirtuous.volunteer_attendance.updateUpdate a Volunteer Attendancewrite
Webhooks5
virtuous.webhooks.createCreate a Webhookwritevirtuous.webhooks.deleteDelete a Webhookdestructivevirtuous.webhooks.getGet a Webhookreadvirtuous.webhooks.set_activeSet the active state of a Webhookwritevirtuous.webhooks.updateUpdate a Webhookwrite
Campaigns4
virtuous.campaigns.getGet Campaignreadvirtuous.campaigns.list_stepsGets Campaign Stepsreadvirtuous.campaigns.queryQuery Campaignsreadvirtuous.campaigns.query_optionsGet Campaign Query Optionsread
Contact collections4
virtuous.contact_collections.createCreate Collection for a Contactwritevirtuous.contact_collections.deleteDelete Collection for a Contactdestructivevirtuous.contact_collections.list_definitionsGet Custom Collections for Contactsreadvirtuous.contact_collections.updateUpdate Collection for a Contactwrite
Event contacts4
virtuous.event_contacts.createCreate an Event Contactwritevirtuous.event_contacts.deleteDelete an Event Contactdestructivevirtuous.event_contacts.getGet an Event Contactreadvirtuous.event_contacts.listGet Event Contacts for an Eventread
Individual collections4
virtuous.individual_collections.createCreate Collection for an Individualwritevirtuous.individual_collections.deleteDelete Collection for an Individualdestructivevirtuous.individual_collections.list_definitionsGet Custom Collections for Individualsreadvirtuous.individual_collections.updateUpdate Collection for an Individualwrite
Tasks4
virtuous.tasks.createCreate a Taskwritevirtuous.tasks.queryQuery Tasksreadvirtuous.tasks.query_optionsGet Task Query Optionsreadvirtuous.tasks.typesGet Task Typesread
Volunteer organizers4
virtuous.volunteer_organizers.createCreate a Volunteer Organizerwritevirtuous.volunteer_organizers.deleteDelete a Volunteer Organizerdestructivevirtuous.volunteer_organizers.getGet Volunteer Organizerreadvirtuous.volunteer_organizers.listGet Volunteer Organizersread
Contact tags3
virtuous.contact_tags.createCreate a Contact Tagwritevirtuous.contact_tags.deleteDelete a Contact Tagdestructivevirtuous.contact_tags.list_by_contactGet Tags for a Contactread
Organizations3
virtuous.organizations.currentGet the Current Organization for the current userreadvirtuous.organizations.listGet the Organizations the current user belongs toreadvirtuous.organizations.switchSwitch the Current Organizationwrite
Tributes3
virtuous.tributes.createCreate a Tributewritevirtuous.tributes.searchSearch for Tributesreadvirtuous.tributes.updateUpdate a Tributewrite
Contact receipts2
virtuous.contact_receipts.getGet Receiptreadvirtuous.contact_receipts.listReceiptsread
Contact references2
virtuous.contact_references.createCreate a Contact Referencewritevirtuous.contact_references.deleteDelete a Contact Referencedestructive
Email lists2
virtuous.email_lists.add_individualsAdd Individuals to an Email Listwritevirtuous.email_lists.searchSearch for an Email Listread
Emails2
virtuous.emails.searchGet Emailsreadvirtuous.emails.sendSend an Email to a list of Contactswrite
Gift designations2
virtuous.gift_designations.queryQuery Gift Designationsreadvirtuous.gift_designations.query_optionsGet Gift Designation Query Optionsread
Tags2
virtuous.tags.listGet all Tagsreadvirtuous.tags.searchFind all Tags that match, fully or partiallyread
Permissions1
virtuous.permissions.listGet Permissions for the current userread
Recurring gift payments1
virtuous.recurring_gift_payments.listGet Payments for a Recurring Giftread
Search1
virtuous.search.searchSearch for Contacts, Individuals or Entitiesread
Questions
The Virtuous CRM MCP server, answered.
Is there a Virtuous CRM MCP server for Claude?
Yes. actionlake is an MCP gateway: a remote MCP server that gives Claude, or another MCP client, 290 Virtuous CRM actions across contacts, gifts, reminders and projects, through the same eight tools it uses for every other connector. actionlake is independent; it is not made or endorsed by Virtuous CRM.
What do I need to connect Virtuous CRM?
Virtuous API key: in Virtuous, Settings > Connectivity > API Keys > Create a Key (choose a permission group). The free call account { op: "connections.requirements", service: "virtuous" } lists exactly what to paste.
Can an AI agent delete or change things in Virtuous CRM?
Only if its key allows it, and only with an explicit confirmation. 24 Virtuous CRM actions are destructive, including delete an Event, delete a Note and delete an Event Attendee. Each runs only with confirm: true. Under the human confirm policy, or an approval rule on the key, the run waits until a named person approves it.
Will an AI agent use up my Virtuous CRM API limit?
actionlake paces every call to the limits in the Virtuous CRM service file: 1,500 calls an hour per connection. Repeated reads are answered from cache (174 Virtuous CRM actions can be), which never reaches Virtuous CRM.
What does a Virtuous CRM action cost?
One upstream call, the only unit actionlake bills. A list that pages bills one call per page (290 Virtuous CRM actions page). Cache hits, searches, dry runs and calls Virtuous CRM refused with 401, 403, 429 or a 5xx are free. The Free plan includes 100,000 calls a month with no card. Paid plans start at US$49 a month for 250,000 calls, with overage from US$0.30 down to US$0.18 per 1,000.
Which Virtuous CRM API does it cover?
The Virtuous REST API (Postman reference collection, latest) at api.virtuoussoftware.com. It is built from Virtuous CRM's documentation as read on 23 October 2026. 290 actions in 45 areas, each one in the signed service file (version 1.0.0).
Can I combine Virtuous CRM with my other systems?
Yes. ask joins Virtuous CRM to HaloPSA or NetSuite on the same customer and returns the answer rather than every row. Virtuous CRM maps crm.contact, which 192 other connectors also map.
Does actionlake keep my Virtuous CRM data, and where?
actionlake processes and stores data in Sydney, Australia; there is no US region yet. Reads may be cached for up to 5 minutes, and a write clears the reads it affects. Each run's request and response is kept, sealed, for your plan's trace window: 1 day on Free, 3 days on Starter, 7 days on Pro, 14 days on Team, 30 days on Business and 30 days on Enterprise. Your Virtuous CRM credential is sealed under your tenant's key, never logged and never returned. Your traffic is not used to train models.
Which AI clients can use it?
Claude Code, tested by us end to end, and the Claude app as a custom connector, tested by us with an existing key. Other MCP clients that support remote servers over Streamable HTTP (MCP revisions 2025-06-18 and 2025-11-25) and OAuth dynamic client registration, or a bearer header, should connect the same way; we have not tested them. Or plain REST, under the same action names.
Give your agent Virtuous CRM today.
Start free - 100,000 calls/month, no card. No signup. Hard caps on every key. Cached answers are free.