Connect EveryAction to ChatGPT: Manage Donor Data and Field Lists
Learn how to connect EveryAction to ChatGPT using a managed MCP server. Automate donor lookups, contribution tracking, and field organizing tasks.
If you need to connect EveryAction to ChatGPT to automate donor research, triage contributions, or manage field organizing data, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between ChatGPT's native tool calls and EveryAction's REST API. You can either spend engineering cycles building, securing, and maintaining this infrastructure yourself, or you can use a managed integration layer to dynamically generate a secure MCP server URL. (If your team uses Claude, check out our guide on connecting EveryAction to Claude or for broader integrations, connecting EveryAction to AI Agents).
Giving a Large Language Model (LLM) read and write access to a sprawling political and nonprofit CRM like EveryAction is an engineering challenge. You have to handle unique identifier constraints, complex bulk import operations, and strict rate limits. Every time NGP VAN updates an endpoint or deprecates a field, you have to update your server code.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for EveryAction, connect it natively to ChatGPT, and execute complex workflows using natural language.
The Engineering Reality of the EveryAction API
A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools via JSON-RPC 2.0, the reality of implementing it against EveryAction's API is painful. You aren't just doing generic CRUD operations - you are navigating a highly specific data model built for political campaigns and nonprofits.
If you decide to build a custom MCP server for EveryAction, you own the entire API lifecycle. Here are the specific integration challenges that break standard assumptions:
The VAN ID and Activist Code Labyrinth
EveryAction revolves around the vanId. When an LLM wants to look up a person, it cannot just search by name and expect a flat record. Searching requires passing specific match candidates, and providing a valid vanId overrides all other search criteria. Furthermore, tags like "Activist Codes" do not always use standard integer IDs; they often require specific VAN encoded identifiers (e.g., EID28CG). If your MCP server schemas do not explicitly guide the LLM on how to format these IDs, the model will hallucinate invalid payloads.
Zipped Bulk Import Constraints
You cannot dump 10,000 JSON records into a standard POST request when dealing with EveryAction bulk data. Creating a file-loading job requires the data to be formatted as a zipped CSV. That zip file must be no larger than 20MB, and the source URL must use SFTP, FTPS, or HTTPS. For an LLM to execute a bulk update, your MCP server must handle the staging of this file to an external location, and simply pass the URL to the EveryAction API.
Rate Limits and 429 Passthrough
EveryAction enforces strict API rate limits to prevent database degradation. When a limit is hit, the API returns a 429 Too Many Requests error. Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream EveryAction API returns a 429, Truto passes that error directly to the caller (your AI agent).
However, Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. It is entirely the responsibility of the calling agent framework to inspect these headers, apply exponential backoff, and retry the request.
Generating the EveryAction MCP Server
Instead of hardcoding tool definitions, Truto generates MCP tools dynamically. When you connect an EveryAction account, Truto parses the integration's resource definitions and documentation records. If an endpoint has a documentation record, it becomes an AI tool. This acts as a strict quality gate ensuring only well-described endpoints are exposed to the LLM.
Each MCP server is scoped to a single integrated account. You can create this server via the Truto UI or programmatically via the API.
Method 1: Via the Truto UI
For ad-hoc usage or internal operations teams, you can generate an MCP server directly from the dashboard.
- Navigate to the Integrated Accounts page in your Truto dashboard.
- Select your connected EveryAction instance.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Select your desired configuration (e.g., filtering to only allow
readmethods, or scoping to specific tags likedonors). - Copy the generated MCP server URL (e.g.,
https://api.truto.one/mcp/a1b2c3d4e5f6...).
Method 2: Via the API
For platform engineers embedding this capability into their own products, you can generate the MCP server programmatically. The API validates the configuration, generates a secure token using an HMAC signing key, stores it in distributed KV, and returns the endpoint.
curl -X POST https://api.truto.one/integrated-account/YOUR_ACCOUNT_ID/mcp \
-H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "EveryAction Field Ops Agent",
"config": {
"methods": ["read", "write"],
"tags": ["field", "voters"]
}
}'The response contains the secure URL you will provide to ChatGPT:
{
"id": "mcp_abc123",
"name": "EveryAction Field Ops Agent",
"config": { "methods": ["read", "write"], "tags": ["field", "voters"] },
"expires_at": null,
"url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}Connecting the MCP Server to ChatGPT
Once you have the Truto MCP URL, connecting it to ChatGPT takes seconds. The URL contains a cryptographic token that securely authenticates requests to that specific EveryAction tenant. No additional OAuth flows or client-side configuration are required.
Method A: Via the ChatGPT UI
If you are using ChatGPT Plus, Team, or Enterprise, you can add custom connectors directly in the interface.
- In ChatGPT, navigate to Settings -> Apps -> Advanced settings.
- Enable the Developer mode toggle.
- Under MCP servers / Custom connectors, click add new.
- Enter a name (e.g., "EveryAction Connector").
- Paste the Truto MCP URL into the Server URL field.
- Click Save.
ChatGPT will immediately perform the MCP initialization handshake, fetching the JSON schemas for all available EveryAction tools.
Method B: Via Manual Config File
If you are running a custom client or using the Claude Desktop application as an alternative testing ground, you can configure the server manually using standard Server-Sent Events (SSE) transport.
{
"mcpServers": {
"everyaction_truto": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"--url",
"https://api.truto.one/mcp/a1b2c3d4e5f6..."
]
}
}
}sequenceDiagram
participant ChatGPT as ChatGPT
participant TrutoMCP as Truto MCP Router
participant KV as Cloudflare KV
participant Proxy as Truto Proxy API
participant Upstream as Upstream API (EveryAction)
ChatGPT->>TrutoMCP: POST /mcp/:token (tools/call)
TrutoMCP->>KV: Hash token & validate expiry
KV-->>TrutoMCP: Token valid
TrutoMCP->>TrutoMCP: Parse flat args against JSON schemas
TrutoMCP->>Proxy: Execute API Request
Proxy->>Upstream: Authenticated Request to EveryAction
Upstream-->>Proxy: JSON Response
Proxy-->>TrutoMCP: Standardized Result
TrutoMCP-->>ChatGPT: JSON-RPC 2.0 Success ResponseSecurity and Access Control
Exposing an enterprise CRM to an autonomous model requires strict access controls. Truto's MCP servers provide granular governance parameters at creation time:
- Method Filtering: Restrict an MCP server to only perform specific operations. Setting
config.methods: ["read"]ensures the LLM can only query data (e.g.,list,get), completely neutralizing the risk of accidental data deletion or modification. - Tag Filtering: Scope the available tools to a specific business domain. Setting
config.tags: ["fundraising"]ensures the agent only sees endpoints related to contributions, hiding activist codes and worksite data. - Require API Token Auth: Setting
require_api_token_auth: trueforces a secondary authentication layer. Knowing the MCP URL is no longer enough; the caller must also inject a valid Truto API token as a Bearer header. - Auto-Expiration: Setting an
expires_atISO datetime ensures temporary access. Cloudflare KV automatically drops the token at expiration, and a Durable Object alarm cleans up the database record, preventing stale endpoints.
EveryAction Hero Tools
When the MCP server initializes, it exposes EveryAction's resources as descriptive, snake_case tools. Here are six high-leverage tools available for your AI agents.
every_action_people_search
Search for a person in EveryAction using specific match candidates like name, date of birth, phone, or email. If the user possesses the specific vanId, it overrides all other criteria for a direct lookup.
"Search EveryAction for a contact named 'Jane Doe' residing in 'Chicago' and retrieve their vanId and custom properties."
list_all_every_action_contributions
Retrieve a list of recent contributions filtered by the donor's vanId. It returns critical fields like the amount, amount refunded, cycle, and source code static paths.
"Pull the complete contribution history for the vanId 100455. Summarize the total amount given in the 2024 cycle."
create_a_every_action_commitment
Create a Recurring Commitment record in EveryAction and process the first installment contribution. Requires the target contact, gateway ID, designation, and an amount between $0.01 and $999,999.99.
"Set up a new recurring monthly commitment for vanId 88392 for $50.00, starting today, using the default gateway ID."
get_single_every_action_activist_code_by_id
Retrieve specific metadata about an Activist Code in EveryAction. Crucially, the ID parameter accepts either standard integers or VAN-encoded identifiers (like EID28CG).
"Look up the activist code EID28CG and tell me the short name, description, and whether the status is currently Active."
list_all_every_action_minivan_exports
List all available MiniVAN Exports in EveryAction. This provides insight into currently generated field canvassing lists, who created them, and the database mode they target.
"List all active MiniVAN exports created this week and summarize the number of canvassers assigned to each."
create_a_every_action_file_loading_job
Create a bulk import job by providing a URL to a zipped, delimited file. This tool supports creating or updating Contacts, Contributions, and ActivistCodes en masse.
"Initiate a file loading job for AV/EV Data using the zipped CSV located at 'https://secure-bucket.example.com/voters.zip'. Apply the 'Score Load' action."
To view the complete schemas, query parameters, and required fields for all available operations, visit the EveryAction integration page.
Workflows in Action
By chaining these tools together, ChatGPT can execute complex, multi-step operations that would traditionally require an analyst clicking through the EveryAction UI for hours.
Workflow 1: Major Donor Briefing Generator
Development directors need comprehensive briefs before calling major donors. An AI agent can compile this instantly.
"Find the donor profile for 'Robert Sterling' in New York. Pull his complete contribution history, identify any active recurring commitments, and summarize his giving patterns over the last three cycles."
every_action_people_search: The agent searches for "Robert Sterling" with the location filter to extract his uniquevanId.list_all_every_action_contributions: Using the retrievedvanId, the agent fetches all past donations.list_all_every_action_commitments: (Assuming a list commitments tool is available) The agent checks for active recurring pledges under thatvanId.- Synthesis: ChatGPT computes total giving, identifies the preferred source codes (e.g., direct mail vs. online), and outputs a clean, markdown-formatted briefing document.
Workflow 2: Field Organizing Turf Assignment Setup
Field directors frequently need to verify volunteer data and prep turf assignments for weekend canvasses.
"Check if volunteer 'Sarah Jenkins' is tagged with the 'Experienced Canvasser' activist code (EID45XA). If she is, find the latest MiniVAN export for 'District 4' and summarize the list size."
every_action_people_search: The agent locates Sarah Jenkins to get hervanId.get_single_every_action_activist_code_by_id: The agent queriesEID45XAto verify the tag exists and is active.every_action_people_activist_codes: (Conceptual step) The agent verifies if Sarah has the tag applied.list_all_every_action_minivan_exports: The agent searches recent exports for "District 4", retrieving thelistSizeand database mode to report back to the field director.
The Strategic Advantage of Managed Infra
Building a custom integration layer for EveryAction requires deep knowledge of NGP VAN's architecture. Your engineering team has to build custom rate limiting logic to catch 429 errors, handle the labyrinth of VAN IDs, and maintain complex JSON schemas for every endpoint. When EveryAction updates their data model, your custom server breaks, and your AI agent hallucinates.
Using a managed MCP layer offloads this operational burden. The tool definitions are derived directly from the API documentation. The routing, pagination injection, and IETF-standard rate limit header normalizations are handled at the infrastructure level. Your team simply generates the URL, passes it to the agent, and focuses on designing better prompts and workflows.
FAQ
- How does Truto handle EveryAction rate limits?
- Truto does not automatically retry or throttle rate-limited requests. It passes the HTTP 429 error directly to the caller, normalizing the upstream rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your AI agent must implement its own exponential backoff logic.
- Can I filter which EveryAction tools ChatGPT can access?
- Yes. When generating the MCP server, you can pass a configuration object restricting tools by HTTP method (e.g., read, write) or by custom tags defined in the integration configuration.
- How do I provide ChatGPT access to bulk data in EveryAction?
- EveryAction requires bulk imports to be formatted as zipped CSVs hosted on an external URL (SFTP/HTTPS). You instruct ChatGPT to use the create_a_every_action_file_loading_job tool, passing the external URL containing your prepared data payload.