Koskamo

VetAgent MCP

A pre-trade safety check for AI agents that simulates trades to detect honeypots, extraction taxes, liquidity depth, and same-ticker impersonation across multiple chains, providing a risk verdict before buying, holding, or recommending a token.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

VetAgent MCP logo, by VetAgentVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-07Operated by VetAgent
MCP endpoint (Streamable HTTP)
https://vetagent.dev/mcp
Vendor documentation

What its tools do

3 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

3 of 3 have a description · 3 of 3 declare behavior hints · 2 of 3 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to vetagent.dev ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Simulate token trades to detect honeypots and extraction taxes
  • Check liquidity depth and exit feasibility for tokens
  • Identify same-ticker impersonation across multiple chains
  • Get a risk verdict (low/medium/high/unknown) before trading

Source and maintenance

Vendor evidenceRegistry 0.2.0
Maintenance checked

Protocol and capabilities

Server
vetagent 0.2.0
MCP protocol negotiated in check
2025-06-18
Tools
3 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Call assess_token_risk before an agent buys, holds, or recommends a token. risk_level 'unknown' means a critical check could not run — it is not a low-risk result and must not be used to justify a trade. Building on this? The maintainer would like to know it is being used, and will tell you before anything changes under you: hello@vetagent.dev, or github.com/jakegu1/vetagent/issues. Free, no signup, no tracking — this server records no addresses, no token queries and no identities, which is also why it cannot tell who you are unless you say.

Tools

3 advertised

assess_token_risk — Assess Token Risk
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

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 on every chain: liquidity depth, trading-pair age, cross-chain presence, same-ticker impersonation. Covers on Ethereum, BSC and Base only: sell simulation (honeypot detection, buy/sell/transfer taxes), whether the contract is open source, and the aggregate verdicts of upstream security scanners. Covers on Solana: the mint/freeze authority, the RugCheck score, and the SPL Token-2022 extension block -- non-transferable, frozen-by-default, transfer fee (with its cap), permanent delegate, transfer hook, pausable, close authority, scaled balances and interest-bearing balances. Every other extension the report carries is named in the answer with the reason it is not scored, so silence about one means it was considered, not that it went unread. No sell simulation runs on Solana, nor on the four other EVM chains accepted as a chain_hint (polygon, arbitrum, optimism, avalanche): nothing there tests whether a holder can sell, so the answer comes back 'unknown' rather than 'low'. No holder concentration on any chain -- on EVM it needs an oracle the benchmark holds out, and on Solana the upstream omits holders. 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, and unknown_kind says whose gap it is: 'infrastructure' and 'mixed' mean an upstream of ours failed and come with next_action 'retry' and retry_after_seconds (in a 'mixed' answer the rest was worked out without that upstream, so the retry can change any of it); 'coverage' comes with 'abstain'. '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'.

assess_token_risk input schema
{
  "type": "object",
  "required": [
    "address"
  ],
  "properties": {
    "address": {
      "type": "string",
      "description": "Token contract address: ERC-20 (0x + 40 hex) or Solana (base58)"
    },
    "verbose": {
      "type": "boolean",
      "default": false,
      "description": "Return full upstream evidence. Off by default to save tokens."
    },
    "chain_hint": {
      "type": "string",
      "description": "Optional 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. Without it, an answer covers one chain -- the one holding the most depth -- and names it."
    }
  }
}
assess_token_risk output schema
{
  "type": "object",
  "required": [
    "address",
    "risk_level",
    "risk_score",
    "confidence",
    "signals"
  ],
  "properties": {
    "driver": {
      "type": [
        "object",
        "null"
      ],
      "description": "The signal that decided the verdict: {name, category}. null when nothing above ok fired."
    },
    "address": {
      "type": "string"
    },
    "signals": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "severity": {
            "enum": [
              "ok",
              "info",
              "warn",
              "critical",
              "fatal"
            ],
            "type": "string"
          }
        }
      }
    },
    "evidence": {
      "type": "object"
    },
    "checked_at": {
      "type": "string",
      "description": "When this answer was made, ISO-8601 UTC."
    },
    "confidence": {
      "enum": [
        "low",
        "medium",
        "high"
      ],
      "type": "string",
      "description": "How complete the input data was — not how safe the token is."
    },
    "risk_level": {
      "enum": [
        "low",
        "medium",
        "high",
        "unknown"
      ],
      "type": "string",
      "description": "'unknown' means a critical check could not be completed. It is NOT a low-risk result and must not justify a trade."
    },
    "risk_score": {
      "type": "integer",
      "description": "0-100; higher is more dangerous"
    },
    "next_action": {
      "enum": [
        "retry",
        "abstain"
      ],
      "type": "string"
    },
    "unknown_kind": {
      "enum": [
        "infrastructure",
        "coverage",
        "mixed"
      ],
      "type": "string",
      "description": "Present only when risk_level is unknown."
    },
    "recommendation": {
      "type": "string"
    },
    "retry_after_seconds": {
      "type": "integer"
    },
    "evidence_max_age_seconds": {
      "type": "integer",
      "description": "Age of the oldest evidence used; 0 when every source answered live."
    }
  }
}
assess_token_risk annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_token_liquidity — Get Token Liquidity
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

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 usable upstream data, not independently verified reserves or executable sell depth. The optional liquidity_reserve_check marker says 'not_checkable' when a positive selected estimate has no computable reserve cap. A missing marker never asserts that reserves, prices or an exit trade were independently verified. '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.

