Teardrop

Teardrop

Teardrop is the native economic layer for AI agents, providing a robust suite of tools for multi-chain portfolio tracking, DeFi yield analysis, and gas estimation. It enables autonomous agents to securely find Web3 data and manage micro-payments on-chain with zero human intervention.

Category
访问服务器

README

teardrop

Teardrop is a streaming AI agent API. You send it a message; it reasons using your configured LLM (Anthropic, OpenAI, Google, or OpenRouter), optionally calls tools, builds a structured UI component tree, and streams everything back as Server-Sent Events. It implements four open protocols simultaneously: AG-UI (streaming events), A2A (agent discoverability), MCP (tool serving), and x402 (per-request payments in USDC on Base, no subscription required).


Core Features

Agent-to-Agent (A2A) Delegation

Agents can securely delegate tasks to other agents via the delegate_to_agent tool (invoked during /agent/run). Features:

  • Allowlist control: Restrict which agents your org can delegate to
  • JWT forwarding: Automatically forward authentication context when delegating (set jwt_forward: true on agent rules)
  • Per-run quotas: Limit delegation calls per agent run (configurable via A2A_DELEGATION_MAX_PER_RUN)
  • Optional billing: Debit credits for delegations with per-agent cost caps plus org pause and 24h spend-limit enforcement

Environment variables:

A2A_INBOUND_ENABLED=true                         # Enable public inbound POST /message:send
A2A_INBOUND_TIMEOUT_SECONDS=60                  # Agent execution timeout for inbound A2A calls
A2A_DELEGATION_ENABLED=true                      # Enable agent-to-agent delegation
A2A_DELEGATION_REQUIRE_ALLOWLIST=true            # Enforce allowlist (default: true)
A2A_DELEGATION_MAX_PER_RUN=3                     # Max delegations per run (default: 3)
A2A_DELEGATION_BILLING_ENABLED=true              # Debit credits for delegations
A2A_DELEGATION_MAX_COST_USDC=100000              # Global delegation cost cap (atomic)
A2A_DELEGATION_PLATFORM_FEE_BPS=500              # Platform fee in basis points (5%)
A2A_DELEGATION_TIMEOUT_SECONDS=120               # HTTP timeout for delegation calls

Platform Tool Marketplace

Teardrop exposes built-in, metered tools through the marketplace catalog. Callers can invoke them:

  • Via the MCP gateway at GET /tools/mcp (direct tool invocation, billed per call).
  • As tools called during agent runs (via POST /agent/run when the agent decides to use them; billed in the run's usage cost).

Pricing is fixed per call in atomic USDC (1,000,000 = $1.00):

Tool Price/call
get_wallet_portfolio $0.004 (4,000 atomic)
web_search $0.015 (15,000 atomic)
get_token_price $0.002 (2,000 atomic)
get_token_price_historical $0.004 (4,000 atomic)
get_protocol_tvl $0.003 (3,000 atomic)
get_yield_rates $0.004 (4,000 atomic)
get_lending_rates $0.003 (3,000 atomic)
http_fetch $0.002 (2,000 atomic)
convert_currency $0.002 (2,000 atomic)
get_eth_balance $0.001 (1,000 atomic)
get_erc20_balance $0.002 (2,000 atomic)
get_block $0.001 (1,000 atomic)
get_transaction $0.002 (2,000 atomic)
get_token_approvals $0.004 (4,000 atomic)
get_defi_positions $0.013 (13,000 atomic)
get_liquidation_risk $0.010 (10,000 atomic)
get_dex_quote $0.005 (5,000 atomic)
get_gas_price $0.002 (2,000 atomic)
resolve_ens $0.003 (3,000 atomic)

In-process utility tools calculate, get_datetime, and count_text_stats have zero marginal cost and are billed at $0.000 per call.

get_yield_rates supports an optional stable_only filter for consistency-focused stablecoin discovery and returns both apy_mean_7d and apy_mean_30d so clients can avoid short-window APY spikes.

Note: For agent runs, tool_pricing_overrides takes precedence over marketplace catalog prices when both exist for the same tool.

Enable with MARKETPLACE_ENABLED=true. When enabled:

  • Tools appear in GET /marketplace/catalog with qualified_name = "platform/{tool_name}" and tool_type = "platform"
  • Public catalog responses include category, total_calls, health_status, is_healthy, display_name, tool_name, and the full input_schema
  • Catalog discovery supports category filtering, sort=popularity, single-tool detail pages at GET /marketplace/catalog/{org_slug}/{tool_name}, author profiles at GET /marketplace/authors/{org_slug}, and LLM-friendly discovery at GET /marketplace/llms.txt
  • Marketplace authors can register external MCP servers and turn discovered tools into listings via POST /marketplace/import/preview and admin-only POST /marketplace/import/publish; publish may omit input_schema and output_schema to reuse the server's normalized discovery result
  • Platform tools are always available during agent runs and are not subscribable via POST /marketplace/subscriptions
  • Agent runs that call these tools incur their marketplace prices (in addition to token costs)
  • Per-org pricing overrides are supported via POST /admin/pricing/tools; overrides apply to both MCP gateway and agent run calls

Marketplace Settlement & USDC Sweeping

Organizations can monetize their agents via a Marketplace. Earned fees are settled to organization wallets on-chain via Coinbase Developer Platform (CDP).

Auto-sweep settings (configure in .env):

MARKETPLACE_SETTLEMENT_CDP_ACCOUNT=td-marketplace   # CDP account for settlement transfers
MARKETPLACE_SETTLEMENT_CHAIN_ID=84532               # Chain ID: 84532=Base Sepolia (testnet), 8453=Base mainnet (production)
MARKETPLACE_TX_CONFIRM_TIMEOUT_SECONDS=90          # Timeout for on-chain tx receipt (90s for mainnet congestion tolerance)
MARKETPLACE_AUTO_SWEEP_ENABLED=true                # Enable automatic earnings sweep
MARKETPLACE_SWEEP_INTERVAL_SECONDS=86400           # Sweep cadence (86400 = 1 day)

Admin APIs:

  • POST /admin/marketplace/sweep — Manually trigger earnings sweep for pending orgs
  • GET /admin/marketplace/settlement-balance — Query the settlement wallet USDC balance

When an org requests a withdrawal, Teardrop:

  1. Settles earned fees to a ledger entry (pending)
  2. Attempts on-chain USDC transfer via CDP to the org's specified address
  3. Records the tx_hash on success, or reverts to pending on failure

Unattended (Scheduled) Agent Runs

Organizations can schedule recurring, unattended agent runs with integrated credit-only billing, stored execution history, and real-time status callbacks.

Scheduled runs settings (configure in .env or system environment):

SCHEDULED_RUNS_ENABLED=true                         # Toggle unattended scheduled run background worker
SCHEDULED_RUNS_TICK_INTERVAL_SECONDS=60             # Polling interval in seconds to claim due runs
SCHEDULED_RUNS_MIN_INTERVAL_SECONDS=300             # Minimum interval in seconds (default: 5 minutes)
SCHEDULED_RUNS_MAX_PER_ORG=20                       # Max schedules allowed per org (active + inactive)
SCHEDULED_RUNS_MAX_CONSECUTIVE_FAILURES=5           # Auto-disable consecutive execution failures threshold
SCHEDULED_RUNS_EXECUTION_TIMEOUT_SECONDS=120        # Timeout in seconds for a single scheduled agent execution
SCHEDULED_RUNS_MAX_CONCURRENCY=4                    # Max scheduled executions run concurrently per tick (<= pg pool headroom)

Developer APIs (under /agent/schedules):

  • POST /agent/schedules — Register a new scheduled prompt and interval
  • GET /agent/schedules — List current schedules for the authenticated org
  • GET /agent/schedules/{id} — Get single schedule configuration
  • PATCH /agent/schedules/{id} — Partially update schedule properties (e.g. toggle enabled or adjust interval_seconds)
  • DELETE /agent/schedules/{id} — Permanently delete a schedule definition
  • GET /agent/schedules/{id}/runs — Query run results (with cursor-based pagination)

When scheduled executions are due, the worker claims a batch using a row-locking query (FOR UPDATE SKIP LOCKED) and advances each run's next_run_at atomically at claim time. Claimed runs execute concurrently up to SCHEDULED_RUNS_MAX_CONCURRENCY, with per-run failure isolation so one error never aborts the rest of the batch. Each execution prepares a dedicated agent thread, verifies credits, and runs the agent. Completed, failed, timed-out, and credit-skipped runs are archived under scheduled_run_results. If configured, execution results are dispatched to an HTTPS-only, SSRF-checked callback URL. Because claims use SKIP LOCKED, multiple worker instances can run side by side to scale throughput horizontally.


Event-Triggered (Reactive) Runs

Beyond fixed intervals, organizations can register event triggers that run the agent in response to inbound webhooks (e.g. an on-chain event, a CRM update, a CI signal). An event trigger stores a prompt template; the inbound JSON payload is interpolated into it at dispatch time. Event triggers reuse the same execution core, credit billing, result history, and callback delivery as scheduled runs.

Event-trigger settings (configure in .env or system environment):

EVENT_TRIGGERS_ENABLED=true                         # Toggle reactive event-triggered runs (inbound ingress)
EVENT_TRIGGERS_MAX_PER_ORG=20                       # Max event triggers allowed per org (active + inactive)
EVENT_TRIGGERS_MAX_CONCURRENCY=8                    # Max in-flight inbound runs per process (beyond this → HTTP 429)
EVENT_TRIGGERS_PROMPT_MAX_CHARS=12000               # Max rendered prompt length after payload interpolation

Management APIs (org-scoped JWT, under /agent/event-triggers):

  • POST /agent/event-triggers — Create a trigger; the signing secret is returned once (only its SHA-256 hash is stored)
  • GET /agent/event-triggers — List triggers for the authenticated org
  • GET /agent/event-triggers/{id} — Get a single trigger
  • PATCH /agent/event-triggers/{id} — Update name, prompt template, enabled, or callback_url
  • DELETE /agent/event-triggers/{id} — Delete a trigger
  • POST /agent/event-triggers/{id}/rotate-secret — Rotate the signing secret (returns the new secret once)
  • GET /agent/event-triggers/{id}/runs — Query run results (cursor pagination)

Inbound dispatch (public, secret-authenticated):

  • POST /agent/events/{trigger_token} — Fire the trigger. Authenticate with the per-trigger secret via the X-Teardrop-Trigger-Secret header (constant-time compared). Optional X-Idempotency-Key (or an idempotency_key body field) gives at-most-once execution across webhook retries. The JSON body is rendered into the prompt template via {{field}} placeholders ({{event_json}} injects the full payload); substitution is scalar-only and length-capped to resist prompt/format-string injection. The agent runs in the background and the endpoint returns 202 Accepted with a run_id; results are retrievable via the runs endpoint and the optional callback. Inbound load is bounded by EVENT_TRIGGERS_MAX_CONCURRENCY (returns 429 when saturated) and a 64 KB payload cap.

Prompt templates interpolate untrusted payload data, so treat rendered prompts as untrusted input to the agent — scope event-trigger tools and credit limits accordingly.


Requirements

  • Python 3.12+
  • An API key for your chosen LLM provider: Anthropic, OpenAI, or Google AI (optional if using BYOK or self-hosted)
  • A Postgres database (local via Docker, or Neon for production)
  • Redis (optional, for caching — falls back to in-memory with TTL)

Setup (PowerShell)

1. Clone and enter the project

git clone https://github.com/teardrop-ai/teardrop.git
cd teardrop

2. Create and activate a virtual environment

python -m venv venv
.\venv\Scripts\Activate.ps1

If you get a script execution error, run first:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

3. Install dependencies

pip install -r requirements.txt

4. Configure environment

Copy-Item .env.example .env

Minimum required contents:

# Global LLM provider fallback: anthropic | openai | google | openrouter (default: openrouter)
# Note: Each org can override via PUT /llm-config
AGENT_PROVIDER=openrouter
# Default model is deepseek/deepseek-v4-flash.
# For OpenRouter DeepSeek models, Teardrop pins provider routing to NovitaAI/DeepInfra.
OPENROUTER_API_KEY=sk-or-...      # required if AGENT_PROVIDER=openrouter
# ANTHROPIC_API_KEY=sk-ant-...     # required if AGENT_PROVIDER=anthropic
# OPENAI_API_KEY=sk-...           # required if AGENT_PROVIDER=openai
# GOOGLE_API_KEY=...              # required if AGENT_PROVIDER=google

DATABASE_URL=postgresql://teardrop:teardrop@localhost:5432/teardrop

# Optional: Redis for distributed caching
# REDIS_URL=redis://localhost:6379/0

5. Generate RSA keys

python scripts/generate_keys.py

6. Run database migrations

python -m migrations.runner

7. Seed default org and admin user

python scripts/seed_users.py

8. Run the API server

uvicorn teardrop.main:app --reload

Server starts at http://localhost:8000. Visit http://localhost:8000/docs for the interactive API explorer.


Deployment

Docker (local full stack)

docker compose build --pull
docker compose up

Starts Postgres + Teardrop API. Migrations run automatically at startup. Keys are generated at build time and mounted from ./keys/. Use docker compose build --pull before rebuilds so refreshed base images are picked up, and add --no-cache when you want a fully fresh rebuild.

Render (production)

The repo includes a render.yaml that configures a Render web service. Set these environment variables in the Render dashboard:

Variable Description
AGENT_PROVIDER anthropic, openai, google, or openrouter (default: openrouter)
AGENT_MODEL Optional global model override (default: deepseek/deepseek-v4-flash). When using OpenRouter DeepSeek models, provider routing is pinned to NovitaAI and DeepInfra.
AGENT_SYNTHESIS_MAX_TOKENS Max output tokens for post-tool synthesis turns (tool_iterations >= 1). Default: 4096.
AGENT_PLANNER_PROVIDER Optional provider override for initial planner turns (tool_iterations==0) when no org-level BYOK config is set.
AGENT_PLANNER_MODEL Optional model override paired with AGENT_PLANNER_PROVIDER for first-pass tool selection speed tuning.
AGENT_SYNTHESIS_PROVIDER Optional provider override for post-tool synthesis turns (tool_iterations >= 1). When unset, uses AGENT_PROVIDER.
AGENT_SYNTHESIS_MODEL Optional model override for synthesis turns, paired with AGENT_SYNTHESIS_PROVIDER.
AGENT_UI_GENERATOR_PROVIDER Provider for UI generation turns (default: google). Important: requires GOOGLE_API_KEY even if main provider is OpenRouter.
AGENT_UI_GENERATOR_MODEL Model for UI generation turns (default: gemini-3-flash-preview).
AGENT_SYNTHESIS_FAST_PATH_ENABLED Enables a synthesis-only fast path that skips tool schema binding when the next turn is clearly final. Default: true.
AGENT_COMPILER_MODE_ENABLED Enables optional staged planner IR (<plan>{...}</plan>) execution. Default: false (safe rollout).
AGENT_CACHE_PREWARM_ENABLED Enables one-time startup prompt-cache prewarm for top active org/provider/model prefixes. Default: true.
AGENT_CACHE_PREWARM_TOP_N Max number of active prefixes warmed per startup batch. Default: 50.
AGENT_LLM_TIMEOUT_SECONDS Timeout in seconds for the planner LLM call (default: 180).
AGENT_TOOL_EXECUTOR_TIMEOUT_SECONDS Timeout in seconds for the overall tool execution node (default: 120).
AGENT_SINGLE_TOOL_TIMEOUT_SECONDS Per-tool deadline in seconds (default: 30). Slow tools are converted into timeout tool messages so synthesis proceeds with partial data.
ANTHROPIC_API_KEY Required if AGENT_PROVIDER=anthropic
OPENAI_API_KEY Required if AGENT_PROVIDER=openai
GOOGLE_API_KEY Required if AGENT_PROVIDER=google
DATABASE_URL Neon Postgres connection string
BILLING_ENABLED true to activate x402 payments
X402_PAY_TO_ADDRESS Treasury wallet (USDC recipient)
X402_NETWORK eip155:8453 for Base mainnet
X402_SCHEME Payment scheme: exact (default) or upto (usage-based via Permit2)
X402_UPTO_MAX_AMOUNT Max ceiling per run for upto scheme (default: $0.50)
SIWE_DOMAIN Your public domain (e.g. api.teardrop.dev)
CORS_ORIGINS Comma-separated allowed origins
AGENT_WALLET_ENABLED true to enable per-org CDP-backed wallets
CDP_API_KEY_ID Coinbase Developer Platform API key ID
CDP_API_KEY_SECRET CDP API key secret (Ed25519 / ECDSA)
CDP_WALLET_SECRET CDP wallet secret (decrypts TEE-stored keys)
CDP_NETWORK CDP network: base-sepolia (testnet) or base (mainnet)
AGENT_WALLET_MAX_BALANCE_USDC Max USDC per agent wallet (default: 100000000 = $100)
MARKETPLACE_ENABLED true to activate the tool marketplace catalog and platform tool billing in the MCP gateway
MARKETPLACE_SETTLEMENT_CDP_ACCOUNT CDP account name for settlement transfers (default: td-marketplace)
MARKETPLACE_SETTLEMENT_CHAIN_ID Chain for USDC sweeps: 8453 = Base mainnet (production), 84532 = Base Sepolia (testnet). Must match CDP_NETWORK.
MARKETPLACE_TX_CONFIRM_TIMEOUT_SECONDS Seconds to wait for on-chain tx receipt after CDP transfer (default: 90). Base mainnet can experience 60–90s delays under congestion.
MARKETPLACE_AUTO_SWEEP_ENABLED true to auto-sweep org earnings on a schedule
MARKETPLACE_SWEEP_INTERVAL_SECONDS Sweep cadence in seconds (default: 86400 = 1 day)
REPUTATION_ROLLUP_ENABLED true to enable periodic recomputation of reputation metrics from tool call event logs (default: false)
REPUTATION_ROLLUP_INTERVAL_SECONDS Interval in seconds between reputation rollup passes (default: 3600 = 1 hour)
MARKETPLACE_CATALOG_URL Public URL of the marketplace catalog used in tool-deactivation emails (optional)
TOOL_BREAKER_ENABLED true to auto-deactivate marketplace tools whose webhooks repeatedly fail (default: true)
TOOL_BREAKER_THRESHOLD Consecutive failures within the window that trip the breaker (default: 5)
TOOL_BREAKER_WINDOW_SECONDS Sliding-window duration in seconds for failure counting (default: 600)
TOOL_CALL_EVENT_LOGGING_ENABLED true to persist per-tool-call telemetry (latency, success, error classes, param hashes) for future ML modeling and reputation rolls (default: true)
BYOK_TIER_PRICING_ENABLED true to use per-token orchestration pricing for BYOK orgs (seeded by migration 041). When false, uses legacy flat byok_platform_fee_usdc. Default: false for backward compatibility.
OPENROUTER_API_KEY Required if AGENT_PROVIDER=openrouter
COINGECKO_API_KEY CoinGecko API key for live price data (optional; rate-limited without key)
TAVILY_API_KEY Tavily API key for the web_search tool (optional; web search disabled without it)
ETHEREUM_RPC_URL Ethereum mainnet JSON-RPC URL (required by Ethereum-based tools)
BASE_RPC_URL Base L2 JSON-RPC URL (required by Base-based tools and marketplace auto-sweep)
LANGSMITH_TRACING Enable LangSmith tracing (default: false)
LANGSMITH_API_KEY LangSmith API key for tracing
LANGSMITH_PROJECT LangSmith project name (default: teardrop)
ORG_TOOL_ENCRYPTION_KEY Fernet key for encrypting webhook auth_header_value at rest. Generate with python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
LLM_CONFIG_ENCRYPTION_KEY Fernet key for encrypting BYOK API keys at rest (same format as above)
REQUIRE_EMAIL_VERIFICATION true to require email verification before login (default: false)
ALLOW_PUBLIC_REGISTRATION false to disable POST /register and force invite-only onboarding (default: true)
TURNSTILE_SECRET_KEY Cloudflare Turnstile secret key for server-side CAPTCHA verification on POST /register (optional)
TURNSTILE_VERIFY_URL Turnstile siteverify URL (default: https://challenges.cloudflare.com/turnstile/v0/siteverify)
RESEND_API_KEY Resend API key for sending verification / invite emails
RESEND_FROM_EMAIL Sender address for transactional emails (e.g. noreply@yourdomain.com)
APP_BASE_URL Public URL of this deployment (used in email links, e.g. https://api.teardrop.dev)
MARKETPLACE_DEFAULT_REVENUE_SHARE_BPS Author revenue share in basis points (default: 7000 = 70% to author, 30% to platform). Hard-coded split; per-author overrides are not supported.
MCP_AUTH_ENABLED true to require authentication on the /tools/mcp MCP gateway
MCP_AUTH_AUDIENCE JWT audience for MCP gateway tokens (default: teardrop-mcp)
MCP_BILLING_ENABLED true to enable credit billing for MCP tool calls
MCP_X402_ENABLED true to accept x402 payments on the MCP gateway
MEMORY_ENABLED Enable persistent agent memory (default: true). Auto-disabled if OPENAI_API_KEY is unset.
SENTRY_DSN Sentry error tracking DSN (optional; leave empty to disable)
REFRESH_TOKEN_EXPIRE_DAYS Refresh token validity window in days (default: 30)
RATE_LIMIT_AUTH_RPM Per-IP rate limit for /token and /auth/siwe/nonce (default: 20)
RATE_LIMIT_REGISTER_RPM Per-IP rate limit for POST /register (default: 5)
AUTH_LOCKOUT_THRESHOLD Failed email-login attempts before temporary lockout (default: 10)
AUTH_LOCKOUT_WINDOW_SECONDS Failed email-login lockout window in seconds (default: 900)
RATE_LIMIT_AGENT_RPM Per-user rate limit for /agent/run (default: 30)
RATE_LIMIT_ORG_AGENT_RPM Per-org aggregate rate limit for /agent/run (default: 100)
RATE_LIMIT_ORG_MCP_RPM Per-org rate limit for MCP gateway (default: 200)
RATE_LIMIT_WEBHOOK_RPM Per-IP rate limit for Stripe webhook (default: 120)
RATE_LIMIT_TEST_WEBHOOK_RPM Per-org rate limit for test-webhook endpoint (default: 10)
TRUSTED_PROXY_COUNT Trusted proxy hops when deriving client IP from X-Forwarded-For (default: 1; set 0 to ignore the header)

Authentication

Teardrop issues RS256 JWTs. All endpoints (except /health, /docs, /billing/pricing, /.well-known/agent-card.json, and the public payment-gated POST /message:send A2A endpoint when A2A_INBOUND_ENABLED=true) require a Bearer token.

1. Client credentials (machine-to-machine)

$resp = Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"client_id":"teardrop-client","client_secret":"<JWT_CLIENT_SECRET>"}'
$token = $resp.access_token

The resulting JWT includes auth_method: "client_credentials". Set JWT_CLIENT_ID and JWT_CLIENT_SECRET in .env.

2. Email + password

$resp = Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"email":"admin@example.com","secret":"<password>"}'

The resulting JWT includes auth_method: "email". Create users via POST /admin/users.

3. SIWE — Sign-In with Ethereum

SIWE lets Ethereum wallet holders authenticate without a password. The JWT issued includes auth_method: "siwe" and the caller's address.

1. GET  /auth/siwe/nonce   → { "nonce": "abc123..." }
2. Construct an EIP-4361 SIWE message with that nonce
3. Sign with your wallet (EIP-191)
4. POST /token  { "siwe_message": "...", "siwe_signature": "0x..." }
   → { "access_token": "..." }

SIWE tokens are the only auth method that can use x402 on-chain payments. New wallet addresses are auto-registered on first login.

Token expiry and refresh tokens

All three auth methods issue access tokens with a 30-minute expiry (expires_in: 1800 seconds in the token response). For applications that need sessions longer than 30 minutes, use refresh tokens:

  • Refresh tokens expire after 30 days and can be exchanged for a new access token + rotated refresh token.
  • Refresh token rotation is atomic with idempotency replay protection — if the same refresh token is submitted twice within the replay window, you'll receive the same new token pair instead of creating duplicates.
  • Single logout via POST /auth/logout revokes your refresh token, ending the session immediately.
# 1. Exchange refresh token for new access token + rotated refresh token
$resp = Invoke-RestMethod -Uri "http://localhost:8000/auth/refresh" `
    -Method Post -ContentType "application/json" `
    -Headers @{ "Cookie" = "refresh_token=<your-refresh-token>" }
    # OR pass as body: -Body '{"refresh_token":"<your-refresh-token>"}'

# New access token and rotated refresh token are in the response
$newAccessToken = $resp.access_token
$newRefreshToken = $resp.refresh_token  # Use this on your next refresh

# 2. Logout (revoke refresh token)
Invoke-RestMethod -Uri "http://localhost:8000/auth/logout" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $accessToken" }

LLM Configuration (Per-Org)

Organizations can configure their preferred LLM provider, model, routing strategy, and optionally bring their own API keys (BYOK). This unlocks:

  • Multi-provider choice: Use Anthropic, OpenAI, Google, or point at self-hosted endpoints (vLLM, Ollama, OpenRouter)
  • Bring Your Own Key (BYOK): Encrypt and store your own API credentials — Teardrop never sees your keys. BYOK orgs pay platform fees for orchestration (per-token when BYOK_TIER_PRICING_ENABLED=true, or flat fee otherwise) in addition to their LLM provider costs.
  • Smart routing: Automatically select models based on cost, speed, or quality
  • Self-hosted support: Use any OpenAI-compatible endpoint via api_base parameter

Org LLM config endpoints

Method Path Auth Description
GET /llm-config Bearer Get your org's LLM config (or global defaults if not configured)
PUT /llm-config Bearer Set or update org LLM config
DELETE /llm-config Bearer Delete config, revert to global defaults

Example: Set org's LLM to GPT-4o with cost-based routing

$token = (Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"client_id":"teardrop-client","client_secret":"<secret>"}').access_token

# Set provider + model + routing strategy
Invoke-RestMethod -Uri "http://localhost:8000/llm-config" `
    -Method Put -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } `
    -Body @{
        provider = "openai"
        model = "gpt-4o"
        routing_preference = "cost"  # or "speed", "quality", "default"
        max_tokens = 4096
        temperature = 0.7
    } | ConvertTo-Json

Example: BYOK — use your own OpenAI key

Invoke-RestMethod -Uri "http://localhost:8000/llm-config" `
    -Method Put -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } `
    -Body @{
        provider = "openai"
        model = "gpt-4o"
        api_key = "sk-..."  # your key (encrypted at rest)
    } | ConvertTo-Json

Example: Self-hosted vLLM or Ollama

Invoke-RestMethod -Uri "http://localhost:8000/llm-config" `
    -Method Put -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } `
    -Body @{
        provider = "openai"
        model = "meta-llama/Llama-2-7b-chat"
        api_base = "http://gpu-cluster.internal:8000/v1"
        api_key = "your-local-key-or-token"
    } | ConvertTo-Json

Routing preferences

When you set routing_preference to a value other than "default", Teardrop will automatically select a model from its standard pool based on your criteria:

Preference Behavior
default Use the provider/model you configured
cost Select the cheapest model (by tokens-in + tokens-out pricing)
speed Select the fastest model (by p95 latency from live benchmarks; falls back to official specs for new deployments)
quality Select the highest quality model (Claude Sonnet > Claude Haiku, etc.)

Note: If you set BYOK (custom API key), routing is disabled — you always use your configured model.

BYOK Platform Fee: BYOK orgs are charged a flat per-run infrastructure fee (BYOK_PLATFORM_FEE_USDC, default 1000 = $0.001) instead of LLM token costs. The fee appears as platform_fee_usdc in usage events and SSE billing events.


Model Benchmarks

Teardrop continuously tracks operational metrics for every LLM deployed. These benchmarks help you make informed routing decisions.

Benchmarks endpoints

Method Path Auth Description
GET /models/benchmarks — Public: all models with catalogue metadata + live metrics
GET /models/benchmarks/org Bearer Org-scoped: metrics for your org's usage only

Example response

Invoke-RestMethod -Uri "http://localhost:8000/models/benchmarks" | ConvertTo-Json | ForEach-Object { $_ | Out-String }

Returns:

{
  "models": [
    {
      "provider": "anthropic",
      "model": "claude-haiku-4-5-20251001",
      "display_name": "Claude Haiku 4.5",
      "context_window": 200000,
      "supports_tools": true,
      "quality_tier": 2,
      "pricing": {
        "tokens_in_cost_per_1k": 0.80,
        "tokens_out_cost_per_1k": 4.00,
        "tool_call_cost": 0.001
      },
      "benchmarks": {
        "total_runs_7d": 156,
        "avg_latency_ms": 450.2,
        "p95_latency_ms": 1200.5,
        "avg_cost_usdc_per_run": 0.015,
        "avg_tokens_per_sec": 52.3
      }
    },
    ...
  ],
  "updated_at": "2026-04-16T14:22:00Z"
}

Understanding the metrics

  • total_runs_7d: Number of runs using this model in the last 7 days (benchmarks only included if >= 10 runs)
  • avg_latency_ms: Average time (ms) from start to completion
  • p95_latency_ms: 95th percentile latency — the slowest 5% of runs
  • avg_cost_usdc_per_run: Average cost per run (input + output tokens + tools)
  • avg_tokens_per_sec: Streaming throughput (useful for real-time applications)
  • quality_tier: Static tier (1=best, 2=good) for quality-based routing

Billing & Payments (x402)

Teardrop implements the x402 payment protocol. When BILLING_ENABLED=true, requests must include payment. Set BILLING_ENABLED=false (default) to run without billing during development.

How it works

Client                         Teardrop                     x402 Facilitator
  │                               │                               │
  │── POST /agent/run ───────────►│                               │
  │   (no payment header)         │                               │
  │◄── 402 Payment Required ──────│                               │
  │    PAYMENT-REQUIRED: <v2>     │                               │
  │    X-PAYMENT-REQUIRED: <reqs> │                               │
  │                               │                               │
  │── POST /agent/run ───────────►│                               │
  │   Payment-Signature: <signed> │── verify payment ────────────►│
  │                               │◄─ verified ───────────────────│
  │◄── SSE stream ────────────────│                               │
  │   (TEXT, TOOL, SURFACE...)    │                               │
  │   BILLING_SETTLEMENT          │── settle (actual cost*) ─────►│
  │   { tx_hash, amount_usdc }    │◄─ tx confirmed ───────────────│

* exact: settles the signed amount. upto: settles actual usage cost ≤ client-signed ceiling.

Payment methods by auth type

Auth method Payment mechanism
siwe x402 on-chain (USDC, exact or upto scheme, per-request)
client_credentials Org prepaid credit balance (off-chain debit)
email Org prepaid credit balance (off-chain debit)

x402 payment schemes

Scheme How it works Config
exact (default) Client signs the exact run price; facilitator settles that amount. X402_SCHEME=exact
upto Client signs a ceiling (X402_UPTO_MAX_AMOUNT); after the run, Teardrop settles the actual usage cost (≤ ceiling) via Permit2. X402_SCHEME=upto

Configuration

BILLING_ENABLED=true
X402_PAY_TO_ADDRESS=0xYourTreasuryWallet
X402_NETWORK=eip155:8453          # Base mainnet (eip155:84532 = Base Sepolia)
X402_FACILITATOR_URL=https://x402.org/facilitator
X402_SCHEME=upto                  # "exact" (default) or "upto" (usage-based settlement)
X402_UPTO_MAX_AMOUNT=$0.50        # Max ceiling per-run for upto (ignored for exact)
BILLABLE_AUTH_METHODS=["siwe", "client_credentials", "email"]    # All three auth methods billed by default

Pricing

Pricing is dynamic via the pricing_rules database table. Current rates (usage-based v1):

Metric Rate
Input tokens $0.0015 / 1k tokens
Output tokens $0.0075 / 1k tokens
Tool calls $0.001 / call
Minimum per run $0.01

Check live pricing: GET /billing/pricing

Running as x402 client (SIWE payments)

# 1. Get a SIWE JWT (see Authentication above)
# 2. Call /agent/run — you'll get a 402 with payment requirements
# 3. Construct and sign the x402 transferWithAuthorization (EIP-3009)
# 4. Retry with the signed payment header

Invoke-RestMethod -Uri "http://localhost:8000/agent/run" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token"; "Payment-Signature" = "<x402-header>" } `
    -Body '{"message":"What is the ETH balance of vitalik.eth?","thread_id":"session-1"}'

The stream will include a BILLING_SETTLEMENT event with the on-chain tx_hash after the run completes.

upto client requirement: Before using X402_SCHEME=upto, the paying wallet must approve Permit2 for USDC on the target chain once: IERC20(USDC).approve(PERMIT2_ADDRESS, type(uint256).max). This is a one-time on-chain transaction per wallet. Clients that have not approved Permit2 can always use scheme: exact from the accepts array in the 402 response as a fallback.

Credit top-up (machine callers)

Admins can add prepaid USDC credit to an org's balance:

Invoke-RestMethod -Uri "http://localhost:8000/admin/credits/topup" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $adminToken" } `
    -Body '{"org_id":"org-123","amount_usdc":1000000}'   # $1.00

A2A Delegation & Cross-Agent Revenue Routing

Teardrop agents can delegate specialist tasks to remote A2A-compliant agents and charge those delegations back to the calling organisation. This enables:

  • Network effect: Agents discover and call each other via published Agent Cards
  • Specialisation: Route complex tasks to domain-expert agents
  • Revenue sharing: Collect payments from delegations and distribute to specialist agent operators
  • Budget control: Per-agent cost caps, global delegation spending limits, and org-level pause/daily spend checks

The public /.well-known/agent-card.json advertises the /tools/mcp gateway under endpoints.mcp_tools. When MARKETPLACE_ENABLED=true, it also includes capabilities.marketplace and endpoints.marketplace_catalog so external A2A clients can discover the paid marketplace catalog without hard-coding Teardrop-specific URLs.

The card also emits additive A2A v1.0 discovery fields such as protocolVersion, supportedInterfaces, securitySchemes, defaultInputModes, and defaultOutputModes while preserving Teardrop-specific endpoints, tools, and authentication metadata for current SDK consumers. supportedInterfaces now advertises both the streaming AG-UI surface (/agent/run) and the blocking inbound A2A surface (/message:send).

The skills/tools sections of the public card are curated: each ToolDefinition carries a show_on_agent_card flag (tools/registry.py), and commoditized utility/low-level RPC primitives (calculate, get_datetime, count_text_stats, convert_currency, get_block, get_erc20_balance, get_eth_balance, get_transaction, read_contract, resolve_ens) are excluded to keep the public discovery surface focused on Teardrop's differentiated capabilities. This does not affect tool availability — every tool remains callable via /agent/run, the full org inventory at GET /agent/tools, and the MCP catalogue at /.well-known/mcp/server-card.json.

Teardrop also publishes x402 discovery metadata at /.well-known/x402 and /.well-known/x402.json. These public, cacheable aliases advertise the canonical paid entrypoints (/message:send, /tools/mcp) alongside the public pricing metadata at /billing/pricing.

Inbound A2A entrypoint

External agents can call Teardrop directly over POST /message:send.

  • Anonymous callers may pay per request with x402 by retrying the call with X-PAYMENT after an initial 402 Payment Required response. The challenge now uses the standard PAYMENT-REQUIRED header and also serves X-PAYMENT-REQUIRED as a legacy compatibility alias.
  • Unpaid anonymous probes receive the 402 Payment Required challenge before request-body validation, which keeps registry validators compatible with empty or malformed probe payloads.
  • The 402 body is a full x402 v2 PaymentRequired payload with top-level resource, accepts, and extensions. On POST /message:send, extensions.bazaar advertises the A2A request and response shape for registries.
  • Authenticated callers may present a Teardrop JWT and reuse the existing credit/x402 billing gate.
  • The current implementation is a single-turn blocking endpoint: it accepts an A2A message payload (or JSON-RPC envelope) and returns a completed Task in a JSON-RPC envelope.
  • Operators may disable the surface with A2A_INBOUND_ENABLED=false; the endpoint then returns 404 and the public agent card stops advertising a2a_message.

How it works

Local Agent                     Teardrop                          Remote Agent
  │                               │                                    │
  │ calls delegate_to_agent ──────│                                    │
  │  + agent_url                  │                                    │
  │  + task_description           │                                    │
  │                               │─ GET /.well-known/agent-card.json ►│
  │                               │◄─ agent capabilities ──────────────│
  │                               │                                    │
  │                               │─ POST /message:send ──────────────►│
  │                               │   (with optional x402 payment)      │
  │                               │◄─ task result ────────────────────│
  │◄──────────  result ───────────│                                    │
  │  + cost_usdc (debited)        │                                    │
  │                               │                                    │
  └─ Credits debited from org ────│                                    │

Configuration

# Enable A2A delegation
A2A_DELEGATION_ENABLED=true
A2A_DELEGATION_TIMEOUT_SECONDS=120
A2A_DELEGATION_MAX_PER_RUN=3         # Max delegations per agent run

# Enable billing for delegations
A2A_DELEGATION_BILLING_ENABLED=true
A2A_DELEGATION_PLATFORM_FEE_BPS=500  # Platform fee: 500 bps = 5%
A2A_DELEGATION_MAX_COST_USDC=100000  # Global delegation cost cap ($0.10)

# For x402 delegations (optional):
X402_TREASURY_PRIVATE_KEY=0x...      # Treasury wallet private key (hex-encoded)

Allowlist & Budget Control

Organisations must explicitly add remote agents to their allowlist before delegating to them:

# Add a trusted agent to the allowlist
$token = (Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"client_id":"teardrop-client","client_secret":"<secret>"}').access_token

Invoke-RestMethod -Uri "http://localhost:8000/a2a/agents" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } `
    -Body @{
        agent_url = "https://specialist.agents.example.com"
        label = "Code Review Specialist"
        max_cost_usdc = 50_000           # Per-delegation cap: $0.05
        require_x402 = $false            # Use org credits (not x402)
    } | ConvertTo-Json

Payment methods for delegations

Setting Billing Method When to use
require_x402=false Org prepaid credits Default: instant, requires upfront org credit balance
require_x402=true x402 on-chain (USDC) Agent requires on-chain payment; uses treasury wallet to sign

Delegation events & audit trail

Every delegation is recorded in the a2a_delegation_events table:

# List delegation events for your org
Invoke-RestMethod -Uri "http://localhost:8000/a2a/delegations?limit=50" `
    -Method Get `
    -Headers @{ Authorization = "Bearer $token" } | ConvertTo-Json

Response:

[
  {
    "id": "evt-abc123",
    "run_id": "run-xyz",
    "agent_url": "https://specialist.agents.example.com",
    "agent_name": "CodeReviewBot",
    "task_status": "completed",
    "cost_usdc": 52500,
    "billing_method": "credit",
    "settlement_tx": "",
    "error": null,
    "created_at": "2026-04-16T14:22:00Z"
  }
]

Delegation in SSE stream

When a delegation occurs during an agent run, the final USAGE_SUMMARY and BILLING_SETTLEMENT events include the delegation cost breakdown:

{
  "event": "USAGE_SUMMARY",
  "data": {
    "run_id": "run-123",
    "tokens_in": 1500,
    "tokens_out": 800,
    "cache_read_tokens": 1200,
    "cache_creation_tokens": 300,
    "tool_calls": 3,
    "cost_usdc": 15000,
    "delegation_cost_usdc": 52500
  }
}

{
  "event": "BILLING_SETTLEMENT",
  "data": {
    "run_id": "run-123",
    "amount_usdc": 67500,
    "tx_hash": "",
    "network": "credit",
    "delegation_cost_usdc": 52500
  }
}

Publishing to Agentic Market

Use the full public URL of the paid A2A surface, for example https://api.teardrop.dev/message:send, with method POST.

Do not register the bare origin https://api.teardrop.dev/. GET / redirects to /docs, and POST / is not a paid Teardrop entrypoint.

Agentic Market validators may probe /.well-known/x402, /.well-known/x402.json, and the configured endpoint URL. Teardrop serves those discovery aliases publicly and issues the x402 challenge on unpaid anonymous POST /message:send requests before body validation.

That challenge now includes:

  • PAYMENT-REQUIRED with the full x402 v2 PaymentRequired envelope.
  • X-PAYMENT-REQUIRED as a legacy alias for older clients that only decode the requirement list.
  • Top-level resource.url describing the paid surface.
  • Top-level extensions.bazaar describing the A2A request and response shape.

Publishing to Smithery

Teardrop automatically advertises its MCP tools via /.well-known/mcp/server-card.json. To distribute on Smithery:

  1. Copy the public base URL of your Teardrop instance into the Smithery URL Deployment wizard.
  2. Provide the following Configuration Schema (JSON) inside the Smithery CLI or publish wizard to expose x402 anonymous capability:
    {
      "type": "object",
      "properties": {
        "apiKey": {
          "type": "string",
          "title": "API Key",
          "x-from": { "header": "x-teardrop-key" },
          "x-to": { "header": "Authorization" }
        }
      }
    }
    
  3. Set the Display Name, Description, Homepage, and Icon within the Smithery dashboard to achieve the maximum 100/100 quality score.

API reference

Core

Method Path Auth Description
GET / — Redirects to /docs
GET /health — Liveness probe
GET /llms.txt — Root LLM-friendly discovery index for public Teardrop surfaces
GET /robots.txt — Public crawler directives with llms.txt pointer
POST /agent/run Bearer Main streaming endpoint (SSE)
POST /message:send Bearer or x402 Blocking inbound A2A endpoint for external agents (when enabled)
GET /agent/tools Bearer Tool inventory for current org (platform, org, and subscribed marketplace tools)
GET /agent/tool-exclusions Bearer List the org's persisted tool exclusions
POST /agent/tool-exclusions Bearer Persist a tool exclusion (merged with per-request tool_policy.exclude_names on every run)
DELETE /agent/tool-exclusions/{tool_name} Bearer Remove a persisted tool exclusion
GET /.well-known/agent-card.json — A2A agent card with MCP discovery and optional marketplace metadata
GET /.well-known/x402 — Public x402 discovery metadata for registries and validators
GET /.well-known/x402.json — Legacy JSON alias for x402 discovery metadata
GET /.well-known/mcp/server-card.json — Static MCP tool catalogue for Smithery
GET /.well-known/agent.json — Legacy alias for the agent card used by older crawlers
GET /.well-known/jwks.json — RS256 public key in JWKS format (for external JWT verification)
GET /docs — Swagger UI
GET /redoc — ReDoc UI

LLM Configuration

Method Path Auth Description
GET /llm-config Bearer Get org's LLM config (or defaults if not set)
PUT /llm-config Bearer Set or update org's LLM configuration
DELETE /llm-config Bearer Delete org config, revert to global defaults

Models

Method Path Auth Description
GET /models/benchmarks — Public: all models with benchmarks
GET /models/benchmarks/org Bearer Org-scoped: benchmarks for your org's usage

Auth

Method Path Auth Description
POST /token — Issue JWT (client-creds, email, or SIWE); returns access_token + refresh_token
GET /auth/me Bearer Return the authenticated user's identity
GET /auth/siwe/nonce — Generate single-use SIWE nonce
POST /register — Self-serve org + user registration (optional invite-only + CAPTCHA gates)
GET /auth/verify-email — Consume one-time email verification token
POST /auth/resend-verification Bearer Re-send verification email
POST /auth/refresh — Exchange refresh token for new access + rotated refresh token
POST /auth/logout Bearer Revoke refresh token (end session)
POST /org/invite Bearer Create org invite link (any authenticated member)
POST /register/invite — Accept invite token + create user account
GET /org/credentials Bearer List org M2M client credentials
POST /org/credentials/regenerate Bearer Rotate all org M2M credentials (admin-only)

Billing

Method Path Auth Description
GET /billing/pricing — Current pricing rules
GET /billing/history Bearer Settled payment history (cursor paginated)
GET /billing/invoices Bearer All run records including pending (cursor paginated)
GET /billing/invoice/{run_id} Bearer Single run receipt
GET /billing/balance Bearer Org prepaid credit balance
GET /billing/credit-history Bearer Credit ledger — top-ups and debits (cursor paginated)
POST /billing/topup/stripe Bearer Start a Stripe checkout session to add credits
GET /billing/topup/stripe/status Bearer Check Stripe checkout session status
GET /billing/topup/usdc/requirements Bearer Get on-chain USDC top-up payment requirements
POST /billing/topup/usdc Bearer Submit and verify an on-chain USDC top-up

GET /billing/balance returns atomic USDC fields. A spending_limit_usdc value of 0 means unlimited daily spend (spending_limit_active=false).

Marketplace

Method Path Auth Description
GET /marketplace/catalog — Public catalog with optional org_slug, category, sort, limit, and cursor query params
GET /marketplace/catalog/{org_slug}/{tool_name} — Public detail for one published catalog tool
GET /marketplace/authors/{org_slug} — Public author profile with aggregate calls and paginated tools
GET /marketplace/llms.txt — Plain-text catalog index for LLM crawlers and SEO surfaces
POST /marketplace/author-config Bearer Create or update author settlement wallet
GET /marketplace/author-config Bearer Get author settlement wallet config
POST /marketplace/import/preview Bearer Preview importable MCP tools, normalized schemas, and publish blockers
POST /marketplace/import/publish Bearer Admin-only publish of MCP-backed marketplace tools
GET /marketplace/balance Bearer Author earnings balance
GET /marketplace/earnings Bearer Author earnings history
GET /marketplace/earnings/by-tool Bearer Author earnings grouped by tool
POST /marketplace/withdraw Bearer Request an author payout
GET /marketplace/withdrawals Bearer Withdrawal history
POST /marketplace/subscriptions Bearer Subscribe to a community marketplace tool
GET /marketplace/subscriptions Bearer List active marketplace subscriptions
DELETE /marketplace/subscriptions/{id} Bearer Unsubscribe from a marketplace tool

GET /marketplace/catalog sorts by name, price_asc, price_desc, or popularity. Categories are defi, search, data, communication, and utility; an empty category is allowed for uncategorized tools. total_calls is sourced from non-financial aggregate stats and is recorded only after successful paid tool calls, not from the immutable earnings ledger.

POST /marketplace/author-config accepts any valid 0x + 40-hex Ethereum/Base address and stores the canonical EIP-55 checksummed form. POST /marketplace/import/publish may omit input_schema and output_schema; when omitted, Teardrop reuses the normalized or synthesized schemas from live MCP discovery.

Wallets

User Wallets (SIWE-linked)

Method Path Auth Description
POST /wallets/link Bearer Link additional wallet via SIWE
GET /wallets/me Bearer List your linked wallets
DELETE /wallets/{wallet_id} Bearer Unlink a wallet

Agent Wallets (CDP-managed, per-org)

Each org can provision a single CDP-backed USDC wallet per chain for receiving delegation payments and marketplace earnings. Enable with AGENT_WALLET_ENABLED=true and set CDP credentials.

Method Path Auth Description
POST /wallets/agent Bearer Provision a CDP-backed agent wallet for your org
GET /wallets/agent Bearer Get org's agent wallet; optionally include on-chain USDC balance
DELETE /wallets/agent Admin Deactivate the org's agent wallet

Example: Provision an agent wallet

$token = (Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"client_id":"teardrop-client","client_secret":"<secret>"}').access_token

Invoke-RestMethod -Uri "http://localhost:8000/wallets/agent" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } | ConvertTo-Json

Example: Get agent wallet with balance

Invoke-RestMethod -Uri "http://localhost:8000/wallets/agent?include_balance=true" `
    -Method Get `
    -Headers @{ Authorization = "Bearer $token" } | ConvertTo-Json

Response includes balance_usdc (atomic units, 6 decimals: 50000000 = $50.00).

Usage

Method Path Auth Description
GET /usage/me Bearer Aggregated token/tool usage for current user

Admin

Method Path Auth Description
POST /admin/orgs Admin Create organisation
POST /admin/users Admin Create user
POST /admin/client-credentials Admin Create M2M client credentials for an org
GET /admin/usage/{user_id} Admin Usage for a specific user
GET /admin/usage/org/{org_id} Admin Usage for an org
GET /admin/billing/revenue Admin Aggregated revenue summary
POST /admin/credits/topup Admin Add prepaid USDC credits to an org
POST /admin/pricing/tools Admin Create or update a per-tool pricing override
DELETE /admin/pricing/tools/{tool_name} Admin Remove a per-tool pricing override
GET /admin/tools/{org_id} Admin List custom tools for an org
GET /admin/memories/org/{org_id} Admin List memories for an org
DELETE /admin/memories/org/{org_id} Admin Delete all memories for an org
GET /admin/mcp/servers/{org_id} Admin List MCP servers for an org
GET /admin/billing/pending Admin List pending settlements
POST /admin/billing/pending/{id}/retry Admin Retry a specific failed settlement
GET /admin/orgs/{org_id}/spending Admin Get org spending config (caps, pause status)
PATCH /admin/orgs/{org_id}/spending Admin Update org spending caps and pause status
GET /admin/marketplace/sweep-status Admin Status of all pending withdrawals
POST /admin/marketplace/sweep-retry/{id} Admin Reset an exhausted withdrawal for retry
POST /admin/marketplace/process-withdrawal/{id} Admin Manually process a single withdrawal

Custom Tools

Per-org webhook-backed tools are injected into the agent at run-time and never appear in the public Agent Card or MCP server. Custom webhook tools are currently read-only and must use the GET HTTP method.

Method Path Auth Description
POST /tools Bearer Register a custom webhook tool
GET /tools Bearer List org's custom tools
GET /tools/{tool_id} Bearer Get a specific custom tool
PATCH /tools/{tool_id} Bearer Update a custom tool
DELETE /tools/{tool_id} Bearer Delete a custom tool
POST /tools/test-webhook Bearer Fire a test request to a webhook URL

Memory

Per-org persistent memory backed by pgvector. Memories are extracted automatically during agent runs and recalled as context on subsequent turns.

Method Path Auth Description
GET /memories Bearer List org memories (cursor paginated)
POST /memories Bearer Store a memory manually
DELETE /memories/{memory_id} Bearer Delete a specific memory

MCP Federation

Connect external MCP servers to your org. Their tools are discovered and made available to the agent alongside the built-in tool set.

Method Path Auth Description
POST /mcp/servers Bearer Register an external MCP server
GET /mcp/servers Bearer List org's MCP servers
GET /mcp/servers/{server_id} Bearer Get a specific MCP server
PATCH /mcp/servers/{server_id} Bearer Update an MCP server
DELETE /mcp/servers/{server_id} Bearer Remove an MCP server
POST /mcp/servers/{server_id}/discover Bearer Trigger tool re-discovery from an MCP server
POST /mcp/servers/{server_id}/test-tool Bearer Diagnostic: invoke one MCP tool without billing, audit, or circuit-breaker effects

A2A Delegation

Agent allowlist and delegation history. Agents must be added to the allowlist before delegating to them.

Method Path Auth Description
POST /a2a/agents Bearer Add a trusted A2A agent to your org's allowlist
GET /a2a/agents Bearer List all trusted agents in your allowlist
DELETE /a2a/agents/{agent_id} Bearer Remove an agent from your allowlist
GET /a2a/delegations Bearer List delegation events for your org (cursor paginated)

Admin A2A endpoints:

Method Path Auth Description
POST /admin/a2a/agents Admin Add a trusted agent to an org's allowlist (admin can add to any org)
GET /admin/a2a/agents/{org_id} Admin List trusted agents for a specific org
DELETE /admin/a2a/agents/{agent_id} Admin Remove an agent from an org's allowlist

Calling the agent (PowerShell)

$token = (Invoke-RestMethod -Uri "http://localhost:8000/token" `
    -Method Post -ContentType "application/json" `
    -Body '{"client_id":"teardrop-client","client_secret":"<secret>"}').access_token

$body = '{"message": "What is 42 * 7?", "thread_id": "my-session-1", "emit_ui": false}'
Invoke-RestMethod -Uri "http://localhost:8000/agent/run" `
    -Method Post -ContentType "application/json" `
    -Headers @{ Authorization = "Bearer $token" } `
    -Body $body

