Skip to main content
Glama
README.md
# MCP-ToolHub — Model Context Protocol Tool Hub & Client Architecture

A production-style implementation of the **Model Context Protocol (MCP)** using the official `mcp` 2.x Python SDK, showcasing modular server registration, automated tool discovery, parameter schema validation, sandboxed filesystem execution, and complete audit trace logging.

---

## 1. What is MCP-ToolHub? (In Plain Language)

The **Model Context Protocol (MCP)** is an open industry standard that allows Large Language Models (LLMs) and autonomous agents to safely connect with external tools, APIs, and data sources. Rather than writing custom integration code for every tool, MCP provides a standard communication protocol between:
- **MCP Servers**: Services that expose tools (e.g., read files, inspect Git repos, hash strings).
- **MCP Clients**: Programs that discover available tools, validate input arguments, execute tools on demand, and capture execution results.

**MCP-ToolHub** is a working architecture demonstrating real MCP client-server communication. It provides three modular MCP servers (Filesystem, Repository, and Utility), dynamic tool discovery with JSON schema reflection, strict path-traversal sandboxing, execution timeouts, and an audit trail API.

---

## 2. Why MCP-ToolHub Exists

1. **Demonstrate Real MCP 2.x Architecture**: Uses the official `mcp.server.mcpserver.MCPServer` interface and official protocol specifications—not simulated mock functions.
2. **Security & Permission Boundaries**: Demonstrates how to prevent arbitrary command execution and directory traversal attacks (`../../etc/passwd`) using a strict sandbox boundary guard.
3. **Robust Tool Client**: Features automatic parameter schema validation, asyncio timeout enforcement, and structured execution traces for every invocation attempt.
4. **Unified API Gateway**: Exposes all discovered MCP tools through a developer-friendly REST API for effortless frontend or AI agent integration.

---

## 3. How It Works

1. **Server Initialization**: Modular MCP servers register safe, typed tools using the `@server.tool()` decorator:
   - **Filesystem Server**: Safe read-only inspection (`safe_read_file`, `safe_list_directory`, `safe_file_stats`) confined to a sandboxed directory.
   - **Repository Server**: Git inspection tools (`validate_commit_hash`, `analyze_code_structure`, `detect_license_type`).
   - **Utility Server**: Cryptographic and token tools (`calculate_hash`, `validate_json`, `estimate_tokens`).
2. **Dynamic Discovery**: The `ToolRegistry` queries each server for its exposed tools, descriptions, and JSON parameter schemas.
3. **Client Invocation & Validation**: When an invocation request arrives, the `MCPClient`:
   - Confirms server availability and tool existence.
   - Validates provided arguments against required schema parameters.
   - Enforces execution timeouts via `asyncio.wait_for`.
   - Traps permission violations and classifies them into `permission_denied` status.
4. **Audit Logging**: Every invocation is appended to an in-memory chronological trace history recording execution ID, duration in milliseconds, inputs, and outputs.

---

## 4. Architecture Diagram

