MCP Tool-Calling Agent

MCP Tool-Calling Agent

Enables an LLM to dynamically discover and call tools across multiple MCP servers (file, GitHub, SQL, Python execution) with authentication, rate limiting, and observability, supporting parallel execution and secure deployment.

Category
访问服务器

README

MCP Tool-Calling Agent

A production-ready Model Context Protocol (MCP) agent that connects a local LLM (Ollama) to multiple tool-serving backends — files, GitHub, SQL, and Python execution — with authentication, observability, security hardening, and container/orchestration deployment built in from the ground up.

Built as a hands-on learning project covering the full lifecycle of an AI agent system: from a single MCP server to a Kubernetes-deployed, Redis-backed, horizontally-scalable multi-agent architecture.


Architecture

                        ┌─────────────────────────────┐
                        │      User Request            │
                        └──────────────┬───────────────┘
                                       │
                        ┌──────────────▼───────────────┐
                        │   Agent Core (agent_core.py)  │
                        │  ┌─────────────────────────┐  │
                        │  │ 1. Authenticate (API key) │  │
                        │  │ 2. Rate limit (Redis)     │  │
                        │  │ 3. Connect to MCP servers │  │
                        │  │ 4. Ask LLM which tool(s)  │  │
                        │  │ 5. Authorize per tool     │  │
                        │  │ 6. Execute (parallel,     │  │
                        │  │    retry, timeout)        │  │
                        │  │ 7. Return final answer     │  │
                        │  └─────────────────────────┘  │
                        └───┬────────┬────────┬────────┬─┘
                            │        │        │        │
                     ┌──────▼──┐ ┌───▼────┐ ┌─▼──────┐ ┌▼────────┐
                     │  File   │ │ GitHub │ │  SQL   │ │ Python  │
                     │  MCP    │ │  MCP   │ │  MCP   │ │  Exec   │
                     │ Server  │ │ Server │ │ Server │ │ MCP     │
                     └─────────┘ └────────┘ └────────┘ └─────────┘
                            │
                     ┌──────▼──────┐        ┌─────────────┐
                     │ Ollama (LLM) │        │ Redis (rate  │
                     │  (host)      │        │ limit state) │
                     └──────────────┘        └─────────────┘

The agent connects to each MCP server as a subprocess over stdio, discovers their tools dynamically, and lets the LLM decide which tool(s) to call based on the user's request. Tool execution, authorization, retries, and metrics are all handled centrally in the agent core.


Features

  • MCP Client + Multi-Server support — dynamic tool discovery across 4 independent MCP servers
  • LLM Tool-Calling — local LLM (Ollama) decides which tool to call and with what parameters
  • Parallel execution — independent tool calls run concurrently via asyncio.gather
  • Retry + timeout — exponential backoff retries and strict timeouts on all network/tool calls
  • Authentication & Authorization — API-key based auth with role-based tool permissions (admin/developer/viewer)
  • Secret management — centralized .env-backed secrets abstraction, swappable for a cloud secret manager
  • Structured logging — JSON logs with automatic request-ID tracking (contextvars)
  • Metrics — Prometheus-compatible counters and histograms (tool calls, latencies, auth failures)
  • Security hardening — subprocess-isolated Python execution, SQL injection prevention, path traversal protection, rate limiting
  • Automated tests — 17 pytest unit + integration tests covering auth, rate limiting, retries, and the full MCP pipeline
  • Containerized — Dockerfile + docker-compose (agent + Redis)
  • Kubernetes-ready — Deployment, Service, ConfigMap, Secret manifests with health probes, tested on Minikube
  • Distributed rate limiting — Redis-backed sliding-window limiter for correct behavior across multiple replicas

Tech Stack

Category Technologies
Language Python 3.11
Protocol Model Context Protocol (MCP) — Client & Server SDK
LLM Ollama (local, tool-calling capable models — e.g. qwen2.5)
Web/API FastAPI, httpx (async)
Tools SQLite, GitHub REST API, subprocess-isolated Python exec
Auth API-key based, role-based authorization
Observability python-json-logger, Prometheus client, OpenTelemetry (SDK installed)
Testing pytest, pytest-asyncio
Containers Docker, Docker Compose
Orchestration Kubernetes (Minikube for local dev)
Scaling Redis (distributed rate limiting)

Project Structure