For multi-turn conversation, reuse the same thread_id across requests. Set emit_ui to false for CLI and machine-to-machine callers to skip the UI generation pass and reduce latency.

Pagination

/billing/history, /billing/invoices, /billing/credit-history, and /memories support cursor-based pagination:

GET /billing/invoices?limit=50
→ { "items": [...], "next_cursor": "2026-04-01T12:00:00.000Z" }

GET /billing/invoices?limit=50&cursor=2026-04-01T12:00:00.000Z
→ { "items": [...], "next_cursor": null }   # no more pages

Running the MCP tool server (optional)

The tools can be served standalone over the MCP protocol for use with Claude Desktop, VS Code, or any MCP-compatible client:

# stdio transport (default – for Claude Desktop / VS Code)
python tools/mcp_server.py

# HTTP SSE transport
python tools/mcp_server.py --transport=sse

How it works

Agent graph (agent/graph.py)

The agent runs as a LangGraph state machine with three nodes:

START → planner → [tool_executor ↩] → ui_generator → END
  • planner — Sends the conversation to the configured LLM with all tools bound. If the LLM decides to call a tool, status is set to EXECUTING; otherwise it moves to UI generation.
  • tool_executor — Runs all pending tool calls in parallel, appends ToolMessage results, and builds a compact slots fact store used by later planner turns.
  • ui_generator — Extracts or generates A2UI component JSON from the final assistant message and attaches it to the state.

