Sponsored by Deepsite.site

Teardrop

Created By
teardrop-ai24 days ago
Streaming AI agent API built on LangGraph. Implements AG-UI, A2A, MCP, and x402 simultaneously. Agents discover it via A2A, call it over SSE, use its tools via MCP, and pay per request in USDC on Base. Per-org MCP federation, pgvector memory, 16 built-in Web3 tools, and dual billing (Stripe + x402).
Content

teardrop

Intelligence beyond the browser

Teardrop is a streaming AI agent API. You send it a message; it reasons using your configured LLM (Anthropic, OpenAI, or Google), 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).


Requirements

  • Python 3.11+
  • An API key for your chosen LLM provider: Anthropic, OpenAI, or Google AI
  • A Postgres database (local via Docker, or Neon for production)

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:

# LLM provider: anthropic | openai | google (default: anthropic)
AGENT_PROVIDER=anthropic
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

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 app: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 up --build

Starts Postgres + Teardrop API. Migrations run automatically at startup. Keys are generated at build time and mounted from ./keys/.

Render (production)

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

VariableDescription
AGENT_PROVIDERanthropic, openai, or google (default: anthropic)
ANTHROPIC_API_KEYRequired if AGENT_PROVIDER=anthropic
OPENAI_API_KEYRequired if AGENT_PROVIDER=openai
GOOGLE_API_KEYRequired if AGENT_PROVIDER=google
DATABASE_URLNeon Postgres connection string
BILLING_ENABLEDtrue to activate x402 payments
X402_PAY_TO_ADDRESSTreasury wallet (USDC recipient)
X402_NETWORKeip155:8453 for Base mainnet
SIWE_DOMAINYour public domain (e.g. teardrop.onrender.com)
CORS_ORIGINSComma-separated allowed origins

Authentication

Teardrop issues RS256 JWTs. All endpoints (except /health, /docs, /billing/pricing, /.well-known/agent-card.json) 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.


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 ──────│                               │
  │    X-PAYMENT-REQUIRED: <reqs> │                               │
  │                               │                               │
  │── POST /agent/run ───────────►│                               │
  │   Payment-Signature: <signed> │── verify payment ────────────►│
  │                               │◄─ verified ───────────────────│
  │◄── SSE stream ────────────────│                               │
  │   (TEXT, TOOL, SURFACE...)    │                               │
  │   BILLING_SETTLEMENT          │── settle on-chain ───────────►│
  │   { tx_hash, amount_usdc }    │◄─ tx confirmed ───────────────│

Payment methods by auth type

Auth methodPayment mechanism
siwex402 on-chain (USDC, exact scheme, per-request)
client_credentialsOrg prepaid credit balance (off-chain debit)
emailOrg prepaid credit balance (off-chain debit)

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
BILLABLE_AUTH_METHODS=["siwe"]    # Add "client_credentials","email" to bill those too

Pricing

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

MetricRate
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.

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

API reference

Core

MethodPathAuthDescription
GET/Redirects to /docs
GET/healthLiveness probe
POST/agent/runBearerMain streaming endpoint (SSE)
GET/.well-known/agent-card.jsonA2A agent card
GET/docsSwagger UI
GET/redocReDoc UI

Auth

MethodPathAuthDescription
POST/tokenIssue JWT (client-creds, email, or SIWE)
GET/auth/meBearerReturn the authenticated user's identity
GET/auth/siwe/nonceGenerate single-use SIWE nonce

Billing

MethodPathAuthDescription
GET/billing/pricingCurrent pricing rules
GET/billing/historyBearerSettled payment history (cursor paginated)
GET/billing/invoicesBearerAll run records including pending (cursor paginated)
GET/billing/invoice/{run_id}BearerSingle run receipt
GET/billing/balanceBearerOrg prepaid credit balance
GET/billing/credit-historyBearerCredit ledger — top-ups and debits (cursor paginated)
POST/billing/topup/stripeBearerStart a Stripe checkout session to add credits
GET/billing/topup/stripe/statusBearerCheck Stripe checkout session status
GET/billing/topup/usdc/requirementsBearerGet on-chain USDC top-up payment requirements
POST/billing/topup/usdcBearerSubmit and verify an on-chain USDC top-up

Wallets

MethodPathAuthDescription
POST/wallets/linkBearerLink additional wallet via SIWE
GET/wallets/meBearerList your linked wallets
DELETE/wallets/{wallet_id}BearerUnlink a wallet

Usage

MethodPathAuthDescription
GET/usage/meBearerAggregated token/tool usage for current user

Admin

MethodPathAuthDescription
POST/admin/orgsAdminCreate organisation
POST/admin/usersAdminCreate user
POST/admin/client-credentialsAdminCreate M2M client credentials for an org
GET/admin/usage/{user_id}AdminUsage for a specific user
GET/admin/usage/org/{org_id}AdminUsage for an org
GET/admin/billing/revenueAdminAggregated revenue summary
POST/admin/credits/topupAdminAdd prepaid USDC credits to an org
POST/admin/pricing/toolsAdminCreate or update a per-tool pricing override
DELETE/admin/pricing/tools/{tool_name}AdminRemove a per-tool pricing override
GET/admin/tools/{org_id}AdminList custom tools for an org
GET/admin/memories/org/{org_id}AdminList memories for an org
DELETE/admin/memories/org/{org_id}AdminDelete all memories for an org
GET/admin/mcp/servers/{org_id}AdminList MCP servers for an org

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.

MethodPathAuthDescription
POST/toolsBearerRegister a custom webhook tool
GET/toolsBearerList org's custom tools
GET/tools/{tool_id}BearerGet a specific custom tool
PATCH/tools/{tool_id}BearerUpdate a custom tool
DELETE/tools/{tool_id}BearerDelete a custom tool

Memory

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

MethodPathAuthDescription
GET/memoriesBearerList org memories (cursor paginated)
POST/memoriesBearerStore a memory manually
DELETE/memories/{memory_id}BearerDelete 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.

MethodPathAuthDescription
POST/mcp/serversBearerRegister an external MCP server
GET/mcp/serversBearerList org's MCP servers
GET/mcp/servers/{server_id}BearerGet a specific MCP server
PATCH/mcp/servers/{server_id}BearerUpdate an MCP server
DELETE/mcp/servers/{server_id}BearerRemove an MCP server
POST/mcp/servers/{server_id}/discoverBearerTrigger tool re-discovery from an MCP server

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"}'
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.

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, then loops back to the planner for further reasoning.
  • ui_generator — Extracts or generates A2UI component JSON from the final assistant message and attaches it to the state.

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

Streaming (app.py)

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

EventWhen
RUN_STARTEDImmediately on request
TEXT_MESSAGE_CONTENTEach LLM token chunk
TOOL_CALL_STARTBefore a tool executes
TOOL_CALL_ENDAfter a tool returns
SURFACE_UPDATEWhen A2UI components are ready
BILLING_SETTLEMENTAfter on-chain payment settles
USAGE_SUMMARYTotal tokens, tools, cost for the run
RUN_FINISHEDAgent completed normally
ERRORUnhandled exception
DONEStream closed

Tools (tools/definitions/)

Sixteen tools are available to the agent and served via MCP:

ToolDescription
calculateEvaluates arithmetic expressions safely (no eval). Supports +, -, *, /, **, %, sqrt, abs, round, floor, ceil, log, sin, cos, tan, pi, e.
convert_currencyConverts between fiat and crypto currencies using CoinGecko and live fiat exchange rates.
decode_transactionDecodes transaction calldata into human-readable form using the supplied ABI or 4byte.directory.
get_blockBlock metadata (timestamp, gas, miner, tx count) by number or "latest".
get_datetimeReturns current UTC date/time. Accepts an optional strftime format string.
get_erc20_balanceERC-20 token balance for an address.
get_eth_balanceETH balance for an Ethereum address (mainnet or Base). Requires ETHEREUM_RPC_URL or BASE_RPC_URL.
get_gas_priceCurrent gas price (gwei) and EIP-1559 fee components on Ethereum or Base.
get_token_priceCrypto asset price in USD (or any supported currency) via CoinGecko.
get_transactionTransaction details and status by hash.
get_wallet_portfolioAggregated token holdings and USD value for an Ethereum or Base wallet.
http_fetchFetches and extracts content from a URL. Includes SSRF protection — private/cloud-metadata IPs are blocked.
read_contractCalls view/pure functions on any smart contract by ABI fragment.
resolve_ensResolves ENS name → address or address → ENS primary name.
summarize_textReturns character, word, sentence, and paragraph counts for a given text.
web_searchWeb search via Tavily. Set TAVILY_API_KEY to activate.

A2UI components (agent/state.py)

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

TypeProps
textcontent, variant (body|heading|caption)
tablecolumns, rows
columnschildren
rowschildren
formfields, submit_label
buttonlabel, action
progressvalue (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
FileContents
001_baseline.sqlCore tables: orgs, users, wallets, siwe_nonces, usage_events
002_billing.sqlAdds billing fields to usage_events; creates pricing_rules
003_pricing_seed.sqlSeeds default usage-based pricing (tokens_in, tokens_out, tool_call rates)
004_credits.sqlAdds org_credits table for prepaid credit balances
005_org_client_credentials.sqlPer-org M2M client credentials (org_client_credentials)
006_credit_ledger.sqlImmutable debit/top-up audit trail (org_credit_ledger)
007_stripe_webhook_events.sqlStripe webhook idempotency table (stripe_webhook_events)
008_usdc_topup_events.sqlUSDC on-chain top-up events (usdc_topup_events)
009_tool_pricing_overrides.sqlPer-tool pricing overrides; seeds web_search, get_token_price, get_wallet_portfolio rates
010_org_tools.sqlPer-org custom webhook tools (org_tools) and audit events
011_org_memories.sqlEnables pgvector; creates org_memories table with HNSW index
012_org_mcp_servers.sqlPer-org MCP server connections (org_mcp_servers) and audit events

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, SSE streaming, billing gate, all route handlers
auth.py             # RS256 JWT: create_access_token, require_auth dependency
billing.py          # 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.py       # Per-org MCP client: CRUD, session pool, tool discovery
org_tools.py        # 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          # Wallet management, SIWE nonce lifecycle
agent/
  graph.py          # LangGraph StateGraph definition and routing
  llm.py            # Multi-provider LLM factory (Anthropic, OpenAI, Google)
  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 012_org_mcp_servers
scripts/
  generate_keys.py  # Generate RSA keypair → keys/private.pem + keys/public.pem
  init_neon.py      # Initialize Neon Postgres schema
  seed_users.py     # Create default org + admin user for local dev

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.

Server Config

{
  "mcpServers": {
    "teardrop": {
      "url": "https://teardrop.onrender.com/tools/mcp"
    }
  }
}
Recommend Servers
TraeBuild with Free GPT-4.1 & Claude 3.7. Fully MCP-Ready.
AiimagemultistyleA Model Context Protocol (MCP) server for image generation and manipulation using fal.ai's Stable Diffusion model.
MiniMax MCPOfficial MiniMax Model Context Protocol (MCP) server that enables interaction with powerful Text to Speech, image generation and video generation APIs.
ChatWiseThe second fastest AI chatbot™
EdgeOne Pages MCPAn MCP service designed for deploying HTML content to EdgeOne Pages and obtaining an accessible public URL.
CursorThe AI Code Editor
RedisA Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
MCP AdvisorMCP Advisor & Installation - Use the right MCP server for your needs
Howtocook Mcp基于Anduin2017 / HowToCook (程序员在家做饭指南)的mcp server,帮你推荐菜谱、规划膳食,解决“今天吃什么“的世纪难题; Based on Anduin2017/HowToCook (Programmer's Guide to Cooking at Home), MCP Server helps you recommend recipes, plan meals, and solve the century old problem of "what to eat today"
Playwright McpPlaywright MCP server
Serper MCP ServerA Serper MCP Server
Jina AI MCP ToolsA Model Context Protocol (MCP) server that integrates with Jina AI Search Foundation APIs.
DeepChatYour AI Partner on Desktop
Zhipu Web SearchZhipu Web Search MCP Server is a search engine specifically designed for large models. It integrates four search engines, allowing users to flexibly compare and switch between them. Building upon the web crawling and ranking capabilities of traditional search engines, it enhances intent recognition capabilities, returning results more suitable for large model processing (such as webpage titles, URLs, summaries, site names, site icons, etc.). This helps AI applications achieve "dynamic knowledge acquisition" and "precise scenario adaptation" capabilities.
Y GuiA web-based graphical interface for AI chat interactions with support for multiple AI models and MCP (Model Context Protocol) servers.
WindsurfThe new purpose-built IDE to harness magic
Visual Studio Code - Open Source ("Code - OSS")Visual Studio Code
Tavily Mcp
BlenderBlenderMCP connects Blender to Claude AI through the Model Context Protocol (MCP), allowing Claude to directly interact with and control Blender. This integration enables prompt assisted 3D modeling, scene creation, and manipulation.
Amap Maps高德地图官方 MCP Server
Baidu Map百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。