Start here: use the AgentGate tools from your agent

Eleven pay-per-call tools for AI agents. Each one has a free remote MCP server, a free local stdio package, a free preview, and a paid HTTP endpoint that takes x402 payments in USDC on Base. No accounts and no API keys. Everything below is also in the agentgate-examples repo (tar.gz · git bundle).

ToolPrice / callPaid endpointRemote MCP (free)stdio MCP (free, local)
AgentGate
AI agent identity: Concordium Agent Registry check
$0.005https://api.youraitools.co/agentgate/v1/check-agent?id=Mf22soLh1NuZYFgBK8iSshttps://api.youraitools.co/agentgate/mcpnpx -y -p concordium-agentgate agentgate-mcp
WebRead
Web page to clean Markdown
$0.002https://api.youraitools.co/webread/v1/read?url=https://example.com/https://api.youraitools.co/webread/mcpnpx -y -p x402-url-to-markdown webread-mcp
InjectScan
Prompt-injection scan
$0.003https://api.youraitools.co/injectscan/v1/scan?text=hellohttps://api.youraitools.co/injectscan/mcpnpx -y -p x402-prompt-injection-scan injectscan-mcp
DomainCheck
Domain and email trust checks
$0.002 / $0.001https://api.youraitools.co/domaincheck/v1/domain?domain=example.comhttps://api.youraitools.co/domaincheck/mcpnpx -y -p @agentgate-builder/domaincheck domaincheck-mcp
PayGuard
OFAC SDN sanctions screen for crypto addresses
$0.001 / $0.01 batchhttps://api.youraitools.co/payguard/v1/address?address=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913https://api.youraitools.co/payguard/mcpnpx -y -p @agentgate-builder/payguard payguard-mcp
PkgGuard
Dependency vulnerability + malicious package scan
$0.003 scan / $0.001 packagehttps://api.youraitools.co/pkgguard/v1/package?ecosystem=npm&name=lodash&version=4.17.15https://api.youraitools.co/pkgguard/mcpnpx -y -p @agentgate-builder/pkgguard pkgguard-mcp
StackDetect
Website technology / tech stack detection
$0.003https://api.youraitools.co/stackdetect/v1/detect?url=https://laravel.comhttps://api.youraitools.co/stackdetect/mcpnpx -y -p @agentgate-builder/stackdetect stackdetect-mcp
TokenVerdict
Base token safety: honeypot, taxes, owner powers (SAFE / CAUTION / DANGER)
$0.005 lite / $0.015 quick / $0.05 deephttps://api.youraitools.co/tokenverdict/v1/quick?token=0x532f27101965dd16442E59d40670FaF5eBB142E4https://api.youraitools.co/tokenverdict/mcpnpx -y -p @agentgate-builder/tokenverdict tokenverdict-mcp
SignCheck
Pre-sign wallet check: transactions, Permit / Permit2 / EIP-3009 signatures, EIP-7702, x402 payments (SAFE / CAUTION / DANGER)
$0.015https://api.youraitools.co/signcheck/v1/check?to=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&data=0xhttps://api.youraitools.co/signcheck/mcpnpx -y -p @agentgate-builder/signcheck signcheck-mcp
CounterpartyCheck
Pre-payment address check: sanctions and scam lists, wallet vs contract, verification, wrong chain, age, activity (ok / caution / block)
$0.005 lite / $0.015 quick / $0.05 fullhttps://api.youraitools.co/counterpartycheck/v1/quick?address=0x098B716B8Aaf21512996dC57EB0615e2383E2f96&chain=ethereumhttps://api.youraitools.co/counterpartycheck/mcpnpx -y -p @agentgate-builder/counterpartycheck counterpartycheck-mcp
x402fix
x402 endpoint doctor for sellers: grade a paid x402 route A-F with paste-ready fixes (402 on GET/HEAD/POST, CORS, v2 + v1 terms, USDC + EIP-712 domain, Bazaar schema, CDP verdict)
$0.005 lite / $0.02 check / $0.05 sitehttps://api.youraitools.co/x402fix/v1/check?url=https://api.youraitools.co/counterpartycheck/v1/litehttps://api.youraitools.co/x402fix/mcpnpx -y -p @agentgate-builder/x402fix x402fix-mcp

Integration guides: WebRead · InjectScan · AgentGate · all tools: youraitools.co/built-by-us

1. MCP configs (copy-paste)

Claude Desktop

