http-semantics-mcp
Click on "Deploy 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., "@http-semantics-mcpis this cache entry fresh? max-age=60, age=30"
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.
http-semantics-mcp
Deterministic HTTP semantics judgement, delivered as an MCP server over stdio.
Status: released — v0.1.0. The server starts, completes the MCP handshake and
reports five tools — cache_evaluate, conditional_evaluate,
cors_evaluate, cors_simulate_fetch and vary_match. Each one ships a JSON
Schema descriptor (input and output) under
src/http_semantics_mcp/schemas/tools/, mirrored byte-identically to
schemas/tools/. All five are judged against frozen golden cases
(18 + 19 + 24 + 10 + 9) and produce byte-identical output; a contract gate
proves the published output schema equals each tool's real key set and value
shapes across every case, and a determinism gate proves same-input /
same-sha256 across all of them. Tagged
v0.1.0,
and the four-leg CI matrix is green. See
plan/05-里程碑.md.
What this is
An oracle for the corners of HTTP that fail silently: CORS, cache semantics,
conditional requests and Vary. You hand it request/response headers as
literals; it hands back a specification-derived verdict plus the rule IDs and
clause references behind it.
No network. No DNS, no TCP, no HTTP.
urlis parsed for scheme/host/port only. There is nothing to capture, proxy or replay.No capture. Input is caller-supplied header literals, not observed traffic.
No security scoring. No grades, no severity, no "is this site safe". Header security scanning is a different job and is out of scope.
Deterministic. Same input → byte-identical serialised output. No clock, no randomness, no environment reads. Time is an argument, not a lookup.
Tools
Tool | Question it answers | Milestone |
| Will the browser let this response through? | M2 ✅ |
| What happens across redirects, hop by hop? | M2 ✅ |
| Can this stored response be served without revalidating? | M3 ✅ |
| Which conditional-request rule decides the status? | M4 ✅ |
| Does this cached entry match the incoming request? | M4 ✅ |
tools/list returns exactly the tools that are implemented. A stub descriptor
would tell a client a capability exists that does not, which is why the
remaining milestones add tools rather than plans.
A cache verdict by hand
Ask whether a stored response is still fresh, and what the numbers are:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"cache_evaluate","arguments":{"now":"2026-01-01T00:00:30Z","response_headers":{"Cache-Control":"max-age=60","Date":"Thu, 01 Jan 2026 00:00:00 GMT"},"stored":{"stored_at":"2026-01-01T00:00:10Z","age":"10"}}}}' \
| python -m http_semantics_mcp{"action":"serve","current_age":30,"freshness_lifetime":60,"is_fresh":true,"must_revalidate":false,"reasons":[],"stale_while_revalidate_window":0}now is an argument, not a clock read: the same call always returns the same
bytes, on any machine, at any time.
What it is not
Not a browser. Verdicts are spec-derived; where an implementation differs from the specification, the specification wins and the divergence is noted.
Not a substitute for
mitmproxy/powhttp-style capture tools. Those need real traffic; this needs a JSON object.Not a security scanner. Out of scope by design (see
plan/01-题目文档.mdsection 6).
Related MCP server: judgment-pack-runtime
Install
Requires Python 3.8 or newer. The runtime has no third-party dependencies.
git clone https://github.com/yuluo554/http-semantics-mcp.git
cd http-semantics-mcp
python -m pip install -e ".[dev]".[dev] installs the test-time dependencies only (pytest, PyYAML). If you
only want to run the server, python -m pip install -e . is enough.
Verify the install:
python -m http_semantics_mcp --version
python -m http_semantics_mcp --selftest--selftest prints one line per check and exits 0 on pass, 1 on failure.
It never prints a verdict — it checks the installation, not your headers.
Run
The server speaks newline-delimited JSON-RPC 2.0 on stdin/stdout.
python -m http_semantics_mcpOr, after installation, the console script:
http-semantics-mcpClient configuration
Claude Code (~/.claude.json or project .mcp.json):
{
"mcpServers": {
"http-semantics": {
"command": "python",
"args": ["-m", "http_semantics_mcp"],
"env": {}
}
}
}Codex (~/.codex/config.toml):
[mcp_servers.http-semantics]
command = "python"
args = ["-m", "http_semantics_mcp"]Any stdio MCP client works: spawn the process, write one JSON object per line, read one JSON object per line.
Protocol surface
Method | Result |
|
|
| no response |
|
|
| registered tools, ASCII-sorted by name |
| tool result, or a JSON-RPC error for an unknown tool |
anything else |
|
Supported protocol versions: 2025-06-18, 2025-03-26, 2024-11-05.
An unrecognised version is answered with 2025-06-18, which the specification
permits; the client decides whether to continue.
Error codes: -32700 parse error, -32600 invalid request, -32601 unknown
method, -32602 invalid params, -32002 not initialized, -32603 internal
error. A tool-level bad input is not a JSON-RPC error: it returns a result
with isError: true.
A handshake by hand
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| python -m http_semantics_mcpA verdict by hand
Ask whether a cross-origin response is allowed, and what to change if not:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"cors_evaluate","arguments":{"method":"GET","url":"https://api.example.com/v1","origin":"https://app.example.com","credentials":"omit","request_headers":{},"response":{"status":200,"headers":{}},"is_preflight":false}}}' \
| python -m http_semantics_mcpThe verdict arrives as one JSON string inside content[0].text:
{"decision":"block","missing_headers":["access-control-allow-origin"],"notes":{"allow_credentials_null_origin":false,"max_age_capped_by_client":false,"wildcard_with_credentials":false},"recommended_headers":{"access-control-allow-origin":"https://app.example.com"},"violations":[{"code":"CORS_MISSING_ALLOW_ORIGIN","detail":"response has no Access-Control-Allow-Origin (origin=https://app.example.com)","spec_ref":["Fetch §CORS check"]}]}decision: "block" is a successful judgement, so isError stays false. Only
a malformed request sets isError: true, and it still answers with a payload
rather than a stack trace.
Development
python -m pytest
python tools/run_gates.py
python tools/mutate_check.py
python tools/smoke_stdio.py
python tools/gen_codes.py --check
python tools/gen_golden.py --check
python tools/gen_schemas.py --check
python scripts/check_release.py --pre-tagpytestruns the full suite (protocol, transport framing, determinism, gates, packaging surface).tools/run_gates.pyruns the eight static gates and names the failing one.tools/mutate_check.pybreaks one behaviour per gate and asserts the gate goes red. A gate that cannot fail is decoration; this script is how that claim is kept honest rather than asserted.tools/smoke_stdio.pystarts the server as a real subprocess and asserts on the raw bytes: every stdout line is JSON, no\r, response count matches request count.tools/gen_codes.py --check,tools/gen_golden.py --checkandtools/gen_schemas.py --checkrecompute the generated artefacts (rule catalogue, golden cases, schema mirror) and compare bytes, so a hand edit that drifts from its source is caught rather than committed.scripts/check_release.py --pre-tagis the release-terminal gate. It is not wired into CI on purpose: before a tag exists, several of its checks must be red, and a permanently red job carries no information.
Repository gates
Eight static gates run in tests, in CI, and inside the release check. Each one
must be provably able to fail (tests/test_gates.py and tests/test_m1_gates.py
inject a defect for every gate, and tools/mutate_check.py proves it end to
end):
Gate | Rule |
purity |
|
no-nondeterminism | the whole runtime package imports no clock, randomness or network; no |
single-serialiser |
|
absolute paths | no machine-specific path (drive letter, home directory, UNC share) in repository text |
line endings | every text file is LF-only and |
oracle independence |
|
golden hygiene | every frozen case has the required fields and no |
code literals | no hand-written package source spells a rule code; the generated catalogue ( |
Two further gates live in the test suite rather than in tools/gates.py,
because they must run the tools instead of reading files:
Gate | Rule |
schema parity | for every tool, |
determinism | two calls on the same input serialise to the same sha256, for every tool and every case, and no output carries a machine-specific path or a date the caller did not supply |
Layout
src/http_semantics_mcp/ server, protocol, registry, judgement layer
schemas/tools/ generated mirror of the in-package JSON Schemas
references/ generated mirror of the in-package code table
data/golden/ frozen golden cases (input + expected output)
data/wpt/ WPT cors/ directory index (paths + blob shas only)
data/wpt-mapping.json WPT cors/ mapping ledger
plan/ the project plan, milestones and release records
tools/ gates, smoke test, generators
scripts/check_release.py release-terminal self-checkThe in-package copies under src/http_semantics_mcp/ are the only editable
sources for codes.json and the tool schemas; the top-level copies are
byte-identical mirrors so an installed distribution and a reader both see the
same contract.
Data and verification
All inputs are synthetic. Domains are reserved examples (example.com,
example.org, example.net, localhost); ETags are explicit fakes; times are
fixed literals. No real response headers, tokens, cookies, HAR or pcap files
are collected, and .gitignore blocks those paths.
Golden cases freeze the input and the expected output. Expected values are
produced by an independent oracle under tools/golden_oracle/, not by the
implementation under test, and a gate forbids the oracle from importing the
judgement layer — otherwise the benchmark would be comparing an implementation
with itself.
Browser behaviour is cross-checked against
web-platform-tests/wpt's cors/
suite (index pinned to commit 850b36a5, data day 2026-10-18), transcribed to
header-level cases in data/golden/. The ledger in data/wpt-mapping.json
accounts for all 45 files in the directory: 15 mapped, 30 listed with a reason
(real network, TLS, timing, browser-proprietary behaviour, or out of scope).
Nothing is guessed at, and no test body is copied into this repository.
Measured on this build
Every number below comes from the local double-interpreter run. CI is now wired
up: the four-leg matrix {ubuntu, windows} × {3.8, 3.12} is green on both the
main push (run
39141511111)
and the v0.1.0 tag push (run
39141686281).
Metric | Value |
Frozen golden cases, byte-identical to production | 87 / 87 |
Rule codes reachable by at least one case (set equality, both directions) | 31 / 31 |
WPT | 15 / 45 (30 / 45 listed with a reason; all 15 mapped rows re-run and reconcile with production) |
Tool descriptors (input + output schema per tool) | 5 |
Static gates | 8 |
Mutations that must turn a gate red | 43 / 43 |
Collected tests | 379 (Python 3.8) / 379 (Python 3.12) |
The three generated artefacts are recomputed and compared byte for byte on
every run (gen_codes --check, gen_golden --check, gen_schemas --check),
and every static gate has at least one mutation proving it can fail.
License
MIT. See LICENSE.
Project plan
plan/00-README总览.md— index, decisions, promise ledgerplan/01-题目文档.md— the problem statement (frozen)plan/02-架构与技术选型.md— architecture and transport contractplan/03-模块详设.md— T1–T5 algorithmsplan/04-数据计划.md— golden cases, WPT mapping, oracle independenceplan/05-里程碑.md— milestones and definition of doneplan/06-交付对标与决策记录.md— scoring map and decision log
Available Tools
5 toolscache_evaluateA
Decide whether a stored response may be reused without revalidating. Applies the RFC 9111 age and freshness arithmetic (Date, Age, Cache-Control, Expires, Last-Modified) and returns action serve|revalidate|miss, the age and freshness lifetime in whole seconds, and the rule IDs with their clause references. now is an argument: the cache never reads a clock.
| Name | Required | Description | Default |
|---|---|---|---|
| now | Yes | evaluation instant (YYYY-MM-DDTHH:MM:SSZ or an HTTP-date) | |
| stored | Yes | ||
| request_headers | No | header name -> value | |
| response_headers | No | header name -> value |
Output Schema
| Name | Required | Description |
|---|---|---|
| action | Yes | |
| reasons | Yes | |
| is_fresh | Yes | |
| current_age | Yes | RFC 9111 section 4.2.3 age, whole seconds |
| must_revalidate | Yes | |
| freshness_lifetime | Yes | whole seconds |
| stale_while_revalidate_window | Yes | whole seconds; 0 when undeclared |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it states the tool is a pure evaluator whose evaluation instant is an argument ('the cache never reads a clock'), which tells the agent the result is deterministic and independent of wall-clock state. It also discloses the exact header classes consumed and the returned action vocabulary. It stops short of explicitly declaring no side effects or network access.
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?
Three dense sentences, no filler. The purpose is front-loaded, followed by the rule set, the return shape, and the key 'now is an argument' caveat that an agent must not miss. 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?
For a nested-input evaluator with an output schema (so return values needn't be spelled out), the description covers purpose, rule basis, return vocabulary, and the clock-independence constraint. The remaining gap is the missing editorial distinction between stored.headers and response_headers, and no note on error behavior for malformed dates or missing required fields.
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 75%, so the schema already documents now, stored, stored_at, and age; baseline is 3. The description adds value by naming the semantically relevant headers (Date, Age, Cache-Control, Expires, Last-Modified) and stressing that now must be supplied, but request_headers and response_headers themselves get no explanation and the split between stored.headers and response_headers is never clarified.
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 names a specific verb and resource: deciding whether a stored response may be reused without revalidating, computed via RFC 9111 age and freshness arithmetic. That is far more precise than a generic 'evaluate cache'. It never distinguishes itself from siblings such as conditional_evaluate or vary_match, so an agent gets no explicit routing help.
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 framing 'Decide whether a stored response may be reused without revalidating' implies the use case (checking cache freshness before serving), but there is no explicit when-to-use, when-not-to-use, or named alternative. An agent must infer that conditional_evaluate handles the conditional-request path instead. Usage is implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
conditional_evaluateA
Judge one request's preconditions and report the status they decide. Evaluates If-Match, If-Unmodified-Since, If-None-Match and If-Modified-Since in the RFC 9110 section 13.2.2 precedence order, stopping at the first applicable one, and returns status 200|304|412, which rule decided it, and the rule IDs with their clause references.
| Name | Required | Description | Default |
|---|---|---|---|
| method | Yes | HTTP request method | |
| resource | Yes | ||
| request_headers | Yes | header name -> value |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | |
| explain | Yes | |
| rule_applied | Yes | |
| weak_comparison_used | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the precedence order applied, the short-circuit behavior ('stopping at the first applicable one'), and the discrete outcome set (200|304|412) plus the deciding rule and clause references. It stops short of stating that evaluation is side-effect free and does not touch the resource.
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?
A single dense sentence that front-loads the action and then the algorithm and outputs in descending priority. Every clause carries information, though the comma-chained precedence/return list is slightly heavy to parse; a second short sentence would have been cleaner without adding length.
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 nested-schema tool with an output schema (so return values need not be explained) and no annotations, the description supplies the algorithm, precedence rule, and outcome set an agent needs. It lacks only the sibling-disambiguation and side-effect/purity statement, which are modest gaps given how self-contained the tool is.
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 67%, so the schema documents most of method, resource.etag, resource.last_modified, and request_headers. The description indirectly signals which header names in request_headers are meaningful (the four conditional headers), which is some added semantic value, but it explains nothing about how method or resource interact with those headers.
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?
Names a specific verb+resource: judging one request's precondition headers and reporting the resulting status. The scope (If-Match, If-Unmodified-Since, If-None-Match, If-Modified-Since) clearly separates it from siblings like cache_evaluate, cors_evaluate, and vary_match; an agent can route without opening the schema.
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 RFC 9110 §13.2.2 framing implies the context (HTTP conditional request evaluation), so usage is inferable. However, it never states when to prefer this over cache_evaluate or vary_match, nor any when-not condition or prerequisite (e.g. that resource state must be supplied). No explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cors_evaluateA
Judge one HTTP response against the Fetch Standard CORS check. Returns decision allow|block, the violated rule IDs with their clause references, the headers that are missing, and what to send instead. No network: url is parsed for scheme/host/port only.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | target URL; only its origin is used | |
| method | Yes | HTTP request method | |
| origin | No | request Origin; omit or null for a same-origin request | |
| response | Yes | ||
| credentials | No | credentials mode of the request | |
| is_preflight | Yes | is this the preflight response? | |
| request_headers | No | header name -> value |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| decision | Yes | |
| violations | Yes | |
| missing_headers | Yes | lowercase header names, ASCII-sorted |
| recommended_headers | Yes | lowercase header name -> value to send instead |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, and it does well: 'No network' establishes this as a pure, side-effect-free evaluation, and it enumerates the return shape (decision allow|block, violated rule IDs with clause references, missing headers, remediation headers). It stops short of explicitly stating determinism or that no state is mutated.
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?
Three dense, front-loaded sentences with no filler: purpose first, then output contract, then the no-network constraint. Every clause carries information an agent needs.
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?
An output schema exists, so return values need not be explained, yet the description still summarizes them usefully. Combined with 7 parameters at 86% schema coverage and the key 'no network' caveat, nothing material an agent needs in order to call this correctly is missing.
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 86%, so the baseline is 3, but the description adds real meaning beyond the schema: 'url is parsed for scheme/host/port only' clarifies how the url parameter is consumed, refining the schema's 'only its origin is used.' It also frames response headers as the object to be judged, which sharpens the nested schema's intent.
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?
Specific verb and resource: 'Judge one HTTP response against the Fetch Standard CORS check,' with the scope constraint that only the URL's origin is used. This implicitly separates it from cors_simulate_fetch (this one does no network work and evaluates a given response), but no sibling is named, so sibling differentiation is inferred rather than explicit.
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?
Usage is implied by 'Judge one HTTP response' and by the statement that the URL is only parsed for scheme/host/port, telling the agent this tool takes an already-observed response. However, there is no explicit when-to-use, when-not-to-use, or named alternative (e.g. cors_simulate_fetch) for the case where the agent has no response yet.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cors_simulate_fetchB
Walk a redirect chain hop by hop and judge each hop with the CORS check. Reports the ordered redirect events (origin_set_to_null, credentials_dropped), the visible response headers, and the effective Access-Control-Max-Age.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | target URL; only its origin is used | |
| mode | No | fetch mode; defaults to cors | |
| method | Yes | HTTP request method | |
| origin | No | request Origin; omit or null for a same-origin request | |
| response | Yes | ||
| redirects | No | ||
| credentials | No | credentials mode of the request | |
| is_preflight | No | is this the preflight response? | |
| request_headers | No | header name -> value |
Output Schema
| Name | Required | Description |
|---|---|---|
| hops | Yes | in occurrence order, not sorted |
| events | Yes | in occurrence order, not sorted |
| decision | Yes | |
| final_type | Yes | |
| visible_headers | Yes | lowercase header names, ASCII-sorted |
| max_age_effective | Yes | whole seconds |
| preflight_occurred | Yes | |
| preflight_cache_key | Yes | per data/README.md section 4.7 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It does usefully disclose the observed behaviors it reports (origin_set_to_null, credentials_dropped, effective Max-Age), which signals a pure, side-effect-free simulation. It does not state that the tool performs no network I/O, that credentials mode changes mid-chain, or how the simulated stack decides hops, leaving some behavioral questions open.
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 tight sentences, front-loaded with the core action and followed by the reporting surface. Every clause carries information, though the parenthetical event list is slightly list-shaped rather than explanatory.
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?
An output schema exists, so the description legitimately need not spell out return shapes, and it nonetheless sketches them. For a 9-parameter, nested-object tool with no annotations and a sibling that overlaps in intent, the description stops short of the routing and semantics detail an agent needs to call it correctly versus cors_evaluate.
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 description coverage is 78% with 9 parameters, so the schema does most of the documentation work. The description adds no parameter-level meaning at all: nothing explains how is_preflight interacts with redirects, or how mode/credentials shape the hop judgments. Baseline 3 is appropriate given the schema covers most fields, though the description could have clarified the semantically loaded ones.
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 gives a specific verb and resource: it walks a redirect chain hop by hop and judges each hop with the CORS check, and it enumerates the outputs (redirect events, visible headers, effective Access-Control-Max-Age). That is much clearer than a restated name. However, it never distinguishes itself from the sibling cors_evaluate, which an agent could easily mistake for this tool.
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?
There is no when-to-use guidance, no statement of prerequisites, and no mention of alternatives, even though cors_evaluate is a direct sibling that plausibly competes for the same intent. The agent must infer from the name alone that this tool is for multi-hop redirect scenarios while cors_evaluate covers a single exchange.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vary_matchB
Decide whether a stored response can be reused for an incoming request, per RFC 9111 section 4.1. Compares the fields named by the stored Vary value under that field's normalisation policy and returns match hit|miss, the fields that differ, the normalised Vary members, and the rule IDs with their clause references.
| Name | Required | Description | Default |
|---|---|---|---|
| cached | Yes | ||
| incoming | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| match | Yes | |
| reasons | Yes | |
| normalized_vary | Yes | lowercase header names, ASCII-sorted |
| differing_headers | Yes | lowercase header names, ASCII-sorted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It does disclose meaningful behavior: comparison is governed by each field's normalisation policy and the result is a hit/miss classification plus differing fields and rule IDs, which implies a read-only, deterministic evaluation. It does not state the safety profile (pure function, no mutation, no network or auth) or how missing headers are treated.
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 sentences, front-loaded with the decision and the normative basis, with the return payload listed afterwards. Dense but every clause carries information; no filler or tautology.
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?
An output schema exists, so return values need not be elaborated (the description nonetheless enumerates them). For a nested two-object computation grounded in an RFC, the definition covers intent and output but omits the parameter-to-field mapping and edge-case semantics, leaving an agent with gaps given 0% schema description coverage.
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 description coverage is 0%, so the description has to compensate for two required nested-object parameters. It does convey the split semantically — the stored Vary value with headers at store time versus the incoming request headers — but never maps this onto the cached.vary, cached.request_headers_at_store and incoming.request_headers fields by name, and says nothing about repeated-header or array handling.
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?
States a specific verb ('Decide whether') and a precise resource (a stored response can be reused for an incoming request), anchored to RFC 9111 section 4.1 and the Vary mechanism. It is far more specific than the sibling names alone, though it never explicitly distinguishes itself from the conceptually adjacent cache_evaluate.
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?
Use is implied by the RFC citation and the 'stored response vs incoming request' framing, but there is no explicit when-to-use, when-not-to-use, or pointer to alternatives such as cache_evaluate or conditional_evaluate. The agent must infer routing from the RFC reference.
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
cache_evaluate - First observed
conditional_evaluate - First observed
cors_evaluate - First observed
cors_simulate_fetch - First observed
vary_match
TDQS
Scored across 5 tools
Most tools target clearly distinct HTTP semantics concerns (cache freshness, Vary matching, conditional preconditions, CORS). The two CORS tools (cors_evaluate for a single response, cors_simulate_fetch for a redirect chain) and the two cache-related tools (cache_evaluate for freshness, vary_match for field matching) are related but their scopes are differentiated in the descriptions.
All names use snake_case with a domain_prefixed convention (cors_*, cache_*, conditional_*, vary_match). Mostly consistent, though cors_simulate_fetch breaks the domain_action pattern slightly with an extra verb.
Five focused tools are well-scoped for a narrow HTTP semantics/RFC-conformance evaluator, with no redundant or filler entries. Each tool earns its place.
The set covers the core RFC 9111 cache reuse path (freshness + Vary), RFC 9110 preconditions, and CORS including redirects, which is solid coverage. Minor gaps exist (e.g., no explicit cache storage/no-store decision or combined end-to-end request evaluation), but agents can work around them.
Maintenance
Related MCP Connectors
Deterministic prompt-injection detector; signed, offline-verifiable verdicts. Not an LLM.
Query SEC EDGAR filings, XBRL financials, and company data via MCP. STDIO or Streamable HTTP.
Validate JSON, YAML, XML and CSV with exact line/column errors and silent-corruption warnings.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA thin stdio client that proxies to the Second Eyes API, enabling wallet-equipped agents to pay via x402 and receive deterministic verdicts.-
- AlicenseNot gradedqualityAmaintenanceServes offline document validation and evaluation operations of the Judgment Pack Specification to MCP clients over stdio, enabling agents to validate and evaluate JPS documents as tool calls. Supports conformance validation, experimental evaluation with disposition and error classes, and corpus testing.2Apache 2.0

yotta-verify-mcpofficial
AlicenseNot gradedqualityBmaintenanceProvides a deterministic pre-install security scan for Agent skills, plugins, and MCP servers via stdio, returning verdicts, audited badges, CI gates, and reports without executing code or making network calls.74 npmMIT- AlicenseNot gradedqualityBmaintenanceExposes an offline data-contract runtime to MCP-capable agents, enabling them to lint ODCS contracts and validate CSV datasets against them via stdio.MIT