MCP Server
A Model Context Protocol server that gives AI assistants full access to the Campaign CRM. Built on the official MCP SDK, it wraps the REST API so that tools like Claude Desktop and Claude Code can manage contacts and track engagement through natural language.
Requires authentication. The MCP server connects to the API using a Sanctum bearer token. You'll need a running instance of the application and a valid API token.
Setup
1. Install dependencies
cd mcp-server && npm install
2. Generate an API token
php artisan app:generate-api-token
3. Configure your client
Add the server to your MCP client configuration. The server reads CONTACTS_API_TOKEN and CONTACTS_API_URL from the project's .env file automatically.
Claude Code (.mcp.json)
{
"mcpServers": {
"contacts": {
"command": "node",
"args": ["mcp-server/index.js"]
}
}
}
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"indigo-nebula-contacts": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/index.js"],
"env": {
"CONTACTS_API_TOKEN": "your-token-here",
"CONTACTS_API_URL": "http://localhost:8000"
}
}
}
}
Remote Access
Claude.ai web and Claude Mobile via Streamable HTTP
The remote server exposes all 48 tools over HTTPS using the Streamable HTTP transport, enabling access from Claude.ai web and Claude Mobile without any local setup.
Private CRM data. This endpoint connects directly to the campaign CRM. The Sanctum bearer token is server-side only and never visible to clients, but the endpoint is publicly reachable. Consider restricting to Anthropic IP ranges if needed.
Connect from Claude.ai
- Go to claude.ai → Settings → Connectors
- Click Add Custom Connector
- Enter the URL:
https://ryangrissinger.com/mcp - Save — tools will appear in your next conversation
Claude Mobile syncs automatically once the connector is saved via the web interface.
Health check
curl https://ryangrissinger.com/mcp/health
Deployment
The remote server runs as a pm2 process on the same server as the Laravel app, proxied through Nginx.
# Start (first time)
pm2 start mcp-server/remote.js --name mcp-remote
# Check status
pm2 status mcp-remote
# View logs
pm2 logs mcp-remote
Env vars required: CONTACTS_API_TOKEN, CONTACTS_API_URL, and optionally MCP_REMOTE_PORT (default 3100).
Nginx proxy block
location /mcp {
proxy_pass http://127.0.0.1:3100/mcp;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding on;
}
Tools
48 tools across 12 resource groups
Contacts
9 toolslist_contacts
List all contacts with pagination
search_contacts
Search by name, email, or notes
get_contact
Get full details including related data
add_contact
Create a new contact
update_contact
Update an existing contact
delete_contact
Soft-delete a contact
restore_contact
Restore a soft-deleted contact
export_contacts
Export all contacts as CSV
import_contacts
Import contacts from CSV content
Roles
3 toolsvolunteer, donor, door_knocker, phone_banker, event_host, sign_location, endorser, advisor, committee_member, precinct_captain
list_contact_roles
List roles for a contact
add_contact_role
Add a role to a contact
remove_contact_role
Remove a role from a contact
Skills
3 toolssocial_media, graphic_design, web_development, writing, public_speaking, fundraising, event_planning, data_entry, canvassing, legal, accounting, photography, videography, translation
list_contact_skills
List skills for a contact
add_contact_skill
Add a skill to a contact
remove_contact_skill
Remove a skill from a contact
Interactions
5 toolsdoor_knock, phone_call, text_message, email, event, meeting, social_media, mail, other
list_interactions
List interactions for a contact
add_interaction
Log a new interaction
get_interaction
Get interaction details
update_interaction
Update an interaction
delete_interaction
Delete an interaction
Donations
5 toolscash, check, credit_card, online, in_kind, other
list_donations
List donations for a contact
add_donation
Record a new donation
get_donation
Get donation details
update_donation
Update a donation
delete_donation
Delete a donation
Yard Signs
5 toolsrequested, placed, removed, damaged, stolen, returned
list_yard_signs
List yard signs for a contact
add_yard_sign
Request or place a yard sign
get_yard_sign
Get yard sign details
update_yard_sign
Update yard sign status
delete_yard_sign
Delete a yard sign
Donor Ask Statuses
5 toolsnot_asked, planned, asked, pledged, donated, declined
list_donor_ask_statuses
List ask statuses for a contact
add_donor_ask_status
Create a donor ask record
get_donor_ask_status
Get ask status details
update_donor_ask_status
Update ask status
delete_donor_ask_status
Delete an ask status
Activity Logs
3 toolslist_activity_logs
List activity logs for a contact
add_activity_log
Add an activity log entry
get_activity_log
Get activity log details
Intelligence Profile
1 toolLong-form markdown intelligence profile attached 1:1 to a contact (background, relationships, motivations).
set_contact_profile
Create or update a contact intelligence profile
Donor Research
1 toolRuns the FEC OpenFEC API search for a contact, computes partisan lean and giving capacity, writes findings back to the contact and the activity log.
research_contact_finances
FEC search + analysis + write-back
Journal
5 toolsCampaign knowledge base. Entries support project grouping, contact linking, and community tagging.
list_journal_entries
List journal entries (filterable)
get_journal_entry
Get a journal entry with linked contacts
add_journal_entry
Create a journal entry
update_journal_entry
Update a journal entry
delete_journal_entry
Delete a journal entry
Fundraising
3 tools1:1 fundraising profile per contact. Tier (1/2/3/not_now) is auto-derived from donor_grade and giving_capacity unless tier_manual_override is set. Ask cycle: planned, asked_1, asked_2, asked_3, committed, received, declined, recurring.
set_fundraising_profile
Create or update a fundraising profile
get_fundraising_profile
Read a fundraising profile
list_fundraising_profiles
List profiles with filters
Architecture
@modelcontextprotocol/sdkstdio — Claude Desktop and Claude Code (local process)
Streamable HTTP — Claude.ai web and Claude Mobile (remote HTTPS)
mcp-server/index.js — stdio entry point
mcp-server/remote.js — HTTP entry point
mcp-server/tools.js — shared tool definitions and handlers