DEV Community

Cover image for Your AI agent needs receipts, not vibes: tracing MCP workflows for small businesses
Stephen Phillips
Stephen Phillips

Posted on Edited on

Your AI agent needs receipts, not vibes: tracing MCP workflows for small businesses

A small-business AI agent is easy to demo and surprisingly hard to trust.

The demo looks clean: connect the agent to email, invoices, a CRM, maybe a few n8n workflows, then ask it to chase unpaid invoices or triage customer messages. It calls the right tools. It writes a neat summary. Everyone nods.

Then Monday happens.

A customer asks why they got the wrong follow-up. The owner wants to know whether the agent actually checked the CRM before it emailed them. The developer opens a log file and finds prompts, HTTP requests, half-useful timestamps, and no story.

That is the line between an AI automation toy and an AI automation system: can you reconstruct what happened after the agent did something real?

For HappyMonkey-style small-business automation, this is the next practical problem after “can the agent call tools?” MCP gives agents a standard way to connect to external systems. n8n and similar tools give teams a place to run repeatable processes. OpenTelemetry and simple receipt logs give you the missing paper trail.

MCP gives the agent hands

The Model Context Protocol is an open standard for connecting AI apps to external systems: local files, databases, tools, search, workflows, prompts. The docs use a USB-C metaphor. Fine. The useful part is the separation.

Instead of hardcoding every integration into the agent, you expose capabilities through MCP servers. The agent discovers a tool, calls it with structured inputs, and gets structured results back.

That matters because small-business stacks are messy. Accounting in one system. Leads from a website form. Bookings in a calendar. The owner still forwards important emails by hand. If every integration needs bespoke agent code, the project dies under maintenance.

MCP makes tool access more regular. It does not magically make the work safe. Once an agent can touch real systems, you need to know what it touched, why, how long it took, what it cost, and what came back.

Tool access without observability is just a more confident black box.

One practical pattern is a dynamic MCP gateway rather than a static pile of servers. We use DynamicMCPProxy for this: the IDE connects to one proxy, sends project/task context, and the proxy lazily activates relevant MCP servers while keeping the active tool count under control. That reduces tool soup. It also creates a control point for receipts: server activation, tool call, latency, and outcome can all pass through one place.

Workflows give the agent rails

This is where tools like n8n fit. AI workflow automation differs from classic app-to-app glue: the AI layer can interpret, decide, and generate, while the workflow layer still provides structure.

That split is useful. Let the agent decide which business action is needed, but put the actual action behind a workflow with retries, validation, credentials, and predictable side effects.

Examples:

  • lookup_customer_balance
  • send_payment_reminder_for_invoice
  • create_follow_up_task
  • summarize_new_leads_from_website
  • draft_wordpress_post_from_source_notes

Each can be an MCP-exposed tool or a workflow behind an MCP server. The agent chooses. The workflow executes.

After a failure, the question is not “did we use MCP?” It is “what exactly happened?”

If an invoice reminder went to the wrong person, you need a trace that answers boring questions quickly:

  • Which user request started this run?
  • Which model answered?
  • Which tools did it call?
  • What arguments did it pass?
  • Which workflow ran?
  • Did the workflow retry?
  • What did the external API return?
  • Did a human approve the final action?

The boring questions are the business-critical ones.

Traces beat giant logs

A normal application log says “this thing happened at this time.” Useful, but agent runs are nested. One request might include planning, retrieval, model calls, tool calls, workflow calls, retries, and a final response.

A trace gives you the tree.

OpenTelemetry is already the common language for tracing distributed systems. Its GenAI semantic conventions cover model requests, token usage, and related AI operations. Treat model calls and agent steps as first-class spans rather than random log lines.

The CNCF has also written about Jaeger evolving for AI-agent traces with OpenTelemetry. Agent observability is being pulled into the same operational world as services, queues, databases, and APIs.

For small-business automation you probably do not need a huge observability platform on day one. You do need the shape of the data to be right.

A practical trace might look like:

customer_email_triage run
  model.plan
  mcp.tool.search_customer_by_email
  mcp.tool.get_recent_orders
  workflow.n8n.create_support_ticket
  model.draft_reply
  human.approval.requested
  email.send
Enter fullscreen mode Exit fullscreen mode

Each span should carry just enough metadata:

span name: mcp.tool.get_recent_orders
customer_id: cust_123
workflow_run_id: n8n_456
latency_ms: 820
status: ok
records_returned: 3
Enter fullscreen mode Exit fullscreen mode

Do not log private customer content by default. Log IDs, counts, status, latency, cost, tool names, model names, and approval state. Keep sensitive payloads somewhere controlled, if you keep them at all.

That design choice matters. Teams choose local AI or self-hosted workflows for privacy, cost, or control. Observability should not undo that by spraying customer emails into a third-party logging account.

The minimum viable agent receipt

If you are building this for a client, start smaller than you think.

For every agent run, save a receipt with:

  1. Trigger — user message, cron, webhook, or inbound email
  2. Decision — short reason the agent chose a tool or workflow
  3. Tool calls — name, redacted args, status, duration
  4. Workflow calls — workflow ID, run ID, status, retry count
  5. Model usage — model name, latency, token count or local runtime estimate
  6. Human gate — approved, edited, or blocked
  7. Outcome — what changed in the real world

A JSON file is enough at first. OpenTelemetry spans can come later. Design as if someone will ask “why did the agent do that?” because someone will.

{
  "run_id": "run_2026_07_04_001",
  "trigger": "inbound_customer_email",
  "agent": "support_triage_agent",
  "model": "local-llm-via-ollama",
  "tool_calls": [
    {
      "name": "mcp.tool.search_customer_by_email",
      "status": "ok",
      "duration_ms": 210,
      "redacted_args": { "email_hash": "..." }
    }
  ],
  "workflow_calls": [
    {
      "name": "n8n.create_support_ticket",
      "run_id": "n8n_456",
      "status": "ok"
    }
  ],
  "human_approval": "required_before_send",
  "outcome": "drafted_reply_and_created_ticket"
}
Enter fullscreen mode Exit fullscreen mode

Not glamorous. It is what keeps the owner from losing confidence the first time a workflow behaves oddly.

A concrete gateway example

In our stack, DynamicMCPProxy started as a way to stop MCP tool soup: one proxy, right servers for the current project, active tool list under a sensible budget.

The same gateway is a natural place for receipts. Recent versions record JSONL events for handshakes, server activation, lazy materialisation, and child MCP tool calls — run_id, span_id, event type, caller identity, status, latency, server name, runtime, argument keys.

The security detail that matters is what it does not record. HMAC-authenticated sidecar calls log a caller such as service:hmac, but not the key. Tool arguments are summarised as keys, types, lengths, and hashes rather than raw customer content. Optional OpenTelemetry export can mirror the trace later; local JSONL still works without shipping sensitive payloads to a vendor.

Pattern for most small-business agents: local receipts first, OpenTelemetry when traffic or risk justifies distributed tracing.

What I would instrument first

Do not start by instrumenting every prompt token. Start where support pain or money lives.

  • Invoices: customer lookup, invoice lookup, payment status, reminder generation, approval, send
  • Leads: source, dedupe, enrichment, CRM write, notification, follow-up task
  • WordPress/content: source URLs, summarisation, draft creation, image generation, human review, publish state — especially publish state
  • Local AI / Ollama: runtime and fallback. If a local model fails and the system falls back to cloud, that should be visible. A silent model switch puts a hole in the privacy story.

The sales angle is reliability, not magic

A lot of small-business AI pitches still sound like magic: “we will automate your operations with agents.” Owners have heard enough of that.

A better pitch is concrete:

“We will automate one repetitive workflow. You will see every tool the agent used, every workflow it triggered, whether a human approved it, and what changed. If something goes wrong, we can replay the receipt.”

Less flashy. More believable.

MCP makes integrations less brittle. Workflow tools make actions repeatable. Observability makes the whole thing accountable.

That combination is what turns a clever prototype into a service you can charge for every month.

Source notes

Top comments (0)