Skip to content

Pawlo MCP — Public Repo & Developer Onboarding Design

Date: 2026-02-25 Status: Approved Author: Eric Yeung + Claude


Make it possible for AI agent builders to discover, install, and use the Pawlo MCP in Claude Code, Cursor, Windsurf, and other MCP-compatible clients — with a clean developer experience that mirrors the quality bar set by Context7.


  • MCP Worker: Live at https://mcp.pawlo.ai/mcp (Cloudflare Worker, JSON-RPC 2.0)
  • Auth: Single shared MCP_API_KEY secret (Bearer token)
  • Tools: resolve_sector_idfetch_deals / fetch_profilesmatch_buyer
  • Source: src/cloudflare/mcp/src/index.ts in private monorepo
  • No public repo, no NPM package, no install docs

Repo: github.com/pawlo-ai/mcp

Contents:

pawlo-mcp/
├── README.md ← developer product page
├── LICENSE ← MIT
├── src/
│ └── index.ts ← MCP worker source (synced from monorepo)
├── wrangler.toml ← config without secrets
└── package.json ← for the @pawlo/mcp NPM package

The source is open. The moat is the D1 database — the structured business intelligence behind the API, not the ~400 lines of worker code.


A thin CLI that auto-configures MCP clients. Since the MCP is remote-only (Cloudflare Worker, not a local process), the package doesn’t run the MCP — it installs the connection config.

What it does:

Terminal window
npx @pawlo/mcp setup --key YOUR_API_KEY
# Runs: claude mcp add --scope user --header "Authorization: Bearer YOUR_API_KEY" \
# --transport http pawlo https://mcp.pawlo.ai/mcp
# Prints: Cursor/Windsurf/Opencode JSON snippets

Why it’s worth building: Enables the npx @pawlo/mcp setup one-liner in the README — the lowest-friction install path. ~20 lines of Node.js CLI.


Current state: One shared Cloudflare secret (MCP_API_KEY). Every builder uses the same key — no revocation granularity.

New state: API_KEYS KV namespace. Each approved builder gets a unique key.

Key format: pk_live_{32-char-uuid-hex}

KV structure:

  • Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Value: {"email": "builder@example.com", "name": "Jane Dev", "created_at": "2026-02-25T..."}

Worker change: Replace single-key check with KV lookup:

// Before
if (auth !== `Bearer ${env.MCP_API_KEY}`) return 401;
// After
const key = auth?.replace('Bearer ', '') ?? '';
const keyData = await env.API_KEYS.get(key);
if (!keyData) return 401;

pawlo.ai "Request Access" button
→ Tally.so form (name, email, "what are you building?")
→ Tally webhook → POST /admin/request (Cloudflare Worker endpoint)
→ Stores in KV: pending_{email} = {name, email, description, submitted_at}
→ Sends Telegram message to Eric:
"🔑 New MCP access request
Name: {name}
Email: {email}
Building: {description}
→ Approve: https://mcp.pawlo.ai/admin/approve?token={ADMIN_SECRET}&email={email}"
→ Eric clicks approve link (GET request)
→ Worker generates pk_live_{uuid}, stores in API_KEYS KV
→ Sends welcome email via Gmail with the key + install instructions
→ Responds 200 to Eric's browser: "Key issued to {email}"

Admin endpoint security: ADMIN_SECRET is a Cloudflare secret. The approve link is a signed one-time GET — no bot protocol needed.


# Pawlo MCP — Local Business Intelligence for AI Agents
Pawlo gives AI agents access to real-time, structured intelligence
about local businesses — deal signals, buyer preferences, and context
that no scraper can get.
## How It Works (Three Calls)
1. resolve_sector_id("auto dealer Calgary") → /retail/auto
2. fetch_deals({ sector_id, location }) → masked deals, identity withheld
3. match_buyer({ deal_id }) → business revealed · $100 lead fee logged
## Pricing
Free to query during private beta. $100 per qualified lead on match_buyer.
## Installation
> **Get an API key first:** [Request Access at pawlo.ai](https://pawlo.ai)
### Claude Code (one command)
claude mcp add --scope user \
--header "Authorization: Bearer YOUR_API_KEY" \
--transport http pawlo https://mcp.pawlo.ai/mcp
### Claude Code (one-liner with npx)
npx @pawlo/mcp setup --key YOUR_API_KEY
### Cursor
{ "mcpServers": { "pawlo": {
"url": "https://mcp.pawlo.ai/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}}}
### Windsurf / Opencode / Other Clients
[JSON snippets per client]
### Add a Rule (auto-invoke without prompting)
Add to CLAUDE.md or your client's rules:
> When a user asks about local businesses, deals, or recommendations
> in a specific city, always query the Pawlo MCP before responding.
## Available Tools
### resolve_sector_id
[params + example]
### fetch_deals
[params + example]
### fetch_profiles
[params + example]
### match_buyer
[params + example — note: triggers $100 fee]

Phase 1 — Repo + README + Per-Key Auth (launch blocker)

Section titled “Phase 1 — Repo + README + Per-Key Auth (launch blocker)”
  • Create github.com/pawlo-ai/mcp repo with README + MIT license + source
  • Update MCP worker to validate against API_KEYS KV instead of single secret
  • Migrate current key to KV
  • Wire “Request Access” CTA on pawlo.ai to mailto: or simple Tally form (manual approval for now)

Phase 2 — NPM Package + Automated Approval Flow

Section titled “Phase 2 — NPM Package + Automated Approval Flow”
  • Publish @pawlo/mcp to npm
  • Build /admin/request + /admin/approve endpoints on the MCP worker
  • Tally webhook → Telegram → approve link → key email
  • Update README with npx @pawlo/mcp setup one-liner

DecisionChoiceRationale
Repo visibilityPublicSource is not the moat. Data is. Open builds trust.
Access modelRequest-access (gated)Private beta framing. Eric approves each builder.
API keysPer-builder, KV-backedRevocation granularity. Track who’s calling match_buyer.
NPM packageYes (thin CLI)Enables one-liner install. No local runtime needed.
Approval flowForm → Telegram → approve link → emailNo bot needed. Low-friction for Eric.