Xyntherium Verify
MCP server
Two tools any AI agent can call before it states a fact or takes an action: verify_answer checks a drafted answer against the passages it relies on, verify_against_document against one document. Each returns every claim marked supported, unsupported or contradicted, with the source passage that decides it.
Endpoint
URL https://www.xyntherium.com/mcp
Header Authorization: Bearer <your API key>Streamable HTTP, stateless; protocol versions 2026-07-28 and 2025-11-25 (and 2025-06-18 / 2025-03-26 clients through initialize). Discovery and tools/list need no key; every tool call does. No check ever runs without a valid key.
Install
Claude Code
claude mcp add --transport http xyntherium-verify https://www.xyntherium.com/mcp \
--header "Authorization: Bearer $XYN_API_KEY"Then claude mcp list shows it connected. Add --scope user to make it available in every project.
Claude Desktop
Settings → Developer → Edit config (claude_desktop_config.json), through the mcp-remote bridge:
{
"mcpServers": {
"xyntherium-verify": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://www.xyntherium.com/mcp", "--header", "Authorization: Bearer ${XYN_API_KEY}"],
"env": { "XYN_API_KEY": "xyn_live_…" }
}
}
}Or Settings → Connectors → Add custom connector with https://www.xyntherium.com/mcpand no key: Claude sends you to Xyntherium to sign in and approve access (OAuth). The access appears on your API keys page as “MCP: Claude” and lasts 90 days.
Cursor
In ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"xyntherium-verify": {
"url": "https://www.xyntherium.com/mcp",
"headers": { "Authorization": "Bearer xyn_live_…" }
}
}
}VS Code
In .vscode/mcp.json; VS Code asks for the key once and stores it securely:
{
"inputs": [{ "type": "promptString", "id": "xyn-key", "description": "Xyntherium API key", "password": true }],
"servers": {
"xyntherium-verify": {
"type": "http",
"url": "https://www.xyntherium.com/mcp",
"headers": { "Authorization": "Bearer ${input:xyn-key}" }
}
}
}Example configs, a tiny client wrapper and an agent system-prompt snippet are in the open-source integration repository: augustbrookz/xyntherium-verify-mcp (MIT).
A 30-second demo
- Install with the Claude Code command above.
- Ask Claude:
Our return policy says: "Refunds are available within 30 days for unopened items with proof of purchase." A customer asks if they can get a refund. Draft a one-sentence reply, then verify it with xyntherium-verify before you show it to me, and fix anything the check flags. - Claude drafts “Yes, refunds are available within 30 days”, calls the tool, and the result names what it dropped:
REVISE: dropped “for unopened items with proof of purchase”.
- Dropped: “Refunds are available within 30 days.” leaves out “for unopened items with proof of purchase”; the source says “within 30 days for unopened items with proof of purchase” (source returns).
Claims:
1. [unsupported] “Refunds are available within 30 days.”; drops “for unopened items with proof of purchase”; source returns: “Refunds are available within 30 days for unopened items with proof of purchase.”.
0 of 1 statements supported · mode fast · rules 2.1.0 · request …Claude then rewrites the reply with the conditions and checks again: SEND.
The same from a shell, without a client:
curl -s -X POST https://www.xyntherium.com/mcp \
-H 'content-type: application/json' -H 'accept: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'curl -s -X POST https://www.xyntherium.com/mcp \
-H "Authorization: Bearer $XYN_API_KEY" \
-H 'content-type: application/json' -H 'accept: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"verify_against_document","arguments":{
"answer":"Refunds are available within 30 days.",
"document_text":"Refunds are available within 30 days for unopened items with proof of purchase."}}}'The tools
verify_answer
Verify a drafted answer against the source passages it relies on BEFORE you state it to the user or act on it. Returns every claim in the answer marked supported, unsupported or contradicted, each with the source passage that decides it, and one verdict for the answer: send, cite_sources, revise or ask_a_person. Call it whenever an answer restates facts from documents in the conversation (a policy, contract, price list, spec, ticket, email, search result, tool output): it catches a dropped condition or exception, a changed number or date, a flipped negation, a wrong entity, and any statement the sources never make. It checks only against the sources you pass: it never fetches URLs and does not check facts about the world. Read-only and idempotent. One call is one check against the API key’s plan.
| answer | required | The drafted answer, exactly as it would be sent or acted on (up to 20,000 characters) |
| sources | required | [{ text, id?, title? }]: the passages the answer must follow (text, never URLs; up to 25 sources of 100,000 characters, 400,000 in total) |
| question | optional | The user's question or the task, if there was one |
| mode | optional | fast (default): code checks plus a fast model. strict: also escalates uncertain claims to a stronger model |
verify_against_document
Verify a drafted answer against ONE document’s text (a policy, contract, spec, README, email, transcript) BEFORE you state it to the user or act on it. Same result as verify_answer: every claim marked supported, unsupported or contradicted with the passage that decides it, plus a verdict (send, cite_sources, revise or ask_a_person). Use it when the answer rests on a single document you have in full; use verify_answer when it rests on several passages. Pass the document text itself, not a URL: nothing is fetched. Read-only and idempotent. One call is one check against the API key’s plan.
| answer | required | The drafted answer |
| document_text | required | The document's text (up to 100,000 characters; pass the relevant sections of a longer one) |
| title | optional | The document's name |
| question | optional | The user's question or the task |
| mode | optional | fast (default) or strict |
The result
Text (the verdict first, then each problem, then every claim) and the same as structured content: verdict (send, cite_sources, revise, ask_a_person), claims[] with statement, status (supported / unsupported / contradicted), reason, source_id, source_passage and material, plus dropped, contradicted, unsupported and unresolved lists, the request id and the evidence-ledger id. A claim the sources do not settle (a prediction, a comparison, a disagreement between sources) is unsupported with a reason saying so. Both tools are read-only and idempotent and change nothing. Everything passed in is treated as untrusted data: it is checked, never followed.
When an agent should call it
The server gives every client these instructions:
Before you state facts drawn from documents in the conversation, or act on them (send a reply, file a change, book, refund, approve), verify the drafted answer: call verify_answer with the answer and the passages it relies on, or verify_against_document with the answer and the one document it rests on. The result marks every claim supported, unsupported or contradicted with the passage that decides it. On REVISE, fix what it names (a dropped condition, a changed number, a claim the sources never make) and check again before proceeding. On ASK A PERSON, tell the user what the sources do not settle instead of guessing. Do not call it for chit-chat, for answers with no source text, or to fact-check the world: it checks only against the text you pass.
Metering, limits and cost
| Plan quota | Every MCP call is one check against your plan's monthly allowance, the same one the API and Verify Gate use (Free 1,000, Builder 8,000, Team 40,000). An answer longer than 25 statements counts as one check per 25. Failed or partial checks are not counted. |
| Free daily limit | 50 MCP checks per day (UTC) on the Free plan. |
| Per-key spend cap | $2.00 of model spend per API key per day (UTC), across every surface the key uses; about 1,666 checks at the measured cost. |
| Global spend cap | $5.00 of model spend per day across every MCP check; past it the server refuses calls until 00:00 UTC and the API is unaffected. |
| Rate limits | 30 calls a minute per account on Free (Builder 120, Team 600); 60 a minute per key by default. |
| Input limits | answer 20,000 characters; 25 sources of 100,000 characters (400,000 in total); document_text 100,000 characters; request body 1.2 MB. Oversized input gets a tool error naming the limit, and nothing is charged. |
| Cost to run | About 0.1¢ of model spend per check in fast mode (measured mean 0.098¢, p95 0.15¢); the plan prices are on the pricing page. |
A refused call comes back as a tool error that says which limit was hit and when it resets, with a Retry-After header. Pricing.
Data handling
- What is sent to Xyntherium: the answer, the source or document text, and the question if you pass one. Nothing else from your conversation, repository or machine. URLs are never fetched.
- What the model sees: the model provider (Anthropic) receives the text needed to split the answer into claims and check each one, under its commercial API terms, which exclude training on API traffic. Xyntherium never trains on your text.
- What is stored: the text and the result, encrypted (AES-256-GCM), for your plan’s retention window: 7 days on Free, 30 on Builder, 90 on Team; then deleted. The evidence ledger (hashes of the text, verdicts and offsets, not the text) is kept 30, 90 or 365 days by plan. Telemetry is structural only: counts, latency, cost, the client name and version, never content.
- Deletion: email support@xyntherium.com from the address on the account to delete everything tied to it. Privacy · Security.
Compatibility
Tested by connecting each client to the hosted server on 24 October 2026 (clients first connected 19 October). “Not tested” means no such client was available for the run, not that it fails.
| Client | Connection | Protocol | Result | Notes |
|---|---|---|---|---|
| Claude Code 2.1.309 | Streamable HTTP (claude mcp add --transport http … --header) | 2026-07-28 | works | Connected with the documented command on 24 October (both tools listed); on 19 October (2.1.301) it called verify_answer and got REVISE with the dropped condition. |
| Raw JSON-RPC client (curl), server 1.2.0 | Streamable HTTP | 2025-11-25 | works | On 24 October: initialize, tools/list (two tools), a keyless call → 401 with WWW-Authenticate, an invalid key → 401, a 1.3 MB body → 413 naming the limits. |
| MCP Inspector CLI | Streamable HTTP | 2025-11-25 | works | initialize, tools/list and tools/call. |
| mcp-remote 0.15.1 (stdio bridge) | stdio to Streamable HTTP | 2025-11-25 | works | tools/list through the bridge Claude Desktop uses; the desktop app itself was not run. |
| Raw 2026-07-28 client (curl) | Streamable HTTP, stateless | 2026-07-28 | works | server/discover, tools/list (ttlMs, cacheScope), tools/call, HeaderMismatch on a wrong Mcp-Method. |
| Claude Desktop | stdio via mcp-remote | 2025-11-25 | not tested | No desktop app in the test environment; the bridge it runs was tested above. |
| Claude (web) | Custom connector, OAuth | — | not tested | OAuth metadata, registration and the sign-in redirect were tested; the full approve-and-connect flow needs a signed-in person. |
| Cursor | Streamable HTTP, headers | — | not tested | No Cursor client in the test environment. |
| VS Code | Streamable HTTP, input variable | — | not tested | No VS Code MCP client could be driven from the test environment. |
Reproducible examples
Each runs exactly as shown with your key; paste the arguments into any client, or call the API with the same body.
A support answer that drops the final-sale exception (drafted by claude-haiku-5-5)
{
"question": "can I get a refund on the jacket I got 2 weeks ago? it doesn't fit",
"answer": "Yes, if it's unworn with tags attached, it's returnable within 30 days of delivery; non-members pay a $7 fee.",
"sources": [
{
"id": "returns",
"title": "Northwind Outfitters: Returns and refunds",
"text": "Returns and refunds\n\nUnworn items can be returned for a full refund within 30 days of delivery. Items must have their original tags attached.\n\nShipping costs are not refunded. Return shipping is free for Northwind members; other customers pay a $7 return label fee, deducted from the refund.\n\nFinal-sale items, including anything bought in the clearance section, cannot be returned or exchanged.\n\nRefunds are issued to the original payment method within 5 business days of receiving the return. Gift purchases are refunded as store credit."
}
]
}Expected: revise, naming “Final-sale items”. Source: The policy is written for this example. The answer is claude-haiku-5-5 output, unedited (run 3 of 5 with a 20-word limit; claude-sonnet-5-5 kept the exception in 3 of 3 runs).
A refund answer that drops the conditions
{
"question": "Can I get a refund?",
"answer": "Refunds are available within 30 days.",
"sources": [
{
"id": "returns",
"title": "Return policy",
"text": "Refunds are available within 30 days for unopened items with proof of purchase."
}
]
}Expected: revise, naming “unopened items” and “proof of purchase”. Source: Written for this example.
A tariff answer that uses the rate from an older HTS revision
{
"question": "What is the general rate of duty under heading 9903.81.87 for goods entered on June 10, 2025?",
"answer": "The general rate of duty under heading 9903.81.87 is the duty provided in the applicable subheading + 25%.",
"sources": [
{
"id": "hts-9903.81.87",
"title": "2025 HTS Revision 14 (in force 2025-06-06 to 2025-06-20), heading 9903.81.87",
"text": "HTSUS 9903.81.87 (2025 HTS Revision 14, in force from 2025-06-06): Except for derivative iron or steel products described in headings 9903.81.89, 9903.81.90 or 9903.81.91, products of iron or steel provided for in the tariff headings or subheadings enumerated in subdivision (j) of note 16 to this subchapter. General rate of duty: The duty provided in the applicable subheading + 50%."
}
]
}Expected: revise, naming “+ 50%”. Source: USITC Harmonized Tariff Schedule, 2025 Revision 14, heading 9903.81.87 (the previous revision, 13, read "+ 25%"). Public domain.
A Medicare coverage answer that drops the documentation requirement
{
"question": "Does Medicare cover a CGM for a beneficiary with problematic hypoglycemia?",
"answer": "A CGM is covered if the beneficiary has a history of problematic hypoglycemia.",
"sources": [
{
"id": "lcd-l33822-criterion-4",
"title": "Glucose Monitors LCD (L33822), coverage criterion 4, as quoted in the Noridian DME MAC clinician checklist (updated 12/3/2025)",
"text": "4. The beneficiary for whom a CGM is being prescribed, to improve glycemic control, meets at least one of the criteria below: A. The beneficiary is insulin-treated; or B. The beneficiary has a history of problematic hypoglycemia with documentation of at least one of the following: Recurrent (more than one) level 2 hypoglycemic events (glucose <54mg/dL (3.0mmol/L)) that persist despite multiple (more than one) attempts to adjust medication(s) and/or modify the diabetes treatment plan; or A history of one level 3 hypoglycemic event (glucose <54mg/dL (3.0mmol/L)) characterized by altered mental and/or physical state requiring third-party assistance for treatment of hypoglycemia."
}
]
}Expected: revise, naming “level 2 hypoglycemic events”. Source: CMS Local Coverage Determination L33822 (Glucose Monitors), criterion 4, verbatim from the Noridian Healthcare Solutions clinician checklist for CGMs. Not medical or coverage advice.
Verdicts describe whether the supplied passages support each claim. They do not establish whether any claim is true in the world. API docs · Terms