![MCP-ToolHub Architecture Diagram](https://mermaid.ink/svg/Zmxvd2NoYXJ0IFRECiAgICBBW01DUCBDbGllbnQgYW5kIFJFU1QgQ2FsbGVyXSAtLT4gQltNQ1AgQ2xpZW50IEVuZ2luZV0KICAgIEIgLS0+IENbRHluYW1pYyBUb29sIFJlZ2lzdHJ5XQogICAgQyAtLT4gRFtUb29sIERpc2NvdmVyeSBhbmQgU2NoZW1hIFJlZmxlY3Rpb25dCiAgICBCIC0tPiBFW0pTT04gU2NoZW1hIEFyZ3VtZW50IFZhbGlkYXRvcl0KICAgIEIgLS0+IEZbU2FuZGJveCBCb3VuZGFyeSBHdWFyZF0KICAgIEIgLS0+IEdbQXN5bmNpbyBUaW1lb3V0IENvbnRyb2xsZXJdCiAgICBGIC0tPiBIW0ZpbGVzeXN0ZW0gTUNQIFNlcnZlcl0KICAgIEUgLS0+IElbUmVwb3NpdG9yeSBJbnNwZWN0aW9uIE1DUCBTZXJ2ZXJdCiAgICBFIC0tPiBKW1V0aWxpdHkgQ3J5cHRvZ3JhcGh5IE1DUCBTZXJ2ZXJdCiAgICBIIC0tPiBLW0V4ZWN1dGlvbiBUcmFjZSBhbmQgQXVkaXQgTG9nZ2VyXQogICAgSSAtLT4gSwogICAgSiAtLT4gSwogICAgSyAtLT4gTFtTdHJ1Y3R1cmVkIFRvb2wgSW52b2NhdGlvbiBSZXNwb25zZV0K)

```mermaid
flowchart TD
    A[MCP Client and REST Caller] --> B[MCP Client Engine]
    B --> C[Dynamic Tool Registry]
    C --> D[Tool Discovery and Schema Reflection]
    B --> E[JSON Schema Argument Validator]
    B --> F[Sandbox Boundary Guard]
    B --> G[Asyncio Timeout Controller]
    F --> H[Filesystem MCP Server]
    E --> I[Repository Inspection MCP Server]
    E --> J[Utility Cryptography MCP Server]
    H --> K[Execution Trace and Audit Logger]
    I --> K
    J --> K
    K --> L[Structured Tool Invocation Response]
```

---

## 5. Technology Stack

- **Protocol & SDK**: Official `mcp` 2.x SDK (`mcp.server.mcpserver.MCPServer`)
- **API Framework**: Python 3.12, FastAPI, Starlette, Pydantic v2
- **Concurrency**: Python `asyncio` with strict deadline timeouts
- **Containerization**: Docker, Docker Compose
- **Quality & Testing**: Pytest, Pytest-Asyncio, Ruff

---

## 6. Project Structure

```text
MCP-ToolHub/
├── .env.example              # Environment variables template
├── .gitignore                # Git exclusions
├── .dockerignore             # Docker build exclusions
├── Dockerfile                # Production container specification
├── docker-compose.yml        # Docker Compose service definition
├── pyproject.toml            # Linter and test configurations
├── requirements.txt          # Python dependencies
├── LICENSE                   # Apache 2.0 License
├── README.md                 # Technical documentation
├── sandbox/                  # Isolated sandbox directory for filesystem tools
│   └── sample.json           # Sample file for read tests
├── toolhub/
│   ├── __init__.py           # Package marker
│   ├── main.py               # FastAPI REST API and routes
│   ├── config.py             # Settings and sandbox path resolution
│   ├── schemas.py            # Pydantic schemas (Metadata, Invocations, Traces)
│   ├── registry.py           # ToolRegistry for multi-server discovery
│   ├── client.py             # MCPClient with timeout, validation, and security
│   └── servers/
│       ├── __init__.py       # Server exports
│       ├── filesystem.py     # Sandboxed read-only filesystem tools
│       ├── repository.py     # Code parsing and Git commit validation tools
│       └── utility.py        # Hashing, JSON validation, and token estimation tools
└── tests/
    ├── __init__.py
    ├── test_discovery.py     # Multi-server tool discovery tests
    ├── test_invocations.py   # Valid tool execution tests
    ├── test_permissions.py   # Path-traversal security boundary tests
    ├── test_error_handling.py# Timeout, missing argument, and unknown server tests
    └── test_api.py           # FastAPI integration tests
```

---

## 7. Setup & Prerequisites

- **Python**: Version 3.10+ (Python 3.12 recommended)
- **Docker**: (Optional, for containerized execution)

---

## 8. Environment Variables

Create your local `.env` file:

```bash
cp .env.example .env
```

| Variable | Default | Description |
|:---|:---|:---|
| `HOST` | `0.0.0.0` | Binding network address |
| `PORT` | `8000` | HTTP port |
| `ENVIRONMENT` | `development` | Runtime environment |
| `SANDBOX_ROOT` | `./sandbox` | Root directory path strictly confining filesystem tools |
| `TOOL_EXECUTION_TIMEOUT_SECONDS` | `10.0` | Maximum allowed tool execution duration before timeout |

---

## 9. Running Locally

```bash
# 1. Install dependencies
pip install -r requirements.txt

# 2. Run the application
python -m uvicorn toolhub.main:app --host 0.0.0.0 --port 8000 --reload
```

Interactive documentation is available at:
`http://localhost:8000/docs`

---

## 10. Docker Usage

### Build and Run with Docker
```bash
docker build -t mcp-toolhub:latest .
docker run -d --name mcp-hub -p 8083:8000 mcp-toolhub:latest
```

### Run with Docker Compose
```bash
docker compose up -d --build
```

---

## 11. API Usage & Discovery Workflow

### 11.1 Discover Available Tools
```bash
curl -X GET "http://localhost:8000/v1/tools"
```
**Response excerpt:**
```json
[
  {
    "name": "calculate_hash",
    "server": "utility",
    "description": "Calculates cryptographic hash digest for input string.",
    "parameters": {
      "properties": {
        "data": {"title": "Data", "type": "string"},
        "algorithm": {"default": "sha256", "title": "Algorithm", "type": "string"}
      },
      "required": ["data"]
    },
    "permission_scope": "isolated_utility"
  }
]
```

### 11.2 Invoke a Tool
```bash
curl -X POST "http://localhost:8000/v1/tools/invoke" \
  -H "Content-Type: application/json" \
  -d '{
    "server": "utility",
    "tool": "calculate_hash",
    "arguments": {
      "data": "Hello MCP World",
      "algorithm": "sha256"
    }
  }'
```
**Response:**
```json
{
  "execution_id": "exec-d4e5f6a1b2",
  "server": "utility",
  "tool": "calculate_hash",
  "arguments": {"data": "Hello MCP World", "algorithm": "sha256"},
  "status": "success",
  "duration_ms": 0.35,
  "result": {
    "algorithm": "sha256",
    "input_bytes": 15,
    "digest": "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"
  },
  "error": null,
  "timestamp": 1726950000
}
```

### 11.3 Security Boundary Enforcement Example
Attempting directory traversal (`../../etc/passwd`) is automatically trapped and blocked:
```bash
curl -X POST "http://localhost:8000/v1/tools/invoke" \
  -H "Content-Type: application/json" \
  -d '{
    "server": "filesystem",
    "tool": "safe_read_file",
    "arguments": {"path": "../../etc/passwd"}
  }'
```
**Response:**
```json
{
  "execution_id": "exec-9c8b7a6d5e",
  "server": "filesystem",
  "tool": "safe_read_file",
  "arguments": {"path": "../../etc/passwd"},
  "status": "permission_denied",
  "duration_ms": 0.42,
  "result": null,
  "error": "Security Violation: Target path '../../etc/passwd' escapes sandbox boundary",
  "timestamp": 1726950000
}
```

---

## 12. Automated Testing

Run the full automated test suite verifying discovery, execution, permissions, and timeout handling:

```bash
python -m pytest tests -v
python -m ruff check .
```

---

## 13. Limitations

- **Read-Only Focus**: Write operations and system-modifying capabilities are intentionally prohibited by design.
- **In-Memory Traces**: Execution traces are stored in memory for educational clarity. For enterprise logging, configure PostgreSQL or Redis persistence.

---

## 14. Security Considerations

- **Strict Sandbox Boundary**: Path resolution verifies `target.relative_to(sandbox_root)` before touching files on disk. Escapes throw `PermissionError`.
- **No Arbitrary Code Execution**: No `eval`, `exec`, or unvetted shell execution tools exist in the system.
- **Resource Limits**: Tool executions are strictly bounded by timeout deadlines preventing denial-of-service hanging.

---

## 15. License

Licensed under the [Apache License, Version 2.0](LICENSE).