toolkit-mcp
by harshhh817
README.md
# toolkit-mcp — an MCP server for Claude
A small but real [Model Context Protocol](https://modelcontextprotocol.io) server
that gives Claude three capabilities it doesn't have on its own: querying a local
SQLite database, searching files inside one directory, and looking up weather.
Built on the official Python SDK (`mcp` v2). Works with Claude Desktop, Claude
Code, and any other MCP client.
---
## The problem
Claude can't see your database, your files, or anything that happened after its
training cutoff. Copy-pasting a schema and some rows into the chat works once and
doesn't scale — and it gives Claude a stale snapshot rather than the ability to
go and look.
## The solution
MCP is the standard interface for handing an assistant real tools. This server
implements five of them, with the boring parts done properly: the database
connection is genuinely read-only, file access can't escape its root, and every
error comes back as data the model can read and correct rather than a crash.
---
## The tools
| Tool | What it does |
|---|---|
| `describe_database` | Lists tables, columns, types and row counts — call it first to learn the schema |
| `query_database` | Runs a read-only `SELECT` / `WITH` query and returns rows |
| `search_files` | Finds files by filename glob or by text content |
| `read_file` | Reads one text file from inside the configured root |
| `get_weather` | Current conditions + forecast via Open-Meteo (free, **no API key**) |
### Security, and why it's two layers deep
`query_database` is the tool most likely to be handed something destructive, so
it has two independent guards:
1. **SQLite's own read-only mode.** The connection is opened as
`file:store.db?mode=ro`, so a write is refused by the database engine — not by
my code.
2. **Statement validation.** Only `SELECT` and `WITH…SELECT` are accepted.
Multiple statements, `PRAGMA`, `ATTACH`, and every DDL/DML keyword are
rejected with a message explaining why. SQL comments are stripped first, so a
forbidden keyword can't hide behind `--`.
`search_files` and `read_file` resolve every path and confirm it is still inside
the configured root. `../../../../etc/passwd`, absolute paths, and symlinks
pointing outside are all refused.
All of this is covered by tests — see below.
---
## Setup
```bash
git clone https://github.com/harshhh817/mcp-server-demo.git
cd mcp-server-demo
pip install -r requirements.txt
python make_sample_db.py # builds data/store.db
```
Verify it works before wiring it into anything:
```bash
python test_server.py
```
### Claude Code
From inside the repo:
```bash
claude mcp add toolkit -- python /absolute/path/to/mcp-server-demo/server.py
```
Or commit a `.mcp.json` at your project root so the whole team gets it:
```json
{
"mcpServers": {
"toolkit": {
"command": "python",
"args": ["/absolute/path/to/mcp-server-demo/server.py"],
"env": {
"TOOLKIT_DB_PATH": "/absolute/path/to/mcp-server-demo/data/store.db",
"TOOLKIT_FILES_ROOT": "/absolute/path/to/mcp-server-demo/sandbox"
}
}
}
}
```
Then check it registered:
```bash
claude mcp list
```
### Claude Desktop
Edit `claude_desktop_config.json`:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"toolkit": {
"command": "python",
"args": ["/absolute/path/to/mcp-server-demo/server.py"],
"env": {
"TOOLKIT_DB_PATH": "/absolute/path/to/mcp-server-demo/data/store.db",
"TOOLKIT_FILES_ROOT": "/absolute/path/to/mcp-server-demo/sandbox"
}
}
}
}
```
Restart Claude Desktop. The tools appear under the tools icon in the chat input.
**Two things that trip people up:** paths must be absolute — MCP servers don't
inherit your shell's working directory. And `"command": "python"` must be a
Python that has `mcp` installed; if you use a virtualenv, point at
`/path/to/venv/bin/python` instead.
---
## Configuration
| Variable | Default | Purpose |
|---|---|---|
| `TOOLKIT_DB_PATH` | `./data/store.db` | SQLite file to query |
| `TOOLKIT_FILES_ROOT` | `./sandbox` | The only directory file tools can reach |
Point these at your own database and folder and the server is immediately useful
— nothing in the tool code is specific to the sample data.
---
## Try it
Once connected, ask Claude things like:
> *What tables are in the database?*
> *Which customer has spent the most, and on what?*
> *Find every file mentioning connection pooling and summarise the issue.*
> *What's the weather in Delhi this week?*
Claude picks the tool, writes the SQL, and reads the result. For the second
question it typically calls `describe_database`, then issues a three-table join
on its own.
---
## Tests
`test_server.py` spawns the server as a subprocess and drives it as a **real MCP
client over stdio** — the same transport Claude Desktop uses. It isn't testing
the functions in-process; it's testing the server.
```bash
python test_server.py
```
Real output:
```
connected to 'toolkit' v1.0.0
tool discovery
ok server advertises 5 tools (describe_database, get_weather, query_database, read_file, search_files)
...
query_database - rejected queries
ok DROP is rejected (only SELECT (or WITH ... SELECT) queries are allowed)
ok stacked statements rejected (only one statement per call; remove the extra ';')
ok comment-hidden DROP rejected (only one statement per call; remove the extra ';')
ok database still intact after attacks
path traversal is refused
ok ../ escape refused ('../server.py' resolves outside the allowed root)
ok absolute path refused ('/etc/passwd' resolves outside the allowed root)
get_weather (live network call)
ok resolves the location (Delhi, National Capital Territory of Delhi, India)
ok returns a temperature (29.2degC, overcast)
40 passed, 0 failed
```
---
## Tech
Python 3.10+ · `mcp` v2 (official SDK) · SQLite · stdlib `urllib` (no HTTP
dependency for the weather tool)
```
server.py tool definitions + MCPServer wiring
toolkit_mcp/
├── database.py read-only SQL, validation, schema introspection
├── files.py sandboxed search and read
└── weather.py Open-Meteo client
make_sample_db.py seeded sample database
test_server.py end-to-end test over real stdio MCP transport
sandbox/ what the file tools are allowed to see
```
> **Note on SDK versions:** `mcp` v2 renamed `FastMCP` to `MCPServer`
> (`from mcp.server.mcpserver import MCPServer`). Most tutorials online still
> show the v1 `FastMCP` import, which raises `ModuleNotFoundError` on v2. This
> repo targets v2.
---
## Building one for your stack
The pattern generalises. A tool is a decorated function with a clear
description and typed arguments — the description is what Claude reads to decide
whether to call it, so it's worth writing carefully. Common asks I can build:
- Query your internal Postgres/MySQL read replica safely
- Search and summarise a documentation or ticket archive
- Call your company's REST API with auth handled server-side
- Read and write to a Google Sheet or Notion database
---
## Hire me
I build MCP servers and Claude Code workflows — tested, documented, and
delivered fast.
- **Fiverr:** [My Fiverr profile](https://www.fiverr.com/harshgupta381)
- **Upwork:** [My Upwork profile](<UPWORK_PROFILE_URL>)
- **GitHub:** [github.com/harshhh817](https://github.com/harshhh817)
Final-year B.Tech CSE · AWS Certified Cloud Practitioner · Delhi, India
MIT licensed — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues