Skip to main content
Glama
neelbarm
by neelbarm

mcp-trustlayer

An MCP server that lets an agent ask whether it is allowed to act on its own output.

Python MCP Tests Dependencies License


An agent that has just extracted values from a document is the worst possible judge of whether those values are correct. It has no distance from its own output. This server moves that judgment outside the model: the agent proposes, a policy you control disposes.

agent  ──  "I extracted these 12 fields, may I write them?"  ──▶  mcp-trustlayer
                                                                       │
       ◀──  "9 post. 3 to a human. Here is why for each."  ────────────┘

Why this exists

Most extraction pipelines gate on one signal, a confidence score, and inherit a failure they never see. Confidence catches the model being unsure. It cannot catch the model being sure and wrong, because nothing in a confidently wrong answer looks hesitant.

The worked example below carries a fee field at 0.94 confidence whose value is the plan-review line item rather than the total. No threshold you could reasonably set catches it. An independent verification pass does.

Related MCP server: mcp-sequentialthinking-qa

Tools

evaluate_fields

Returns a disposition per field, one of post, review, or escaped.

{
  "fields": [
    { "name": "permit_number", "value": "BLD-2024-041877", "confidence": 0.99, "verification": "verified" },
    { "name": "permit_fee",    "value": "$1,240.00",       "confidence": 0.94, "verification": "mismatch" },
    { "name": "contractor",    "value": "Meridian",        "confidence": 0.38, "verification": "not_found" }
  ],
  "high_stakes": ["permit_number"],
  "verified": true
}
1 posted, 2 held for review, 0 escaped

[POST]    permit_number = 'BLD-2024-041877' (0.99/0.95) verified
[HOLD]    permit_fee    = '$1,240.00'       (0.94/0.85) verification mismatch
[HOLD]    contractor    = 'Meridian'        (0.38/0.85) confidence 0.38 below bar 0.85

Pass "verified": false to model what happens with no verification pass. The fee field flips to escaped, meaning it was written to the record while unsupported by its source. That number is what the second pass is worth.

calibrate_threshold

Sweeps the bar and reports review load against escaped errors, with and without verification, so the threshold gets chosen deliberately rather than inherited.

bar    verify-on: hold/escaped   verify-off: hold/escaped
0.85      3 / 0                     2 / 1
0.90      5 / 0                     4 / 1
0.95      7 / 0                     7 / 0

Install

No dependencies. Python 3.10+.

git clone https://github.com/neelbarm/mcp-trustlayer
cd mcp-trustlayer
python -m mcp_trustlayer.server

Claude Desktop

{
  "mcpServers": {
    "trustlayer": {
      "command": "python",
      "args": ["-m", "mcp_trustlayer.server"],
      "cwd": "/path/to/mcp-trustlayer"
    }
  }
}

Speaking to it directly

MCP is JSON-RPC 2.0 over stdio, so you can drive it with a pipe.

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | python -m mcp_trustlayer.server

Design notes

The protocol is implemented directly, not via an SDK. protocol.py is about 90 lines and handles initialize, tools/list, and tools/call over newline-delimited JSON-RPC. Keeping it dependency-free makes the wire format legible, which matters more in a reference implementation than convenience does.

Notifications get no response. notifications/initialized carries no id and must not be replied to. This is the most common place a hand-rolled MCP server breaks, so there is a test for it.

Tool errors return content, not crashes. A raised exception comes back as isError: true with the message in the content block, so the model can see what went wrong and adjust rather than losing the connection.

Descriptions are written for the model, not for a human reading docs. Each tool description says when to call it, because that text is the only instruction the model gets.

Tests

python -m pytest tests -q     # 10 passed

The suite includes an end-to-end case that spawns the server as a subprocess and speaks real JSON-RPC over stdio, rather than only calling the handler in-process.

MIT. Built by Neel Barmecha.

Available Tools

2 tools
calibrate_thresholdB

Sweep the confidence threshold across a range and report how review load trades against errors that get through. Use this to choose a bar deliberately rather than accepting a default.

ParametersJSON Schema
NameRequiredDescriptionDefault
lowNo
highNo
stepNo
fieldsYes
high_stakesNoField names held to the stricter bar.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must carry the transparency burden. It discloses that the tool sweeps a range and reports a tradeoff, implying read-only analysis, but it does not explicitly state side effects, return format, or whether any state is mutated. This is a moderate amount of behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. Every sentence adds value: the first states the function, the second gives usage guidance. It is efficiently front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The complexity is high: 5 parameters, a nested 'fields' object, no output schema, and low schema coverage. The description does not explain parameter semantics, return structure, or how 'high_stakes' affects behavior. It is insufficient for an agent to fully understand the tool's inputs and outputs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20% (only 'high_stakes' has a description). The tool description does not compensate by explaining parameters like 'fields', 'low', 'high', or 'step'. It only alludes to a range conceptually, which is insufficient for agents to correctly construct inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Sweep' clearly indicates the action, and 'confidence threshold across a range' specifies the resource. 'Report how review load trades against errors' defines the output. However, it does not explicitly distinguish this from the sibling tool 'evaluate_fields', so it lacks sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states 'Use this to choose a bar deliberately rather than accepting a default', which gives a clear when-to-use context. It does not mention when not to use it or any alternative tools, so exclusions are missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evaluate_fieldsA

Decide which extracted fields may be written to a system of record and which must go to a person. Returns a disposition per field: post, review, or escaped. Call this before acting on extracted data.

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldsYes
verifiedNoWhether a verification pass actually ran. Set false to measure what that pass is worth.
high_stakesNoField names held to the stricter bar.
standard_barNoConfidence a normal field must clear.
high_stakes_barNoStricter bar for costly-to-get-wrong fields.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the return type (disposition per field) and the exact possible values ('post, review, or escaped'), and signals that it is a decision/routing tool rather than a mutating one. This is transparent enough for safe use, though it doesn't elaborate on side effects (likely none) or edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and result. The second sentence gives a clear call-to-action. No wasted words or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential context: what it decides, what it returns (including the three disposition values), and when to call it. It does not fully elaborate on the decision logic (e.g., how thresholds are applied), but that is partially covered by the schema. For a tool with a fairly rich parameter set, this is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides informative descriptions for all parameters, including the meaning of confidence, verification, and the threshold bars. The description itself does not add much parameter-level detail beyond naming the dispositions, so it meets the baseline for high schema coverage but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Decide') and names the resource ('extracted fields') and the outcome (disposition per field: post, review, or escaped). It clearly distinguishes from its sibling by framing this as the pre-action evaluation step ('Call this before acting on extracted data').

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool ('before acting on extracted data'), which is clear contextual guidance. However, it does not mention alternatives or exclusions relative to the sibling tool 'calibrate_threshold', so it stops short of full comparative guidance.

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.

  1. 2 tool updatesv0.1.0
    • First observedcalibrate_threshold
    • First observedevaluate_fields

TDQS

A3.8/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: evaluate_fields determines field dispositions, while calibrate_threshold analyzes trade-offs across threshold values. There is no overlap in their responsibilities.

Naming Consistency5/5

Both tools follow the same verb_noun pattern ('evaluate_fields', 'calibrate_threshold'), using consistent lowercase with underscores. The pattern is predictable and clear.

Tool Count4/5

With only 2 tools, the set is slightly thin, but this matches the narrow, focused scope of the trust-layer functionality. Each tool earns its place.

Completeness3/5

The workflow is missing a way to actually apply the calibrated threshold to the evaluate_fields tool; calibration is informational but there is no explicit 'set_threshold' or parameter. This creates a notable gap for end-to-end usage.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers