top of page

From Prototype to Production: Building Client-Ready AI Agents with MCP and ADK

  • 3 minutes ago
  • 7 min read

By Codersarts Team · AI Agent Architecture · 12 min read

Most AI agents never make it out of the demo. They look brilliant on a localhost screen share, impress a room full of stakeholders, and then quietly die somewhere between "let's move forward" and the first production incident.


The gap between a working prototype and a client-ready agent isn't a feature gap — it's an engineering and architecture gap. This post closes it. You'll learn exactly how to use Model Context Protocol (MCP) and Agent Development Kit (ADK) together to build AI agents that hold up in the real world — under real load, with real users, and real client expectations.



The Problem With Most AI Agent Prototypes

Prototype agents fail in production for the same reasons, every time:

  • No auth or credential management — API keys hardcoded, tokens not rotated

  • No error handling — one bad tool response breaks the whole chain

  • No observability — you can't trace what the agent decided or why

  • No fallback behavior — dead ends instead of graceful degradation

  • No scalability design — it worked for one user; it breaks for fifty


These aren't edge cases. They're the baseline requirements any client will discover the moment real usage begins.


The solution isn't more LLM prompting. It's better architecture — specifically, a stack built around MCP for tool and context management, and ADK for agent lifecycle and orchestration.



What Is MCP? (Model Context Protocol)

Model Context Protocol (MCP) is an open standard that defines how AI models communicate with external tools, data sources, and services. Think of it as the USB-C of AI integrations — one standard interface, many compatible devices.


Before MCP, every agent had its own bespoke way of calling tools. Custom function schemas, ad-hoc JSON structures, inconsistent error formats. Maintaining them was a nightmare; extending them was worse.


MCP solves this with a clean client-server model:

  • MCP Server — exposes tools, resources, and prompts

  • MCP Client — the agent that consumes them

  • Transport Layer — stdio for local, HTTP/SSE for remote



Basic MCP Server Setup



from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types

app = Server("my-agent-tools")

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="get_customer_data",
            description="Fetch customer record by ID",
            inputSchema={
                "type": "object",
                "properties": {
                    "customer_id": {"type": "string"}
                },
                "required": ["customer_id"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_customer_data":
        # Your actual data fetching logic
        customer = await fetch_customer(arguments["customer_id"])
        return [types.TextContent(type="text", text=str(customer))]

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(read_stream, write_stream, app.create_initialization_options())

This server can now be consumed by any MCP-compatible client — your agent, Claude Desktop, or a custom orchestrator — without rewriting integration code each time.


Why this matters for production: You can swap, version, and permission-scope tools independently of the agent logic. Your agent doesn't need to know where the data comes from. It just knows what tools it has.



What Is ADK? (Agent Development Kit)

ADK (Agent Development Kit) is a framework — popularized by Google's open-source release — for building, running, and orchestrating AI agents. It handles the parts of agent development that have nothing to do with prompting:


  • Agent lifecycle — initialization, session management, teardown

  • Multi-agent orchestration — routing, subagent delegation, handoffs

  • Built-in tool integration — including MCP server support

  • Evaluation and testing — structured evals before deployment

  • Deployment targets — local, cloud run, Vertex AI Agent Engine


ADK gives you a structured way to define agents in code, not just in prompts.



A Basic ADK Agent Definition



from google.adk.agents import Agent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters

root_agent = Agent(
    name="client_support_agent",
    model="gemini-2.0-flash",
    description="Handles customer support queries using CRM and ticketing tools",
    instruction="""
        You are a client support agent. Use available tools to:
        1. Look up customer records before responding
        2. Check open tickets before suggesting solutions
        3. Always confirm resolution before closing a ticket
        Never guess — if data is unavailable, say so explicitly.
    """,
    tools=[
        MCPToolset(
            connection_params=StdioServerParameters(
                command="python",
                args=["./mcp_servers/crm_server.py"]
            )
        )
    ]
)

ADK handles the session, runs the tool calls, manages the model loop, and gives you structured logs — without you wiring any of that manually.



MCP + ADK Together: The Stack That Scales

Used alone, each is useful. Used together, they form a production-grade agent architecture.




┌──────────────────────────────────────────────────────────┐
│                     CLIENT INTERFACE                     │
│              (Web App / Slack / API Endpoint)            │
└─────────────────────────┬────────────────────────────────┘
                          │
┌─────────────────────────▼────────────────────────────────┐
│                    ADK ORCHESTRATOR                      │
│         Root Agent → Subagents → Response Assembly       │
└──────┬──────────────────┬───────────────────┬────────────┘
       │                  │                   │
┌──────▼──────┐  ┌────────▼──────┐  ┌────────▼──────┐
│  MCP Server │  │  MCP Server   │  │  MCP Server   │
│    (CRM)    │  │  (Ticketing)  │  │  (Knowledge   │
│             │  │               │  │    Base)       │
└─────────────┘  └───────────────┘  └───────────────┘

ADK manages the agent logic and orchestration. MCP manages the tool surface and data access. Neither bleeds into the other's responsibility.


Real-World Example: Client-Facing Support Agent

A B2B SaaS company wants to deflect 60% of support tickets with an AI agent that can:

  • Look up account data

  • Read open tickets

  • Search a knowledge base

  • Escalate to human if confidence is low


Without this stack: One monolithic agent with hardcoded API calls, no escalation logic, no logging, impossible to maintain.


With MCP + ADK:

  • Three MCP servers (CRM, ticketing, knowledge base) — each independently maintained

  • Root ADK agent routes queries to specialized subagents

  • Escalation is a built-in tool: escalate_to_human(reason, transcript)

  • Full session logs available for QA review

  • New tool or data source? Add an MCP server — zero agent logic changes




Prototype to Production: The 5-Step Process


Step 1 — Define Agent Scope and Tool Boundaries (with MCP)

Before writing a single line of agent logic, define:

  • What can this agent do (tools)?

  • What can it access (resources)?

  • What can it not do (explicit constraints in the system prompt)?


Map each capability to an MCP tool. This forces you to think in interfaces, not implementations — and makes handoff to a client dramatically easier.


Agent Scope Document (internal):
- Tool: get_account_info         → CRM MCP Server
- Tool: list_open_tickets        → Support MCP Server
- Tool: search_knowledge_base    → Docs MCP Server
- Tool: escalate_to_human        → Internal MCP Server
- Out of scope: billing changes, contract modifications

Step 2 — Build and Test Locally with ADK

Use ADK's built-in dev runner and evaluation tools during development:


# Run agent locally with ADK CLI
adk run agent.py

# Run structured evals
adk eval agent.py tests/eval_cases.json

Write eval cases that cover:

  • Happy path queries

  • Ambiguous or incomplete inputs

  • Tool failure scenarios

  • Escalation triggers


Don't skip evals. This is the single most common shortcut that causes production failures.



Step 3 — Add Auth, Logging, and Error Handling

This is where most prototypes stop. Don't.


Auth: Use environment-scoped secrets, never hardcoded. ADK supports credential injection at the server level.



# MCP Server with proper credential handling
import os
from dotenv import load_dotenv

load_dotenv()

CRM_API_KEY = os.getenv("CRM_API_KEY")
if not CRM_API_KEY:
    raise EnvironmentError("CRM_API_KEY is required")

Error handling in every tool:


@app.call_tool()
async def call_tool(name: str, arguments: dict):
    try:
        result = await fetch_data(arguments)
        return [types.TextContent(type="text", text=str(result))]
    except TimeoutError:
        return [types.TextContent(type="text", text="ERROR: Data source timed out. Please retry.")]
    except PermissionError:
        return [types.TextContent(type="text", text="ERROR: Insufficient permissions for this record.")]

Logging: ADK provides session-level trace logs. Pipe them to your observability stack (Datadog, Grafana, CloudWatch) before go-live.



Step 4 — Deploy with Multi-Agent Orchestration

For anything beyond a single-task agent, use ADK's multi-agent pattern:



from google.adk.agents import Agent

# Specialized subagents
account_agent = Agent(
    name="account_lookup_agent",
    model="gemini-2.0-flash",
    instruction="Only look up and return account information. Nothing else.",
    tools=[crm_toolset]
)

ticket_agent = Agent(
    name="ticket_agent",
    model="gemini-2.0-flash",
    instruction="Handle ticket queries only. Escalate billing or legal matters.",
    tools=[ticketing_toolset]
)

# Root orchestrator
root_agent = Agent(
    name="support_orchestrator",
    model="gemini-2.0-flash",
    instruction="Route queries to the appropriate subagent. Assemble the final response.",
    sub_agents=[account_agent, ticket_agent]
)

Deploy to Cloud Run or Vertex AI Agent Engine for managed scaling.



Step 5 — Monitor, Iterate, and Hand Off to Client


Before handoff, verify:

  • [ ] Agent handles tool failures gracefully

  • [ ] Escalation paths are tested and working

  • [ ] All credentials are rotated and environment-scoped

  • [ ] Session logs are flowing to observability

  • [ ] Eval suite passes at >90% on defined test cases

  • [ ] Response latency is within agreed SLA

  • [ ] A rollback plan exists


Monitoring to set up:

  • Tool call success/failure rate

  • Escalation rate (leading indicator of agent confusion)

  • Average session length

  • User satisfaction signal (thumbs up/down, CSAT)




What "Client-Ready" Actually Means

A working agent and a client-ready agent are not the same thing. Here's the difference:

Working Agent

Client-Ready Agent

Succeeds in happy path

Handles failure gracefully

You know why it works

Client can audit why it decided

Runs on your machine

Runs reliably at scale

Demo-able

Documentable and handoff-able

Fixed prompt

Version-controlled, updatable



Client handover package should include:

  1. Architecture doc — what each agent and MCP server does

  2. Runbook — how to restart, redeploy, roll back

  3. Eval suite — so they can verify after any changes

  4. Escalation map — what the agent can't handle and why

  5. Observability dashboard — live view of agent health


When a client can look at a dashboard and understand what their agent is doing without calling you, you've built something production-ready.



The Stack Worth Using

If you're building AI agents for clients or internal teams, the MCP + ADK combination is currently the most mature path from idea to production:

  • MCP gives you clean, swappable, permissionable tool surfaces

  • ADK gives you structured orchestration, evals, and deployment targets

  • Together they give you an architecture you can explain, maintain, and hand off


The agents that survive production aren't the most clever ones. They're the ones built on a foundation that makes debugging, extending, and operating them tractable for everyone involved — not just the person who built them.




Not Building It Yourself?

If you're a product, ops, or engineering leader who wants to deploy AI agents without the R&D overhead, we can help.


We design and build production-ready AI agents — scoped, deployed, and handed off with full documentation in under 4 weeks.



No pitch. Just clarity on what's possible for your specific use case.



We Offer

  • Custom AI agent design and development

  • MCP server integration for your existing tools and systems

  • Production deployment with observability and monitoring setup

  • Client-ready handoff with full documentation and runbooks

  • Ongoing maintenance, iteration, and support


Tags: AI Agents, MCP, ADK, LLM Engineering, Agent Architecture, Production AI, Google ADK, Model Context Protocol

Comments


bottom of page