Skip to content

MCP server

Markdown

Concierge runs a remote MCP server, so your coding agent can read and write your inbox. A reply sent from your editor reaches the customer’s app live and by push, exactly like a reply from the dashboard. “Triage my support, fix the crash Ana reported, and reply to her” is one prompt.

Environment URL
Hosted https://mcp.conciergesdk.com/mcp
Local dev http://localhost:4100/mcp

It speaks MCP over Streamable HTTP, so it works with any client that does: Claude Code, Cursor, Codex, Windsurf, VS Code with GitHub Copilot, Gemini CLI, Zed and others. Config for each is below.

Clients that support MCP OAuth (Claude Code, Cursor, Codex) need nothing but the URL:

Terminal window
claude mcp add --transport http concierge https://mcp.conciergesdk.com/mcp

The first call opens your browser: sign in to the dashboard, review what the agent can do, and click Allow. The agent registers itself, signs in with PKCE and keeps a refresh token, so you only do this once. It acts as you in the organization that was active when you clicked Allow, and its replies carry your name.

Anyone can register an app under any name, so the consent screen marks every agent Unverified app and shows where access will be sent. Allow only if that address is your own computer (localhost or 127.0.0.1) or a site you started the connection from. Redirects must be https or a loopback http address. Clients that redirect to a custom scheme (for example cursor://) work only when the server operator allows that scheme; otherwise use an API key below. An agent that asks for concierge:read without concierge:write gets read only access.

Scripts, CI and clients without OAuth sign in with a staff API key: ck_ plus 40 characters. It’s shown once, and only a hash is stored.

  • Dashboard: create a key in your settings (it calls POST /v1/api-keys { name }). List keys with GET /v1/api-keys (prefix only) and revoke with DELETE /v1/api-keys/:id.
  • CLI, local dev:
Terminal window
pnpm --filter mcp key:create
# or, explicitly:
pnpm --filter mcp key:create -- --email [email protected] --org org_... --name "Claude Code"

Every flag is optional; it defaults to the seeded demo user and their first organization. --quiet prints only the key.

A key belongs to one organization and acts as the person who created it, so replies are signed with their name. It stops working the moment it’s revoked or that person leaves the org. Anyone can revoke their own keys; owners and admins can revoke any key in the org.

Claude Code (with a key; drop the header to use OAuth instead):

Terminal window
claude mcp add --transport http concierge https://mcp.conciergesdk.com/mcp --header "Authorization: Bearer ck_..."

For local dev, use http://localhost:4100/mcp instead (start it with pnpm dev:mcp).

Cursor (.cursor/mcp.json) and other clients that take JSON config:

{
"mcpServers": {
"concierge": {
"url": "https://mcp.conciergesdk.com/mcp",
"headers": { "Authorization": "Bearer ck_..." }
}
}
}

Codex (~/.codex/config.toml):

[mcp_servers.concierge]
url = "https://mcp.conciergesdk.com/mcp"
http_headers = { Authorization = "Bearer ck_..." }

Windsurf (~/.codeium/windsurf/mcp_config.json):

{
"mcpServers": {
"concierge": {
"serverUrl": "https://mcp.conciergesdk.com/mcp",
"headers": { "Authorization": "Bearer ck_..." }
}
}
}

VS Code with GitHub Copilot (.vscode/mcp.json, agent mode):

{
"servers": {
"concierge": {
"type": "http",
"url": "https://mcp.conciergesdk.com/mcp",
"headers": { "Authorization": "Bearer ck_..." }
}
}
}

Gemini CLI (~/.gemini/settings.json):

{
"mcpServers": {
"concierge": {
"httpUrl": "https://mcp.conciergesdk.com/mcp",
"headers": { "Authorization": "Bearer ck_..." }
}
}
}

Zed (settings.json):

{
"context_servers": {
"concierge": {
"url": "https://mcp.conciergesdk.com/mcp",
"headers": { "Authorization": "Bearer ck_..." }
}
}
}

Any other MCP client: point it at https://mcp.conciergesdk.com/mcp as a Streamable HTTP (sometimes labeled “HTTP”) server with the header Authorization: Bearer ck_.... Clients that only launch local stdio servers can bridge with npx mcp-remote https://mcp.conciergesdk.com/mcp --header "Authorization: Bearer ck_...".

Then ask things like “triage my support inbox”.

Every tool returns a short text summary plus structured content. IDs from another organization behave exactly like missing IDs.

Tool What it does
list_apps Your apps with app keys, connected state and open conversation counts.
list_conversations Filter by status (open, snoozed, closed, all; default open), appId, priority, query (name, email, user id, message text) and limit.
get_conversation Messages (paged with before), the customer with metadata and breadcrumbs, devices and status.
reply Replies as you. The customer gets it live and by push, and the AI pauses on that thread. Optional status. Idempotent on clientId.
send_card A review card (store link) or an offer card (paywall id), with optional text.
update_conversation Set status, priority or aiState.
search_customers By name, email, user id, customer id or a metadata value.
get_customer Profile, devices and conversation summary.
get_app_stats Open, snoozed, closed, unread, AI resolved, median first response, customers and 7 day volume.
get_setup_instructions SDK install steps for ios, android or react-native, with your app key filled in.
verify_install Whether the first real message arrived, devices per platform, SDK versions and push readiness.
list_knowledge The AI agent’s knowledge base.
upsert_knowledge Adds or updates a knowledge article, matched by id, then by title. Takes the structured fields (feature, screenPath, steps, planRequired, knownIssues, relatedScreens, deepLinkId) and draft: true to leave it for review.
list_screens The feature map: screen ids and titles your app registered with registerScreen (never deep links).
list_knowledge_gaps Questions the AI couldn’t answer, most asked first.
import_conversations Imports past conversations from your previous support tool as history (externalId, customer userId, status, metadata, messages with role, body and createdAt). Idempotent by externalId, at most 100 conversations and 2,000 messages a call. Never triggers AI replies, push or emails. Owner or admin, Pro. See Switch.
export_customer_data Everything stored for one end user (by customerId, or appId and userId) as JSON, for a GDPR or CCPA access request. Owner or admin.
delete_customer_data Permanently deletes all data for one end user, photos included. Owner or admin, never with a read only token, and confirm must repeat the customerId (or userId).
list_incidents Version incidents: spikes of similar tickets from one app version, with counts, first and last seen, and the auto reply.
get_incident One incident with its newest tickets, OS and build.
set_incident_auto_reply The one reply affected users get (open conversations now, new matching tickets as they arrive), or null to stop. Pro.
resolve_incident Closes an incident; with fixedInVersion and notify every affected conversation hears it is fixed. dismiss for a false alarm.
  • triage (/mcp__concierge__triage in Claude Code): open conversations grouped by urgency, patterns across them, and drafted replies. Nothing is sent without your approval.
  • build-knowledge (/mcp__concierge__build-knowledge app_... in your app’s repo, optional focus): reads your screens, settings, paywall, flags, errors and strings, proposes missing registerScreen calls, shows the articles it plans, then writes them as drafts. See Knowledge autopilot.
  • fix-and-reply (/mcp__concierge__fix-and-reply cnv_...): finds the bug in your current repo from the report, breadcrumbs and device info, fixes and tests it, then replies and sets the status.

concierge://conversation/{id} is a Markdown transcript of a conversation. The listing shows the 50 most recent conversations, and ids autocomplete.

  • Requests from a browser Origin are refused unless it’s localhost or on your allow list. CLI agents send no origin and are fine.
  • Every request checks the key or token and the person’s org membership.
  • Anything a customer wrote (messages, names, metadata, breadcrumbs, tool results) reaches the agent inside <customer_message> or <customer_data> blocks, escaped, with a standing rule that it is data and never instructions. grant_promo, send_card, upsert_knowledge and call_client_tool are marked destructive, so clients ask before running them.
  • grant_promo follows your workspace comp policy: owners and admins only by default, at most 31 days, 20 grants a day and 2 per customer per 30 days, and an optional entitlement list. Change it under Offers, Limits.
  • Each person gets 120 MCP requests a minute, and at most 3 call_client_tool waits at once.
  • OAuth access tokens are short lived JWTs (one hour) issued only for this MCP server; refresh tokens last 30 days.