mcp-tool-calling-agent/
├── agent/
│   └── agent_core.py          # Main agent loop: auth, LLM calls, tool routing, parallel execution
├── servers/
│   ├── file_server.py         # File read tool (path-traversal protected)
│   ├── github_server.py       # GitHub repo info + issue creation
│   ├── sql_server.py          # SQLite read-only queries (injection-hardened)
│   └── python_server.py       # Sandboxed Python code execution
├── client/
│   └── mcp_client.py          # Standalone MCP client (tool discovery demo)
├── auth/
│   ├── auth_manager.py        # Authentication + role-based authorization
│   ├── secret_manager.py      # Centralized secrets access
│   ├── rate_limiter.py        # In-memory rate limiter (single-instance)
│   └── redis_rate_limiter.py  # Redis-backed rate limiter (multi-replica)
├── observability/
│   ├── logger.py              # Structured JSON logging with request IDs
│   └── metrics.py             # Prometheus metrics definitions
├── tools/
│   └── retry_utils.py         # Retry (exponential backoff) + timeout decorators
├── tests/                     # pytest unit + integration tests
├── k8s/                       # Kubernetes manifests (Deployment, Service, ConfigMap)
├── docs/                      # Phase-by-phase build documentation
├── data/                      # SQLite database (gitignored, auto-created)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt           # Local (Windows) development dependencies
├── requirements-docker.txt    # Linux-container-safe dependencies
├── pytest.ini
└── .env                       # Secrets (gitignored, never committed)

Setup Instructions

Prerequisites

  • Python 3.10+
  • Ollama installed, with a tool-calling-capable model pulled (e.g. ollama pull qwen2.5)
  • Docker Desktop (for containerized/Kubernetes runs)
  • Node.js (for MCP Inspector, optional debugging tool)

Local Development

# Clone and enter the project
git clone https://github.com/<your-username>/mcp-tool-calling-agent.git
cd mcp-tool-calling-agent

# Create and activate a virtual environment
python -m venv venv
venv\Scripts\activate        # Windows
# source venv/bin/activate   # macOS/Linux

# Install dependencies
pip install -r requirements.txt

# Configure secrets
copy .env.example .env       # then fill in your values
# Required: AGENT_API_KEYS=devkey123:developer,adminkey456:admin,viewkey789:viewer
# Optional: GITHUB_TOKEN=... (for GitHub tools)

# Ensure Ollama is running with a tool-capable model
ollama list

# Run the agent
python -m agent.agent_core

Run Tests

pytest -v

Run with Docker Compose (agent + Redis)

docker compose build
docker compose up

Deploy to Kubernetes (Minikube)

minikube start --driver=docker
kubectl create secret generic agent-secrets --from-env-file=.env
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

minikube image build -t mcp-tool-calling-agent-agent:latest -f Dockerfile .
kubectl delete pod -l app=mcp-agent   # trigger a fresh pull of the newly built image

kubectl get pods
kubectl logs -f deployment/mcp-agent-deployment

Phase-by-Phase Build Summary

This project was built incrementally across 14 phases, each documented in detail under docs/.

Phase Focus Key Deliverable
1 Project Setup + MCP Basics Environment, dependencies, MCP protocol concepts
2 First MCP Server Single-tool file_server.py, tested via MCP Inspector
3 MCP Client + Tool Discovery Dynamic tool discovery, no hardcoding
4 LLM Tool-Calling Agent Core Full Think → Act → Observe → Respond loop (Ollama)
5 More Tools + Multi-Server GitHub, SQL, Python servers; multi-server routing agent
6 Async/Parallel + Retry/Timeout Concurrent tool execution, exponential backoff retries
7 Auth + Secret Manager API-key auth, role-based tool authorization
8 Logging & Monitoring Structured JSON logs, Prometheus metrics
9 Security Hardening Sandboxed Python exec, SQL injection & path traversal defenses
10 Testing 17 pytest unit + integration tests
11 Dockerize Dockerfile, docker-compose, Linux-compatible dependencies
12 Kubernetes Deployment Minikube deployment with health probes, Secrets, ConfigMaps
13 Advanced Scaling Redis-backed distributed rate limiting
14 GitHub Push + Docs This README, repo setup, final polish

Each phase document in docs/ includes: what was built, errors encountered and how they were resolved, final working code/commands, and important notes for future reference.


Security Notes

  • All secrets live in .env, which is git-ignored and never committed.
  • The Python execution tool runs in an isolated subprocess with a strict timeout and restricted builtins (no file/network access).
  • SQL queries are restricted to SELECT only, with a dangerous-keyword blocklist and a database-level PRAGMA query_only enforcement.
  • File access is restricted to the project directory (path traversal protected).
  • Rate limiting (Redis-backed) protects against request flooding, with a fail-open policy if Redis is temporarily unavailable.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选