Odel
Agent Broker

Agent Broker

@basilalshukailiCommunicationPythonUpdated 2w ago

AI agents find, message & book SMBs; pay per call in USDC on Base via x402. 14 tools, compliant.

Server endpointStreamable HTTP

This is the third-party server itself — Odel doesn't run it. Hitting this URL directly talks straight to the upstream server with no auth or proxying. Connect through Odel to front it with managed auth.

Agent Broker — SMB Transaction & Communication MCP Server

An agent-callable MCP server that lets autonomous AI agents find, verify, message, schedule with, and transact with small and mid-sized businesses (SMBs) through a single compliance-enforced tool surface.

MCP License Python Edge Registry Tests

Live endpoint: https://agent-broker-edge.basil-agent.workers.dev/mcp (streamable-http, always-on Cloudflare edge)


Why this exists

There are ~60 million long-tail small businesses in the US — barbers, plumbers, accountants, home cleaners — and they have no API surface. AI agents that need to schedule a haircut, get a quote, or send a confirmation today must either drive a browser, cold-call by voice, or give up.

This server is the missing middle layer. Agents call us; we route to the right SMB through whichever channel reaches them fastest — Cal.com → SMS → voice AI → email — with full TCPA / GDPR / CASL / 10DLC compliance enforced as a non-bypassable gate.


Current status (honest)

CapabilityStatus
MCP endpoint (streamable-http)Livehttps://agent-broker-edge.basil-agent.workers.dev/mcp
14 MCP toolsLive (callable today)
Compliance gate (TCPA/GDPR/CASL)Live
REST + A2A + OpenAI/Anthropic tool surfacesLive
SMB supply networkDemo — 20+ seed SMBs; demo bookings return demo_smb_no_live_booking
Per-call payments via x402/USDC on BaseComing soon — not yet active — tools are currently free
Production SMB onboardingPlanned — real businesses not yet enrolled

The MCP server is live and callable right now. Bookings hit demo data, and per-call payments (x402/USDC) are not yet charged. Both are in progress.


14 MCP Tools

All tools are callable via MCP, REST, OpenAI function calling, Anthropic tool_use, or A2A protocol.

#ToolWhat it does
1find_businessSearch SMBs by vertical, location, and capability — free
2verify_businessConfirm an SMB is real, operating, and capable of the requested service — free
3send_messageSend SMS, email, or voice with full compliance pre-check (TCPA/GDPR/CASL)
4capture_leadStructured intake of a prospect into an SMB pipeline with CRM integration
5schedule_appointmentBook, reschedule, or cancel — tries direct booking API, falls back to voice AI
6send_transactional_confirmationTCPA-exempt OTPs, booking confirmations, receipts
7handle_inboundClassify inbound messages: booking / cancel / opt-out / question / complaint
8escalate_to_humanHand off a stuck or ambiguous task to a human operator with full context
9get_statusPoll the current state of an async operation — free
10get_outcomeRetrieve the final OutcomeReceipt (with cost and reason codes) — free
11preview_costEstimate cost, latency, and success probability before committing — free
12self_testVerify service health and all claimed capabilities are responding — free
13import_booking_urlTurn any Cal.com, Calendly, Doctolib, Booksy, OpenTable, Square, Acuity, or Fresha URL into a bookable SMB record
14call_businessPlace a conversational voice-AI phone call to a business on behalf of a consumer

Quick start

Connect via MCP (Claude Desktop, Cursor, Continue, etc.)

{
  "mcpServers": {
    "agent-broker": {
      "url": "https://agent-broker-edge.basil-agent.workers.dev/mcp"
    }
  }
}

No API key required for read-only tools. State-changing tools accept an optional X-Agent-Identity bearer token.

Discover tools (JSON-RPC)

curl -X POST https://agent-broker-edge.basil-agent.workers.dev/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Call a tool (JSON-RPC)

curl -X POST https://agent-broker-edge.basil-agent.workers.dev/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "find_business",
      "arguments": {
        "vertical": "personal_services",
        "location": {"zip_or_city": "30309"},
        "capability": "haircut"
      }
    }
  }'

OpenAI function calling

import httpx, openai
tools = httpx.get(
    "https://agent-broker-edge.basil-agent.workers.dev/.well-known/openai-tools.json"
).json()["tools"]
client = openai.OpenAI()
resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Book a haircut in Atlanta Saturday under $50"}],
    tools=tools,
)

Anthropic tool use

import httpx, anthropic
tools = httpx.get(
    "https://agent-broker-edge.basil-agent.workers.dev/.well-known/anthropic-tools.json"
).json()["tools"]
client = anthropic.Anthropic()
msg = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "Book a haircut in Atlanta Saturday under $50"}],
)

Plain REST

curl -X POST https://agent-broker-edge.basil-agent.workers.dev/ops/find_business \
  -H "Content-Type: application/json" \
  -d '{"vertical":"personal_services","location":{"zip_or_city":"30309"},"capability":"haircut"}'

Discovery surfaces

SurfaceURL
MCP (streamable-http)https://agent-broker-edge.basil-agent.workers.dev/mcp
MCP descriptorhttps://agent-broker-edge.basil-agent.workers.dev/.well-known/mcp.json
OpenAI function toolshttps://agent-broker-edge.basil-agent.workers.dev/.well-known/openai-tools.json
Anthropic tool_usehttps://agent-broker-edge.basil-agent.workers.dev/.well-known/anthropic-tools.json
A2A (Agent-to-Agent)https://agent-broker-edge.basil-agent.workers.dev/.well-known/agents.json
OpenAI ChatGPT pluginhttps://agent-broker-edge.basil-agent.workers.dev/.well-known/ai-plugin.json
llms.txthttps://agent-broker-edge.basil-agent.workers.dev/llms.txt
OpenAPI 3.1https://agent-broker-edge.basil-agent.workers.dev/openapi.yaml
Glama MCP RegistryListed via glama.json
MCP RegistryListed via server.json

Architecture

AI agent
   |
   v  MCP / REST / A2A
Cloudflare Worker edge  (agent-broker-edge.basil-agent.workers.dev)
   |  300+ PoPs globally -- discovery served from edge bundle in 40-70 ms
   |
   +-- GET /.well-known/* /manifest /llms.txt  --> embedded snapshot (40-70 ms)
   +-- POST /mcp  initialize / tools/list      --> embedded snapshot (40-65 ms)
   +-- POST /mcp  tools/call  /ops/*           --> proxy to origin  (170-190 ms)
                |
                v
        Python FastAPI  (smb-broker.onrender.com)
                |  Cron keep-alive every 2 min (eliminates Render cold starts)
                |
                +-- 14 operation handlers  (core/)
                +-- Compliance gate        (compliance/pre_check)
                +-- Channel adapters       (channels/ -- Twilio, Cal.com, Vapi, SendGrid)
                +-- Billing + outcome store
                +-- All .well-known / MCP endpoints (also served from edge bundle)

The edge worker can outlive the origin: discovery still works even if the origin is down. Idempotency is keyed by (agent_id, operation, idempotency_key) with 24h TTL. Async operations return pending_async; poll with get_status / get_outcome.


Compliance

Every outbound communication passes through compliance/pre_check():

  1. Content classification — blocks restricted categories (gambling, adult, cannabis, spam)
  2. Opt-out check — TCPA STOP keyword, GDPR right-to-be-forgotten, CASL
  3. Consent check — TCPA written consent, GDPR opt-in, CASL implied/express
  4. 10DLC registry check — US SMS campaign compliance
  5. Two-party recording consent — CA, FL, IL, MD, MA, MT, NV, NH, PA, WA
  6. Audit log — PII stored as SHA-256 hash, never plaintext

Violations surface as ComplianceViolationError and are never silently bypassed.


Repo layout

agentbroker/
+-- core/                  # 14 operation handlers + shared Pydantic models
+-- channels/              # Twilio, SendGrid, Vapi, Bland, Cal.com, Playwright
+-- compliance/            # pre_check, jurisdiction_rules, consent_store, audit_log
+-- reliability/           # retry, circuit_breaker, channel_fallback, async_runner
+-- billing/               # meter, budget_guard, receipt_signer, pricing_tiers
+-- telemetry/             # tracer, log_redactor, metrics_emitter
+-- storage/               # outcome_store, idempotency_store
+-- supply/                # smb_directory (20+ seed/demo SMBs)
+-- onboarding/            # self_serve, verification_flow, channel_capture
+-- feedback/              # failure_classifier, attribution_engine, outcome_evaluator
+-- optimizer/             # ab_router, selection_analytics, weekly_report
+-- agent_interface/       # manifest_server, mcp_server, well_known, identity, webhooks
+-- manifest/              # manifest.json, mcp_tools.json, openapi.yaml
+-- api/                   # errors.md, identity.md, async.md
+-- docs/                  # mission, architecture, compliance, ADRs
+-- edge/                  # Cloudflare Worker (TypeScript/Hono)
+-- deploy/                # Dockerfile, docker-compose.yml
+-- tests/                 # unit, contract, compliance, fault_injection, agent_sim
+-- main.py                # FastAPI entry point
+-- config.py              # Centralized config from env
+-- requirements.txt

Local development

# Install dependencies
pip install -r requirements.txt

# Run tests (103 passing)
python -m pytest tests/ -q

# Start the API
python main.py
# --> http://localhost:8000/docs      (Swagger UI)
# --> http://localhost:8000/mcp       (MCP endpoint)
# --> http://localhost:8000/manifest  (capability manifest)

# Run the agent simulation harness
python -m tests.agent_sim.harness

# Self-test
python -c "import asyncio; from agent_interface.self_test import run_self_test; print(asyncio.run(run_self_test()).all_passed)"

Or with Docker:

docker compose -f deploy/docker-compose.yml up

Documentation


Contributing

This is a proprietary project. Issues and discussion are welcome — open a GitHub issue to report bugs or suggest features. Pull requests require prior discussion with the maintainer.


License

Proprietary — contact for licensing terms.


Built by Basil Al-Shukaili. Listed on the MCP Registry and Glama.