AI & MCP
Connect Claude and other AI agents to your TEASE workspace over a scoped, tenant-isolated MCP server.
TEASE ships a Model Context Protocol (MCP) server so an AI agent — Claude, or any
MCP-compatible client — can read your analytics and operate your workspace on your behalf.
You point the client at one endpoint, authenticate with a scoped al_live_* key, and the
agent discovers everything it can do at runtime. No SDK, no per-tool wiring, no glue code.
The server speaks JSON-RPC 2.0 over a single POST /mcp. Every call is authenticated,
scope-gated, and isolated to the workspace that owns the key. Message bodies are never stored.
What you get
Ask in natural language — "which sources drove the most revenue last week?", "draft a win-back campaign for dormant fans" — and the agent calls the right tools, reads back the results, and reasons over them. The catalog spans analytics reads, link management, landings, content, and campaigns.
Connect in 60 seconds
Mint a key
Create an al_live_* key with the scopes the agent needs. Start with read for analysis-only
agents; add write when the agent should change resources. See
Authentication for the full key model.
curl -X POST https://app.tease.link/api/admin/api-keys \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "claude-desktop", "scopes": ["read"] }'The full token is shown once. Copy it now.
Point your client at the server
Add the TEASE MCP server to your client config. For Claude Desktop, edit
claude_desktop_config.json (or use Settings → Developer → Edit Config) and add an HTTP
MCP server with a Bearer Authorization header:
{
"mcpServers": {
"tease": {
"type": "http",
"url": "https://app.tease.link/mcp",
"headers": {
"Authorization": "Bearer al_live_a1b2c3d4_…"
}
}
}
}Restart and verify
Restart the client. It performs the initialize handshake, calls tools/list, and the TEASE
tools appear in the agent's tool picker. Ask it "call whoami" to confirm the connection is
live and reporting your workspace.
Treat the key like a password
Anyone holding the key can act as your workspace within its scopes. Store it in your client's secret store, never commit it, and revoke it the moment it leaks. Read-only keys are the safe default for agents that only need to analyze.
Protocol
The endpoint is JSON-RPC 2.0. One HTTP POST /mcp carries exactly one JSON-RPC object.
Authentication is the same Bearer scheme as the rest of the API.
| Property | Value |
|---|---|
| Endpoint | POST https://app.tease.link/mcp |
| Encoding | JSON-RPC 2.0 (one object per request) |
| Auth | Authorization: Bearer al_live_… |
| Content type | application/json |
| Protocol version | 2025-06-18 |
A request that omits or presents an invalid key is rejected with HTTP 401 before any method runs. Malformed JSON returns a JSON-RPC parse error (see Errors).
initialize
The handshake. The client announces itself; the server returns its protocol version, capabilities, and identity. Send this once per session before any other method.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "claude-desktop", "version": "1.0.0" }
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": { "listChanged": false } },
"serverInfo": { "name": "tease" }
}
}After initialize, well-behaved clients send the notifications/initialized notification.
Notifications carry no id and the server answers with HTTP 202 and an empty body.
tools/list
Returns the catalog: every tool the agent is allowed to call, as name + description +
inputSchema only. This is the single source of truth — clients discover capabilities here
rather than from a hardcoded list, so the catalog can grow without a client change.
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "get_stats",
"description": "Read workspace performance stats for a period.",
"inputSchema": {
"type": "object",
"properties": {
"period": { "type": "string", "enum": ["7d", "30d", "90d"] }
},
"required": []
}
}
]
}
}Each entry follows the standard MCP tool shape:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Stable identifier you pass to tools/call. |
description | string | yes | One-line summary of what the tool does. |
inputSchema | object | yes | JSON Schema for the tool's arguments — the agent uses it to build a valid call. |
Treat tools/list as authoritative. Do not hardcode tool names or argument shapes from these
docs — read them from the catalog at runtime so your integration never drifts.
tools/call
Invoke one tool by name with arguments matching its inputSchema. The result is wrapped in an
MCP content block.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_stats",
"arguments": { "period": "7d" }
}
}{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{ "type": "text", "text": "{ \"revenue\": 4820.50, \"subscribers\": 173 }" }
],
"isError": false
}
}The arguments object must satisfy the tool's inputSchema. Any required property that is
missing is rejected before the tool runs.
get_stats returns the full revenue.sources block. Every real-source, organic, and pending
row includes a required seven-counter Full Attribution funnel object:
new, old, ftl, paid, paid_after, ftl_paid, and entered.
| Param | Type | Required | Description |
|---|---|---|---|
name | string | yes | The tool name from tools/list. |
arguments | object | no | Arguments matching the tool's inputSchema. Defaults to {}. |
Tool errors vs transport errors
A failure inside a tool is not a protocol error. The call still returns result with
isError: true and the message in the content block, so the agent can read the failure and
decide what to do. Transport-level problems (bad method, unknown tool, missing argument,
insufficient scope) come back as JSON-RPC error objects instead — see below.
Errors
Protocol-level failures use standard JSON-RPC error codes plus one TEASE-specific code for scope. The shape is always:
{
"jsonrpc": "2.0",
"id": 3,
"error": { "code": -32601, "message": "Method not found: 'tools/foo'" }
}| Code | Meaning | Typical cause |
|---|---|---|
-32700 | Parse error | The request body was not valid JSON. Returned with HTTP 400 and id: null. |
-32600 | Invalid Request | Missing jsonrpc: "2.0" or the method field. |
-32601 | Method not found | A method other than initialize, tools/list, or tools/call. |
-32602 | Invalid params | Unknown tool name, or a required argument was missing. |
-32001 | Insufficient scope | The key lacks the write or automation grant the tool requires. |
A 401 (HTTP, not JSON-RPC) means the Bearer key was absent, malformed, or revoked — it is
returned before any method is dispatched.
Scopes & permissions
Every tools/call is gated by the scopes on the key that made the request. Scope is enforced
server-side at call time — a key can never reach a tool above its grant, regardless of what the
agent attempts.
| Scope | Unlocks |
|---|---|
read | Read-only tools — analytics, leaderboards, drills, lookups. The safe default for analysis agents. |
write | Tools that create, update, or delete resources you own (on top of read). |
automation | An opt-in grant for sending and cadence tools. Grant it explicitly on a key when an agent should send on your behalf. |
Automation is opt-in by design
The automation scope is never implied by write. It must be granted explicitly per key, so
an agent that can edit resources still cannot reach sending or cadence tooling unless you
deliberately allow it. Calling an automation tool without the grant returns -32001.
For the full key lifecycle — minting, the one-time secret, rotation, and revocation — see Authentication.
Tool catalog
The catalog is discovered at runtime via tools/list — names, descriptions, and
inputSchema only. The groups below are a high-level map of what areas the agent can work in,
not a behavioral spec; for the exact, current set of tools and their arguments, always read
tools/list.
Analytics reads
Workspace stats, revenue forecasting, spender and fan drills, cohort ranking, churn
signals, chatter and script performance, content performance, goal progress. Examples:
get_stats, revenue_forecast, list_spenders, get_fan_detail, rank_cohorts,
churn_risk, chatter_leaderboard, script_performance, goal_progress, whoami.
Smart links (/r/<slug>)
The ONE shareable funnel link — a policy smart link that holds BOTH a paid and a trial
destination and splits traffic by weighted, per-country rules (sticky per visitor). Attach
real destinations, read full routing health with ready fixes, and dry-run "where would a
visitor from country X land?" before anything goes live. Start here. Examples:
create_policy_smartlink, list_policy_smartlinks, update_smartlink_policy,
dress_country, get_smartlink_routing, resolve_smartlink_route.
Link inventory (building blocks)
The pool of raw OF links that FEED the smart link above — fill it in one step with
provision_domain_links, then list, toggle, retire, and attach conversion pixels. These are
inventory, not the link you share. Examples: provision_domain_links, list_smart_links,
get_smart_link, toggle_smart_link, delete_smart_link, set_smart_link_pixel,
list_smart_link_pixels.
Landings & domains
Build and publish link-in-bio pages: domains, geo-segments, button stacks, icons, and the
draft to publish workflow. Examples: list_domains, get_domain_config, connect_domain,
suggest_domain, create_segment, update_segment, create_button, update_button,
list_icons, publish, discard.
Content & vault
Search your AI-tagged vault, inspect folders and drops, read content performance, surface
content gaps and requests. Examples: content_search, content_folder, content_drop,
content_performance, content_requests, vault_gaps.
Campaigns & chat
Build and run mass-messaging campaigns and read the inbox: create, preview, schedule,
start, pause, cancel, and read campaign results, plus audience preview and price
suggestions. Examples: list_campaigns, create_campaign, preview_campaign,
start_campaign, pause_campaign, cancel_campaign, campaign_results,
audience_preview, inbox_waiting, suggest_price.
Account config
Read and tune your account's economics + routing config: fan spend tiers, the suggested PPV
price ladder, content and copilot benchmark bands, integration hosts, and your country tiers
(geo_classify: T1 / T2 / blocklist). set_config merges a sparse patch — only the keys you
pass change. Examples: get_config, set_config.
Fan attribution
Raise source + country coverage on your ORGANIC fans: pull the whale-first work-list, read
each fan's full DM history, and write a graded source/country guess back to your tables. Ship
the method to your agent as a Skill from your fans export. Examples:
list_fans_needing_attribution, get_fan_conversation, set_fan_attribution.
Automation
Opt-in cadence and control tools, gated behind the automation scope. Examples:
get_automation_optin, set_automation_optin, automation_overview.
Several tools double as in-band documentation — calling guide, automation_guide, or
automation_overview returns guidance the agent can read before it acts. The agent learns the
surface from the catalog, not from hardcoded knowledge.
Attribute your fans
Raise source + country coverage on your organic fans. Every fan who arrived through a tracked link already has an exact source — the click told us. The rest are organic, and the only evidence of where they came from is what they wrote in their DMs. TEASE attributes them in two tiers:
- Automatic sweep — a server model reads captured conversations and fills source + country for every fan it can. This is the floor, and it runs on its own.
- Your own agent (this) — point your Claude at the residual the sweep couldn't resolve and let it read each conversation in full. A strong model on the raw thread is the precision tier: it lifts coverage toward complete, whales first.
Both tiers write the same record, so an agent-set attribution shows up in your Fans grid and fan cards exactly like the automatic one — with a dashed "presumed" badge until the evidence is strong enough to promote it to the money-canon.
The loop — three tools
A write-scoped key unlocks these (mint one on the API keys page — see
Authentication):
list_fans_needing_attribution
Get the work-list, already ordered whale-first. Filter by what's missing (missing_source
default, missing_country, missing_either, all_scanned). Fans who came through a tracked
link are excluded from missing_source — their source is a fact, not a guess.
get_fan_conversation
Pull one fan's full captured DM history (oldest-first), your chatter notes, an active-hours hint, and whatever is already known about him. Discovery ("how did you find me?") lives in the earliest messages — read the start hardest.
set_fan_attribution
Write the decision back: source, source_confidence, country, country_confidence, a short
evidence quote, optional tags. Confidence ≥ 0.6 promotes the guess to the money-canon
(unless a hard tracked-link source already wins); below that it is kept as "presumed" for
coverage. A field left null on a re-write keeps the prior value — you can only improve.
Ship it as a Skill
Export your fans (Scaner → Fans → Export) and the ZIP now includes SKILL.md — a
drop-in Skill that teaches your agent the exact method: the channel list, the country cues
(language, slang, name → region, active hours), confidence calibration, and worked examples.
Add it to your Claude and it runs the loop above with the same discipline the server sweep uses.
Ask in natural language — "attribute my top organic fans by source and country" — and the agent works the list, reads each thread, and writes graded guesses straight into your tables. A graded guess beats a blank; it never fabricates a place or platform the fan didn't imply.
Trust & safety
The MCP server is built so you can hand an agent real capability without handing over your account.
Scoped keys
Every call carries a scope. Read-only keys can never mutate; write and automation are
separate, explicit grants. Scope is enforced at call time, server-side.
Tenant isolation
A key only ever sees the workspace that created it. Every read and write is scoped to that owner — there is no cross-account access through MCP, ever.
No stored message bodies
The server reasons over your data to answer; it does not persist the contents of the JSON-RPC messages it processes. Chat reads expose live threads without storing bodies.
Revocable & auditable
Revoke a key and it stops working immediately — every agent using it is cut off. Key activity, including last-used time, is visible in your dashboard.
Automation stays gated
Sending and cadence tools require the explicit automation scope and respect the same
ban-safe, off-by-default delivery posture as the rest of TEASE. Granting read or write to
an agent never enables it to send on your behalf.
FAQ
Next steps
- Authentication — key format, scopes, rotation, revocation.
- Smart Links — the trackable links many MCP tools operate on.
- API Reference — the REST surface behind the same
al_live_*keys.