# RidgeTech Lead Generator — MCP endpoint

Machine-readable connection guide for AI agents. RidgeTech exposes a curated
[Model Context Protocol](https://modelcontextprotocol.io) server so an agent can
generate and manage sales leads on behalf of its human.

Human site: <https://leads.ridgetech.ai> · Agent discovery: <https://leads.ridgetech.ai/llms.txt>

## Endpoint

| Environment | URL | Transport |
|---|---|---|
| Production | `https://leads.ridgetech.ai/mcp` | MCP Streamable HTTP (stateless) |
| Staging | `https://staging-leads.ridgetech.ai/mcp` | MCP Streamable HTTP (stateless) |

## Authentication (OAuth 2.1 — interactive sign-in)

RidgeTech is an OAuth 2.1 resource server fronting its existing **Supabase Auth**
(*Sign in with Google / Meta / email*). There is **no separate API-token
system**. A spec-compliant MCP client discovers and runs the whole flow for your
human — no manual token handling:

1. The client calls `/mcp`, gets a **401** carrying
   `WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource"`.
2. It reads the discovery metadata
   (`/.well-known/oauth-protected-resource` → `/.well-known/oauth-authorization-server`),
   **dynamically registers** (RFC 7591), and opens the RidgeTech **sign-in page**
   in a browser.
3. Your human signs in — or an already-open RidgeTech browser session is reused —
   and clicks **Allow**.
4. The client receives a Supabase access token (with refresh) and presents it as
   `Authorization: Bearer <token>` on **every** request thereafter.

- A **RidgeTech account is required.** If your human doesn't have one, they sign
  up at <https://leads.ridgetech.ai> and finish workspace setup first.
- PKCE (**S256**) is mandatory and authorization codes are single-use. A client
  that already holds a Supabase access token may present it as a Bearer header
  directly and skip the browser flow.
- Error semantics:
  - Missing / invalid / expired token → **401** (carries the discovery pointer above).
  - Valid token but no provisioned account → **403** with
    `{"code": "account_required"}` — sign in and set up a workspace, then reconnect.

## Scope & safety

- Every call is scoped to your authenticated **tenant/account** — you only ever
  see and act on your own data.
- Only a curated, external-safe subset (**60 tools**) is exposed. Destructive
  (delete), admin/team, billing/checkout, bulk-send, and
  integration-credential tools are intentionally **not** available over MCP.
- **Some tools cost money.** Tools marked **💲 metered** below queue real
  discovery / enrichment runs or call paid AI providers; that usage is billed
  to the account. All other tools are free reads or draft-only authoring.
- **Campaign authoring is draft-only.** Campaign tools create/edit/pause/archive
  campaigns but never start bulk sending — that stays a human action in the UI.
  The one outbound-send tool is `send_lead_email`: **a single email to a single
  existing lead per call**, permission-gated and rate-limited. Confirm subject +
  body with your user before calling it.
- Usage is attributed to the account; per-call activity is logged
  (tool, tenant, status, duration) without secrets.
- **Rate limit:** tool calls are capped per account per minute. Exceeding it
  returns a rate-limit error with a retry hint — back off and retry.

## Tools

### Leads
- `list_leads` — list leads, optionally filtered by audience, stage, or tier
- `get_lead` — fetch full details for a single lead
- `create_lead` — create a new lead
- `update_lead` — partial update of a single lead by current company name
- `update_lead_stage` — move a lead to a different pipeline stage
- `get_pipeline_summary` — summary of leads grouped by pipeline stage
- `get_dashboard_stats` — totals: leads, audiences, pipeline breakdown, tier-A count

### Lead candidates (AI discovery output)
- `list_lead_candidates` — list candidates produced by Find Leads runs
- `accept_lead_candidate` — promote a pending candidate to a real lead
- `reject_lead_candidate` — reject a pending candidate
- `bulk_accept_lead_candidates` — accept multiple pending candidates (max 200/call)
- `bulk_reject_lead_candidates` — reject multiple pending candidates (max 200/call)

### Lead discovery & enrichment (💲 metered — these run real, billed compute)
- `start_find_leads` — **💲 metered.** Kick off a Find Leads discovery run for an
  audience (Perplexity + Claude pipeline). Returns a `run_id`; poll with
  `get_discovery_run`. Billed per run.
- `research_related_leads` — **💲 metered.** Queue a follow-up discovery run cued
  by an existing lead. Returns the queued `discovery_run_id`. Billed per run.
- `enrich_lead` — **💲 metered.** Run a Perplexity enrichment pass on one lead,
  filling only empty fields in place. Billed per call.
- `research_organization` — **💲 metered.** Run the AI org-research flow for your
  own organization profile and return the updated profile. Billed per call.
- `web_search` — **💲 metered.** Grounded web search via Perplexity with
  citations. Billed per call.
- `cancel_discovery_run` — cancel a queued or running discovery run (free).

### Audiences
- `list_audiences` — list configured audiences / target segments
- `get_audience` — full details for one audience (pain points, scoring criteria)
- `create_audience` — create a new target audience / segment
- `update_audience` — partially update an existing audience

### Discovery runs
- `list_discovery_runs` — recent Find Leads discovery runs, newest first
- `get_discovery_run` — status, counts, and errors for one run
- `recall_audience_findings` — what the discovery agent has learned about an audience

### Campaigns (read)
- `list_campaigns` — the account's campaigns, newest first
- `get_campaign` — one campaign by id or name
- `list_campaign_targets` — leads enrolled in a campaign
- `list_campaign_steps` — the steps in a campaign, ordered

### Campaigns (authoring — draft-only, never sends)
- `create_campaign` — create a new campaign (starts in `draft`)
- `update_campaign` — edit a campaign's name, description, send mode, mappings
- `create_campaign_step` — append a step (outreach or targeted-ad) to a campaign
- `preview_campaign_targeting` — preview which leads a targeting spec would enroll
- `pause_campaign` — move an active campaign to `paused`
- `complete_campaign` — mark a campaign `completed`
- `archive_campaign` — archive a campaign
  > Note: there is **no** `start_campaign` tool on this surface — agents author
  > and stage campaigns; a human starts bulk outbound sending from the UI. For
  > a single one-off email to one lead, see `send_lead_email` below.

### Outbound send (single-recipient)
- `send_lead_email` — send ONE email to ONE existing lead via the account's
  configured sender. Requires the `send_messages` permission; the send is
  rate-limited, stamped on the lead's interaction history for audit, and
  metered as a write. Body supports a markdown-lite subset (paragraphs,
  `##`/`###` headings, `- ` bullets, `---` rules, `[text](url)` links,
  `**bold**`, `*italic*`) rendered to rich HTML with a plain-text fallback.
  **Always confirm recipient, subject, and body with your user before
  calling.** There is no bulk-send tool on this surface.

### Templates (read + authoring)
- `list_templates` — the account's message templates
- `get_template` — one template by id or name
- `create_template` — create a message template
- `update_template` — partial update of a template by id or name
- `clone_template` — duplicate an existing template
- `archive_template` — archive a template
- `unarchive_template` — restore an archived template
- `draft_template` — **💲 metered.** AI-draft a template (subject + body) from a
  brief using the audience profile as context. Billed per call.

### Content (read + generation)
- `list_content_assets` — Content Studio assets (newest first) with previews
- `get_content_asset` — one Content Studio asset in full
- `generate_content` — **💲 metered.** Create a Content Studio asset and queue AI
  generation. Returns the asset; poll `get_content_asset` for the result.
  Billed per generation.

### Ad creatives (read — content only, no ad-account credentials)
- `list_ad_creatives` — the account's ad creatives (headlines, descriptions)
- `get_ad_creative` — one ad creative by name, in full
- `list_ad_deployments` — ad deployments for the account, optionally by campaign

### Organization
- `get_organization_profile` — the tenant's organization profile
- `update_organization_profile` — update fields on your org profile (brand voice,
  target customers, value props, etc.)
- `attach_text_to_org` — attach a text knowledge document to your org profile
- `list_organization_documents` — knowledge documents attached to the org profile
- `list_integration_templates` — available templates for source integrations

### Memory
- `save_memory` — persist a fact, preference, or goal to long-term memory
- `recall_memories` — search long-term memory for relevant context

### Account
- `get_me` — the calling user's identity + tenant context (email, role)
- `get_onboarding_status` — whether the user has finished provisioning a workspace

## Connect

### Claude Code (recommended)

```bash
claude mcp add --transport http ridgetech-leads https://leads.ridgetech.ai/mcp/
```

On first use Claude Code hits the 401, discovers the OAuth metadata, registers a
client, and opens the RidgeTech sign-in page in your browser. Sign in (or reuse
an already-open RidgeTech session) and click **Allow** — the connection then
completes and `tools/list` returns the 60 tools above. The server name
(`ridgetech-leads`) is just a local label; pick any name you like.

### Any OAuth-capable MCP client

Point the client at `https://leads.ridgetech.ai/mcp` over **Streamable HTTP**;
it will run the same discovery → browser sign-in flow described under
[Authentication](#authentication-oauth-21--interactive-sign-in).

### Manual token (clients without OAuth support)

If a client can't do the OAuth handshake but you already hold a Supabase access
token, present it directly:

```json
{
  "mcpServers": {
    "ridgetech-leads": {
      "transport": "streamable-http",
      "url": "https://leads.ridgetech.ai/mcp",
      "headers": { "Authorization": "Bearer <supabase-access-token>" }
    }
  }
}
```

Then `tools/list` returns the 60 tools above; `tools/call` runs one against your
account. Tools outside this list are neither listed nor callable.
