Building Production MCP Servers: Lessons from Wiring AI to Real B2B Lead-Gen Pipelines
Model Context Protocol (MCP) went from "interesting Anthropic spec" to "the way AI agents talk to the real world" in roughly six months. By mid-2026, every major AI coding tool, agent framework, and enterprise automation platform has MCP support. I built pp-mcp-leadgen — Parcel Perform's MCP server for B2B lead-gen tooling — and I want to share what building a production MCP server actually looks like, beyond the quickstart docs.
What MCP Actually Is (Past the Hype)
MCP is a protocol that lets AI models discover and call tools hosted on external servers via a standardized JSON-RPC interface. Think of it as a typed REST API designed specifically for LLM consumption — the tool definitions (name, description, input schema) are the contract the model reads to decide what to call and how.
The key insight is that MCP shifts tool definitions out of your application code and into a standalone server. This means: your tools are reusable across different agents, different models, and different orchestration frameworks — without rewriting integration logic each time.
The Architecture of pp-mcp-leadgen
Our MCP server exposes six tools to the Sales Agent: prospect_lookup (Apollo), company_enrich (Clearbit), email_validate, crm_check (HubSpot), linkedin_signal, and campaign_history. The Sales Agent's LangGraph graph calls these tools as needed during its enrichment phase.
# Tool definition pattern that works well for LLM consumption
{
"name": "prospect_lookup",
"description": "Look up a B2B prospect by email or LinkedIn URL. Returns company, role, seniority, and contact confidence score. Use before drafting outreach.",
"inputSchema": {
"type": "object",
"properties": {
"email": {"type": "string", "description": "Business email address"},
"linkedin_url": {"type": "string", "description": "LinkedIn profile URL"}
},
"oneOf": [{"required": ["email"]}, {"required": ["linkedin_url"]}]
}
}Tool Design Gotchas: What LLMs Need That Humans Don't
1. Tool Names Are Prompts
The model reads your tool name and description to decide when and how to use it. Names like "get_data" or "fetch" are useless. Names like "prospect_lookup" and "campaign_history" tell the model the domain, the action, and the expected object — in two words. Description text is even more important: explain *when to use* the tool, not just what it does.
2. Granularity: One Tool Per Decision
We initially had a single "enrich_prospect" tool that called Apollo, Clearbit, and HubSpot in one shot. The problem: when enrichment partially failed, the agent couldn't retry just the failing source. Split tools by data source and let the agent compose. Finer granularity = more reliable agent reasoning.
3. Return Schemas the Model Can Navigate
Keep return objects flat and labeled. The model has to reason about your output. Deeply nested JSON with generic key names forces the model to guess. We flattened everything into typed fields with descriptive names: "company_employee_count" instead of "data.company.size". One afternoon of response schema redesign cut our prompt token count by 30%.
Production Considerations
Authentication: our MCP server uses API key auth per client (the LangGraph agent is a client). Keys are rotated monthly via AWS Secrets Manager — the agent fetches the key at startup, not at every call.
Rate limiting: each upstream tool (Apollo, HubSpot) has its own rate limits. We implement per-tool token buckets inside the MCP server. The agent never sees upstream rate limit errors — it sees a clean "tool temporarily unavailable, retry in Xs" response, which LangGraph handles gracefully.
Observability: every tool call logs to ELK with: tool name, input hash (not raw input — PII concern), latency, upstream status, and campaign ID. This lets us spot degraded upstream APIs before they cascade into agent failures.
The Real Payoff: Reusability
The Sales Agent was our first MCP consumer. Three months later, we wired the same MCP server to a separate AI Visibility scoring pipeline that needed company enrichment data. Zero changes to the MCP server — the pipeline just registered as a new client. This is the actual value proposition of MCP as infrastructure: build the tool layer once, connect many agents to it.
Takeaways
If you're building AI agents that need to talk to external APIs, build an MCP server — even if you only have one agent today. The protocol forces you to write clean, well-described tool interfaces, which makes your agents more reliable. Invest in the tool description text as much as the implementation. And design for observability from the start: your future self will be debugging agent runs at 2am and they'll thank you.