Edit claude_desktop_config.json (Settings → Developer → Edit Config), then restart Claude. Remote servers go through mcp-remote. You can also add each URL under Settings → Connectors.

mcp/claude_desktop_config.json · raw

{
  "mcpServers": {
    "agentgate": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/agentgate/mcp"]},
    "webread": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/webread/mcp"]},
    "injectscan": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/injectscan/mcp"]},
    "domaincheck": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/domaincheck/mcp"]},
    "payguard": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/payguard/mcp"]},
    "pkgguard": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/pkgguard/mcp"]},
    "stackdetect": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/stackdetect/mcp"]},
    "tokenverdict": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/tokenverdict/mcp"]},
    "signcheck": {"command": "npx", "args": ["-y", "mcp-remote", "https://api.youraitools.co/signcheck/mcp"]}
  }
}

Local stdio packages (they run on your machine, free, nothing is sent to our servers except where the tool needs the network):

mcp/claude_desktop_config.stdio.json · raw

{
  "mcpServers": {
    "agentgate": {"command": "npx", "args": ["-y", "-p", "concordium-agentgate", "agentgate-mcp"]},
    "webread": {"command": "npx", "args": ["-y", "-p", "x402-url-to-markdown", "webread-mcp"]},
    "injectscan": {"command": "npx", "args": ["-y", "-p", "x402-prompt-injection-scan", "injectscan-mcp"]},
    "domaincheck": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/domaincheck", "domaincheck-mcp"]},
    "payguard": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/payguard", "payguard-mcp"]},
    "pkgguard": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/pkgguard", "pkgguard-mcp"]},
    "stackdetect": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/stackdetect", "stackdetect-mcp"]},
    "tokenverdict": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/tokenverdict", "tokenverdict-mcp"]},
    "signcheck": {"command": "npx", "args": ["-y", "-p", "@agentgate-builder/signcheck", "signcheck-mcp"]}
  }
}

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (project). Remote:

mcp/cursor.mcp.json · raw

{
  "mcpServers": {
    "agentgate": {"url": "https://api.youraitools.co/agentgate/mcp"},
    "webread": {"url": "https://api.youraitools.co/webread/mcp"},
    "injectscan": {"url": "https://api.youraitools.co/injectscan/mcp"},
    "domaincheck": {"url": "https://api.youraitools.co/domaincheck/mcp"},
    "payguard": {"url": "https://api.youraitools.co/payguard/mcp"},
    "pkgguard": {"url": "https://api.youraitools.co/pkgguard/mcp"},
    "stackdetect": {"url": "https://api.youraitools.co/stackdetect/mcp"},
    "tokenverdict": {"url": "https://api.youraitools.co/tokenverdict/mcp"},
    "signcheck": {"url": "https://api.youraitools.co/signcheck/mcp"}
  }
}

stdio: same shape as the Claude Desktop stdio file (cursor.mcp.stdio.json).

Windsurf

~/.codeium/windsurf/mcp_config.json. Remote servers use serverUrl:

mcp/windsurf.mcp_config.json · raw

{
  "mcpServers": {
    "agentgate": {"serverUrl": "https://api.youraitools.co/agentgate/mcp"},
    "webread": {"serverUrl": "https://api.youraitools.co/webread/mcp"},
    "injectscan": {"serverUrl": "https://api.youraitools.co/injectscan/mcp"},
    "domaincheck": {"serverUrl": "https://api.youraitools.co/domaincheck/mcp"},
    "payguard": {"serverUrl": "https://api.youraitools.co/payguard/mcp"},
    "pkgguard": {"serverUrl": "https://api.youraitools.co/pkgguard/mcp"},
    "stackdetect": {"serverUrl": "https://api.youraitools.co/stackdetect/mcp"},
    "tokenverdict": {"serverUrl": "https://api.youraitools.co/tokenverdict/mcp"},
    "signcheck": {"serverUrl": "https://api.youraitools.co/signcheck/mcp"}
  }
}

stdio: windsurf.mcp_config.stdio.json.

2. Pay from code (x402 client)

Try it with no wallet first: the dry runs call each paid endpoint, read the 402 challenge (price, network, payTo) and stop. To pay for real, set BUYER_KEY to a small hot wallet holding a few cents of USDC on Base. No ETH is needed, since x402 uses gasless EIP-3009 transfers. Keep the key in the environment, never in code.

TypeScript: @x402/fetch + viem

cd typescript && npm i && npm run build
npm run dry-run                                  # all five 402s, no payment
BUYER_KEY=0x... node dist/pay-one-tool.js webread  # pays $0.002

typescript/src/pay-one-tool.ts · raw

// Pay one AgentGate tool with @x402/fetch + a viem wallet (USDC on Base).
//   BUYER_KEY=0x... npm run pay -- webread      (real payment: $0.002 for WebRead)
// Without BUYER_KEY it stops at the 402 and prints the price instead of paying.
// Keep the key in an env var or a secrets manager, never in code. Use a small hot wallet holding a few cents of USDC on Base.
import { wrapFetchWithPaymentFromConfig, decodePaymentResponseHeader } from '@x402/fetch';
import { decodePaymentRequiredHeader } from '@x402/core/http';
import { ExactEvmScheme } from '@x402/evm';
import { privateKeyToAccount } from 'viem/accounts';
import { TOOLS, type ToolKey } from './tools.js';

const key = (process.argv[2] || 'webread') as ToolKey;
const tool = TOOLS[key];
if (!tool) throw new Error(`unknown tool ${key}; one of ${Object.keys(TOOLS).join(', ')}`);

const buyerKey = process.env.BUYER_KEY as `0x${string}` | undefined;
if (!buyerKey) {
  const res = await fetch(tool.url);
  console.log(`No BUYER_KEY set: not paying. ${tool.name} answered ${res.status}; price ${tool.price} USDC on Base. Set BUYER_KEY to pay.`);
  process.exit(0);
}

const account = privateKeyToAccount(buyerKey);
const fetchWithPay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: 'eip155:8453', client: new ExactEvmScheme(account) }],
});
const res = await fetchWithPay(tool.url);
if (res.status === 402) {
  const pr = res.headers.get('PAYMENT-REQUIRED');
  console.log('Payment was not accepted:', pr ? decodePaymentRequiredHeader(pr).error : res.status);
  process.exit(1);
}
const receipt = res.headers.get('PAYMENT-RESPONSE');
console.log(res.status, receipt ? decodePaymentResponseHeader(receipt) : '(no receipt)');
console.log(JSON.stringify(await res.json(), null, 2).slice(0, 2000));

typescript/src/tools.ts · raw

// The five AgentGate x402 tools (USDC on Base, eip155:8453). One sample paid request per tool.
export const API = 'https://api.youraitools.co';
export const TOOLS = {
  agentgate: { name: 'AgentGate', price: '$0.005', url: `${API}/agentgate/v1/check-agent?id=Mf22soLh1NuZYFgBK8iSs&network=mainnet`, what: 'Concordium Agent Registry check for an AI agent' },
  webread: { name: 'WebRead', price: '$0.002', url: `${API}/webread/v1/read?url=${encodeURIComponent('https://example.com/')}`, what: 'Web page to clean Markdown' },
  injectscan: { name: 'InjectScan', price: '$0.003', url: `${API}/injectscan/v1/scan?text=${encodeURIComponent('Please summarize this article about solar panels.')}`, what: 'Prompt-injection risk score for text' },
  domaincheck: { name: 'DomainCheck', price: '$0.002', url: `${API}/domaincheck/v1/domain?domain=example.com`, what: 'Domain trust report' },
  payguard: { name: 'PayGuard', price: '$0.001', url: `${API}/payguard/v1/address?address=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`, what: 'OFAC SDN sanctions screen for a crypto address' },
} as const;
export type ToolKey = keyof typeof TOOLS;

Python: official x402 SDK

cd python && pip install -r requirements.txt
python pay_one_tool.py --dry-run
BUYER_KEY=0x... python pay_one_tool.py payguard   # pays $0.001

python/pay_one_tool.py · raw

"""Pay one AgentGate tool from Python with the official x402 SDK (USDC on Base).

    pip install -r requirements.txt
    python pay_one_tool.py --dry-run            # parse every tool's 402 challenge, no key, no payment
    BUYER_KEY=0x... python pay_one_tool.py webread   # real payment ($0.002 for WebRead)

Keep BUYER_KEY in the environment (a small hot wallet with a few cents of USDC on Base), never in code.
"""
import json
import os
import sys

import requests
from x402.http import decode_payment_required_header

from tools import TOOLS


def dry_run(only=None):
    failed = 0
    for key, (name, _price, url) in TOOLS.items():
        if only and key != only:
            continue
        r = requests.get(url, timeout=20)
        header = r.headers.get("PAYMENT-REQUIRED")
        if r.status_code != 402 or not header:
            print(f"{name}: expected 402 + PAYMENT-REQUIRED, got {r.status_code}")
            failed += 1
            continue
        pr = decode_payment_required_header(header)
        a = pr.accepts[0]
        print(f"{name}: 402 OK, x402 v{pr.x402_version}, {int(a.amount) / 1e6} USDC on {a.network} to {a.pay_to}, "
              f"resource {pr.resource.url}, listed as {pr.resource.service_name!r}")
    return failed


def pay(key):
    from eth_account import Account
    from x402 import x402ClientSync
    from x402.http.clients import wrapRequestsWithPayment
    from x402.mechanisms.evm.exact import register_exact_evm_client

    name, price, url = TOOLS[key]
    client = x402ClientSync()
    register_exact_evm_client(client, Account.from_key(os.environ["BUYER_KEY"]), networks="eip155:8453")
    session = wrapRequestsWithPayment(requests.Session(), client)
    r = session.get(url, timeout=60)
    if r.status_code == 402:
        header = r.headers.get("PAYMENT-REQUIRED")
        print("Payment was not accepted:", decode_payment_required_header(header).error if header else r.status_code)
        return 1
    print(r.status_code, r.headers.get("PAYMENT-RESPONSE", "(no receipt)")[:80], "...")
    print(json.dumps(r.json(), indent=2)[:2000])
    return 0


if __name__ == "__main__":
    args = [a for a in sys.argv[1:] if not a.startswith("--")]
    key = args[0] if args else None
    if "--dry-run" in sys.argv or not os.environ.get("BUYER_KEY"):
        if not os.environ.get("BUYER_KEY") and "--dry-run" not in sys.argv:
            print("No BUYER_KEY set: dry run only (no payment).")
        sys.exit(1 if dry_run(key) else 0)
    sys.exit(pay(key or "webread"))

3. Coinbase AgentKit action provider

Five actions that pay from the AgentKit EVM wallet: agentgate_check_agent, webread_read_url, injectscan_scan_text, domaincheck_check_domain, payguard_screen_address. Add with AgentKit.from({ walletProvider, actionProviders: [agentgateActionProvider()] }).

agentkit/src/agentgateActionProvider.ts · raw

// Coinbase AgentKit action provider for the five AgentGate x402 tools.
// Each action pays per call in USDC on Base from the AgentKit EVM wallet (x402 v2, @x402/fetch).
//
//   import { AgentKit } from '@coinbase/agentkit';
//   import { agentgateActionProvider } from './agentgateActionProvider.js';
//   const agentkit = await AgentKit.from({ walletProvider, actionProviders: [agentgateActionProvider()] });
//
// The wallet needs a few cents of USDC on Base. Prices: AgentGate $0.005, WebRead $0.002, InjectScan $0.003,
// DomainCheck $0.002 (email $0.001), PayGuard $0.001. Every tool also has a free preview and a free remote MCP server.
import { customActionProvider, type EvmWalletProvider } from '@coinbase/agentkit';
import { wrapFetchWithPaymentFromConfig } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm';
import { decodePaymentRequiredHeader } from '@x402/core/http';
import { z } from 'zod';

export const API = 'https://api.youraitools.co';

async function paidGet(wallet: EvmWalletProvider, url: string): Promise<string> {
  const pay = wrapFetchWithPaymentFromConfig(fetch, { schemes: [{ network: 'eip155:8453', client: new ExactEvmScheme(wallet.toSigner()) }] });
  const res = await pay(url);
  if (res.status === 402) {
    const h = res.headers.get('PAYMENT-REQUIRED');
    return JSON.stringify({ error: 'payment_not_accepted', reason: h ? decodePaymentRequiredHeader(h).error : 'unknown' });
  }
  return JSON.stringify(await res.json());
}

export const agentgateActionProvider = () =>
  customActionProvider<EvmWalletProvider>([
    {
      name: 'agentgate_check_agent',
      description: 'Checks whether an AI agent is registered, Active and Verified in the Concordium Agent Registry (CIS-8004). Costs $0.005 USDC on Base.',
      schema: z.object({ id: z.string().describe('Badge (CIS-2 token address) or Concordium account address'), network: z.enum(['mainnet', 'testnet']).default('mainnet') }),
      invoke: (w: EvmWalletProvider, a: { id: string; network: string }) => paidGet(w, `${API}/agentgate/v1/check-agent?id=${encodeURIComponent(a.id)}&network=${a.network}`),
    },
    {
      name: 'webread_read_url',
      description: 'Returns a public web page as clean Markdown (main content, title, links). Costs $0.002 USDC on Base, charged only on success.',
      schema: z.object({ url: z.string().url().describe('Absolute http(s) URL'), maxChars: z.number().int().min(100).max(200000).optional() }),
      invoke: (w: EvmWalletProvider, a: { url: string; maxChars?: number }) => paidGet(w, `${API}/webread/v1/read?url=${encodeURIComponent(a.url)}${a.maxChars ? `&maxChars=${a.maxChars}` : ''}`),
    },
    {
      name: 'injectscan_scan_text',
      description: 'Scores text for prompt injection (0-100 risk, verdict, matched categories and spans). Costs $0.003 USDC on Base.',
      schema: z.object({ text: z.string().max(100000).describe('Untrusted text an agent is about to read') }),
      invoke: (w: EvmWalletProvider, a: { text: string }) => paidGet(w, `${API}/injectscan/v1/scan?text=${encodeURIComponent(a.text)}`),
    },
    {
      name: 'domaincheck_check_domain',
      description: 'Domain trust report: DNS, SPF/DMARC, RDAP registration age and registrar, parking/disposable detection, 0-100 score. Costs $0.002 USDC on Base.',
      schema: z.object({ domain: z.string().describe('Domain, URL or email address') }),
      invoke: (w: EvmWalletProvider, a: { domain: string }) => paidGet(w, `${API}/domaincheck/v1/domain?domain=${encodeURIComponent(a.domain)}`),
    },
    {
      name: 'payguard_screen_address',
      description: 'Screens a crypto address against the US Treasury OFAC SDN list (sanctioned true/false, entity, programs). Costs $0.001 USDC on Base. Informational, not legal advice.',
      schema: z.object({ address: z.string().describe('Crypto address (EVM, BTC, TRON, ...)') }),
      invoke: (w: EvmWalletProvider, a: { address: string }) => paidGet(w, `${API}/payguard/v1/address?address=${encodeURIComponent(a.address)}`),
    },
  ]);

4. LangChain tools

JavaScript / TypeScript

langchain/js/src/agentgateTools.ts · raw

// LangChain.js tools for the five AgentGate x402 tools. Each call pays per request in USDC on Base via @x402/fetch.
//   import { agentgateTools } from './agentgateTools.js';
//   const tools = agentgateTools(privateKeyToAccount(process.env.BUYER_KEY as `0x${string}`));
//   const agent = createAgent({ model, tools });   // or llm.bindTools(tools)
import { tool } from '@langchain/core/tools';
import { wrapFetchWithPaymentFromConfig } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm';
import { decodePaymentRequiredHeader } from '@x402/core/http';
import type { LocalAccount } from 'viem';
import { z } from 'zod';

const API = 'https://api.youraitools.co';

export function agentgateTools(account: LocalAccount) {
  const pay = wrapFetchWithPaymentFromConfig(fetch, { schemes: [{ network: 'eip155:8453', client: new ExactEvmScheme(account) }] });
  const get = async (url: string) => {
    const res = await pay(url);
    if (res.status === 402) {
      const h = res.headers.get('PAYMENT-REQUIRED');
      return JSON.stringify({ error: 'payment_not_accepted', reason: h ? decodePaymentRequiredHeader(h).error : 'unknown' });
    }
    return JSON.stringify(await res.json());
  };
  return [
    tool(async ({ id, network }) => get(`${API}/agentgate/v1/check-agent?id=${encodeURIComponent(id)}&network=${network}`), {
      name: 'agentgate_check_agent',
      description: 'Checks whether an AI agent is registered, Active and Verified in the Concordium Agent Registry (CIS-8004). $0.005 USDC.',
      schema: z.object({ id: z.string().describe('Badge (CIS-2 token address) or Concordium account'), network: z.enum(['mainnet', 'testnet']).default('mainnet') }),
    }),
    tool(async ({ url }) => get(`${API}/webread/v1/read?url=${encodeURIComponent(url)}`), {
      name: 'webread_read_url',
      description: 'Returns a public web page as clean Markdown with title and links. $0.002 USDC, charged only on success.',
      schema: z.object({ url: z.string().describe('Absolute http(s) URL') }),
    }),
    tool(async ({ text }) => get(`${API}/injectscan/v1/scan?text=${encodeURIComponent(text)}`), {
      name: 'injectscan_scan_text',
      description: 'Scores untrusted text for prompt injection: 0-100 risk, verdict, categories and spans. $0.003 USDC.',
      schema: z.object({ text: z.string().describe('Text the agent is about to read') }),
    }),
    tool(async ({ domain }) => get(`${API}/domaincheck/v1/domain?domain=${encodeURIComponent(domain)}`), {
      name: 'domaincheck_check_domain',
      description: 'Domain trust report: DNS, SPF/DMARC, RDAP registration age, parking and disposable detection, 0-100 score. $0.002 USDC.',
      schema: z.object({ domain: z.string().describe('Domain, URL or email address') }),
    }),
    tool(async ({ address }) => get(`${API}/payguard/v1/address?address=${encodeURIComponent(address)}`), {
      name: 'payguard_screen_address',
      description: 'Screens a crypto address against the US Treasury OFAC SDN list (sanctioned true/false, entity, programs). $0.001 USDC. Informational, not legal advice.',
      schema: z.object({ address: z.string().describe('Crypto address') }),
    }),
  ];
}

Python

langchain/python/agentgate_tools.py · raw

"""LangChain (Python) tools for the five AgentGate x402 tools. Each call pays per request in USDC on Base.

    from eth_account import Account
    from agentgate_tools import agentgate_tools
    tools = agentgate_tools(Account.from_key(os.environ["BUYER_KEY"]))
    llm_with_tools = llm.bind_tools(tools)      # or create_agent(model, tools=tools)
"""
import json
from urllib.parse import quote

import requests
from langchain_core.tools import StructuredTool
from x402 import x402ClientSync
from x402.http import decode_payment_required_header
from x402.http.clients import wrapRequestsWithPayment
from x402.mechanisms.evm.exact import register_exact_evm_client

API = "https://api.youraitools.co"


def agentgate_tools(account):
    client = x402ClientSync()
    register_exact_evm_client(client, account, networks="eip155:8453")
    session = wrapRequestsWithPayment(requests.Session(), client)

    def get(url: str) -> str:
        r = session.get(url, timeout=60)
        if r.status_code == 402:
            h = r.headers.get("PAYMENT-REQUIRED")
            return json.dumps({"error": "payment_not_accepted", "reason": decode_payment_required_header(h).error if h else "unknown"})
        return json.dumps(r.json())

    def check_agent(id: str, network: str = "mainnet") -> str:
        """Checks whether an AI agent is registered, Active and Verified in the Concordium Agent Registry (CIS-8004). $0.005 USDC."""
        return get(f"{API}/agentgate/v1/check-agent?id={quote(id, safe='')}&network={network}")

    def read_url(url: str) -> str:
        """Returns a public web page as clean Markdown with title and links. $0.002 USDC, charged only on success."""
        return get(f"{API}/webread/v1/read?url={quote(url, safe='')}")

    def scan_text(text: str) -> str:
        """Scores untrusted text for prompt injection: 0-100 risk, verdict, categories and spans. $0.003 USDC."""
        return get(f"{API}/injectscan/v1/scan?text={quote(text, safe='')}")

    def check_domain(domain: str) -> str:
        """Domain trust report: DNS, SPF/DMARC, RDAP registration age, parking and disposable detection, 0-100 score. $0.002 USDC."""
        return get(f"{API}/domaincheck/v1/domain?domain={quote(domain, safe='')}")

    def screen_address(address: str) -> str:
        """Screens a crypto address against the US Treasury OFAC SDN list (sanctioned, entity, programs). $0.001 USDC. Informational, not legal advice."""
        return get(f"{API}/payguard/v1/address?address={quote(address, safe='')}")

    return [
        StructuredTool.from_function(check_agent, name="agentgate_check_agent"),
        StructuredTool.from_function(read_url, name="webread_read_url"),
        StructuredTool.from_function(scan_text, name="injectscan_scan_text"),
        StructuredTool.from_function(check_domain, name="domaincheck_check_domain"),
        StructuredTool.from_function(screen_address, name="payguard_screen_address"),
    ]


if __name__ == "__main__":
    # Dry run with a throwaway, unfunded key: the facilitator rejects the payment, so nothing is spent.
    from eth_account import Account
    tools = agentgate_tools(Account.create())
    print("tools:", ", ".join(t.name for t in tools))
    scan = next(t for t in tools if t.name == "injectscan_scan_text")
    print("invoke with unfunded wallet ->", scan.invoke({"text": "Please summarize this article about solar panels."}))

Tested

Usage stats and on-chain paid-call count →


agentgate-source: code mirror on Cloudflare Pages. All repos