Skip to main content

On This Page

Build an MCP-Style Routed AI Agent System with Dynamic Tool Exposure

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

How to Build an MCP Style Routed AI Agent System with Dynamic Tool Exposure Planning, Execution, and Context Injection

This tutorial builds a fully functional MCP-style routed agent system from scratch using Python and OpenAI. The system integrates tool discovery, intelligent routing, and structured planning to manage complex workflows. By implementing dynamic capability exposure, the agent limits its tool view to only the most relevant functions for any given task.

Why This Matters

In typical agent architectures, exposing all available tools to a model increases tool selection entropy and the risk of accidental misuse. This system addresses technical reality by implementing a hybrid router that uses heuristics and LLM reasoning to filter capabilities, reducing latency and improving focus. By restricting access to a maximum of three tools per task, the system ensures that the agent remains within safety and efficiency bounds while maintaining high-signal context injection.

Key Insights

  • The Model Context Protocol (MCP) standardizes connections between models and tools using structured schemas for name, description, and input parameters.
  • Dynamic capability exposure reduces model distraction by filtering toolsets based on task-specific heuristics and LLM-driven routing decisions.
  • Context injection enriches prompts with selected tool outputs and retrieved document snippets before final response generation.
  • A TF-IDF based LocalRetriever allows the agent to search a local corpus of documents for conceptual knowledge like ‘Router Policies’ or ‘Context Injection’.
  • Safe Python execution is achieved through restricted global namespaces and contextlib-based stdout redirection to prevent unauthorized system access.

Working Examples

Pydantic models for defining structured tool specifications and calls in an MCP-compliant format.

class ToolSpec(BaseModel):
    name: str
    description: str
    input_schema: Dict[str, Any]
    tags: List[str] = Field(default_factory=list)

class ToolCall(BaseModel):
    tool_name: str
    arguments: Dict[str, Any]

A sandboxed Python execution tool with restricted built-ins and captured output for safe agent calculations.

def tool_python_exec(code: str) -> Dict[str, Any]:
    allowed_builtins = {"abs": abs, "print": print, "len": len, "sum": sum, "dict": dict, "list": list}
    local_ns = {}
    global_ns = {"__builtins__": allowed_builtins, "np": np, "pd": pd, "math": math}
    stdout_buffer = io.StringIO()
    try:
        with contextlib.redirect_stdout(stdout_buffer):
            exec(code, global_ns, local_ns)
        return {"stdout": stdout_buffer.getvalue(), "locals": {k: repr(v)[:500] for k, v in local_ns.items()}}
    except Exception as e:
        return {"error_message": str(e)}

Practical Applications

  • AI Research Assistant: Uses the HybridMCPRouter to select between vector_retrieve for local knowledge and web_search for recent data, preventing unnecessary tool calls. Pitfall: Over-reliance on web search for local concepts can lead to irrelevant external noise.
  • Tabular Data Analysis: Combines dataset_loader for schema inspection with python_exec for summary statistics. Pitfall: Attempting complex math in a direct LLM response instead of using the Python tool results in calculation errors.

References:

Continue reading

Next article

Resolving Paper MCP Connectivity in Docker Dev Containers

Related Content