MCP server
Connect Claude Desktop (or any MCP client) to a Project88 org for read-only access to your data tables, pages, calendar, dials, and agents.
Project88 exposes a remote Model Context Protocol server so MCP-aware clients — Claude Desktop, Cursor, and others — can read from your org directly. No browser session, no copy-paste of data: the client calls tools against your workspace, and you keep the chat thread.
The server runs as the mcp Supabase Edge Function and authenticates
via per-org bearer tokens.
What it exposes
Read-only access to your org's core data. The same org_id scoping that
governs the rest of Project88 applies — a token can only see one org's
data, and only what an admin would be allowed to see.
| Tool | Returns |
|---|---|
list_data_tables | All data tables in the org |
query_data_table | Rows from a specific table, paginated |
search_pages | Pages matched by title (case-insensitive) |
list_calendar_events | Events in a time window (default: next 7 days) |
get_calendar_event | Full record for one event by id |
list_dial_buckets | All dial buckets configured in the org |
get_dial_bucket_stats | Activity counts (calls, meetings, etc.) per bucket |
list_agents | Agents in the org with their model and tools config |
get_current_time | Current server time in ISO 8601 |
Writes (create/update/delete) are intentionally not part of v1 — clients
like Claude Desktop call tools without confirming each one, and we don't
want a hallucinated delete_event to land in production data. A
write-tool surface with explicit confirmation policies is on the roadmap.
Connect Claude Desktop
-
Mint a token. Run this from any place where you're signed in as an org admin (the in-app SQL console,
psql, or the Supabase dashboard):select * from public.mcp_token_issue( '<your-org-id>'::uuid, 'Claude Desktop on my laptop' );The
raw_tokencolumn is shown exactly once — copy it now. Only the sha-256 hash is stored. -
Add the connector in Claude Desktop. Settings → Connectors → Add custom connector:
- Name — anything (e.g. "Project88")
- URL —
https://<your-project-ref>.functions.supabase.co/mcp - Authentication — Bearer, value = the
raw_tokenfrom step 1
-
Confirm it's listed. Start a new chat in Claude Desktop. The connector should show up in the tools menu with the 9 tools listed above. If it doesn't, check the desktop app's logs — usually a transport or auth error.
A first-party UI for issuing and revoking tokens lives under Settings → Connections → MCP tokens when available; until that ships, the SQL flow above is the path.
What's stored, what isn't
Stored in mcp_tokens | Not stored |
|---|---|
org_id, name, token_prefix (first 12 chars) | The raw token |
| sha-256 hash of the token | Anything reversible |
created_by, created_at, last_used_at | |
revoked_at (set on revoke; row never deleted) |
The hash is one-way: if you lose the raw token, you can't recover it — revoke and issue a new one.
Revoke a token
update public.mcp_tokens
set revoked_at = now()
where id = '<token-id>';mcp_token_authenticate checks revoked_at is null on every request,
so revocation takes effect immediately on the next call.
How requests are authorized
Every request to the mcp function carries an
Authorization: Bearer p88_... header. The function:
- Strips the
Bearerprefix and sha-256-hashes the token. - Calls the
mcp_token_authenticate(hash)RPC (SECURITY DEFINER, callable only by the service role). - The RPC returns the matching
token_id+org_id, and bumpslast_used_at. - Tool handlers run with that
org_idbaked into every query — the caller can never override it.
Unknown tokens, revoked tokens, and non-p88_-prefixed bearer values are
all rejected with 401 Unauthorized.
Limits and caveats
- One org per token. If you administer multiple orgs, issue a separate token per org and add each as its own connector in Claude Desktop.
- Read-only. No write tools, no mutation RPCs, no destructive surface. This is deliberate.
- No rate limiting yet. Claude can issue tool calls in tight loops; per-token quotas will land before this surface is opened to end-customers.
- Identifiers are UUIDs. Tools expect
table_id,event_id,bucket_idas UUIDs — get them from the correspondinglist_*tool first.
Where to next
- Tools — how Project88's own agents call tools
- Data tables — the shape of what
query_data_tablereturns - Vault and secrets — how Project88 stores credentials in general