DEV Community

Hamdi Alaqal
Hamdi Alaqal

Posted on

Building Autonomous Agents with Zero-Dependency Python and Model Context Protocol (MCP)

Building AI agents often starts with installing bloated orchestration frameworks that obscure what's actually happening under the hood. But Anthropic's Model Context Protocol (MCP) standardizes tool integration into clean JSON-RPC 2.0.

In this tutorial, we will build a minimal, local-first agent client using only Python's standard library (json, subprocess, os), connected to structured MCP server schemas.

Why MCP Matters

Instead of writing custom code for every tool:

  • Client: Your agent runtime.
  • Protocol: JSON-RPC 2.0.
  • Server: Lightweight local or remote tools exposing deterministic schemas.

Step 1: The Machine-Readable Catalog

Rather than browsing static websites, we use a structured JSON schema:


json
{
  "id": "mcp-free-01",
  "name": "SQLite & Local File MCP",
  "category": "Database & Storage",
  "protocol": "Model Context Protocol (JSON-RPC 2.0)",
  "input_schema_summary": "{\"query\": \"string (SQL)\"}"
}
Step 2: Zero-Dependency Client
​Here is the minimal runner:

import json

class MinimalMCPClient:
    def __init__(self, catalog_path):
        with open(catalog_path, 'r', encoding='utf-8') as f:
            self.catalog = json.load(f)

    def execute(self, tool_id: str, args: dict):
        tool = next((t for t in self.catalog if t["id"] == tool_id), None)
        if not tool:
            raise ValueError(f"Tool {tool_id} not found")
        return {"status": "success", "tool": tool["name"], "args": args}

Step 3: Try the Full Open-Source Starter Kit
​I open-sourced a complete starter kit containing:
​5 vetted core MCP server schemas (JSON & CSV).
​Clean Python client & deterministic agent router.
​Sample Claude Desktop configuration (server_configs.json).
​Repository: https://github.com/Hamdialaqal/mcp_developer_stack_v1.0.0
​Clone it and run in under 60 seconds:
git clone 

[https://github.com/Hamdialaqal/mcp_developer_stack_v1.0.0.git](https://github.com/Hamdialaqal/mcp_developer_stack_v1.0.0.git)
cd mcp_developer_stack_v1.0.0/free_tier
python3 examples/minimal_mcp_client.py

Feedback and pull requests are welcome!
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
tercelyi profile image
tercel •

Love that you went for “zero-dependency” and stuck to json + a plain class. That line in the catalog example:

"input_schema_summary": "{\"query\": \"string (SQL)\"}"

implies the client is basically trusting a human-readable summary of the schema, not the full machine-validated contract. Do you see the next step being:

  • fetching full MCP tool schemas over JSON‑RPC, and
  • generating argument validation / prompts from them at runtime?

Right now execute() is essentially a router:

tool = next((t for t in self.catalog if t["id"] == tool_id), None)
return {"status": "success", "tool": tool["name"], "args": args}
Enter fullscreen mode Exit fullscreen mode

which is great for teaching the idea, but also highlights a core question: where do you personally draw the line between “minimal” and “too much magic”? For example:

  • Would you keep subprocess handling and streaming responses out of this client, and let the agent layer worry about it?
  • Or push more into the client so any LLM just talks JSON‑RPC and everything else is hidden?

Also curious: with your “SQLite & Local File MCP” example, are you thinking of a 1‑tool‑per‑server pattern, or a fatter local server that exposes multiple tools (SQL, file ops, maybe embeddings) under one schema?