get_token_liquidity input schema
{
  "type": "object",
  "required": [
    "address"
  ],
  "properties": {
    "address": {
      "type": "string",
      "description": "Token contract address"
    },
    "chain_hint": {
      "type": "string",
      "description": "Optional chain name; disambiguates forks that share addresses"
    }
  }
}
get_token_liquidity output schema
{
  "type": "object",
  "required": [
    "address",
    "status"
  ],
  "properties": {
    "chains": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "status": {
      "enum": [
        "ok",
        "not_found",
        "unpriced",
        "drained",
        "unavailable"
      ],
      "type": "string"
    },
    "address": {
      "type": "string"
    },
    "price_usd": {
      "type": [
        "number",
        "null"
      ]
    },
    "checked_at": {
      "type": "string",
      "description": "When this answer was made, ISO-8601 UTC."
    },
    "pairs_total": {
      "type": "integer"
    },
    "served_stale": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Present 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_usd": {
      "type": [
        "number",
        "null"
      ]
    },
    "volume_24h_usd": {
      "type": [
        "number",
        "null"
      ]
    },
    "liquidity_reserve_check": {
      "enum": [
        "not_checkable"
      ],
      "type": "string",
      "description": "The positive upstream estimate was retained, but its reserve amounts could not be checked. Absence of this marker makes no verification claim."
    }
  }
}
get_token_liquidity annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
find_new_hot_pools — Find New Hot Pools
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

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.

find_new_hot_pools input schema
{
  "type": "object",
  "properties": {
    "chain": {
      "type": "string",
      "default": "solana",
      "description": "Chain name, e.g. solana / ethereum / base / bsc"
    },
    "limit": {
      "type": "integer",
      "default": 10,
      "maximum": 50,
      "minimum": 1
    }
  }
}
find_new_hot_pools output schema
{
  "type": "object",
  "required": [
    "status",
    "chain",
    "network",
    "count",
    "scanned",
    "sources_ok",
    "sources_failed",
    "pools"
  ],
  "properties": {
    "chain": {
      "type": "string"
    },
    "count": {
      "type": "integer",
      "description": "How 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."
    },
    "pools": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "pool_id",
          "name",
          "token_address",
          "kind"
        ],
        "properties": {
          "kind": {
            "enum": [
              "new",
              "trending"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "pool_id": {
            "type": "string"
          },
          "price_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "liquidity_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "pool_age_days": {
            "type": [
              "integer",
              "null"
            ]
          },
          "token_address": {
            "type": "string",
            "description": "The base token. This is the field to hand to assess_token_risk -- pool_id is not an address, and passing it produced six empty answers before the discovery-to-vetting seam was fixed."
          },
          "volume_24h_usd": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      }
    },
    "status": {
      "enum": [
        "ok",
        "partial"
      ],
      "type": "string",
      "description": "Completeness only: ok means both listings were observed; partial means only one usable listing was observed. This is not a token risk verdict or a safety endorsement."
    },
    "network": {
      "type": "string",
      "description": "The upstream's own name for the chain, which differs from `chain` (eth vs ethereum)."
    },
    "scanned": {
      "type": "integer",
      "description": "How many distinct pools were examined before the limit was applied. Always >= count."
    },
    "checked_at": {
      "type": "string",
      "description": "When this answer was made, ISO-8601 UTC."
    },
    "sources_ok": {
      "type": "array",
      "items": {
        "enum": [
          "new",
          "trending"
        ],
        "type": "string"
      },
      "description": "Which of the two upstream listings answered. Both means a full scan."
    },
    "served_stale": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Present only when an upstream was unreachable and cached data was used. Each entry names the source and its age in seconds."
    },
    "sources_failed": {
      "type": "array",
      "items": {
        "enum": [
          "new",
          "trending"
        ],
        "type": "string"
      },
      "description": "Which 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."
    }
  },
  "description": "Discovery only, never an endorsement. Call assess_token_risk on token_address before saying anything about a pool's risk."
}
find_new_hot_pools annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
279 ms
95th percentile latency
279 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 279 ms · metadata changed · 3 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http vetagent-mcp https://vetagent.dev/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add vetagent-mcp --url https://vetagent.dev/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable vetagent-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "vetagent-mcp": {
      "url": "https://vetagent.dev/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "vetagent-mcp": {
      "type": "streamableHttp",
      "url": "https://vetagent.dev/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start vetagent-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "vetagent-mcp": {
      "type": "http",
      "url": "https://vetagent.dev/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http vetagent-mcp https://vetagent.dev/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://vetagent.dev/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "vetagent-mcp": {
      "serverUrl": "https://vetagent.dev/mcp"
    }
  }
}

Let your agent find its tools

Find servers like VetAgent MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run VetAgent MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing