Skip to main content
Glama

VetAgent

MCP registry vetagent MCP connector – tool definition quality and endpoint health on Glama License: MIT

A pre-trade safety check for AI agents. Before an agent buys, holds, or recommends a token, it calls VetAgent and gets an actionable verdict — low / medium / high / unknown — plus the specific signals behind it, instead of a wall of numbers to interpret.

Remote MCP endpoint: https://vetagent.dev/mcp · Landing page: https://vetagent.dev Using it, or think it got a token wrong? hello@vetagent.dev — or open an issue.

// assess_token_risk("0x…", chain_hint="ethereum")
{
  "risk_level": "medium",
  "risk_score": 36,
  "confidence": "high",
  "signals": [
    {"severity": "ok",   "name": "Liquidity is adequate",     "category": "liquidity"},
    {"severity": "ok",   "name": "Buys and sells normally",   "category": "honeypot"},
    {"severity": "warn", "name": "Contract is closed source", "category": "contract"}
  ],
  "recommendation": "Medium risk. Real signals fired but none are fatal. Review liquidity, holder distribution and contract permissions before deciding."
}

Install

Nothing to install. It is a remote server: no package, no container, no API key, no signup. Add one URL.

Claude Code:

claude mcp add --transport http vetagent https://vetagent.dev/mcp

Cline, Cursor, Claude Desktop, or any other MCP client — add to the MCP config:

{
  "mcpServers": {
    "vetagent": {
      "type": "http",
      "url": "https://vetagent.dev/mcp"
    }
  }
}

Confirm it worked — three tools should come back:

curl -s -X POST https://vetagent.dev/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Not using MCP? The same engine answers over plain HTTP: GET https://vetagent.dev/assess/<address>

See llms-install.md for the version written for an agent doing the installing, and docs/AGENT-INTEGRATION.md for how to use the output once connected.


Related MCP server: contract-auditor

unknown is not low

This is the single most important thing to know about the output.

VetAgent is fail-closed. When a check cannot run — an upstream is down, a buy/sell simulation fails, no liquidity data comes back — it returns unknown and lists exactly what was missing in evidence.data_gaps. It never substitutes an optimistic middle value, and it never sizes a position for you.

confidence measures how complete the input data was, not how safe the token is.

A risk tool that honestly says "I don't know" is useful. One that guesses is not.


Tools

Tool

What it does

assess_token_risk(address, chain_hint?, verbose?)

Full risk profile: sellability simulation, liquidity depth, pair age, holder concentration, contract permissions, upstream aggregate verdicts

get_token_liquidity(address, chain_hint?)

Liquidity snapshot for the primary pair, with an explicit status so "upstream failed" is distinguishable from "no pools exist"

find_new_hot_pools(chain?, limit?)

Newest / hottest pools on a chain. Discovery only — not a safety endorsement

Pass chain_hint whenever you know it. Ethereum forks such as PulseChain inherit contract addresses, so the same address exists on multiple chains with wildly different prices; the hint removes that ambiguity. (Without it, VetAgent prefers canonical chains — see _CHAIN_RANK in src/risk.py.)

Full agent-facing contract: docs/AGENT-INTEGRATION.md.


Accuracy benchmark

Most token-risk tools publish a feature list. We publish our error rates and the method behind them — including the parts that do not work yet — against labels produced by data sources the engine does not read.

What is measured today: a 4.3% false positive rate on 162 healthy tokens, a 15.3% unknown rate, and 22.9% of GoPlus-tagged centralised tokens rated high -- almost all abandoned pools holding cents, not USDT, which is rated low.

What is not measured today: recall. Sampling has turned up 30 dead tokens in 576, because every public source ranks by liquidity and rugged pools fall off the listing entirely. Rather than compute a detection rate on a single sample and present it as a result, that figure is left blank until the daily snapshot archive matures enough to supply a real cohort. An earlier version of this section claimed "measured recall", which the benchmark file itself contradicted.

bench/results.md — current numbers, method, and known limits.

Why it is built this way:

  • Independent labels. If the benchmark labelled tokens using honeypot.is — which the engine reads — it would only measure whether VetAgent can relay honeypot.is. Labels come from realized market outcome (price/volume history) and from GoPlus, which is deliberately held out of the engine.

  • A runtime assertion, not a promise. The benchmark records every endpoint each side touched and fails the run if the two sets intersect. A circular benchmark is worse than none, so it is made structurally impossible rather than documented.

  • An ablation column. A token that already collapsed has ~zero liquidity today, so flagging it is close to tautological. Results are therefore reported twice: with all signals, and with liquidity/lifecycle signals removed. The gap is what the engine actually contributes beyond the obvious.

  • unknown rate reported alongside recall. A tool that answers unknown to everything has perfect recall and zero value.

python bench/build_dataset.py --limit 250   # sample + label (independent sources)
python bench/run_benchmark.py               # score the local engine, write results.md

Tests

python tests/test_risk.py               # engine regressions, offline, real upstream snapshots
python tests/test_mcp.py                # MCP protocol conformance
python tests/test_upstream_contract.py  # live: asserts the JSON paths we depend on still exist

Every case in tests/ is pinned to a defect that actually reached production.

The contract test earns its keep: VetAgent's worst bug was reading simulationResult.isHoneypot when honeypot.is puts that flag in honeypotResult. The key did not exist, the lookup returned None, it was read as False, and the honeypot check silently passed every token it was ever asked about. No mocked test could have caught that — only one that calls the real API and asserts the shape.

Rule for this repo: a commit that claims to fix something ships with a test that was red before it.


Architecture

Cloudflare Python Worker, no heavy dependencies.

src/
  entry.py        HTTP routing (entry class must be named Default)
  risk.py         risk engine — assess / liquidity / new_pools
  mcp_server.py   hand-written streamable-http MCP endpoint (JSON-RPC 2.0)
  landing.html    landing page
bench/            accuracy benchmark (independent labels + ablation)
tests/            regression, protocol, and upstream-contract suites
docs/             agent integration guide, handoff, MCP registry manifest

The MCP endpoint is hand-written rather than using the official mcp package: that package pulls in pydantic's C extensions, which do not install on Cloudflare Python Workers. Plain JSON-RPC turned out to be smaller and fully client-compatible.

Data sources

Source

Used for

DexScreener

pairs, price, liquidity, volume, pair age

GeckoTerminal

liquidity fallback, new/trending pools

honeypot.is

EVM buy/sell simulation, taxes, aggregate risk, contract openness

RugCheck

Solana rug score, mint/freeze authority, holder concentration

GoPlus is not used by the engine — it is reserved as the benchmark's held-out oracle. Adding it to the engine requires giving the benchmark a new independent labeller first, or the accuracy numbers stop meaning anything.

Where things are written down

Four documents, one job each. If something is in two of them, one of them is wrong.

Document

Answers

README.md (this file)

What is this, how do I call it

docs/DECISIONS.md

Why is it built this way, and what enforces each rule

docs/HANDOFF.md

Where things stand, what breaks, what to do next

docs/STRATEGY.md

Who pays, what the moat is, when to shut it down

Why a change was made lives in the commit message, which is immutable and attached to the diff. Why a line of code looks odd lives in a comment next to that line. Neither gets copied into a document, because a copy rots without anyone noticing.

Scope

VetAgent reports observable on-chain risk. It is not financial advice, it does not size positions, and it cannot see off-chain risk — team behaviour, social engineering, or a rug executed through governance. Treat low as "no fatal signal found in the checks that ran", never as "safe to buy".

License

Not yet chosen — see docs/HANDOFF.md.

Available Tools

3 tools
assess_token_riskAssess Token RiskA
Read-onlyIdempotent
Inspect

Safety check to run BEFORE buying, holding, or recommending a token. Returns an actionable verdict (low / medium / high / unknown), a 0-100 risk score, and the individual signals behind it. Covers: sell simulation (honeypot detection, buy/sell/transfer taxes), liquidity depth, trading-pair age, cross-chain presence, whether the contract is open source, and on Solana the mint/freeze authority and holder concentration — plus the aggregate verdicts of upstream security scanners. IMPORTANT: risk_level 'unknown' means a critical check could not be completed. It is NOT a low-risk result and must not be used to justify a trade; evidence.data_gaps lists exactly what was missing. 'confidence' measures how complete the input data was, not how safe the token is. Reports observable on-chain risk only. Not financial advice, does not size positions, and cannot see off-chain risk such as team behaviour, social engineering, or a rug executed through governance. Treat 'low' as 'no fatal signal found in the checks that ran', never as 'safe to buy'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesToken contract address: ERC-20 (0x + 40 hex) or Solana (base58)
verboseNoReturn full upstream evidence. Off by default to save tokens.
chain_hintNoOptional chain name (ethereum / bsc / base / polygon / arbitrum / solana). Strongly recommended: Ethereum forks such as PulseChain inherit contract addresses, so the same address exists on several chains at wildly different prices.

Output Schema

ParametersJSON Schema
NameRequiredDescription
addressYes
signalsYes
evidenceNo
confidenceYesHow complete the input data was — not how safe the token is.
risk_levelYes'unknown' means a critical check could not be completed. It is NOT a low-risk result and must not justify a trade.
risk_scoreYes0-100; higher is more dangerous
recommendationNo

TDQS

A4.4/5.0
Behavior5/5

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

The annotations only declare the tool read-only, idempotent, and non-destructive. The description goes far beyond this by explaining the critical semantics of 'unknown', the meaning of 'confidence', the data_gaps output, and the tool's blind spots (off-chain risk, team behavior, governance rugs). This is exactly the kind of behavioral context an agent needs to avoid misusing the result.

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

Conciseness4/5

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

The description is front-loaded with the tool's purpose and return value, then moves through coverage, critical caveats, and limitations. It is somewhat long but earns its length given the safety-critical nature of the tool. A small amount of redundancy exists between 'Reports observable on-chain risk only' and the later 'cannot see off-chain risk' phrasing.

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

Completeness5/5

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

Given the tool's complexity, the presence of an output schema, and the safety-sensitive use case, the description provides everything needed: what checks are performed, how to interpret non-obvious outputs like 'unknown' and 'confidence', and what the tool cannot detect. No critical operational context is missing.

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 100% parameter descriptions, including detailed guidance on chain_hint and verbose. The tool description does not add new parameter-level meaning, but it doesn't need to because the schema field descriptions are already thorough. This matches the baseline for high schema coverage.

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 clearly identifies the tool as a pre-trade safety check that outputs a risk verdict, a 0-100 score, and supporting signals. It names the specific resource (token) and the action (assess risk), and the coverage list makes its scope unambiguous.

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 explicitly tells the agent when to use the tool: before buying, holding, or recommending a token. It also gives important when-not guidance: 'unknown' must not justify a trade, 'low' means no fatal signal found, and off-chain risks are out of scope. It does not explicitly compare against sibling tools like get_token_liquidity or find_new_hot_pools, but the usage context is otherwise clear.

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

find_new_hot_poolsFind New Hot PoolsA
Read-only
Inspect

Scan a chain for the newest and most active trading pools, returning name, token_address, price, liquidity, 24h volume and pool age. Discovery only. New pools carry inherently high risk and appearing here is NOT a safety endorsement — pass token_address straight to assess_token_risk for anything you intend to act on.

ParametersJSON Schema
NameRequiredDescriptionDefault
chainNoChain name, e.g. solana / ethereum / base / bscsolana
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
chainYes
countYesHow many pools are in `pools`. NOT how many were examined -- that is `scanned`. This field reported the fetched total beside a shorter list until 2026-09-08, so a caller reading it believed it had seen twenty pools when it had three.
poolsYes
networkYesThe upstream's own name for the chain, which differs from `chain` (eth vs ethereum).
scannedYesHow many distinct pools were examined before the limit was applied. Always >= count.
sources_okYesWhich of the two upstream listings answered. Both means a full scan.
served_staleNoPresent only when an upstream was unreachable and cached data was used. Each entry names the source and its age in seconds.
sources_failedYesWhich listings did NOT answer. A non-empty array means this is a PARTIAL scan: a smaller `scanned` here is a coverage gap, not a quiet market. Treat it as missing information, not as absence.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already cover read-only/open-world/non-destructive behavior, and the description adds the important caveat that appearing here is 'NOT a safety endorsement' and that new pools carry high risk. This is valuable non-obvious context beyond the annotations, though it doesn't elaborate on ordering, freshness, or rate-limit behavior.

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 crisp sentences, front-loaded with the action and return fields, with the risk caveat placed second. No wasted words and no repetition of schema or annotation data.

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

Completeness5/5

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

For a simple two-parameter, zero-required discovery tool with an output schema, the description is complete: it states the purpose, output scope, risk posture, and the follow-up action. The only minor omission is explicit guidance on get_token_liquidity, which is a usage-guideline nuance rather than a completeness gap.

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 description conveys no input-parameter meaning; chain is explained in the schema and limit is only self-evident from its name plus min/max/default constraints. With 50% schema coverage, the description doesn't add enough to lift parameter understanding beyond what the schema already offers.

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?