When AGENT_COMPILER_MODE_ENABLED=true, planner turns may emit an optional staged <plan>{...}</plan> block. The executor then runs staged calls with dependency-aware argument resolution while preserving the same graph topology.

Conversation history persists across turns via AsyncPostgresSaver (Postgres-backed LangGraph checkpointer).

Streaming (teardrop/routers/agent.py)

POST /agent/run returns a live SSE stream. Event types emitted:

Event When
RUN_STARTED Immediately on request
TEXT_MESSAGE_CONTENT Each LLM token chunk
TOOL_CALL_START Before a tool executes
TOOL_CALL_END After a tool returns
SURFACE_UPDATE When A2UI components are ready
BILLING_SETTLEMENT After on-chain payment settles
USAGE_SUMMARY Total tokens, cache-read/create tokens, tools, and cost for the run
RUN_FINISHED Agent completed normally
ERROR Unhandled exception
DONE Stream closed

Tools (tools/definitions/)

Twenty-five tools are available to the agent and served via MCP:

Tool Description
calculate Evaluates arithmetic expressions safely (no eval). Supports +, -, *, /, **, %, sqrt, abs, round, floor, ceil, log, sin, cos, tan, pi, e.
convert_currency Converts between fiat and crypto currencies using CoinGecko and live fiat exchange rates.
decode_transaction Decodes transaction calldata into human-readable form using the supplied ABI or 4byte.directory.
delegate_to_agent Delegate a task to a remote A2A-compliant agent. Discovers capabilities, sends a message, handles optional x402 payment, debits org credits, and records audit events.
get_block Block metadata (timestamp, gas, miner, tx count) by number or "latest".
get_datetime Returns current UTC date/time. Accepts an optional strftime format string.
get_erc20_balance ERC-20 token balance for an address.
get_eth_balance ETH balance for an Ethereum address (mainnet or Base). Requires ETHEREUM_RPC_URL or BASE_RPC_URL.
get_gas_price Current gas price (gwei) and EIP-1559 fee components on Ethereum or Base.
get_token_price Crypto asset price in USD (or any supported currency) via CoinGecko.
get_transaction Transaction details and status by hash.
get_wallet_portfolio Aggregated token holdings and USD value for an Ethereum or Base wallet.
http_fetch Fetches and extracts content from a URL. Includes SSRF protection — private/cloud-metadata IPs are blocked, and every redirect hop is re-validated before being followed.
read_contract Calls view/pure functions on any smart contract by ABI fragment.
resolve_ens Resolves ENS name → address or address → ENS primary name.
count_text_stats Returns character, word, sentence, and paragraph counts for a given text.
web_search Web search via Tavily. Set TAVILY_API_KEY to activate.
get_defi_positions Aggregate DeFi positions (Aave v3, Compound v3, Uniswap v3 LP) for a wallet on Ethereum or Base.
get_dex_quote Best Uniswap v3 swap quote across all fee tiers on Ethereum or Base via on-chain QuoterV2.
get_liquidation_risk Assess DeFi liquidation risk for up to 50 wallets across Aave v3 and Compound v3.
get_token_approvals Audit ERC-20 token allowances and flag risky unlimited approvals across major DeFi spenders. Returns an error field when the full RPC approval batch fails so consumers can treat results as incomplete instead of "clean".
get_lending_rates Current on-chain lending supply/borrow rates for Aave v3 and Compound v3 on Ethereum or Base. Returns per-asset APY snapshots and Compound utilization for stablecoin yield comparisons.
get_protocol_tvl Total Value Locked (TVL) for a DeFi protocol via DeFiLlama: current USD TVL, 7d/30d change, per-chain breakdown, and optional daily historical series. Supports batching and 3,000+ protocols.
get_token_price_historical Historical crypto price data via CoinGecko over a 1–365 day window. Returns period statistics (start, end, % change, high, low) plus a downsampled daily series.
get_yield_rates DeFi yield pool rates from DeFiLlama across 1,000+ protocols and all chains. Returns pools sorted by APY with TVL, base/reward APY, and 7d/30d mean APY context.

A2UI components (agent/state.py)

The agent can return structured UI alongside text. Supported component types:

Type Props
text content, variant (body|heading|caption)
table columns, rows
columns children
rows children
form fields, submit_label
button label, action
progress value (0–100), label

Database

Teardrop uses Postgres (Neon recommended for production, local via Docker for development).

Migrations

All schema changes are in migrations/versions/. Run them with:

python -m migrations.runner
File Contents
001_baseline.sql Core tables: orgs, users, wallets, siwe_nonces, usage_events
002_billing.sql Adds billing fields to usage_events; creates pricing_rules
003_pricing_seed.sql Seeds default usage-based pricing (tokens_in, tokens_out, tool_call rates)
004_credits.sql Adds org_credits table for prepaid credit balances
005_org_client_credentials.sql Per-org M2M client credentials (org_client_credentials)
006_credit_ledger.sql Immutable debit/top-up audit trail (org_credit_ledger)
007_stripe_webhook_events.sql Stripe webhook idempotency table (stripe_webhook_events)
008_usdc_topup_events.sql USDC on-chain top-up events (usdc_topup_events)
009_a2a_delegation.sql A2A delegation allowlist support for remote agents (a2a_allowed_agents)
009_tool_pricing_overrides.sql Per-tool pricing overrides; seeds web_search, get_token_price, get_wallet_portfolio rates
010_org_tools.sql Per-org custom webhook tools (org_tools) and audit events
011_org_memories.sql Enables pgvector; creates org_memories table with HNSW index
012_org_mcp_servers.sql Per-org MCP server connections (org_mcp_servers) and audit events
013_mcp_marketplace.sql Marketplace visibility flags (publish_as_mcp, marketplace_description, base_price_usdc) on org tools
013_settlement_retry.sql Settlement retry tracking columns for auto-sweep background worker
014_org_spending_limits.sql Per-org spending caps and pause/resume controls (org_spending_limits)
015_memory_ttl_dedup.sql Memory TTL expiry and near-duplicate deduplication support
016_email_verification.sql Email verification tokens and email_verified flag on users
017_org_invites.sql Org invite tokens and acceptance flow (org_invites)
018_refresh_tokens.sql Persistent refresh tokens for 30-day sessions (refresh_tokens)
019_org_llm_config.sql Per-org LLM provider/model/BYOK config (org_llm_config)
020_usage_provider_model.sql Adds provider and model columns to usage_events for per-model billing
021_model_pricing.sql Dynamic per-model pricing table (model_pricing)
022_model_pricing_seed.sql Seeds default pricing for all models in the catalogue
023_siwe_login_sessions.sql SIWE session persistence for nonce replay protection
024_a2a_delegation_billing.sql A2A delegation billing: extends a2a_allowed_agents with cost caps; creates a2a_delegation_events audit table
025_org_agent_wallets.sql CDP-backed agent wallets (org_agent_wallets) and audit events (agent_wallet_events)
026_a2a_jwt_forward.sql JWT forwarding flag on A2A delegation rules
026_normalize_revenue_share.sql Backfills and normalises revenue share in basis points
027_marketplace_tool_pricing.sql Per-tool pricing overrides for marketplace authors
028_marketplace_subscriptions.sql Org marketplace tool subscriptions (marketplace_subscriptions)
029_marketplace_platform_tools.sql Platform built-in metered tool enablement in marketplace
029_sweep_retry_columns.sql Auto-sweep retry tracking and backoff columns on withdrawal records
030_siwe_nonce_address_binding.sql Binds SIWE nonces to the signing address to prevent cross-wallet replay
031_activate_bench_tools.sql Activates benchmark tooling entries
031_byok_platform_fee.sql BYOK flat platform fee column on org_llm_config
032_refresh_token_successor.sql Refresh token successor chaining for atomic rotation
033_get_token_approvals.sql Schema support for get_token_approvals tool
034_get_defi_positions.sql Schema support for get_defi_positions tool
035_get_liquidation_risk.sql Schema support for get_liquidation_risk tool
036_get_dex_quote.sql Schema support for get_dex_quote tool
037_fix_haiku_pricing.sql Corrects Claude Haiku 4.5 token pricing to $0.80/$4.00 per 1k
038_org_llm_config_allow_openrouter.sql Expands provider CHECK constraint to allow openrouter in org_llm_config
039_new_model_pricing_seed.sql Pricing for DeepSeek V3.2 (superseded), Gemini 3 Flash Preview, and Claude Sonnet 4.6
040_marketplace_catalog_indexes.sql Compiles composite and pricing indexing for marketplace search/filters
040_v4_flash_pricing.sql Replaces DeepSeek V3.2 pricing with V4 Flash (same Teardrop rates, lower provider cost)
041_byok_tier_pricing.sql BYOK tier pricing: adds is_byok BOOLEAN to pricing_rules; seeds 5 provider-level BYOK rows at 50 atomic USDC/1k tokens
042_org_tool_schema_hash.sql Org tool schema_hash + last_schema_changed_at tracking for change detection
043_marketplace_subscription_schema_hash.sql Adds subscribed_schema_hash TEXT to org_marketplace_subscriptions
044_gemini_3_flash_pricing_fix.sql Corrects google-gemini-3-flash-preview-v1 from 125in/500out → 625in/3750out
045_get_token_price_historical_seed.sql Seeds get_token_price_historical into marketplace_platform_tools at 4,000 atomic USDC ($0.004)
046_web3_marketplace_seed.sql Marketplace seeding for web3 tools: get_eth_balance, get_erc20_balance, get_block, get_transaction
047_get_protocol_tvl_seed.sql Seeds get_protocol_tvl into marketplace_platform_tools at 3,000 atomic USDC ($0.003)
048_get_yield_rates_seed.sql Seeds get_yield_rates into marketplace_platform_tools at 4,000 atomic USDC ($0.004)
049_org_tool_output_schema_validation.sql Org tool output schema validation support
050_billable_tool_calls_accounting.sql Adds billable_tool_calls, billable_tool_names, failed_tool_calls, failed_tool_names to usage_events
051_gpt54_mini_pricing_seed.sql Seeds openai-gpt54-mini-v1: 938in/5625out per 1k tokens, run_price=10000 atomic USDC
052_get_lending_rates_marketplace_seed.sql get_lending_rates added to marketplace platform tools ($0.003)
053_zero_cost_tool_overrides.sql Zero-cost tool_pricing_overrides for calculate, get_datetime, count_text_stats
054_usage_events_cache_tokens.sql Adds cache_read_tokens, cache_creation_tokens to usage_events for telemetry
055_org_tool_get_only_constraint.sql Enforces GET-only active org webhook tools (chk_active_tool_get_only constraint)
056_web_search_price_alignment.sql Aligns web_search marketplace price to 15,000 atomic USDC ($0.015)
057_credit_ledger_debit_index.sql Partial index idx_credit_ledger_debit_time on org_credit_ledger(org_id, created_at DESC) WHERE operation='debit'
058_marketplace_dashboard_catalog.sql Public marketplace dashboard metadata: tool categories, aggregate call stats, catalog indexes, and platform category seeds
059_x402_payment_nonces.sql x402 payment-header replay guard table (x402_payment_nonces)
060_org_tools_partial_unique_name.sql Swaps table-level UNIQUE tool name constraint for partial index on active tools only
061_marketplace_catalog_search.sql Trigram indexes for marketplace catalog free-text search (trgm across tool/author metadata)
062_a2a_inbound_events.sql Inbound A2A audit ledger table (a2a_inbound_events) for caller identity and billing outcomes
063_org_tools_mcp_backed.sql Extends org_tools to support MCP-backed tool references alongside webhooks
064_scheduled_runs.sql Schedules and execution logs for recurring prompt runs (scheduled_runs & scheduled_run_results)
065_event_triggers.sql Event-triggered reactive prompt runs via webhook dispatches (adds trigger_token & secret_hash)
066_tool_call_events.sql Telemetry event logs (tool_call_events) for ML parameters and reputation tracking/user ratings (run_feedback)

