Debug how your agent reads every tool
Mockd captures the full conversation between your agent and its tools. Inspect each call, replay the session, and find exactly where the model misreads a tool — before it ever touches production.
crm.notes.createCreates a note and attaches it to one or more CRM records.
From the tool catalog — what the agent read.
crm.notes.create with 2 values:bodystringrequiredText content of the note.
associationsarrayoptionalIDs of the records the note is attached to.
Exactly the data the agent sent (JSON)
{
"body": "Logged Q3 expansion deal from agent.",
"associations": ["deal_9981"]
}Rate limited — injected on purpose by the Mockd scenario „429 burst". Your agent waited 250 ms and the retry came back with 201 — from the mock, not the real tool.
{
"error": "RATE_LIMITED",
"message": "Too many requests. Injected by Mockd scenario 'burst'.",
"retryAfterMs": 250
}crm.contacts.searchquery: "acme"200142mscrm.contacts.searchok · 200started 12:04:01.221 · took 142 ms · 3 fieldsFull-text search across CRM contacts; returns matching records.
From the tool catalog — what the agent read.
Agent inputrequired 1/1 · 0 unknownI'm callingcrm.contacts.searchwith 3 values:querystringrequiredSearch term — e.g. a company name or email address.
"acme"propertiesarrayoptionalWhich contact fields to include in the result.
emailcompanylifecyclestagelimitnumberoptionalMaximum number of matches.
10Exactly the data the agent sent (JSON)
{ "query": "acme", "properties": ["email", "company", "lifecyclestage"], "limit": 10 }200 okServer responsewhat the tool returned{ "total": 2, "results": [ { "id": "5512", "company": "Acme Inc.", "email": "ops@acme.io" }, { "id": "5513", "company": "Acme Labs", "email": "hi@acmelabs.dev" } ] }crm.contacts.getid: 551220088mscrm.contacts.getok · 200started 12:04:01.402 · took 88 ms · 2 fieldsLoads a single contact by its unique ID.
From the tool catalog — what the agent read.
Agent inputrequired 1/1 · 0 unknownI'm callingcrm.contacts.getwith 2 values:contactIdstringrequiredUnique ID of the contact.
"5512"propertiesarrayoptionalWhich fields to load.
emailcompanyownerlifecyclestageExactly the data the agent sent (JSON)
{ "contactId": "5512", "properties": ["email", "company", "owner", "lifecyclestage"] }200 okServer responsewhat the tool returned{ "id": "5512", "company": "Acme Inc.", "email": "ops@acme.io", "owner": "rep_42", "lifecyclestage": "opportunity" }crm.deals.createname: "Acme – Q3 Expansion"201196mscrm.deals.createok · 201started 12:04:01.690 · took 196 ms · 4 fieldsCreates a new deal in the CRM pipeline.
From the tool catalog — what the agent read.
Agent inputrequired 1/1 · 0 unknownI'm callingcrm.deals.createwith 4 values:dealnamestringrequiredDisplay name of the deal.
"Acme – Q3 Expansion"amountnumberoptionalDeal value in the account's currency.
48000pipelinestringoptionalID of the pipeline the deal sits in.
"default"dealstagestringoptionalCurrent stage in the sales process.
"qualifiedtobuy"Exactly the data the agent sent (JSON)
{ "dealname": "Acme – Q3 Expansion", "amount": 48000, "pipeline": "default", "dealstage": "qualifiedtobuy" }201 okServer responsewhat the tool returned{ "id": "deal_9981", "dealname": "Acme – Q3 Expansion", "amount": 48000, "createdAt": "2026-06-19T12:04:01Z" }crm.associations.createdeal_9981 ↔ 551220074mscrm.associations.createok · 200started 12:04:01.871 · took 74 ms · 3 fieldsLinks two CRM records together, e.g. a deal with a contact.
From the tool catalog — what the agent read.
Agent inputrequired 3/3 · 0 unknownI'm callingcrm.associations.createwith 3 values:fromobjectrequiredRecord the association starts from — type (e.g. "deal") and id.
{object with 2 fieldstype:"deal"id:"deal_9981"}toobjectrequiredRecord being linked to — also type and id.
{object with 2 fieldstype:"contact"id:"5512"}associationTypestringrequiredType of link (e.g. deal_to_contact).
"deal_to_contact"Exactly the data the agent sent (JSON)
{ "from": { "type": "deal", "id": "deal_9981" }, "to": { "type": "contact", "id": "5512" }, "associationType": "deal_to_contact" }200 okServer responsewhat the tool returned{ "status": "ASSOCIATED", "from": "deal_9981", "to": "5512" }crm.notes.createinjectedrate limit — injected42931mscrm.notes.create429 errorinjected: 429 burststarted 12:04:02.005 · took 31 ms · 2 fieldsCreates a note and attaches it to one or more CRM records.
From the tool catalog — what the agent read.
Agent inputrequired 1/1 · 0 unknownI'm callingcrm.notes.createwith 2 values:bodystringrequiredText content of the note.
"Logged Q3 expansion deal from agent."associationsarrayoptionalIDs of the records the note is attached to.
deal_9981Exactly the data the agent sent (JSON)
{ "body": "Logged Q3 expansion deal from agent.", "associations": ["deal_9981"] }429 errorServer responsewhat the tool returnedRate limited — injected on purpose by the Mockd scenario „429 burst". Your agent waited 250 ms and the retry came back with 201 — from the mock, not the real tool.
{ "error": "RATE_LIMITED", "message": "Too many requests. Injected by Mockd scenario 'burst'.", "retryAfterMs": 250 }crm.notes.create↻ retry okretried after 250ms backoff201110mscrm.notes.createok · 201started 12:04:02.379 · took 110 ms · 2 fieldsCreates a note and attaches it to one or more CRM records.
From the tool catalog — what the agent read.
Agent inputrequired 1/1 · 0 unknownI'm callingcrm.notes.createwith 2 values:bodystringrequiredText content of the note.
"Logged Q3 expansion deal from agent."associationsarrayoptionalIDs of the records the note is attached to.
deal_9981Exactly the data the agent sent (JSON)
{ "body": "Logged Q3 expansion deal from agent.", "associations": ["deal_9981"] }201 okServer responsewhat the tool returned{ "id": "note_4471", "createdAt": "2026-06-19T12:04:02Z" }
Everything captured, for every call
Each tool call your agent makes is recorded in full — so you see not just what happened, but why.
crm.deals.createdealname: "Acme – Q3" amount: 48000 pipeline: "default"
Tool & arguments
The exact tool the model picked and the arguments it filled in.
id: "deal_9981" amount: 48000 createdAt: "…01Z"
Response
The synthetic payload Mockd returned — shaped like the real thing.
Latency & status
How long the call took, and whether it succeeded, failed or was throttled.
Injected scenario
Whether the response was forced by a scenario — a 429, a timeout, an empty set.
From config to first trace in under five minutes
No SDK to install, no code to change. Mockd looks exactly like a real MCP server to your agent — it just answers with synthetic data and records everything.
Pick a mock
Choose a server from the catalog — start with HubSpot — or bring your own MCP. You get a ready-to-paste connection config.
- HubSpot24 tools
- Salesforce31 toolssoon
- Slack18 toolssoon
- Stripe27 toolssoon
- Notion15 toolssoon
Paste it into your agent
Drop the config into Claude, Cursor, the OpenAI Agents SDK or any MCP client. No code changes, no SDK to install.
{ "mcpServers": { "mockd": { "url": "https://mock-d.com/hubspot/mcp" } } }
Run your agent
Let it work. Every tool call is routed to the Mockd endpoint and answered with realistic, deterministic data.
crm.contacts.search200142mscrm.contacts.get20088mscrm.deals.create201196mscrm.associations.create20074ms
Watch, then tune
Inspect each call in the live trace viewer, spot where the model misreads a tool, and fix your system prompt until it's right.
crm.deals.createmisreadA control room for your agent's tools
The pieces that turn 'it seemed to work' into a tight, observable feedback loop.
Full-fidelity trace viewer
Every tool call captured with arguments, response, latency and status — a LangSmith-style timeline built for MCP.
crm.contacts.search142mscrm.deals.create196mscrm.notes.create429Error & latency injection
Flip a switch to return 429s, empty sets or slow responses and prove your agent recovers.
Latency you control
Simulate real-world response times to see how your agent paces itself.
Prompt diffing
Compare two system prompts across the same tool calls, side by side.
Stays in your sandbox
Nothing leaves to a third party. Mocked data is synthetic by design.
Bring your own MCP
Point Mockd at any custom MCP server. We render its tool descriptions, capture every call, and let you tune prompts against your own tools.
See your agent's first trace
Point your agent at a Mockd endpoint and watch every tool call land in real time.
Start testing — freecrm.contacts.search142mscrm.deals.create196mscrm.notes.create110ms