States a concrete action ('Scan a chain') and a specific resource ('newest and most active trading pools'), and lists the exact return fields. It also frames itself as 'Discovery only' and routes to assess_token_risk, distinguishing it from the risk-assessment sibling.

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 'Discovery only' line and the explicit instruction to send token_address to assess_token_risk for anything you intend to act on give clear when/when-not guidance. However, it never addresses get_token_liquidity as the targeted single-token liquidity lookup, so the sibling comparison is incomplete.

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

get_token_liquidityGet Token LiquidityA
Read-onlyIdempotent
Inspect

Liquidity snapshot for a token's primary trading pair: price, 24h volume, pair count and the chains it trades on. Check 'status' before using the numbers. 'ok' means real data. 'unavailable' means the upstream request failed, which does NOT mean the token has no liquidity. 'not_found' means no trading pair exists for this address at all. 'unpriced' means pairs exist but no source has costed them, so liquidity_usd is null and the depth is unknown -- this is NOT a report of zero liquidity. 'drained' means every pool on the token's own chain reports its depth and every one is empty: there is nothing to sell into.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesToken contract address
chain_hintNoOptional chain name; disambiguates forks that share addresses

Output Schema

ParametersJSON Schema
NameRequiredDescription
chainsNo
statusYes
addressYes
price_usdNo
pairs_totalNo
served_staleNoPresent only when an upstream was unreachable and this answer used cached data. Each entry names the source and how many seconds old it was.
liquidity_usdNo
volume_24h_usdNo

TDQS

A4.5/5.0
Behavior5/5

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

The description richly discloses behavior beyond the annotations: it explains failure modes, what null liquidity means, that 'unavailable' does not indicate zero liquidity, and what 'drained' implies for tradability. This is exactly the interpretive context an agent needs and goes well beyond the readOnlyHint/idempotentHint annotations.

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 compact but information-dense, with the core purpose front-loaded and status semantics following in a structured, readable sequence. Every sentence adds value by preventing a specific misinterpretation, so the length is justified and efficient.

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

Completeness5/5

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

Given the tool's moderate complexity, full schema coverage, rich annotations, and presence of an output schema, the description is complete. It covers the main data returned, the critical status field, edge cases, and the meaning of null values — everything an agent needs to correctly interpret results.

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?

Schema description coverage is 100%, so the baseline is 3. The description does not add new parameter-level detail beyond the schema, but the schema already documents 'address' and 'chain_hint' sufficiently, including the fork-disambiguation purpose of chain_hint. No compensation is needed.

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 opens with a specific verb and resource: "Liquidity snapshot for a token's primary trading pair," and lists concrete outputs such as price, 24h volume, pair count, and chains. This clearly distinguishes it from sibling tools like find_new_hot_pools or assess_token_risk, which target discovery and risk assessment rather than current liquidity measurement.

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 gives clear operational guidance: check 'status' before trusting numbers, and interprets each status value so the agent knows how to act on 'unavailable', 'not_found', 'unpriced', and 'drained'. It does not explicitly name sibling alternatives or state when to prefer them, but it provides strong context for correct usage.

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. Dates show when Glama detected each change.

  1. 3 tool updatesv0.1.0
    • First observedassess_token_risk
    • First observedfind_new_hot_pools
    • First observedget_token_liquidity

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct stage in the token-vetting workflow: discovery of new pools, risk assessment, and liquidity snapshot. Although assess_token_risk and get_token_liquidity both touch liquidity, their purposes and outputs are clearly separated (verdict vs. market data).

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern: find_new_hot_pools, assess_token_risk, get_token_liquidity. The verbs are descriptive and the object nouns clearly identify the target resource.

Tool Count5/5

Three tools is well-scoped for a focused vetting agent: one discovery entry point, one risk-check entry point, and one liquidity-data entry point. No tool is redundant and none is missing from the core workflow.

Completeness4/5

The set covers the full discovery-to-risk-to-liquidity pipeline with no dead ends. Minor gaps exist, such as no historical-tracking or token-profile/summary tool beyond the risk check, but agents can work around them.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Token safety oracle for AI agents. Honeypot detection, 17 scam pattern checks, LP lock verification across 6 EVM chains. Score 0-100 with risk flags. ERC Token Safety Score standard.
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Quick-scan a smart contract for rug, honeypot, or centralization risk before sending funds. It combines verified source, live on-chain state, and heuristic Solidity analysis to return a SAFE/CAUTION/HIGH-RISK verdict.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Checks token contract safety for honeypot, tax, proxy, blacklist, ownership risks, and returns a risk score, enabling rug-pull protection for agents via pay-per-call x402 micropayments.
    MIT