Neon (production)

Set DATABASE_URL to your Neon connection string (no +asyncpg prefix needed — the app strips it automatically).


Project structure

app.py              # FastAPI app, lifespan, middleware, background workers, router registration
routers/            # APIRouter modules (agent.py: POST /agent/run SSE + GET /agent/tools)
agent_stream.py     # AG-UI SSE framing and A2UI stream-filter helpers
auth.py             # RS256 JWT & refresh tokens (auth methods: email, client_credentials, SIWE)
billing/            # x402 billing layer, pricing, invoice queries, credit system
cache.py            # Redis cache helpers
config.py           # Settings via pydantic-settings (reads .env)
memory.py           # Per-org pgvector memory: LLM extraction, recall, CRUD
mcp_client/         # Per-org MCP client: CRUD, session pool, tool discovery
org_tools/          # Per-org custom webhook tools: CRUD, caching, execution
usage.py            # UsageEvent model, usage recording and aggregation
users.py            # Org + User models, CRUD, PBKDF2-SHA256 password hashing
wallets.py          # User wallet management, SIWE nonce lifecycle
agent_wallets.py    # CDP-backed agent wallet provisioning, balance queries, audit
agent/
  graph.py          # LangGraph StateGraph definition and routing
  llm.py            # Multi-provider LLM factory (Anthropic, OpenAI, Google, OpenRouter)
  nodes.py          # planner, tool_executor, ui_generator implementations
  state.py          # AgentState, A2UIComponent, TaskStatus schemas
tools/
  registry.py       # ToolRegistry: versioned, with deprecation lifecycle
  mcp_server.py     # Standalone FastMCP server for MCP protocol clients
  definitions/      # One file per tool (calculate, get_datetime, web_search, …)
  __init__.py       # Global registry singleton, get_langchain_tools()
migrations/
  runner.py         # Applies SQL migrations in order
  versions/         # 001_baseline through 039_new_model_pricing_seed
shared/             # Internal shared utilities: db pool registry, audit inserts, webhook caller
scripts/
  generate_keys.py  # Generate RSA keypair → keys/private.pem + keys/public.pem
  audit_dependencies.py  # Review direct Python dependencies for OSV vulnerabilities and upgrade drift
  init_neon.py      # Initialize Neon Postgres schema
  seed_users.py     # Create default org + admin user for local dev

Coinbase Developer Platform Integration

Teardrop can provision per-org USDC wallets via Coinbase Developer Platform (CDP) for receiving delegation payments and marketplace earnings. This requires:

  1. CDP Account: Create one at https://cdp.coinbase.com
  2. API Credentials:
    • Go to Developer Settings → API Keys
    • Create a key with wallet:create permission
    • Note the Key ID and Key Secret (Ed25519 or ECDSA)
    • Note the Wallet Secret (used to decrypt keys stored in AWS Nitro Enclaves)
  3. Environment variables:
    AGENT_WALLET_ENABLED=true
    CDP_API_KEY_ID=<your-key-id>
    CDP_API_KEY_SECRET=<your-key-secret>
    CDP_WALLET_SECRET=<your-wallet-secret>
    CDP_NETWORK=base-sepolia       # or 'base' for mainnet
    AGENT_WALLET_MAX_BALANCE_USDC=100000000  # $100 balance cap (optional)
    
  4. Pricing: CDP charges $0.005 per operation. Free tier includes 5,000 ops/month.

Each org can hold one wallet per chain (e.g., Base Sepolia testnet, Base mainnet). Wallets auto-receive delegation payments and MCP marketplace earnings.


License

Teardrop is licensed under the Business Source License 1.1.

  • Free to use for non-production evaluation and development.
  • Commercial production use requires a commercial license from the maintainer.
  • Change Date: April 3, 2030 — on this date the code automatically converts to AGPL-3.0-only.

See LICENSE for full terms. For commercial licensing enquiries, see the contact address in the LICENSE file.

Contributions are welcome under the same license — see CONTRIBUTING.md. To report a security vulnerability, see SECURITY.md.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选