mcp-agent-tools
π€ mcp-agent-tools
A custom MCP (Model Context Protocol) server that gives AI agents real-world tools: file access, read-only MySQL queries, web summarization, calculations, and system info. Built to understand how agentic tool calling works end-to-end β server side and client side.
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Client (AI Agent) β
β Claude Code / Qwen Code / Claude Desktop β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β stdio (JSON-RPC)
βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ
β MCP Server (this) β
β β
β ββββββββββββ ββββββββββββ ββββββββββββ βββββββββββββ β
β βread_file β βquery_ β βsummarize_β βcalculator β β
β βlist_dir β βmysql β βurl β βget_datetimeβ β
β β β β(SELECT β β β βsysinfo β β
β β β β only) β β β βword_count β β
β ββββββββββββ ββββββββββββ ββββββββββββ βββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββTools (8)
Tool | What it does | Safety |
| Read a text file (first 5000 chars) | read-only, path validation |
| List directory contents with type indicators | read-only |
| Query MySQL database | SELECT-only guardrail |
| Fetch & summarize a webpage | no writes, timeout protected |
| Evaluate math expressions safely | AST-based (no eval) |
| Current date/time (UTC + local) | read-only |
| System information (OS, Python, arch) | read-only |
| Count words, chars, lines, sentences | read-only |
Quick start
# 1. Clone and set up
git clone https://github.com/zyay/mcp-agent-tools.git
cd mcp-agent-tools
python -m venv venv && venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
# 2. Install dependencies
pip install -r requirements.txt
# 3. Set up MySQL (optional β for query_mysql tool)
mysql -u root -p < setup.sql
# 4. Test the server
python client_test.pyConnecting an MCP client
Option 1: Qwen Code
qwen mcp add agent-tools -- python /full/path/to/server.pyOr add to .qwen/settings.json:
{
"mcpServers": {
"agent-tools": {
"command": "python",
"args": ["/full/path/to/mcp-agent-tools/server.py"]
}
}
}Option 2: Claude Code
claude mcp add agent-tools -- python /full/path/to/server.pyOption 3: Claude Desktop
Edit claude_desktop_config.json:
{
"mcpServers": {
"agent-tools": {
"command": "python",
"args": ["/full/path/to/mcp-agent-tools/server.py"]
}
}
}Location:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Option 4: Any MCP client
The server uses stdio transport (JSON-RPC over stdin/stdout). Any MCP-compatible client can connect.
Usage examples
Once connected, the AI agent can use these tools naturally:
File operations
User: "What's in the config file at ./settings.json?"
Agent: [calls read_file("./settings.json")]Database queries
User: "Show me all clients with projects over $1000"
Agent: [calls query_mysql("SELECT * FROM clients WHERE price > 1000")]Web research
User: "What does the Python docs say about async generators?"
Agent: [calls summarize_url("https://docs.python.org/3/reference/expressions.html")]Calculations
User: "If I have 150 items at $12.99 each with 15% discount, what's the total?"
Agent: [calls calculator("150 * 12.99 * 0.85")]System debugging
User: "What Python version am I running and what OS?"
Agent: [calls sysinfo()]MySQL setup
The query_mysql tool connects to a demo database. Set up:
# Load demo data
mysql -u root -p < setup.sql
# Verify
mysql -u root -p -e "SELECT * FROM demo.clients;"Environment variables
Variable | Default | Description |
|
| MySQL server host |
|
| MySQL username |
| (empty) | MySQL password |
|
| Database name |
Example with custom credentials:
set MYSQL_HOST=localhost
set MYSQL_USER=myuser
set MYSQL_PASS=mypassword
python server.pyDesign decisions
Decision | Why |
SELECT-only guardrail | An agent with DROP TABLE access is a bug waiting to happen. Least-privilege by default. |
AST calculator | No |
stdio transport | Simplest, works with any MCP client. No HTTP server needed. |
Docstrings = tool descriptions | The |
Error messages, not exceptions | Tools return error strings instead of raising β the agent can read the error and adapt. |
No state between calls | Each tool call is independent. No shared state = no race conditions. |
Testing
# Run the test client β lists all tools and calls each one
python client_test.py
# Expected output:
# π§ Tools (8): ['read_file', 'list_dir', 'query_mysql', 'summarize_url', ...]
# β
query_mysql: [{'id': 1, 'name': 'Firma A', ...}, ...]
# β
calculator: 100.0
# β
get_datetime: UTC: 2026-08-11 ...
# ...Adding your own tools
@mcp.tool()
def my_tool(param: str) -> str:
"""Describe what this tool does β the LLM reads this description.
Be specific about:
- What it does
- What parameters it takes
- What it returns
- Any safety considerations
"""
# Your implementation
return f"Result for {param}"Then restart the server. The new tool appears automatically.
Production upgrade path
Human-in-the-loop β add confirmation prompts for destructive operations
Auth / permissions β per-tool access control, API keys
HTTP transport β deploy as a remote MCP server (streamable-http)
Rate limiting β prevent abuse of web fetching / database queries
Logging β structured logs for debugging and auditing
More databases β PostgreSQL, SQLite, MongoDB adapters
What I learned
MCP protocol: JSON-RPC over stdio, tool schema from docstrings
Why guardrails matter: agents are powerful but need boundaries
AST-based evaluation: safe math without
eval()security risksTool description quality directly affects agent behavior
The MCP ecosystem is growing fast β Claude, Qwen Code, Cursor all support it
Security
Check | Status |
No | β AST-based calculator only |
SELECT-only MySQL guardrail | β All non-SELECT queries rejected |
Path traversal protection | β Sandbox with allowed_paths + blocked_paths |
Timeout on network calls | β All HTTP calls have timeouts |
Rate limiting | β Configurable per-tool rate limits |
Human-in-the-loop writes | β 2-step prepare β confirm flow |
Tool-call logging | β Every call logged to JSONL |
Config-driven tool enable/disable | β Toggle tools in config.yaml |
License
MIT