ground-truth-mcp
Ground Truth
Live fact-checking tools for AI agents.
Ground Truth gives AI agents read-only verification tools for live public data: free endpoint reachability checks, free security-header inspection, pricing-page scans, pricing-page comparisons, evidence-backed claim checks, package-market sizing, compliance scans, named package comparisons, and multi-step hypothesis tests.
You can use Ground Truth three ways:
Free endpoint and security-header checks for lightweight verification
Agentic pay-per-use with x402-compatible clients or an xpay proxy
A team subscription with
X-API-Keybilling and predictable monthly usage
Live: https://ground-truth-mcp.anishdasmail.workers.dev
Try This First
These two tools work without signup or an API key:
check_endpoint: verify that a public URL or API endpoint responds.inspect_security_headers: inspect HSTS, CSP, frame protections, and related browser-facing security headers.
Example prompts:
"Use Ground Truth to check whether https://api.github.com responds."
"Use Ground Truth to inspect security headers for https://example.com."
"Before recommending this API, use Ground Truth to verify the endpoint is reachable."
Related MCP server: Demaciains MCP Server
What Ground Truth Verifies
Ground Truth helps agents check facts before they answer, recommend, or act.
Verification | What it checks | Example |
Pricing claims | Pulls live pricing from product pages | "Does Stripe have a free tier?" |
Pricing comparisons | Compares multiple pricing pages side by side | "Which vendor shows a free trial right now?" |
Compliance posture | Scans trust pages for enterprise signals | "Does this vendor mention SOC 2, GDPR, and SCIM?" |
Security posture | Inspects browser-facing security headers | "Does this app expose HSTS and CSP?" |
Competitor existence | Checks whether real alternatives show up in npm or PyPI | "Are there edge-first Prisma alternatives?" |
API endpoints | Confirms a URL exists and responds | "Does this endpoint return 200?" |
All results come from live data and are cached for 5 minutes for faster repeat checks.
Complementary MCP Servers
Ground Truth is strongest when paired with a broader discovery or browser tool:
Tavily MCP Server for real-time web search and content discovery before you run a claim or pricing check.
Firecrawl MCP Server for deeper crawling and JS-heavy page extraction when raw HTML heuristics are not enough.
mcp-server-browserbase for interactive browser verification on pages that need clicks, auth, or client-side rendering.
These are complementary to Ground Truth rather than substitutes: they help you find or render the page, while Ground Truth helps you verify the resulting claim.
If you are filling in Glama related servers for this project, start with these three:
Tavily MCP ServerFirecrawl MCP Servermcp-server-browserbase
Why AI Agents Need Verification
Training data goes stale. Docs change. Pricing changes. Competitors appear. Endpoints break. Policies move.
Ground Truth gives agents a way to check before they commit:
Before quoting a price, pull the live pricing page
Before comparing vendors, scan their live pricing pages side by side
Before repeating a compliance claim, scan the live trust page
Before asserting a security baseline, inspect the response headers
Before saying a competitor does not exist, search the live registry
Before recommending an API, confirm the endpoint responds
Before calling one package more popular, compare real package metadata
Before repeating a policy, verify the language on the current public page
The result is simple: agents that are less confident for the wrong reasons and more reliable when it matters.
Example Workflows
Verify a pricing claim
"Notion costs $8 per user per month for teams."
Use check_pricing on the live pricing page before repeating the number.
Check whether a competitor exists
"There is no good edge ORM alternative to Prisma."
Use estimate_market to search npm for edge orm and see what already exists.
Compare vendor pricing pages
"Vendor A is cheaper than Vendor B."
Use compare_pricing_pages to compare live pricing pages before repeating the claim.
Scan a trust page
"This vendor supports SOC 2, GDPR, and SCIM."
Use assess_compliance_posture before treating that as current fact.
Inspect browser-facing security headers
"This app has a strong public security baseline."
Use inspect_security_headers before making the claim.
Validate an API endpoint
"Use the OpenAI
/v1/modelsendpoint to list available models."
Use check_endpoint before recommending it in docs, code, or support replies.
Compare package popularity
"Vue has overtaken React."
Use compare_competitors to compare live package metadata instead of guessing.
Test a market assumption
"There are fewer than 50 MCP tools on npm."
Use test_hypothesis with a count-based check and return the actual result.
Confirm whether a support policy applies
"AWS Business support includes 24/7 phone support."
Use verify_claim against the current AWS support page before treating that as fact.
Access Modes
Free
Free tier includes limited monthly endpoint and security-header checks.
check_endpointinspect_security_headers100 requests per calendar month
Tracked by Cloudflare client IP in production, or
X-Anonymous-Client-Idfor local/dev testingNo signup or API key required
Agentic pay-per-use
Paid tools also support agentic pay-per-use.
Use an x402-compatible MCP client, or put an xpay MCP proxy in front of this server
Tool pricing starts at
$0.01per call and varies by toolBest for autonomous agents or variable workloads
Includes
estimate_market,check_pricing,compare_pricing_pages,compare_competitors,verify_claim,assess_compliance_posture, andtest_hypothesis
Team
Team subscription uses API-key billing with predictable monthly usage.
Requires
X-API-Keywith active billingDefault quota of 5,000 requests per calendar month
Monthly usage tracked per API key and tool
Includes all paid verification tools
API Examples
Direct API with curl
Direct HTTP calls to /mcp are session-based. Initialize once, keep the returned mcp-session-id, then call tools with that header.
The examples below use the team plan with X-API-Key. For agentic pay-per-use, use an x402-capable MCP client or put an xpay proxy in front of this server.
SESSION_ID="$(curl -i -s -X POST https://ground-truth-mcp.anishdasmail.workers.dev/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {
"name": "ground-truth-example",
"version": "1.0.0"
}
},
"id": 0
}' | tr -d '\r' | awk '/^mcp-session-id:/ {print $2}')"
curl -X POST https://ground-truth-mcp.anishdasmail.workers.dev/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: $SESSION_ID" \
-H "X-API-Key: $GROUND_TRUTH_API_KEY" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "check_pricing",
"arguments": {
"url": "https://stripe.com/pricing"
}
},
"id": 1
}'JavaScript fetch
const initResponse = await fetch("https://ground-truth-mcp.anishdasmail.workers.dev/mcp", {
method: "POST",
headers: {
"Accept": "application/json, text/event-stream",
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "initialize",
params: {
protocolVersion: "2025-03-26",
capabilities: {},
clientInfo: {
name: "ground-truth-example",
version: "1.0.0",
},
},
id: 0,
}),
});
const sessionId = initResponse.headers.get("mcp-session-id");
if (!sessionId) {
throw new Error("Missing mcp-session-id from initialize response");
}
const response = await fetch("https://ground-truth-mcp.anishdasmail.workers.dev/mcp", {
method: "POST",
headers: {
"Accept": "application/json, text/event-stream",
"Content-Type": "application/json",
"Mcp-Session-Id": sessionId,
"X-API-Key": process.env.GROUND_TRUTH_API_KEY,
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "tools/call",
params: {
name: "compare_competitors",
arguments: {
packages: ["react", "vue"],
registry: "npm",
},
},
id: 1,
}),
});
const result = await response.json();
console.log(result);Free endpoint check
curl -X POST https://ground-truth-mcp.anishdasmail.workers.dev/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "check_endpoint",
"arguments": {
"url": "https://api.github.com"
}
},
"id": 1
}'Lightweight request checks for free access, team-plan billing, invalid keys, inactive billing, quota enforcement, and active paid access live in test-usage-enforcement.sh.
MCP Setup
If you use Claude Desktop, Cursor, or another MCP client, Ground Truth can plug in as a verification tool for your agent.
MCP stands for Model Context Protocol. It is the standard that lets AI apps call external tools.
If you want agentic pay-per-use without changing your app code, register this MCP URL with xpay and share the resulting proxy URL instead.
Claude Desktop
Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"ground-truth": {
"url": "https://ground-truth-mcp.anishdasmail.workers.dev/mcp",
"headers": {
"X-API-Key": "gt_live_your_key_here"
}
}
}
}Cursor
Add this to .cursor/mcp.json in your project or ~/.cursor/mcp.json globally:
{
"mcpServers": {
"ground-truth": {
"url": "https://ground-truth-mcp.anishdasmail.workers.dev/mcp",
"headers": {
"X-API-Key": "gt_live_your_key_here"
}
}
}
}Claude Code skill
If you want the same workflow without running a server, see claude-skill/.
Use Cases
Support
Verify a pricing claim before sending it to a customer
Check whether a support policy applies before escalating
Confirm an API endpoint exists before recommending it in a reply
Inspect public security headers before repeating a security claim
Product
Test whether a market assumption is true before writing a spec
Check whether a competitor exists before framing a roadmap
Compare package popularity before making a platform choice
Compare pricing pages before telling a team one vendor is cheaper
Compliance
Scan trust pages for SOC 2, GDPR, HIPAA, DPA, SSO, and SCIM signals
Verify pricing or packaging claims before repeating them internally
Check that a public terms or policy URL is reachable and current
Security & vendor diligence
Compare competitor pricing across live pages
Inspect browser-facing security headers before recommending or approving a vendor
Validate positioning claims with structured checks
Tool Reference
Tool | Tier | What it does |
| Free | Checks whether a URL or API endpoint exists and responds |
| Paid | Counts packages in npm or PyPI for a search term |
| Paid | Extracts prices, plans, and free-tier signals from a page |
| Free | Checks common browser-facing security headers on a public URL |
| Paid | Compares multiple live pricing pages side by side |
| Paid | Compares packages side by side with live metadata |
| Paid | Checks whether live sources support or contradict a claim |
| Paid | Scans a trust page for compliance and enterprise-security signals |
| Paid | Runs pass/fail tests against a live-data assumption |
Full reference: API_USAGE.md
Architecture
Ground Truth keeps the current Cloudflare Workers architecture:
Runtime: Cloudflare Workers
Storage: Durable Objects with SQLite for cache and usage logs
API keys: Cloudflare KV
Billing: Stripe team subscriptions plus x402-compatible pay-per-use
Protocol: MCP
Language: TypeScript
Distribution
Ground Truth is set up for multiple discovery and monetization paths:
Official MCP Registry publishing through
server.jsonfor ecosystem-wide discovery.Smithery URL publishing. This server exposes Streamable HTTP at
/mcpand a static server card at/.well-known/mcp/server-card.jsonfor metadata fallback.xpay MCP monetization. You can register the live
/mcpURL with xpay to get a managed pay-per-tool proxy without changing the server code.MCP Market directory listing for additional discovery.
Apify is optional if you want a separate marketplace-native Actor version later; the current project stays optimized for remote MCP delivery rather than an Actor-first runtime.
Development
cd ground-truth-mcp
npm install
npx wrangler devDeployment notes live in SETUP.md.
GitHub Releases
Stable GitHub releases are created automatically when you push a version tag that matches v*.
git tag v0.4.0
git push origin v0.4.0That tag triggers .github/workflows/release.yml, which typechecks the project and publishes a GitHub release from the tag. This is the repo-side piece Glama uses to detect stable releases during maintenance scans.
Glama Release
Glama releases are Docker-based, not GitHub releases. This repo includes a Dockerfile that starts the Worker locally through Wrangler on port 3000.
docker build -t ground-truth-mcp .
docker run --rm -p 3000:3000 ground-truth-mcpFor the Glama flow:
Claim the server in Glama.
Open the Dockerfile admin page, use this repository
Dockerfile, and run the deploy test.After the deploy test succeeds, click Make Release, choose a version, and publish.
If the score page still shows
No LICENSE, trigger a re-scan in the Glama admin interface after GitHub has recognized the rootLICENSEfile.If the score page still shows
No related servers, use Add related servers in the claimed Glama UI and addTavily MCP Server,Firecrawl MCP Server, andmcp-server-browserbase. That checklist item is managed on Glama's side rather than inglama.json.
If Glama generates an mcp-proxy-based build spec instead of using the repository Dockerfile, point the command at npm run start:glama:stdio. That bridge exposes the existing remote Ground Truth MCP endpoint over stdio so mcp-proxy can host it.
Documentation
API_USAGE.md for API calls and tool arguments
SETUP.md for deployment and billing setup
claude-skill/ for the zero-deployment Claude Code version
Support
License
MIT — see LICENSE
Made by Anish Das
Last updated: April 29, 2026
Available Tools
16 toolsassess_compliance_postureCompliance Signal ScanARead-onlyIdempotentInspect
Scan a public security, trust, compliance, or legal page for common enterprise buying signals before you claim a vendor supports a particular compliance posture. It looks for public references to SOC 2, ISO 27001, GDPR, HIPAA, DPA terms, subprocessors, SSO, SCIM, encryption, and data residency language. This is a signal scanner, not proof of certification or legal sufficiency.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public trust, security, compliance, or policy URL to scan. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | Compliance or trust page that was analyzed. |
| cached | No | True when the page body came from the 5-minute cache. |
| matchedSignals | No | Signal names that were detected on the page. |
| signals | No | Boolean scan results for common enterprise compliance and security signals. |
| pageLength | No | Size of the fetched page body in characters. |
| error | No | Fetch or parsing error when the page could not be analyzed. |
check_endpointEndpoint Reachability CheckARead-onlyIdempotentInspect
Perform one live, unauthenticated fetch against a public URL or API endpoint before you recommend it, document it, or build on top of it. Use this when the question is simply whether an endpoint currently responds and what kind of response it returns. It reports HTTP status, content type, elapsed time, likely auth/rate-limit signals, and a short response sample. A successful result only proves basic reachability at fetch time. Do not use it to validate authenticated flows, POST side effects, JavaScript execution, or deeper business logic.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public http(s) URL or bare domain to probe. Bare domains like google.com are accepted and normalized to https:// automatically. |
Output Schema
| Name | Required | Description |
|---|---|---|
| inputUrl | No | Original user input when normalization changed it, for example when https:// was added. |
| url | Yes | Normalized URL that was actually fetched. |
| accessible | Yes | True when the endpoint returned a 2xx HTTP status. |
| status | No | HTTP status code returned by the endpoint, when a response was received. |
| contentType | No | Response Content-Type header, if present. |
| responseTimeMs | No | Elapsed request time in milliseconds. |
| authRequired | No | True when the server responded with 401 or 403, which usually means credentials are required. |
| rateLimited | No | True when the server responded with 429 Too Many Requests. |
| sampleResponse | No | First 1,000 characters of the response body for quick inspection. Use this as a debugging hint only; it may be truncated and should not be treated as a complete page capture. |
| error | No | Validation or network error when the request could not be completed. |
check_pricingPricing Page ScanARead-onlyIdempotentInspect
Fetch a public pricing page and extract first-pass pricing signals before you quote plan costs, free tiers, or plan names. Use this when you already have a likely pricing URL and need a quick live scan of visible page text. It returns price-like strings, heuristic plan labels, free or free-trial signals, and cache information. It does not map prices to exact plans, normalize currencies, execute checkout flows, or guarantee that a price applies to a specific region or customer type. JavaScript-rendered, logged-in, or heavily obfuscated pricing details can be missed. Results are cached for 5 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public pricing or plans URL to analyze. Prefer the specific pricing page, for example https://stripe.com/pricing, rather than a generic homepage. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | Pricing page that was analyzed. |
| cached | No | True when the page body came from the 5-minute cache instead of a new fetch. |
| pricesFound | No | Distinct price-like strings extracted from the page text. These are not linked back to specific plans or billing conditions. |
| plansDetected | No | Lowercased heuristic plan labels detected from the page text. They are useful hints, not authoritative plan identifiers. |
| hasFreeOption | No | True when the page contains signals that a free plan or $0 option exists somewhere on the page. This is a page-level signal, not proof that the offer is currently self-serve or globally available. |
| hasFreeTrial | No | True when the page contains signals that a free trial exists somewhere on the page. |
| pageLength | No | Size of the fetched page body in characters. |
| error | No | Fetch or parsing error when the pricing page could not be analyzed. |
compare_competitorsNamed Package ComparisonARead-onlyIdempotentInspect
Compare two or more exact package names side by side using live npm or PyPI metadata. Use this when you already know the candidate packages and need evidence for claims such as 'tool A is newer', 'tool B is still maintained', or 'these packages use different licenses'. It returns per-package registry metadata in input order, with field availability varying by registry. Missing or unpublished packages return found=false. Do not use it to discover unknown alternatives, estimate market size, or compare packages across different registries. Registry responses are cached for 5 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| packages | Yes | Two to ten exact package names from the same registry, for example ['react', 'vue']. Use exact registry names, not search phrases or categories. | |
| registry | No | Registry that all package names belong to. All compared packages must come from the same registry, and returned metadata fields differ slightly between npm and PyPI. | npm |
Output Schema
| Name | Required | Description |
|---|---|---|
| packages | Yes | Package names that were requested for comparison. |
| registry | Yes | Registry used for all comparisons. |
| comparisons | Yes | Per-package lookup results returned in the same order as the input package list. Some fields only exist for npm or only for PyPI, so consumers should treat absent fields as normal. |
compare_pricing_pagesPricing Page ComparisonARead-onlyIdempotentInspect
Compare two to five public pricing pages side by side before you make competitive pricing or packaging claims. Use this when you want a quick, live comparison of visible prices, free-plan signals, and plan-name hints across vendors. The output is heuristic and page-level: it does not map every price to every plan or normalize regional billing differences.
| Name | Required | Description | Default |
|---|---|---|---|
| pages | Yes | Two to five named pricing pages to compare side by side. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Per-page pricing signals returned in input order. |
| summary | Yes | Aggregate counts across all compared pricing pages. |
create_monitorCreate MonitorAInspect
Create a persistent monitor that tracks a URL, pricing page, package version, endpoint status, vendor claim, or custom keyword pattern over time. Monitors run automatically on their configured schedule (hourly/daily/weekly) via the Cloudflare cron trigger, or on demand with run_monitor_now. Results are stored in the Durable Object SQLite database. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Human-readable name for this monitor. | |
| target_type | Yes | What to monitor. url/endpoint: HTTP reachability and status. pricing_page: pricing signals (prices, plans, free tier). package: package version on npm or pypi (target_value as 'npm:pkg-name' or 'pypi:pkg-name'). vendor_claim: keyword presence at a URL (target_value=claim text, instructions=URL to check). custom_prompt: comma-separated keywords checked against a URL (target_value=URL, instructions=keywords). | |
| target_value | Yes | Primary target. For url/endpoint/pricing_page/custom_prompt: a public https URL. For package: 'npm:package-name' or 'pypi:package-name'. For vendor_claim: the claim text to search for. | |
| instructions | No | Supplementary instructions. For vendor_claim: the URL to check. For custom_prompt: comma-separated keywords. Optional for other types. | |
| schedule | No | How often the monitor runs automatically. manual means only via run_monitor_now. | daily |
| notification_destination | No | Optional destination for change alerts (email or webhook URL). Stored for future use. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique monitor ID. |
| name | Yes | Monitor name. |
| target_type | Yes | Monitor target type. |
| target_value | Yes | Monitor target value. |
| schedule | Yes | Monitor schedule. |
| created_at | Yes | Creation timestamp ISO 8601. |
| error | No | Error message if creation failed. |
delete_monitorDelete MonitorADestructiveIdempotentInspect
Permanently delete a monitor and all its stored results. This action cannot be undone. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| monitor_id | Yes | The monitor ID to delete. |
Output Schema
| Name | Required | Description |
|---|---|---|
| monitor_id | Yes | |
| deleted | Yes | |
| results_deleted | Yes | Number of result records also deleted. |
| error | No |
estimate_marketPackage Market SearchARead-onlyIdempotentInspect
Search npm or PyPI to estimate how crowded a package category is before you claim that a market is empty, niche, or competitive. Use this when you have a category or search phrase such as 'edge orm' and want live result counts plus representative matches. Do not use it to compare exact known package names or to infer adoption from downloads; it reflects search results, not market share. Registry responses are cached for 5 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Short registry search phrase to evaluate, for example 'mcp memory server' or 'edge orm'. | |
| registry | No | Registry to search. Use 'npm' for JavaScript ecosystems and 'pypi' for Python ecosystems. | npm |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | Search phrase that was evaluated. |
| registry | Yes | Registry that was searched. |
| totalResults | Yes | Total number of matching packages reported by the registry search. |
| topResults | Yes | Representative top search matches that help interpret the market count. |
generate_change_reportGenerate Change ReportARead-onlyIdempotentInspect
Generate a summary report of monitor activity for a time window. Shows monitors run, changes detected, failures, risk levels, and recommended follow-up actions. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | Report period. daily covers the past 24 hours, weekly covers the past 7 days. | daily |
| include_unchanged | No | When true also lists monitors with no detected changes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| period | Yes | |
| from | Yes | |
| to | Yes | |
| summary | Yes | |
| changes | Yes | |
| failures | Yes | |
| recommended_actions | Yes | |
| error | No |
get_monitor_resultGet Monitor ResultsARead-onlyIdempotentInspect
Retrieve the most recent run results for a monitor, including change details, confidence score, evidence URLs, and any error information. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| monitor_id | Yes | The monitor ID to retrieve results for. | |
| limit | No | Maximum number of results to return, newest first. |
Output Schema
| Name | Required | Description |
|---|---|---|
| monitor_id | Yes | |
| results | Yes | |
| total | Yes | |
| error | No |
inspect_security_headersSecurity Header InspectionARead-onlyIdempotentInspect
Fetch a public URL and inspect security-relevant response headers before you claim that a product or endpoint has a strong browser-facing security baseline. Use this for quick due diligence on public apps and docs sites. It checks for common headers such as HSTS, CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy, and X-Content-Type-Options. It does not replace a real security review, authenticated testing, or vulnerability scanning.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public http(s) URL or bare domain to inspect. Bare domains are normalized to https:// automatically. |
Output Schema
| Name | Required | Description |
|---|---|---|
| inputUrl | No | Original user input when normalization changed it. |
| url | Yes | Normalized URL that was fetched. |
| accessible | Yes | True when the endpoint returned an HTTP response. |
| status | No | HTTP status code returned by the endpoint. |
| https | Yes | True when the normalized URL used https. |
| presentCount | No | Number of tracked security headers that were present. |
| score | No | Heuristic security-header score based on how many tracked headers were present. |
| headers | No | Tracked response headers and their raw values when present. |
| missingRecommended | No | Tracked headers that were not present on the response. |
| error | No | Validation or network error when the request could not be completed. |
list_monitorsList MonitorsARead-onlyIdempotentInspect
List all monitors owned by this API key, with last run status and schedule. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| active_only | No | When true returns only active monitors. Set false to include paused monitors. |
Output Schema
| Name | Required | Description |
|---|---|---|
| monitors | Yes | List of monitors belonging to this API key. |
| total | Yes | Total number of monitors returned. |
| error | No |
list_resourcesServer Resource DiscoveryARead-onlyIdempotentInspect
List all available Ground Truth tools and their access tiers. Zero-cost schema discovery. Call this to explore what verification tools are available before making a tool call. No quota consumption, no API key required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| freeTools | Yes | Tools available in the free tier with no API key required. |
| paidTools | Yes | Tools requiring team API key or agentic payment. |
| monitorTools | Yes | Monitor management tools requiring team API key. |
| serverVersion | Yes | Current server version. |
run_monitor_nowRun Monitor NowAInspect
Immediately run a monitor's verification check outside its normal schedule. Records the result and returns whether the observed value changed since the last run. Counts against your monthly quota. Requires a team API key.
| Name | Required | Description | Default |
|---|---|---|---|
| monitor_id | Yes | The monitor ID returned by create_monitor. |
Output Schema
| Name | Required | Description |
|---|---|---|
| monitor_id | Yes | |
| result_id | Yes | |
| status | Yes | |
| changed | Yes | |
| old_value | Yes | |
| new_value | Yes | |
| confidence | Yes | |
| evidence | Yes | |
| run_at | Yes | |
| error | No |
test_hypothesisMulti-step Hypothesis TestARead-onlyIdempotentInspect
Run a small verification plan made of concrete live checks and summarize whether a hypothesis is supported. Use this when one conclusion depends on multiple simple checks such as endpoint reachability, npm search counts, or whether a page contains an exact substring. This is a coordination tool, not an open-ended research agent: every test must be explicitly defined in advance, and tests run in order with no branching or early exit. The final verdict is mechanical: all tests passing => SUPPORTED, zero passing => REFUTED, otherwise PARTIALLY SUPPORTED. Use verify_claim when you already have evidence URLs, estimate_market for category sizing, and compare_competitors when you already know exact package names.
| Name | Required | Description | Default |
|---|---|---|---|
| hypothesis | Yes | Claim to test, for example 'there are fewer than 50 MCP email servers on npm'. | |
| tests | Yes | Ordered list of one to ten checks to run. Each test object uses only the fields required by its type. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hypothesis | Yes | Hypothesis that was evaluated. |
| tests | Yes | Per-test execution results in input order. |
| verdict | Yes | High-level verdict for the hypothesis. |
verify_claimClaim Support CheckARead-onlyIdempotentInspect
Check whether a factual claim is supported by a specific set of public evidence URLs that you already have. For each source, the tool performs a case-insensitive keyword match over the fetched page body, then marks that source as supporting the claim when at least half of the supplied keywords appear. Use this for evidence-backed claim checks on known pages, not for open-ended search, semantic reasoning, or contradiction extraction. The aggregate verdict is driven only by the per-page keyword support ratio. Fetched pages are cached for 5 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| claim | Yes | Plain-language claim to verify, for example 'AWS Business support includes 24/7 phone support'. | |
| evidence_urls | Yes | One to ten public documentation, pricing, policy, or support URLs that are likely to contain direct evidence for the claim. | |
| keywords | Yes | Keywords or short phrases that should appear on supporting pages. Matching is case-insensitive substring matching, so choose phrases that are likely to appear verbatim. |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | Yes | Claim that was evaluated. |
| sources | Yes | Per-source evidence results. |
| verdict | Yes | Aggregate verdict across all supplied sources. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.5.1- Added
create_monitor - Added
delete_monitor - Added
generate_change_report - Added
get_monitor_result - Added
list_monitors - Added
list_resources - Added
run_monitor_now - Changed
test_hypothesis1 field changed- changed
Input schema / properties / tests / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this endpoint check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "type": { - "const": "endpoint_exists", - "description": "Perform one unauthenticated GET request and pass when the endpoint returns a 2xx HTTP status.", - "type": "string" - }, - "url": { - "description": "Public URL to probe, for example https://api.github.com.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "description", - "type", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this npm lower-bound count check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "query": { - "description": "npm search phrase to count, for example 'mcp email server'.", - "minLength": 2, - "type": "string" - }, - "threshold": { - "description": "Lower bound that the npm search result count must exceed.", - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "npm_count_above", - "description": "Search npm and pass when the reported result count is strictly greater than the threshold.", - "type": "string" - } - }, - "required": [ - "description", - "type", - "query", - "threshold" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this npm upper-bound count check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "query": { - "description": "npm search phrase to count, for example 'business verification mcp'.", - "minLength": 2, - "type": "string" - }, - "threshold": { - "description": "Upper bound that the npm search result count must stay below.", - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "npm_count_below", - "description": "Search npm and pass when the reported result count is strictly less than the threshold.", - "type": "string" - } - }, - "required": [ - "description", - "type", - "query", - "threshold" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this response-content check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "substring": { - "description": "Exact case-sensitive text to search for in the fetched response body.", - "minLength": 1, - "type": "string" - }, - "type": { - "const": "response_contains", - "description": "Fetch a public URL and pass when the response body contains the exact substring using case-sensitive matching. The tool does not parse DOM structure or execute JavaScript before matching.", - "type": "string" - }, - "url": { - "description": "Public URL whose response body should contain the expected text.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "description", - "type", - "url", - "substring" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this endpoint check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "type": { + "const": "endpoint_exists", + "description": "Perform one unauthenticated GET request and pass when the endpoint returns a 2xx HTTP status.", + "type": "string" + }, + "url": { + "description": "Public URL to probe, for example https://example.com.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm lower-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'mcp email server'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Lower bound that the npm search result count must exceed.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_above", + "description": "Search npm and pass when the reported result count is strictly greater than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm upper-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'business verification mcp'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Upper bound that the npm search result count must stay below.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_below", + "description": "Search npm and pass when the reported result count is strictly less than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this response-content check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "substring": { + "description": "Exact case-sensitive text to search for in the fetched response body.", + "minLength": 1, + "type": "string" + }, + "type": { + "const": "response_contains", + "description": "Fetch a public URL and pass when the response body contains the exact substring using case-sensitive matching. The tool does not parse DOM structure or execute JavaScript before matching.", + "type": "string" + }, + "url": { + "description": "Public URL whose response body should contain the expected text.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url", + "substring" + ], + "type": "object" + } +]
3 tool updates
v0.4.4- Changed
assess_compliance_posture10 fields changed- added
Output schema / properties / signals / properties / dataResidency / descriptionAdded value: +"True when the page references data residency, data regions, or regional storage controls." - added
Output schema / properties / signals / properties / dpa / descriptionAdded value: +"True when the page references a data processing agreement or DPA." - added
Output schema / properties / signals / properties / encryption / descriptionAdded value: +"True when the page references encryption, data encrypted at rest, or data encrypted in transit." - added
Output schema / properties / signals / properties / gdpr / descriptionAdded value: +"True when the page references GDPR or the General Data Protection Regulation." - added
Output schema / properties / signals / properties / hipaa / descriptionAdded value: +"True when the page references HIPAA compliance language." - added
Output schema / properties / signals / properties / iso27001 / descriptionAdded value: +"True when the page references ISO 27001 certification or compliance language." - added
Output schema / properties / signals / properties / scim / descriptionAdded value: +"True when the page references SCIM provisioning." - added
Output schema / properties / signals / properties / soc2 / descriptionAdded value: +"True when the page references SOC 2 or SOC2 compliance language." - added
Output schema / properties / signals / properties / sso / descriptionAdded value: +"True when the page references SSO or single sign-on." - added
Output schema / properties / signals / properties / subprocessorList / descriptionAdded value: +"True when the page references subprocessors or a subprocessor list."
- Changed
check_endpoint1 field changed- changed
Output schema / properties / sampleResponse / descriptionPrevious value: -"First 1,000 characters of the response body for quick inspection."New value: +"First 1,000 characters of the response body for quick inspection. Use this as a debugging hint only; it may be truncated and should not be treated as a complete page capture."
- Changed
compare_pricing_pages13 fields changed- added
Output schema / properties / pages / items / properties / cached / descriptionAdded value: +"True when this page body came from the 5-minute cache." - added
Output schema / properties / pages / items / properties / error / descriptionAdded value: +"Fetch or parsing error for this specific pricing page when it could not be analyzed." - added
Output schema / properties / pages / items / properties / hasFreeOption / descriptionAdded value: +"True when this page contains visible text suggesting a free plan, free tier, or $0 option." - added
Output schema / properties / pages / items / properties / hasFreeTrial / descriptionAdded value: +"True when this page contains visible text suggesting a free trial." - added
Output schema / properties / pages / items / properties / name / descriptionAdded value: +"Short vendor or product label from the input page object." - added
Output schema / properties / pages / items / properties / pageLength / descriptionAdded value: +"Size of this fetched page body in characters." - added
Output schema / properties / pages / items / properties / plansDetected / descriptionAdded value: +"Lowercased heuristic plan labels detected on this page, such as free, pro, team, or enterprise." - added
Output schema / properties / pages / items / properties / pricesFound / descriptionAdded value: +"Distinct price-like strings extracted from this page. These are page-level hints and are not mapped to specific plans." - added
Output schema / properties / pages / items / properties / url / descriptionAdded value: +"Pricing page URL that was fetched for this named vendor." - added
Output schema / properties / summary / properties / pagesCompared / descriptionAdded value: +"Number of pricing pages included in the comparison." - added
Output schema / properties / summary / properties / pagesWithFreeOption / descriptionAdded value: +"Number of pages with page-level text suggesting a free plan, free tier, or $0 option." - added
Output schema / properties / summary / properties / pagesWithFreeTrial / descriptionAdded value: +"Number of pages with page-level text suggesting a free trial." - added
Output schema / properties / summary / properties / pagesWithVisiblePrices / descriptionAdded value: +"Number of pages where at least one price-like string was detected."
7 tool updates
v0.4.0- Added
assess_compliance_posture - Changed
check_pricing5 fields changed- changed
Input schema / properties / url / descriptionPrevious value: -"Public pricing-page URL to analyze, for example https://stripe.com/pricing."New value: +"Public pricing or plans URL to analyze. Prefer the specific pricing page, for example https://stripe.com/pricing, rather than a generic homepage." - changed
Output schema / properties / hasFreeOption / descriptionPrevious value: -"True when the page contains signals that a free plan or $0 option exists."New value: +"True when the page contains signals that a free plan or $0 option exists somewhere on the page. This is a page-level signal, not proof that the offer is currently self-serve or globally available." - changed
Output schema / properties / hasFreeTrial / descriptionPrevious value: -"True when the page contains signals that a free trial exists."New value: +"True when the page contains signals that a free trial exists somewhere on the page." - changed
Output schema / properties / plansDetected / descriptionPrevious value: -"Normalized plan labels detected from the page text."New value: +"Lowercased heuristic plan labels detected from the page text. They are useful hints, not authoritative plan identifiers." - changed
Output schema / properties / pricesFound / descriptionPrevious value: -"Distinct price-like strings extracted from the page text."New value: +"Distinct price-like strings extracted from the page text. These are not linked back to specific plans or billing conditions."
- Changed
compare_competitors3 fields changed- changed
Input schema / properties / packages / descriptionPrevious value: -"Two to ten exact package names from the same registry, for example ['react', 'vue']."New value: +"Two to ten exact package names from the same registry, for example ['react', 'vue']. Use exact registry names, not search phrases or categories." - changed
Input schema / properties / registry / descriptionPrevious value: -"Registry that all package names belong to. All compared packages must come from the same registry."New value: +"Registry that all package names belong to. All compared packages must come from the same registry, and returned metadata fields differ slightly between npm and PyPI." - changed
Output schema / properties / comparisons / descriptionPrevious value: -"Per-package lookup results returned in the same order as the input package list."New value: +"Per-package lookup results returned in the same order as the input package list. Some fields only exist for npm or only for PyPI, so consumers should treat absent fields as normal."
- Added
compare_pricing_pages - Added
inspect_security_headers - Changed
test_hypothesis3 fields changed- changed
Input schema / properties / tests / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this endpoint check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "type": { - "const": "endpoint_exists", - "description": "Perform one unauthenticated GET request and pass when the endpoint returns a 2xx HTTP status.", - "type": "string" - }, - "url": { - "description": "Public URL to probe, for example https://api.github.com.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "description", - "type", - "url" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this npm lower-bound count check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "query": { - "description": "npm search phrase to count, for example 'mcp email server'.", - "minLength": 2, - "type": "string" - }, - "threshold": { - "description": "Lower bound that the npm search result count must exceed.", - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "npm_count_above", - "description": "Search npm and pass when the reported result count is strictly greater than the threshold.", - "type": "string" - } - }, - "required": [ - "description", - "type", - "query", - "threshold" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this npm upper-bound count check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "query": { - "description": "npm search phrase to count, for example 'business verification mcp'.", - "minLength": 2, - "type": "string" - }, - "threshold": { - "description": "Upper bound that the npm search result count must stay below.", - "minimum": 0, - "type": "integer" - }, - "type": { - "const": "npm_count_below", - "description": "Search npm and pass when the reported result count is strictly less than the threshold.", - "type": "string" - } - }, - "required": [ - "description", - "type", - "query", - "threshold" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "description": { - "description": "Short explanation of what this response-content check is meant to prove.", - "minLength": 3, - "type": "string" - }, - "substring": { - "description": "Exact case-sensitive text to search for in the fetched response body.", - "minLength": 1, - "type": "string" - }, - "type": { - "const": "response_contains", - "description": "Fetch a public URL and pass when the response body contains the exact substring using case-sensitive matching.", - "type": "string" - }, - "url": { - "description": "Public URL whose response body should contain the expected text.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "description", - "type", - "url", - "substring" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this endpoint check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "type": { + "const": "endpoint_exists", + "description": "Perform one unauthenticated GET request and pass when the endpoint returns a 2xx HTTP status.", + "type": "string" + }, + "url": { + "description": "Public URL to probe, for example https://api.github.com.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm lower-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'mcp email server'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Lower bound that the npm search result count must exceed.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_above", + "description": "Search npm and pass when the reported result count is strictly greater than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm upper-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'business verification mcp'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Upper bound that the npm search result count must stay below.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_below", + "description": "Search npm and pass when the reported result count is strictly less than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this response-content check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "substring": { + "description": "Exact case-sensitive text to search for in the fetched response body.", + "minLength": 1, + "type": "string" + }, + "type": { + "const": "response_contains", + "description": "Fetch a public URL and pass when the response body contains the exact substring using case-sensitive matching. The tool does not parse DOM structure or execute JavaScript before matching.", + "type": "string" + }, + "url": { + "description": "Public URL whose response body should contain the expected text.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url", + "substring" + ], + "type": "object" + } +] - changed
Output schema / properties / tests / items / properties / actual / descriptionPrevious value: -"Observed value or diagnostic string that explains the result."New value: +"Observed value or diagnostic string that explains the result. The format varies by test type and is meant for human interpretation, not strict machine parsing." - changed
Output schema / properties / verdict / properties / summary / descriptionPrevious value: -"Aggregate verdict across the full test plan."New value: +"Aggregate verdict across the full test plan: all pass => SUPPORTED, none pass => REFUTED, otherwise PARTIALLY SUPPORTED."
- Changed
verify_claim2 fields changed- changed
Input schema / properties / keywords / descriptionPrevious value: -"Keywords or short phrases that should appear on supporting pages. Matching is case-insensitive substring matching."New value: +"Keywords or short phrases that should appear on supporting pages. Matching is case-insensitive substring matching, so choose phrases that are likely to appear verbatim." - changed
Output schema / properties / verdict / properties / summary / descriptionPrevious value: -"High-level verdict derived from the supporting-source ratio."New value: +"High-level verdict derived from the supporting-source ratio: all sources supporting => CONFIRMED, none => UNCONFIRMED, majority => LIKELY TRUE, otherwise LIKELY FALSE."
6 tool updates
v0.1.1- Changed
check_endpoint4 fields changed- changed
Input schema / properties / url / descriptionPrevious value: -"The URL to probe"New value: +"Public http(s) URL or bare domain to probe. Bare domains like google.com are accepted and normalized to https:// automatically." - removed
Input schema / properties / url / formatRemoved value: -"uri" - added
Input schema / properties / url / minLengthAdded value: +1 - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "accessible": { + "description": "True when the endpoint returned a 2xx HTTP status.", + "type": "boolean" + }, + "authRequired": { + "description": "True when the server responded with 401 or 403, which usually means credentials are required.", + "type": "boolean" + }, + "contentType": { + "description": "Response Content-Type header, if present.", + "type": [ + "string", + "null" + ] + }, + "error": { + "description": "Validation or network error when the request could not be completed.", + "type": "string" + }, + "inputUrl": { + "description": "Original user input when normalization changed it, for example when https:// was added.", + "type": "string" + }, + "rateLimited": { + "description": "True when the server responded with 429 Too Many Requests.", + "type": "boolean" + }, + "responseTimeMs": { + "description": "Elapsed request time in milliseconds.", + "minimum": 0, + "type": "integer" + }, + "sampleResponse": { + "description": "First 1,000 characters of the response body for quick inspection.", + "type": "string" + }, + "status": { + "description": "HTTP status code returned by the endpoint, when a response was received.", + "type": "integer" + }, + "url": { + "description": "Normalized URL that was actually fetched.", + "type": "string" + } + }, + "required": [ + "url", + "accessible" + ], + "type": "object" +}
- Changed
check_pricing2 fields changed- changed
Input schema / properties / url / descriptionPrevious value: -"URL of the pricing page to analyze"New value: +"Public pricing-page URL to analyze, for example https://stripe.com/pricing." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cached": { + "description": "True when the page body came from the 5-minute cache instead of a new fetch.", + "type": "boolean" + }, + "error": { + "description": "Fetch or parsing error when the pricing page could not be analyzed.", + "type": "string" + }, + "hasFreeOption": { + "description": "True when the page contains signals that a free plan or $0 option exists.", + "type": "boolean" + }, + "hasFreeTrial": { + "description": "True when the page contains signals that a free trial exists.", + "type": "boolean" + }, + "pageLength": { + "description": "Size of the fetched page body in characters.", + "minimum": 0, + "type": "integer" + }, + "plansDetected": { + "description": "Normalized plan labels detected from the page text.", + "items": { + "type": "string" + }, + "type": "array" + }, + "pricesFound": { + "description": "Distinct price-like strings extracted from the page text.", + "items": { + "type": "string" + }, + "type": "array" + }, + "url": { + "description": "Pricing page that was analyzed.", + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" +}
- Changed
compare_competitors4 fields changed- changed
Input schema / properties / packages / descriptionPrevious value: -"Package names to compare (e.g. ['express', 'fastify', 'koa'])"New value: +"Two to ten exact package names from the same registry, for example ['react', 'vue']." - added
Input schema / properties / packages / items / minLengthAdded value: +1 - added
Input schema / properties / registry / descriptionAdded value: +"Registry that all package names belong to. All compared packages must come from the same registry." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "comparisons": { + "description": "Per-package lookup results returned in the same order as the input package list.", + "items": { + "additionalProperties": false, + "properties": { + "author": { + "description": "Package author when PyPI metadata includes one.", + "type": "string" + }, + "cached": { + "description": "True when the lookup came from the 5-minute cache.", + "type": "boolean" + }, + "created": { + "description": "Package creation timestamp when npm provides one.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Short package summary from the registry.", + "type": "string" + }, + "error": { + "description": "Fetch error when registry metadata could not be retrieved for this package.", + "type": "string" + }, + "found": { + "description": "True when the registry lookup succeeded and returned package metadata.", + "type": "boolean" + }, + "keywords": { + "description": "Registry keywords or tags associated with the package.", + "items": { + "type": "string" + }, + "type": "array" + }, + "lastPublished": { + "description": "Publish timestamp of the latest version when npm provides one.", + "type": [ + "string", + "null" + ] + }, + "latestVersion": { + "description": "Latest package version known to the registry.", + "type": "string" + }, + "license": { + "description": "Package license metadata when provided by the registry.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "Package name that was looked up.", + "type": "string" + }, + "totalVersions": { + "description": "Number of published versions when npm metadata includes a version history.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "name", + "found" + ], + "type": "object" + }, + "type": "array" + }, + "packages": { + "description": "Package names that were requested for comparison.", + "items": { + "type": "string" + }, + "type": "array" + }, + "registry": { + "description": "Registry used for all comparisons.", + "enum": [ + "npm", + "pypi" + ], + "type": "string" + } + }, + "required": [ + "packages", + "registry", + "comparisons" + ], + "type": "object" +}
- Changed
estimate_market4 fields changed- changed
Input schema / properties / query / descriptionPrevious value: -"Search query (e.g. 'mcp memory server')"New value: +"Short registry search phrase to evaluate, for example 'mcp memory server' or 'edge orm'." - added
Input schema / properties / query / minLengthAdded value: +2 - changed
Input schema / properties / registry / descriptionPrevious value: -"Which registry to search"New value: +"Registry to search. Use 'npm' for JavaScript ecosystems and 'pypi' for Python ecosystems." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "query": { + "description": "Search phrase that was evaluated.", + "type": "string" + }, + "registry": { + "description": "Registry that was searched.", + "enum": [ + "npm", + "pypi" + ], + "type": "string" + }, + "topResults": { + "description": "Representative top search matches that help interpret the market count.", + "items": { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short package summary from registry metadata.", + "type": "string" + }, + "name": { + "description": "Package name returned by the registry.", + "type": "string" + }, + "score": { + "description": "Registry relevance score when npm provides one.", + "type": "string" + }, + "version": { + "description": "Latest version string returned in the result payload.", + "type": "string" + } + }, + "required": [ + "name", + "description", + "version" + ], + "type": "object" + }, + "type": "array" + }, + "totalResults": { + "anyOf": [ + { + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Total number of matching packages reported by the registry search." + } + }, + "required": [ + "query", + "registry", + "totalResults", + "topResults" + ], + "type": "object" +}
- Changed
test_hypothesis11 fields changed- changed
Input schema / properties / hypothesis / descriptionPrevious value: -"The claim to test"New value: +"Claim to test, for example 'there are fewer than 50 MCP email servers on npm'." - added
Input schema / properties / hypothesis / minLengthAdded value: +5 - added
Input schema / properties / tests / descriptionAdded value: +"Ordered list of one to ten checks to run. Each test object uses only the fields required by its type." - removed
Input schema / properties / tests / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / tests / items / anyOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this endpoint check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "type": { + "const": "endpoint_exists", + "description": "Perform one unauthenticated GET request and pass when the endpoint returns a 2xx HTTP status.", + "type": "string" + }, + "url": { + "description": "Public URL to probe, for example https://api.github.com.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm lower-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'mcp email server'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Lower bound that the npm search result count must exceed.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_above", + "description": "Search npm and pass when the reported result count is strictly greater than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this npm upper-bound count check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "query": { + "description": "npm search phrase to count, for example 'business verification mcp'.", + "minLength": 2, + "type": "string" + }, + "threshold": { + "description": "Upper bound that the npm search result count must stay below.", + "minimum": 0, + "type": "integer" + }, + "type": { + "const": "npm_count_below", + "description": "Search npm and pass when the reported result count is strictly less than the threshold.", + "type": "string" + } + }, + "required": [ + "description", + "type", + "query", + "threshold" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "description": "Short explanation of what this response-content check is meant to prove.", + "minLength": 3, + "type": "string" + }, + "substring": { + "description": "Exact case-sensitive text to search for in the fetched response body.", + "minLength": 1, + "type": "string" + }, + "type": { + "const": "response_contains", + "description": "Fetch a public URL and pass when the response body contains the exact substring using case-sensitive matching.", + "type": "string" + }, + "url": { + "description": "Public URL whose response body should contain the expected text.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "description", + "type", + "url", + "substring" + ], + "type": "object" + } +] - removed
Input schema / properties / tests / items / propertiesRemoved value: -{ - "description": { - "type": "string" - }, - "query": { - "type": "string" - }, - "substring": { - "type": "string" - }, - "threshold": { - "type": "number" - }, - "type": { - "enum": [ - "endpoint_exists", - "npm_count_above", - "npm_count_below", - "response_contains" - ], - "type": "string" - }, - "url": { - "type": "string" - } -} - removed
Input schema / properties / tests / items / requiredRemoved value: -[ - "description", - "type" -] - removed
Input schema / properties / tests / items / typeRemoved value: -"object" - added
Input schema / properties / tests / maxItemsAdded value: +10 - added
Input schema / properties / tests / minItemsAdded value: +1 - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "hypothesis": { + "description": "Hypothesis that was evaluated.", + "type": "string" + }, + "tests": { + "description": "Per-test execution results in input order.", + "items": { + "additionalProperties": false, + "properties": { + "actual": { + "description": "Observed value or diagnostic string that explains the result.", + "type": [ + "string", + "number", + "null" + ] + }, + "description": { + "description": "Human-readable explanation of the check.", + "type": "string" + }, + "passed": { + "description": "True when the test condition was satisfied.", + "type": "boolean" + }, + "type": { + "description": "Test type that was executed.", + "enum": [ + "endpoint_exists", + "npm_count_above", + "npm_count_below", + "response_contains" + ], + "type": "string" + } + }, + "required": [ + "description", + "type", + "passed", + "actual" + ], + "type": "object" + }, + "type": "array" + }, + "verdict": { + "additionalProperties": false, + "description": "High-level verdict for the hypothesis.", + "properties": { + "failed": { + "description": "Number of tests that failed.", + "minimum": 0, + "type": "integer" + }, + "passed": { + "description": "Number of tests that passed.", + "minimum": 0, + "type": "integer" + }, + "summary": { + "description": "Aggregate verdict across the full test plan.", + "enum": [ + "SUPPORTED", + "REFUTED", + "PARTIALLY SUPPORTED" + ], + "type": "string" + } + }, + "required": [ + "passed", + "failed", + "summary" + ], + "type": "object" + } + }, + "required": [ + "hypothesis", + "tests", + "verdict" + ], + "type": "object" +}
- Changed
verify_claim6 fields changed- changed
Input schema / properties / claim / descriptionPrevious value: -"The factual claim to verify"New value: +"Plain-language claim to verify, for example 'AWS Business support includes 24/7 phone support'." - added
Input schema / properties / claim / minLengthAdded value: +5 - changed
Input schema / properties / evidence_urls / descriptionPrevious value: -"URLs to cross-reference against"New value: +"One to ten public documentation, pricing, policy, or support URLs that are likely to contain direct evidence for the claim." - changed
Input schema / properties / keywords / descriptionPrevious value: -"Keywords that should appear if the claim is true"New value: +"Keywords or short phrases that should appear on supporting pages. Matching is case-insensitive substring matching." - added
Input schema / properties / keywords / items / minLengthAdded value: +1 - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "claim": { + "description": "Claim that was evaluated.", + "type": "string" + }, + "sources": { + "description": "Per-source evidence results.", + "items": { + "additionalProperties": false, + "properties": { + "accessible": { + "description": "True when the evidence page could be fetched.", + "type": "boolean" + }, + "cached": { + "description": "True when the page body came from the 5-minute cache.", + "type": "boolean" + }, + "error": { + "description": "Fetch error when the evidence page could not be checked.", + "type": "string" + }, + "keywordsMatched": { + "description": "Subset of supplied keywords that were found on the page.", + "items": { + "type": "string" + }, + "type": "array" + }, + "keywordsTotal": { + "description": "Total number of keywords the tool looked for on this page.", + "minimum": 0, + "type": "integer" + }, + "matchRatio": { + "description": "Matched-keyword ratio for this source, from 0 to 1.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "supports": { + "description": "True when the page met the current support threshold of at least half of the supplied keywords.", + "type": "boolean" + }, + "url": { + "description": "Evidence URL that was checked.", + "type": "string" + } + }, + "required": [ + "url", + "accessible", + "supports" + ], + "type": "object" + }, + "type": "array" + }, + "verdict": { + "additionalProperties": false, + "description": "Aggregate verdict across all supplied sources.", + "properties": { + "confidence": { + "description": "Share of sources that supported the claim.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "contradicting": { + "description": "Number of sources not marked as supporting the claim.", + "minimum": 0, + "type": "integer" + }, + "summary": { + "description": "High-level verdict derived from the supporting-source ratio.", + "enum": [ + "CONFIRMED", + "UNCONFIRMED", + "LIKELY TRUE", + "LIKELY FALSE" + ], + "type": "string" + }, + "supporting": { + "description": "Number of sources marked as supporting the claim.", + "minimum": 0, + "type": "integer" + }, + "total": { + "description": "Total number of evidence sources checked.", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "supporting", + "contradicting", + "total", + "confidence", + "summary" + ], + "type": "object" + } + }, + "required": [ + "claim", + "sources", + "verdict" + ], + "type": "object" +}
6 tool updates
v0.1.0- First observed
check_endpoint - First observed
check_pricing - First observed
compare_competitors - First observed
estimate_market - First observed
test_hypothesis - First observed
verify_claim
TDQS
Scored across 16 tools
Each tool has a clearly defined purpose with minimal overlap. While some tools like verify_claim and test_hypothesis might seem similar, their descriptions distinctly separate them: verify_claim does keyword matching on given URLs, while test_hypothesis runs a small plan of varied checks. Other tools like check_pricing and compare_pricing_pages are also well-differentiated by scope.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., assess_compliance_posture, check_endpoint, list_monitors). There are no deviations or mixed conventions, making it easy for an agent to predict tool names.
With 16 tools, the server covers a wide range of verification scenarios without being bloated. The count is well-scoped for the domain of ground truth checking, including monitoring, pricing, compliance, and endpoint verification.
The tool set is comprehensive for the stated purpose, covering most common verification needs. Minor gaps might include the absence of a tool for checking social proof or user reviews, but overall the surface covers the core workflows (monitoring, pricing, compliance, security headers, package comparison, and claim verification).
Maintenance
Related MCP Connectors
Independent checks of paid x402 data sellers and of AI-agent access to shopping and travel sites
x402-paid analytics, market intelligence, research, and LLM inference for AI agents.
Pay-per-use AI and data tools via x402: image, video, music, voice, search, crypto. USDC.
Live AI agent trust oracle: audit synthetic IQ, latency & JSON compliance via x402 or free tokens.
Related MCP Servers
AlicenseAqualityCmaintenanceThis server enables AI systems to integrate with Tavily's search and data extraction tools, providing real-time web information access and domain-specific searches.421,505 npm2,477MIT- AlicenseNot gradedqualityDmaintenanceProvides 19 AI-powered business intelligence tools for tasks such as SEO audits, company enrichment, and market analysis. These services are accessible through a pay-per-use model utilizing the x402 protocol on the Base network.MIT
- AlicenseAqualityCmaintenanceTrust layer for AI agents: 22 pay-per-call x402 tools for scam and fraud checks, payment pre-flight, wallet screening, policy approvals, contact extraction and company research. Free preview with no wallet; paid calls settle in USDC on Base.2280 npmMIT
- AlicenseNot gradedqualityCmaintenanceProvides AI agents with honest benchmark rankings (Agentic Memory Index and Agentic Search Index) for AI tools, plus graded checks and telemetry for x402 endpoints.8 npmMIT