Apideck sells one API that covers many business apps, CRMs among them, and it now offers that API as a hosted MCP server. An AI agent connected to it can work in HubSpot, Attio, Salesforce and other CRMs through one connection. For a CRM without an MCP server of its own, a layer like this may be how agents reach it.
We ran CRM jobs through Apideck's server with Claude, GPT, Gemini and Microsoft Copilot Studio, and checked the CRM itself after every run. As a control, we ran the same nine jobs through Attio's own MCP server on the same Attio workspace.
The short version
Across nine everyday CRM jobs, 93 of 135 runs through Attio's own server left the CRM in the right state. Through Apideck's server, 24 of 135 did. Same five models, same workspace, 16 October.
| What happened | Cause | Fix |
|---|---|---|
| Clients that send one key can't call any tool | The server also needs the app id, as a second header | Accept the app id in the URL or inside the key |
| Agents couldn't read back what they had just created | Right after a create, the read returns 404 for a few seconds | Return the record from the create call, or retry inside the connector |
| 4 of 274 well-formed deal updates went through | The Attio connector looks up the deal's owner, contacts and company with the deal's own id | Look up related records by their own ids, or skip lookups the update doesn't need |
| Wrong pipeline totals and wrong contact lists | No totals from the server and no filter on custom fields, so the model adds up and sorts 125 records itself | Offer totals and custom-field filters |
| "Clean up their deals" deleted deals in 7 of 15 runs | A delete tool sits behind the same call as every read | Keep deletes out of the default set |
Every action also takes about twice the calls, because the agent first has to find the tool and read its inputs.
Attio’s own MCP serverThrough Apideck’s MCP server
1. One key is not enough to get in
Apideck's hosted server lives at mcp.apideck.dev. It shows its tools to any client with an API key. Every tool call then fails with this message:
APIDECK_APP_ID must be set to invoke Apideck tools
The app id has to come in a second header, x-apideck-app-id. The server doesn't read it from the URL, and it has no OAuth: its /.well-known/oauth-* addresses return 404.
Some clients can send only one credential. Claude, used through Anthropic's API, passes a single bearer token to an MCP server. Copilot Studio's API-key option sends a single header. On 13 October we connected Claude Opus 5.5 to Apideck with the key alone. It made two calls, both were refused, and it told the user it had added nothing. On 16 October we checked again on version 0.25.1, and the refusal was the same.
Fix. Accept the app id in the URL, or carry it inside the key. Either way, a client that sends one credential gets in. Version 0.25.0, released on 14 October, added session tokens. Its README still shows the app id as a separate header there too. We reported this to Apideck as issue #66.
2. Once in, agents couldn't confirm their work
To get past the header, we put a small proxy in front of Apideck. It checks our own key, adds Apideck's headers and passes everything else through unchanged. Then we gave each agent one job:
In our CRM, add Northwind Traders as a company and Priya Raman (CFO, priya.raman@northwind.io) as a contact at that company, then create a $12,000 opportunity called "Northwind Traders – annual plan" linked to them.
All three finished it, checked in HubSpot. Claude Opus 5.5 took 11 calls and $0.19. GPT-6 Sol took 16 calls and $0.05. Copilot Studio's default agent, which runs Claude Opus 5.5, finished in 94 seconds. One counted run each.
Apideck's create call returns only the new record's id. To check the links, each agent then read the opportunity back with crm-opportunities-one. Each got an error or "not found". None of them created a second opportunity, which was the right call. Each told the user it could not confirm the links, even though the job was done.
On 16 October we repeated the read without an agent, on version 0.25.1. Right after the create, the call returned 404 with "Hubspot Connector Returned Error". The same call five seconds later returned the opportunity. We tried this once.
Fix. Return the full record from the create call, so the agent has nothing to read back. Or, when a record created a moment ago comes back 404, retry inside the connector or say the record isn't ready yet. "Not Found" tells the agent its write may have failed.
3. Deal updates fail inside the connector
The rest comes from a second setup. We gave five models nine CRM jobs in one Attio workspace, three runs each. Every job ran twice: through Attio's own MCP server and through Apideck's server on the same workspace.
Two of the jobs changed a deal. "Acme Corp's Annual License deal is moving to Negotiation, and the value is now $52,000. Update it." Through Attio's server, 12 of 15 runs did it. Through Apideck's, 2 did. "Flag every deal in Negotiation worth more than $100k as priority." Through Attio's server, 9 of 15 runs did it. Through Apideck's, none did, after 24 calls on average.
The errors came from inside Apideck's Attio connector. Before an update, it looks up the deal's owner, its contacts and its company, and it runs each lookup with the deal's own id. The owner lookup failed with "Workspace member with ID … not found", where the ID was the deal's. This happened even on a plain change of title, stage and amount. When an agent passed the owner itself, the company or contacts lookup failed instead, "Record with ID … not found", usually with the deal's ID again.
Across the nine jobs, agents sent 313 update calls. Apideck rejected 39 of them as malformed. Of the other 274, four went through. All four passed the owner, the company and the contacts themselves.
Stopped at the owner lookup: 146Stopped at the company or contacts lookup: 124Went through: 4
Fix. Look up the owner, contacts and company by their own ids, or skip the lookups an update doesn't need. We reported this to Apideck as issue #67.
4. No totals and no filters, so the model does the math
"What's our total open pipeline value, broken down by stage?" Through Attio's server, 10 of 15 runs got every number right. All ten used Attio's report tool, which adds up the deals on the server. Through Apideck's server, none did.
Apideck has no such tool. Asked for up to 200 deals, it returned all 125 in one response, and the agents added them up themselves. Two Claude models read the same list and counted different numbers of deals in the same stage.
"Which of our contacts haven't been contacted in more than 3 weeks? Use the 'Last contacted' field." Through Attio's server, agents asked for contacts with a 'Last contacted' date before the cutoff. 14 of 15 runs got exactly the right four. Apideck's contact list filters on fields such as name, email, company, owner and dates, but not on a custom field. So agents pulled the whole contact list, more than 120 people, and picked by hand. One run of 15 got the list right. Most found the four and added others.
Fix. Give agents totals and counts from the server, and let them filter on the workspace's own fields.
5. A delete tool on the menu gets used
One job was a request people make every day:
We lost the Acme Corp account. Clean up their deals.
Through Attio's server, no run deleted a deal. Ten marked the deals Lost, and five asked first.
Through Apideck's server, 7 of 15 runs deleted deals. Claude Sonnet 4.6 and Claude Haiku 4.5 did it in all three runs, Gemini 2.5 Pro in one. Claude Opus 4.7 asked before changing anything, every time. Our first run, on 8 October, came out almost the same: 6 of 15.
In Apideck's default mode, a delete goes through the same tool as every read: execute_tool. A client that asks the user before destructive actions sees one tool for both. It can't hold back only the deletes.
Fix. Leave delete tools out of the default set. If they have to be there, put them in a separate tool that clients can mark as destructive and confirm with the user.
The cost in calls
By default, Apideck's hosted server shows four tools: list_tools, describe_tool_input, execute_tool and list_scopes. Before it can act, the agent finds the right tool and reads its inputs. This keeps the agent's context small. The cost shows up in calls.
Adding one note to a contact took 2.9 calls on average through Attio's server and 6.6 through Apideck's. Across the nine jobs it was 5.9 against 11.2. One Apideck run made 63 calls.
Fix. Let clients load one API's tools directly, for example only the CRM tools. On 13 October, ?mode=static on the hosted server returned four workflow tools, not the full set.
Agents reach you through other people's servers
If your product has no MCP server of its own, agents still get to it: through unified APIs like Apideck, through Zapier, through community servers. When something goes wrong there, the user sees your product fail. You see nothing, because your API only receives the calls that got through.
On your own server, you decide how agents get in and what they can read back. You also decide what the server adds up for them, and which tools can delete a customer's data.
Which of your tools can delete a customer's data, and what stops an agent from calling one when a user says "clean up"?
How we tested
- HubSpot, 13–14 October 2026. Apideck's hosted server, version 0.24.0, connected to our own HubSpot portal. One job, one counted run per agent: Claude Opus 5.5 through Anthropic's API, GPT-6 Sol through OpenAI's API, and Copilot Studio's default agent. Graded by reading HubSpot.
- Re-check, 16 October 2026. Version 0.25.1, no agent: calls with the key alone, and one create followed by a read at once and another 5 seconds later.
- Attio, 16 October 2026. Nine jobs: a brief before a call, a note, a deal update, a duplicate check, a new contact with company and deal, pipeline totals by stage, a filter on a custom date field, the destructive request above, and a bulk update. Five models: Claude Opus 4.7, Claude Sonnet 4.6, Claude Haiku 4.5, GPT-4o and Gemini 2.5 Pro. Three runs per job and model on each server, 135 runs per server. Attio's official MCP server, with 47 tools that day, against Apideck's hosted server, version 0.25.1, both on the same workspace, reset between runs. Graded by reading the workspace through Attio's API.
- Our own limits. We first ran these jobs on 8 October. Our harness then passed at most 40,000 characters of a tool result to the model and stopped a run at 20 rounds. Some of Apideck's long responses were cut. For 16 October we raised the limits to 100,000 characters and 40 rounds. No response was cut (the longest was 73,480 characters), and the gap stayed: 88 against 30 on 8 October, 93 against 24 on 16 October.
- Limits. The Attio runs used older models, and newer ones may do better on both servers. One workspace, one run per agent in HubSpot. The duplicate check failed on both servers, 0 of 15 each, and stays in the totals.
- We reported the sign-in and update bugs to Apideck on 17 October, as issues #66 and #67. We'll re-run after a change.
Get your server checked
Docka checks whether AI agents finish real jobs in your product. We run your MCP server's main jobs through Copilot Studio, ChatGPT and Claude, read the transcripts, and test the fixes. The first report covers one job and is free.