Skip to main content
Glama
ThePrakashV

MCP Tool-Calling Agent

by ThePrakashV

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.


Related MCP server: Enterprise MCP Gateway and Tool Registry

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.


F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ThePrakashV/mcp-tool-calling-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server