Connect DonorPerfect to ChatGPT: Manage Donors, Gifts, and Pledges
Learn how to connect DonorPerfect to ChatGPT using a managed MCP server. Automate donor research, gift entry, and custom SQL queries without writing integration code.
If you want to connect DonorPerfect to ChatGPT so your AI agents can log gifts, query donor history, update custom fields, and manage pledges, you need a Model Context Protocol (MCP) server. This server acts as the critical translation layer between ChatGPT's JSON-RPC tool calls and DonorPerfect's specialized database procedures.
If your team uses Claude, check out our guide on connecting DonorPerfect to Claude and connecting DonorPerfect to AI Agents.
Giving a Large Language Model (LLM) read and write access to an older, highly structured CRM like DonorPerfect is a steep engineering challenge. You either spend weeks building, hosting, and maintaining a custom MCP server to map LLM arguments to DonorPerfect's specific stored procedures, or you use a managed infrastructure layer.
This guide breaks down exactly how to use Truto to generate a secure, authenticated MCP server for DonorPerfect, connect it natively to ChatGPT, and execute complex fundraising workflows using natural language.
The Engineering Reality of the DonorPerfect 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, implementing it against DonorPerfect's API requires understanding its unique architectural quirks.
If you decide to build a custom MCP server for DonorPerfect, you own the entire API lifecycle. Here are the specific integration challenges that break standard REST assumptions when working with this platform:
Destructive Overwrites (The dp_savedonor Trap)
Unlike modern REST APIs that support PATCH for partial updates, DonorPerfect relies heavily on stored procedures like dp_savedonor and dp_savegift. These procedures expect the entire object payload. If you omit a field in your update request, DonorPerfect clears that data in the database. If an LLM attempts to update just a donor's phone number without fetching their existing data first, it will wipe out their address, email, and preferences. Your MCP implementation must forcefully guide the LLM to perform a read-modify-write pattern.
Segmented User Defined Fields (UDFs)
DonorPerfect does not return custom fields as a flat JSON dictionary on the donor or gift object. Instead, User Defined Fields (UDFs) live in separate tables (DPUDF, DPGIFTUDF, DPADDRESSUDF). Writing to them requires calling entirely separate XML-based stored procedures like dp_save_udf_xml. An LLM trying to "update the donor's custom major gift status" needs explicit tools and instructions to query the main record, find the matching_id, and then fire an XML procedure against the correct UDF table.
Custom SQL Execution as a Core Pattern
Because the standard endpoints return fixed sets of fields, fetching comprehensive data often requires executing raw read-only SQL via the API. DonorPerfect exposes this capability, but handing raw SQL execution to an LLM requires strict scoping and pagination logic (using OFFSET and FETCH NEXT). Building this safely into a custom MCP server is risky and time-consuming.
Rate Limits and Client Responsibility
DonorPerfect enforces strict rate limits. A critical factual note on how Truto handles this: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream API returns an HTTP 429, Truto passes that error directly back to the caller. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. The caller - your LLM framework or agent - is entirely responsible for detecting the 429 and implementing retry and backoff logic. Do not expect the MCP server to absorb these limits.
flowchart TD
A["ChatGPT (Client)"] -->|"JSON-RPC tools/call"| B["Truto MCP Server<br>(Managed)"]
B -->|"Normalized request"| C["Truto Proxy API"]
C -->|"Stored Procedure (e.g. dp_savegift)"| D["DonorPerfect API"]
D -->|"HTTP 429 Rate Limit"| C
C -->|"Standardized 429 Headers"| B
B -->|"Error response (isError: true)"| AHow to Generate a Secure DonorPerfect MCP Server
Instead of building custom middleware to handle these stored procedures, you can use Truto to dynamically generate a secure MCP server URL. Truto maps DonorPerfect's endpoints, SQL runners, and XML procedures into clean JSON-RPC tools instantly.
You first need to connect a DonorPerfect account. In the Truto dashboard, navigate to Integrated Accounts -> New Integrated Account, select DonorPerfect, and provide the API credentials. Truto securely vaults these credentials.
Once connected, you can generate the MCP server in two ways.
Method 1: Via the Truto UI
- Navigate to the Integrated Accounts page for your DonorPerfect connection.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Configure the server. You can optionally filter which tools the LLM can access by selecting specific methods (e.g., only
read) or specific tags (e.g.,donors,gifts). - Set an optional expiration date if this server should be temporary.
- Click Create and copy the generated MCP server URL (it will look like
https://api.truto.one/mcp/a1b2c3...). Treat this URL as a secret.
Method 2: Via the Truto API
For teams building automated agent infrastructure, you can provision MCP servers programmatically.
Make a POST request to /integrated-account/:id/mcp, using your Truto API token and the integrated_account_id of the connected DonorPerfect instance.
curl -X POST https://api.truto.one/integrated-account/$INTEGRATED_ACCOUNT_ID/mcp \
-H "Authorization: Bearer $TRUTO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "DonorPerfect Agent MCP",
"config": {
"methods": ["read", "write"],
"tags": ["donors", "gifts", "udfs"]
}
}'The response returns your dedicated, authenticated endpoint:
{
"id": "mcp_12345",
"name": "DonorPerfect Agent MCP",
"config": {
"methods": ["read", "write"],
"tags": ["donors", "gifts", "udfs"]
},
"expires_at": null,
"url": "https://api.truto.one/mcp/a1b2c3d4e5f6g7h8"
}How to Connect the MCP Server to ChatGPT
With your secure URL in hand, you can immediately expose the DonorPerfect tools to ChatGPT. There are two primary ways to do this, depending on your environment.
Method 1: Via the ChatGPT UI
If you are using ChatGPT Pro, Plus, Business, Enterprise, or Education accounts, you can add custom connectors directly in the browser.
- Open ChatGPT and navigate to Settings -> Apps -> Advanced settings.
- Ensure Developer mode is enabled.
- Under MCP servers / Custom connectors, click Add new server.
- Enter a descriptive name (e.g., "DonorPerfect CRM").
- Paste your Truto MCP URL into the Server URL field.
- Save the configuration. ChatGPT will immediately perform a handshake, call
tools/list, and make the DonorPerfect tools available in your chat sessions.
Method 2: Via Manual Configuration File (Local / CLI)
If you are running local AI agents, using desktop clients, or testing with the MCP Inspector, you can connect via the standard Server-Sent Events (SSE) transport wrapper provided by the MCP community.
Create an mcp-config.json file:
{
"mcpServers": {
"donorperfect": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"--url",
"https://api.truto.one/mcp/a1b2c3d4e5f6g7h8"
]
}
}
}Your local agent framework will use this wrapper to proxy standard internal MCP commands to Truto's remote JSON-RPC endpoint.
DonorPerfect Hero Tools for AI Agents
Truto dynamically generates tools based on the available DonorPerfect endpoints. Here are 6 high-leverage hero tools that unlock powerful fundraising workflows for your AI agents.
donor_perfect_donors_search
This tool executes the dp_donorsearch procedure. It acts exactly like the search screen in the DonorPerfect UI, supporting wildcards (%). It returns high-level summaries including donor_id, name, address, and gift_total for each match.
"Find the donor ID and giving history for a donor whose last name starts with 'Vander' and lives in New York."
get_single_donor_perfect_donor_by_id
Retrieves the complete donor record (name, address, phones, email, giving totals) from the DP table for a specific donor_id. This is a mandatory first step before updating any donor data due to DonorPerfect's overwrite behavior.
"Get the full constituent record for donor ID 10452 so we can review their current communication preferences."
create_a_donor_perfect_gift
Executes dp_savegift to log a new gift. It handles main gifts (record type G), soft credits (S), and pledge payments (where plink equals the parent pledge's gift ID).
"Log a new gift of $500 for donor ID 10452. Set the gift date to today and assign it to the 'Annual Fund' campaign."
update_a_donor_perfect_gift_by_id
Updates an existing gift using dp_savegift. Contextual note for agents: Every single field is overwritten. The agent must be instructed to fetch the gift first with get_single_donor_perfect_gift_by_id and send the complete payload back with modifications.
"Fetch gift ID 99201. Once you have the full record, update the GL code to 'Unrestricted' and send the entire payload back to save the changes."
create_a_donor_perfect_user_defined_field_value
Because UDFs are stored in separate tables, this tool executes the dp_save_udf_xml procedure to set a custom field value on a donor, gift, or contact record. The UDF field name must already exist in the system.
"Update the custom field 'MAJOR_PROSPECT_STATUS' to 'Qualified' for donor matching ID 10452."
donor_perfect_queries_execute
Allows the LLM to run read-only SQL SELECT statements directly against the DonorPerfect tables (e.g., DP, DPUDF, DPGIFT). Responses are capped at 500 rows per call, requiring OFFSET ... FETCH NEXT for pagination.
"Write and execute a SQL query against the DPGIFT table to find the top 5 largest donations made in the last 30 days."
For the complete inventory of DonorPerfect MCP tools and their detailed JSON schemas, view the DonorPerfect integration page.
Workflows in Action
Once connected, ChatGPT can orchestrate complex, multi-step DonorPerfect workflows that previously required custom Python scripts or manual data entry.
Scenario 1: Donor Research and Gift Entry
Development officers often receive checks with incomplete donor information and need to find the record, update custom metadata, and log the gift.
"I just received a $1,000 check from a 'Sarah Connor' in Los Angeles. Search for her in DonorPerfect. If she exists, fetch her full record, update her 'LAST_ENGAGEMENT' custom field to today's date, and log the $1,000 gift to the 'Capital Campaign'."
Step-by-step execution:
- The agent calls
donor_perfect_donors_searchpassing{ "last_name": "Connor%", "city": "Los Angeles" }to find thedonor_id. - The agent calls
get_single_donor_perfect_donor_by_idto verify it is the correct person. - The agent calls
create_a_donor_perfect_user_defined_field_valueto execute the XML procedure updating the custom field. - Finally, the agent calls
create_a_donor_perfect_giftpassing thedonor_id, amount, and campaign details.
Scenario 2: The Read-Modify-Write Update Trap
When a donor moves, their address must be updated. Because of the dp_savedonor overwrite behavior, the agent must carefully orchestrate the update.
"Donor ID 8472 moved. Change their street address to 123 Main St, Seattle, WA, but make absolutely sure you don't delete their phone numbers or email addresses in the process."
Step-by-step execution:
- The agent calls
get_single_donor_perfect_donor_by_idand stores the complete JSON representation of the donor in its context window. - The agent modifies the specific address keys in the JSON payload, leaving the phone and email arrays untouched.
- The agent calls
update_a_donor_perfect_donor_by_idwith the completely assembled, modified payload.
sequenceDiagram
participant Agent as AI Agent
participant MCP as Truto MCP
participant DP as DonorPerfect
Agent->>MCP: Call tools/get_single_donor_perfect_donor_by_id
MCP->>DP: Execute SELECT
DP-->>MCP: Full Donor Payload
MCP-->>Agent: Full Donor Payload
Note over Agent: Agent modifies ONLY<br>the address fields internally
Agent->>MCP: Call tools/update_a_donor_perfect_donor_by_id<br>(Sends ENTIRE payload)
MCP->>DP: Execute dp_savedonor
DP-->>MCP: Success
MCP-->>Agent: SuccessSecurity and Access Control
Exposing an enterprise CRM to an autonomous AI agent requires strict boundaries. Truto MCP servers support configuration parameters that limit what the agent can do.
- Method Filtering: By passing
"methods": ["read"]during server creation, you strip out allcreate,update, anddeletetools. The LLM can query gifts and donors but cannot modify the database. - Tag Filtering: By passing
"tags": ["gifts"], the MCP server will only generate tools associated with gift processing, hiding donor creation or system configuration tools. - Expiration: Set
expires_at(an ISO datetime) when creating the server. Truto schedules automated alarms that destroy the server credentials when the time expires - perfect for temporary contractor access or limited-scope agent runs. - API Token Auth: For shared environments, you can set
require_api_token_auth: true. The MCP client must pass a valid Truto API token in the Authorization header to connect, ensuring possession of the URL alone isn't enough to execute tools.
Stop wrangling legacy XML stored procedures and destructive update logic. By routing ChatGPT through a managed MCP server, your AI agents get safe, structured access to DonorPerfect immediately.
FAQ
- How do I prevent ChatGPT from overwriting existing donor data in DonorPerfect?
- DonorPerfect's update endpoints (like dp_savedonor) perform complete overwrites. You must instruct your LLM to always call the get_single_donor_perfect_donor_by_id tool first, merge its intended changes into the complete existing payload, and send the full object back in the update payload.
- How does Truto handle DonorPerfect API rate limits?
- Truto does not retry, throttle, or apply backoff on rate limit errors. It passes HTTP 429 errors directly to the caller, normalizing the rate limit data into standard headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. Your AI agent is responsible for retrying.
- Can ChatGPT execute custom SQL queries against DonorPerfect?
- Yes. Truto provides a specific MCP tool (donor_perfect_queries_execute) that allows AI agents to run read-only SQL SELECT statements directly against DonorPerfect tables like DP, DPGIFT, and DPCODES.
- How do I filter which DonorPerfect tools ChatGPT can access?
- When creating the MCP server via Truto, you can pass a configuration object with 'methods' (e.g., 'read' only) or 'tags' (e.g., 'donors', 'gifts') to strictly limit the operations exposed to the LLM.