ToolForge MCP Server
by Abhigyan6091
README.md
<div align="center">
# โ๏ธ ToolForge
### Agent Tool Infrastructure & MCP Platform
**A production-grade runtime that gives AI agents governed, observable, and secure access to tools.**
[](https://www.python.org/downloads/)
[](LICENSE)
[](https://modelcontextprotocol.io/)
[](#testing)
[](.github/workflows/ci.yml)
[](#-performance--reliability-benchmarks)
[](#-performance--reliability-benchmarks)
[](#-performance--reliability-benchmarks)
[](#-performance--reliability-benchmarks)
[](#-performance--reliability-benchmarks)
</div>
---
## What is ToolForge?
Modern AI agents call tools as raw function calls โ with no governance, no observability, and no reliability guarantees. **ToolForge fills that gap.**
It acts as a **secure execution gateway** between your AI agent and the outside world, providing a full lifecycle for every tool invocation:
| Stage | What it does |
|---|---|
| ๐ **Discover** | Semantic registry with semver, categories, and full-text search |
| โ
**Validate** | Auto-generated JSON Schema from Python type hints via Pydantic v2 |
| ๐ **Authorize** | Capability-based RBAC permissions checked before every execution |
| โก **Execute** | Async-first runtime with timeouts, retries, and sandboxing |
| ๐ **Observe** | Structured `ToolResult` โ execution ID, latency, retry count, error metadata |
| ๐ **Expose** | MCP stdio & HTTP, LangGraph adapter, OpenAI function calling schemas |
---
## Architecture
```mermaid
flowchart LR
subgraph Clients["Clients"]
A1["๐ค AI Agent"]
A2["๐ฅ๏ธ Claude Desktop"]
A3["โก Cursor / IDE"]
A4["๐ REST API"]
end
subgraph Gateway["ToolForge Gateway"]
direction TB
B["๐ Auth Layer\nAPI Key ยท JWT"]
C["๐ก๏ธ RBAC Engine\nRoles ยท Capabilities"]
D["โฑ๏ธ Rate Limiter\nSliding Window"]
B --> C --> D
end
subgraph Runtime["Execution Runtime"]
direction TB
E["๐ Input Validation\nJSON Schema ยท Pydantic"]
F["๐ Sandbox\nDocker ยท Subprocess"]
G["๐ Retry + Timeout\nExponential Backoff"]
H["๐ฆ ToolResult\nID ยท Latency ยท Error"]
E --> F --> G --> H
end
subgraph Registry["Tool Registry"]
direction TB
I["๐ 26 Standard Tools\nSemver ยท Categories"]
J["๐ Semantic Search\nFull-Text + Category"]
I --- J
end
subgraph Infra["Infrastructure"]
K[("๐ PostgreSQL\nAudit Logs")]
L[("โก Redis\nRate Limits ยท Cache")]
M["๐ Prometheus\n/metrics exporter"]
end
Clients --> Gateway
Gateway --> Runtime
Runtime --> Registry
Runtime --> Infra
```
---
## ๐ Performance & Reliability Benchmarks
ToolForge is benchmarked under high concurrency and automated fault injection to ensure low latency, high throughput, and zero-drop recovery for agent tool execution:
| Metric | Result | Benchmark Details / Conditions |
|---|:---:|---|
| โฑ๏ธ **p95 Tool Execution Latency** | **`206.92 ms`** *(Mixed I/O)*<br>`0.10 ms` *(Core Micro-op)* | Evaluated across 2,000 multi-category tool calls (Files, SQLite, Redis, Data Transforms, Python REPL, AI Vector Search) |
| ๐ฅ **Throughput (tools/sec)** | **`533.16 tools/sec`** *(Mixed I/O)*<br>`14,946.50 tools/sec` *(In-Memory)* | Sustained asynchronous throughput under concurrent worker load (`asyncio` semaphore pool) |
| ๐ฅ **Tool Execution Success Rate** | **`100.00%`** | **2,000 / 2,000** successful tool executions with zero schema or runtime failures |
| โก **Concurrent Execution Speedup** | **`36.46x`** | **`1.584s`** *(Sequential)* vs. **`0.043s`** *(Concurrent)* for 50 parallel I/O-bound agent tasks ($S = T_{seq} / T_{conc}$) |
| ๐ก๏ธ **Recovery Rate** | **`100.00%`** | **80 / 80** transient faults (network glitches, timeout spikes, connection resets) self-healed via exponential backoff retries |
### Latency Percentiles (Mixed Ecosystem Workload)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Min Latency: 0.19 ms โ p50 (Median): 44.62 ms โ
โ Avg Latency: 56.24 ms โ p90 Latency: 66.96 ms โ
โ p95 Latency: 206.92 ms โ p99 Latency: 223.73 ms โ
โ Max Latency: 239.35 ms โ Evaluated: 2,000 runs โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
---
## Quick Start
**Install:**
```bash
git clone https://github.com/your-username/toolforge
cd toolforge
pip install -e .
```
**Register and execute a custom tool:**
```python
import asyncio
from toolforge import ToolForge
tf = ToolForge()
@tf.tool(
name="calculate_tax",
description="Calculate income tax for a given gross income and rate.",
version="1.0.0",
category="finance",
)
def calculate_tax(income: float, rate: float = 0.2) -> float:
return income * rate
async def main():
result = await tf.execute("calculate_tax", {"income": 120_000.0, "rate": 0.28})
print(result.status.value) # 'success'
print(f"${result.result:,.2f}") # '$33,600.00'
print(result.execution_id) # UUID for tracing
asyncio.run(main())
```
**Load all 26 standard tools in one line:**
```python
from toolforge import ToolForge
tf = ToolForge.with_standard_tools()
```
---
## Standard Tool Ecosystem โ 26 Tools
| Category | Tools |
|---|---|
| ๐ **Web** | `web_search`, `web_fetch`, `http_request` |
| ๐ **Files** | `file_read`, `file_write`, `file_search`, `directory_list` |
| ๐ **Data** | `pdf_extract`, `csv_read`, `json_transform` |
| ๐๏ธ **Database** | `sql_query` *(read-only guard)*, `sql_schema`, `redis_get`, `redis_set` |
| ๐ฟ **Git** | `git_status`, `git_diff`, `git_log` |
| ๐ **GitHub** | `github_search`, `github_file`, `github_issue`, `github_actions` |
| ๐ **Code** | `python_execute`, `shell_execute` |
| ๐ง **AI** | `embedding_generate`, `vector_search`, `rerank` |
---
## Core Features
### Custom Tool Registration
```python
from toolforge import tool, RetryPolicy, StandardCapability
@tool(
name="fetch_stock_price",
description="Fetch live stock price from market API.",
version="1.0.0",
category="finance",
capabilities=[StandardCapability.NETWORK.value],
timeout=10.0,
retry_policy=RetryPolicy(max_retries=3, initial_delay_sec=0.5),
)
async def fetch_stock_price(ticker: str) -> dict:
"""Fetch stock data for given ticker symbol."""
return {"ticker": ticker, "price": 185.42}
```
### Structured Tool Results
Every execution returns a fully typed `ToolResult` โ no raw dicts, no guessing:
```python
result = await tf.execute("web_search", {"query": "python asyncio"})
result.execution_id # UUID โ for distributed tracing
result.tool_name # "web_search"
result.tool_version # "1.0.0"
result.status # SUCCESS | FAILED | TIMEOUT | PERMISSION_DENIED
result.result # structured output
result.error # ToolErrorInfo(code, message, retryable)
result.duration_ms # wall-clock latency
result.retry_count # retries attempted before success
result.unwrap() # raises RuntimeError on failure, else returns result
```
### Capability-Based Permissions
```python
from toolforge import PermissionContext
ctx = PermissionContext(
caller_id="research_agent",
granted_capabilities={"network", "filesystem_read"},
)
# โ
Tool requires 'network' โ succeeds
result = await tf.execute("web_search", {"query": "AI"}, context=ctx)
# โ Tool requires 'code_execution' โ returns PERMISSION_DENIED, never raises
result = await tf.execute("python_execute", {"code": "..."}, context=ctx)
print(result.status.value) # 'permission_denied'
```
---
## MCP Protocol Integration
Expose all 26 tools to Claude Desktop, Cursor, or any MCP-compatible client with **zero configuration**.
**Stdio transport** (for Claude Desktop / Cursor):
```python
import asyncio
from toolforge import ToolForge
tf = ToolForge.with_standard_tools()
mcp = tf.create_mcp_server(server_name="my-toolforge")
asyncio.run(mcp.run_stdio())
```
Or directly via CLI:
```bash
python -m toolforge.integrations.mcp
```
**HTTP transport** (for remote agents):
```bash
# POST /mcp โ JSON-RPC 2.0
curl -X POST http://localhost:8000/mcp \
-H "X-API-Key: tf-..." \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
**MCP methods implemented:**
| Method | Description |
|---|---|
| `initialize` | Capability handshake with client info |
| `tools/list` | Dynamic schema discovery for all tools |
| `tools/call` | Executes tool through ToolForge runtime (RBAC + retry) |
| `resources/list` | Spec-compliant resource listing |
| `prompts/list` | Spec-compliant prompt listing |
| `ping` | Heartbeat keepalive |
---
## LangGraph & OpenAI Adapters
**LangGraph:**
```python
tools = tf.to_langgraph_tools() # List[LangGraphToolWrapper]
# graph = create_react_agent(llm, tools)
```
Each wrapper supports `.invoke()` (sync) and `.ainvoke()` (async) with `args_schema` for type validation.
**OpenAI function calling:**
```python
openai_tools = tf.to_openai_tools(category="web")
# โ [{"type": "function", "function": {"name": ..., "parameters": {...}}}]
from toolforge import parse_openai_tool_call
tool_name, args = parse_openai_tool_call(tool_call_obj)
result = await tf.execute(tool_name, args)
```
---
## Enterprise Security
Initialize the hardened `SecuredToolForge` client:
```python
from toolforge import SecuredToolForge, Role, RateLimitConfig
tf = SecuredToolForge.with_standard_tools(
rate_limit_config=RateLimitConfig(requests_per_minute=60),
circuit_failure_threshold=5,
circuit_recovery_timeout_sec=30.0,
)
# Issue scoped API keys per role
dev_key = tf.api_keys.issue_key(user_id="alice", role=Role.DEVELOPER)
agent_key = tf.api_keys.issue_key(user_id="bob", role=Role.AGENT)
# Execute with key-based auth and RBAC enforcement
result = await tf.execute("python_execute", {"code": "print('hello')"}, api_key=dev_key)
# Query auto-redacted audit events
events = tf.audit.get_events(caller_id="alice")
```
**Security features at a glance:**
- ๐ **Authentication** โ SHA-256 hashed API key store + signed JWT bearer tokens
- ๐ฅ **RBAC Hierarchy** โ `admin > developer > agent > viewer` with per-category capability enforcement
- โฑ๏ธ **Rate Limiting** โ Sliding-window per-user and per-tool limits (in-memory or Redis)
- ๐ **Circuit Breaker** โ `CLOSED โ OPEN โ HALF_OPEN` protecting against cascading failures
- ๐ณ **Sandboxed Execution** โ Ephemeral Docker containers (CPU/memory caps, read-only rootfs, no networking); graceful subprocess fallback
- ๐ **Audit Logging** โ Structured JSON events with automatic secret/token redaction
---
## FastAPI Platform Server
Start the server:
```bash
uvicorn toolforge.server:app --host 0.0.0.0 --port 8000 --workers 4
```
**Complete REST API:**
| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/health` | Liveness probe |
| `GET` | `/ready` | Readiness probe with DB verification |
| `GET` | `/api/v1/tools` | List tools with search & category filters |
| `GET` | `/api/v1/tools/{name}` | Full JSON Schema for a specific tool |
| `POST` | `/api/v1/tools/{name}/execute` | Synchronous tool execution |
| `POST` | `/api/v1/tools/batch` | Batch execute multiple tools |
| `POST` | `/api/v1/jobs` | Enqueue async background job |
| `GET` | `/api/v1/jobs/{id}` | Poll job status & result |
| `POST` | `/api/v1/auth/keys` | Issue scoped API keys |
| `POST` | `/api/v1/auth/token` | Issue JWT access tokens |
| `GET` | `/api/v1/audit` | Query historical execution records |
| `GET` | `/api/v1/metrics` | JSON metrics summary |
| `GET` | `/metrics` | Prometheus text exposition format |
| `POST` | `/mcp` | Remote MCP JSON-RPC 2.0 |
| `GET` | `/mcp/sse` | MCP Server-Sent Events stream |
---
## Observability Dashboard
Navigate to `http://localhost:8000/` for a live dark-themed control plane SPA dashboard:
- **๐ KPI Metrics Hub** โ Real-time execution volume, success rates, and p95 latencies
- **๐ Tool Explorer** โ Searchable grid across all 8 categories with full JSON schema inspector
- **๐งช Interactive Playground** โ Execute any tool live with formatted response and latency benchmarks
- **๐ Live Audit Stream** โ Execution history with expandable sanitized request/response inspection
- **๐ MCP Protocol Hub** โ Connection guides for Cursor & Claude Desktop + JSON-RPC 2.0 tester
- **๐ Security Panel** โ Issue API keys and JWT tokens directly from the browser
---
## Autonomous Agent Demo
ToolForge ships a built-in **Autonomous Repository Debugger** that resolves bugs entirely on its own through the secured runtime:
```bash
python examples/repo_debugger_agent.py
```
The agent executes a 6-step autonomous loop:
```
Step 1 discover โ directory_list + file_search find project structure
Step 2 reproduce โ python_execute run failing tests
Step 3 inspect โ file_read read buggy source
Step 4 patch โ file_write apply autonomous fix
Step 5 verify โ python_execute re-run tests โ green
Step 6 report โ structured summary root cause + timing
```
**Output:**
```
[REPORT] AGENT RESOLUTION SUMMARY
Total Steps: 6
Total Runtime: 249.6ms
Root Cause: Unhandled division by zero in calculator.py
Resolution: Patched divide() with explicit ValueError guard
Final Status: RESOLVED
```
---
## Production Deployment
**Docker Compose** (FastAPI Server + PostgreSQL 16 + Redis 7):
```bash
docker compose up --build
```
| URL | Description |
|---|---|
| `http://localhost:8000/` | Web dashboard |
| `http://localhost:8000/docs` | Swagger / OpenAPI docs |
| `http://localhost:8000/health` | Health check |
| `http://localhost:8000/metrics` | Prometheus metrics |
---
## CI/CD โ GitHub Actions
Every push runs a [4-job pipeline](.github/workflows/ci.yml):
```
Lint (ruff) โ Test Matrix (3 OS ร 3 Python) โ Agent Smoke Test โ Docker Build
```
| Job | Details |
|---|---|
| **Lint** | `ruff check` + `ruff format --check` โ fast-fail gate |
| **Test Matrix** | Ubuntu ยท Windows ยท macOS ร Python 3.11 ยท 3.12 ยท 3.13 = **9 environments** |
| **Agent Demo** | Full autonomous agent run end-to-end |
| **Docker Build** | Multi-stage image build with GHA layer cache |
---
## Testing
```bash
# Run all 86 tests (unit, integration, API, agent)
python -m pytest tests/ -v
```
```
86 passed in 6.89s
```
---
## Tech Stack
<div align="center">
`Python 3.11+` ยท `FastAPI` ยท `Pydantic v2` ยท `SQLAlchemy 2.0` ยท `PostgreSQL` ยท `Redis` ยท `Docker` ยท `MCP Protocol` ยท `LangGraph` ยท `Prometheus`
</div>
---
## Contributing
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
Built with Python 3.11+, Pydantic v2, FastAPI, SQLAlchemy 2.0, and async-first patterns throughout.
---
<div align="center">
<sub>Made with โ๏ธ by the ToolForge team ยท Apache 2.0 License</sub>
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues