mcp-tools
{
"answer": "This is a zero-dependency MCP server that exposes five safe, deterministic tools over stdio for LLM clients like Claude Desktop:\n\n- calc — Evaluate arithmetic expressions safely using AST allow-listing. Rejects code-execution payloads (__import__('os').system(...)) rather than running them.\n- search — BM25 keyword search over a bundled document corpus (or your own notes via MCPTOOLS_CORPUS). Returns top-k matches with relevance scores; fully local, no network.\n- grade_answer — Deterministically check a draft answer against source texts, flagging unsupported sentences and fabricated figures. Lexical, not an LLM judge — useful for agents to verify their own work before responding.\n- model_drift — Read-only lookup of how live LLMs (e.g., gpt-5, claude-opus, gemini) score on a public frozen eval suite: accuracy, latency, answer length, reliability, refusal rate, and week-over-week changes. Omit the model parameter to list all 16 tracked models.\n- compare_runs — Per-case comparison of a project's latest eval run against the previous one, so a better average can't hide individual regressions. Useful for CI-style quality gates.\n\nOperationally, it supports structured stderr logs, in-process metrics (calls/errors per tool), an optional SQLite result trail via MCPTOOLS_DB, and runs in Docker. The protocol is implemented from the spec with no SDK and no external dependencies."
}
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-toolsCalculate 2 + 3 * 4"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-tools
A Model Context Protocol server, implemented from the spec — no MCP SDK, no dependencies.
MCP is how a language-model client (Claude Desktop, an agent) discovers and calls tools a server exposes. It's JSON-RPC 2.0; a local server speaks it over stdio. This repo implements that protocol directly — the whole surface a tool server needs is initialize → notifications/initialized → tools/list → tools/call — so the protocol is legible instead of hidden behind a library.
It exposes five tools, all safe by construction — three fully local and deterministic, two read-only lookups against public endpoints (no keys, no writes):
Tool | What it does | Why it's safe |
| Evaluate an arithmetic expression | Parses to an AST and allow-lists arithmetic nodes only — no |
| BM25 keyword search over a bundled corpus | Read-only, no network. The corpus is read once at startup; no tool argument can reach the filesystem. The ranking is Okapi BM25 — the same length-normalised, saturation-aware scoring that matches the published SciFact baseline in rag-eval-lab, reimplemented here so this server has zero dependencies. |
| Is a live model still scoring what it used to? | Read-only GET of the public model-drift board — accuracy, latency, answer length, reliability and refusal rate for 16 models, plus what moved since last week's run. No key, no write. |
| Did a project's latest eval run regress against the one before it? | Read-only GET of eval-history's per-case comparison — so a better average can't hide the case that broke. |
| Check a draft answer against its sources and name the sentences they don't support | No LLM judge. A model grading hallucination is itself a model output — you can't tell a real unsupported claim from the judge having an off day, and you can't reproduce last week's verdict. This is lexical: a figure that appears nowhere in the sources fails the sentence outright (invented statistics are the strongest tell), and low content-word coverage flags claims the sources never make. |
A real MCP session over stdio — no client, no key, no network. calc is handed
__import__("os").system("rm -rf ~") and answers isError with the AST element it refused; the
server stays up, and the next call flags the one sentence the source does not support.
Run it yourself: ./demo/session.sh.
Play it as a terminal session — the text is selectable.
Use it with Claude Desktop
Add this to claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"mcp-tools": { "command": "python", "args": ["-m", "mcptools"] }
}
}Restart Claude Desktop and ask it to "search your notes for how rate limiting allows bursts", "use calc to work out 17 * 23 + 4", or — the useful one — paste some source material and ask it to draft an answer and then grade its own answer against those sources. It discovers the tools and calls them.
faithfulness 50% — 1 of 2 claim(s) not supported by the sources
Claims your sources do not support:
• It was adopted by 80% of search engines in 2011.
↳ figure(s) not in sources: 2011, 80
Cut these, or cite a source that backs them.That last tool is the point of the whole thing: it gives an agent a way to check its own work before it answers, without trusting another model's opinion about it. Point search at your own notes with "env": {"MCPTOOLS_CORPUS": "/path/to/notes.json"} (a { "id": "text", ... } file).
Related MCP server: calculator-mcp-server
Run it directly
pip install -e .
python -m mcptools # serves on stdio; type/paste JSON-RPC, one message per line# the handshake, by hand:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{}}}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"calc","arguments":{"expression":"2 + 3 * 4"}}}
# → {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"14"}],"isError":false}}The part worth stealing: it's testable without a client
An MCP server you can only exercise with Claude Desktop open isn't really testable. Because the protocol is plain JSON-RPC, the dispatch is a pure function of a message — so the suite drives the real handshake directly and launches the server in a subprocess and speaks MCP to it over stdio, asserting that three requests get three replies and the notification gets none. The guardrail is tested through the protocol too: code thrown at calc comes back as an MCP tool-error (isError: true), so the model sees the failure and the server stays up.
pip install -e ".[dev]" && pytest -q # 39 tests, stdlib onlyThe two live tools are tested against fixtures, never the network: the fetcher is resolved at call time so a test can substitute it, and the suite passes with sockets blocked. What is tested for real is failure — a network problem comes back as an MCP tool error the model can read and route around, not an exception that takes the server down for every other tool.
Operating it: logs, metrics, and an optional trail
A server you deploy needs more than correct replies — and all three of these are stdlib, none of them touch stdout (that's the JSON-RPC channel; a stray write corrupts the protocol):
Structured logs on stderr. Every
tools/callemits one JSON line — tool,duration_ms,isError, and the size of each argument — with aservingand astoppingline bracketing the session, the latter carrying a per-tool usage summary. Seeobs.py.In-process metrics. Calls and errors per tool, as a snapshot and on shutdown.
An optional result trail. Point
MCPTOOLS_DBat a file and the results ofgrade_answerandmodel_driftare persisted to SQLite — one row per call, behind a hand-rolled migration keyed onPRAGMA user_version(the zero-dependency form of Alembic). Unset, nothing is written and the server behaves exactly as before. Seestore.py.
Run it in Docker
docker build -t mcp-tools .
docker run -i --rm mcp-tools # MCP over stdio; -i keeps stdin open
# persist the trail — mount a dir and point MCPTOOLS_DB at it:
docker run -i --rm -v "$PWD/data:/data" -e MCPTOOLS_DB=/data/history.db mcp-toolsCI builds this image and completes a real MCP handshake through it, so "it runs in a container" is checked, not claimed.
Design notes
Notifications get no reply. A JSON-RPC message with no
idis a notification;notifications/initializedis handled by producing nothing, per the spec.Two error channels, on purpose. An unknown method or a missing argument is a JSON-RPC protocol error (
-32601/-32602); a tool that fails returns a result withisError: true. The model should adapt to a failed tool call, not have the connection torn down under it.Why from scratch. The official SDK is excellent and the right choice for production. Implementing the protocol directly here is the point of the repo: ~150 lines makes the whole lifecycle visible, and it keeps the dependency count at zero.
MIT · by Erik Hill
Available Tools
5 toolscalcA
Evaluate an arithmetic expression safely (no code execution; names, calls and imports are rejected).
| Name | Required | Description | Default |
|---|---|---|---|
| expression | Yes | e.g. '2 + 3 * 4' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses safety constraints (no code execution, rejection of names/calls/imports) which is critical. Lacks details on output format, but sufficient for a simple calculator.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with essential information and safety note. No extraneous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a simple tool with one parameter. Lacks specification of return type or error handling, but adequate given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a descriptive example. Description adds safety context but does not further clarify the parameter beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it evaluates arithmetic expressions safely, with explicit rejection of code execution. Distinguishes from siblings like search or grade_answer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Indicates safe usage for arithmetic, but does not explicitly specify when not to use or provide alternatives. Context signals show no obvious overlap with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_runsA
Ask whether a project's most recent stored eval run regressed against the one before it — per-case, so a better average can't hide a case that broke.
| Name | Required | Description | Default |
|---|---|---|---|
| suite | Yes | the suite/run name, e.g. 'rag-eval-lab' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It explains the per-case comparison and that it uses the two most recent runs, but omits edge cases like missing runs or output behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence. It is concise but could be more structured with separate statements for purpose and behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema, and the description does not explain return values or how results are presented. While the purpose is clear, completeness is lacking for a comparison tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description complements the parameter by indicating its role in identifying the suite. But it adds no new details beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool compares the two most recent eval runs per-case to detect regression, with a specific verb and resource. It distinguishes itself from siblings like search or grade_answer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (checking regression) but does not provide explicit guidance on when not to use or mention alternatives. It relies on context of sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grade_answerA
Check a draft answer against its sources and report which sentences the sources do NOT support — fabricated figures and claims the sources never make. Deterministic and lexical, not a model judgement. Call this on your own answer before giving it to the user when the answer is supposed to be grounded in provided material.
| Name | Required | Description | Default |
|---|---|---|---|
| answer | Yes | the answer to check | |
| sources | Yes | the source texts the answer is supposed to rest on | |
| threshold | No | min fraction of a sentence's content words that must appear in the sources (default 0.6) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It discloses that the tool is 'Deterministic and lexical, not a model judgement', which is a key behavioral trait. It also explains what it reports (unsupported sentences). However, it does not mention any side effects, rate limits, or output format details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two sentences with no wasted words. The first sentence states the core action and result; the second sentence provides usage guidance and a behavioral note. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 3-parameter set with full schema coverage and no output schema or annotations, the description covers purpose, usage, and a key behavioral trait (deterministic). However, it lacks information about the return value format (e.g., does it return a list of unsupported sentences? a score?), which would help an agent interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 100% (all 3 parameters have descriptions). The tool description adds marginal value beyond the schema: it characterizes the unsupported sentences as 'fabricated figures and claims the sources never make', but this is more about purpose than parameter semantics. The threshold parameter's description in the schema is already clear; the tool description doesn't add new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Check a draft answer against its sources and report which sentences the sources do NOT support'. It uses specific verbs ('check', 'report') and a specific resource ('draft answer', 'sources'). The sibling tools (calc, search, model_drift, compare_runs) are unrelated, so there's no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool: 'Call this on your own answer before giving it to the user when the answer is supposed to be grounded in provided material.' This provides clear context, though it does not explicitly state when not to use it or mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
model_driftA
Look up how a live LLM is currently scoring on a public, frozen eval suite (accuracy, latency, answer length, reliability, refusal rate) and whether those moved since the previous weekly run. Use it to check whether a model you're about to rely on has quietly changed. Omit model to list every tracked model.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | e.g. 'gpt-5', 'claude-opus', 'gemini' — matched loosely; omit for all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that the data is from a 'public, frozen eval suite' and that metrics include accuracy, latency, answer length, reliability, refusal rate. It also mentions weekly runs and drift tracking. While rate limits or auth are not mentioned, the read-only nature is clear from 'look up'. A minor gap is absence of explicit read-only declaration, but context sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-structured sentences. First sentence states the action and key metrics; second sentence provides use case and optional parameter usage. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description enumerates the returned metrics (accuracy, latency, answer length, reliability, refusal rate) and mentions the comparison to previous weekly run. For a simple lookup tool with one optional parameter, this is complete enough for an agent to understand input and output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter 'model' with schema description. The description adds concrete examples ('gpt-5', 'claude-opus', 'gemini') and the behavior when omitted ('list every tracked model'). Schema coverage is 100%, yet description still adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb phrase 'Look up how a live LLM is currently scoring on a public, frozen eval suite' and clearly identifies the resource (model performance metrics). It distinguishes from sibling tools like calc or search by focusing on drift detection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use it to check whether a model you're about to rely on has quietly changed.' Provides an alternative usage: 'Omit model to list every tracked model.' No ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
BM25 keyword search over a small bundled document corpus; returns the top matches with their scores.
| Name | Required | Description | Default |
|---|---|---|---|
| k | No | how many results (default 3) | |
| query | Yes | search terms |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the algorithm (BM25), corpus nature (small bundled), and output (top matches with scores). However, it does not address permissions, query limits, or whether the search is destructive. It is adequate but not thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that conveys the essential information (algorithm, corpus, output). No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool with 2 parameters and no output schema, the description fully covers the functionality: what it searches over, which algorithm, and what it returns. No gaps given the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers both parameters with descriptions (100% coverage). The description adds no extra meaning beyond the schema, so baseline score of 3 is appropriate. The schema already defines 'query' as 'search terms' and 'k' with default and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the tool's function as 'BM25 keyword search over a small bundled document corpus' and states the output ('returns the top matches with their scores'). The specific verb 'search' and resource 'small bundled document corpus' distinguishes it from sibling tools like 'calc' or 'model_drift'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does but provides no explicit guidance on when to use it versus alternatives, such as when the corpus is appropriate or limitations. Sibling tools are different, so implicit differentiation exists, but no when-not or alternative recommendations are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
calc - First observed
compare_runs - First observed
grade_answer - First observed
model_drift - First observed
search
TDQS
Scored across 5 tools
Each tool has a completely distinct purpose: arithmetic evaluation, keyword search, answer grading, model monitoring, and eval comparison. No overlap in functionality.
Names are mostly descriptive and use lowercase with underscores, but there is slight inconsistency: calc and search are single words, while others follow a verb_noun or noun_noun pattern. Still very readable.
5 tools is a well-scoped set for a utility server. Each tool serves a clear, non-redundant purpose, neither too few nor too many.
The tool set covers the stated utilities (math, search, answer checking, model drift, run comparison) comprehensively for its scope. Minor gaps like source management could exist but aren't critical.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Free OpenAI-compatible inference with signed provenance receipts and 3 focused MCP tools.
Security & DLP proxy for MCP: tool-poisoning scans, PII redaction on tool args/results. Beta.
All public upAPI operations as MCP tools: web scraping, search, screenshots, PDF, OCR and more.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides 18 tools including calculator operations (add, subtract, multiply, divide, power, sqrt, log, trigonometric functions) and secure sandboxed file operations (read, write, append, delete, list) for LangGraph agents and MCP clients. Features async support, YAML configuration, comprehensive logging, and path traversal protection.-
- AlicenseNot gradedqualityDmaintenanceProvides a comprehensive set of mathematical functions as MCP tools, enabling language models to perform calculations including arithmetic, trigonometry, logarithms, and more.101MIT
- FlicenseNot gradedqualityCmaintenanceProvides basic calculator operations (add, subtract, multiply, divide) as MCP tools for use with Claude Desktop and other MCP clients.-
- AlicenseAqualityBmaintenanceProvides a safe scientific runtime for agents with typed math operations including calculus, algebra, statistics, unit conversion, and more via MCP tools.4Apache 2.0