{"mcp_url":"https://mcp.character.app/mcp","resource_metadata_url":"https://mcp.character.app/.well-known/oauth-protected-resource/mcp","scopes":["email"],"profiles":[{"id":"full","title":"Full tool surface for the transport","url":"https://mcp.character.app/mcp?profile=full"},{"id":"creator","title":"Make stories and clips (default)","url":"https://mcp.character.app/mcp?profile=creator"},{"id":"showrunner","title":"Plan and run a Series","url":"https://mcp.character.app/mcp?profile=showrunner"},{"id":"writer","title":"Write Episodes against canon","url":"https://mcp.character.app/mcp?profile=writer"},{"id":"producer","title":"Render and review","url":"https://mcp.character.app/mcp?profile=producer"},{"id":"operator","title":"Direct fal + local film","url":"https://mcp.character.app/mcp?profile=operator"},{"id":"read_only","title":"Browse a Universe safely","url":"https://mcp.character.app/mcp?profile=read_only"}],"selected_profile":null,"clients":[{"id":"codex","label":"Codex","mechanism":"cli","snippet":"codex mcp add charactr --url https://mcp.character.app/mcp\ncodex mcp login charactr --scopes email","fileSnippet":"[mcp_servers.charactr]\nurl = \"https://mcp.character.app/mcp\"\ntool_timeout_sec = 120\n# headless: bearer_token_env_var = \"CHARACTR_TOKEN\"","fileHint":"~/.codex/config.toml","login":"codex mcp login charactr --scopes email","auth":"codex mcp add charactr --url <url> writes the config and immediately opens a browser, blocking on a localhost callback. Its default OAuth request asks for `openid profile email phone offline_access`; the platform now publishes an ES256 signing key, so `openid` is expected to work, but a consented `openid` exchange has not yet been witnessed — if `codex mcp add` fails at the token exchange, sign in with the scoped `codex mcp login charactr --scopes email` line instead.","headless":"bearer-header","notes":"A bearer token is a short-lived (~1h) Supabase access token."},{"id":"claude-code","label":"Claude Code","mechanism":"cli","snippet":"claude mcp add --transport http -s user charactr https://mcp.character.app/mcp","fileSnippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","fileHint":"~/.claude.json under \"mcpServers\"","login":"claude mcp login charactr","auth":"claude mcp login charactr — opens a browser. On a machine with no browser, claude mcp login charactr --no-browser prints the authorization URL and reads the pasted redirect back.","headless":"oauth-no-browser","notes":"A typeless { \"url\" } block is a configuration error in Claude Code — the \"type\": \"http\" field is required."},{"id":"claude-desktop","label":"Claude Desktop","mechanism":"ui","snippet":"Claude app → Settings → Connectors → Add custom connector → name it charactr → URL: https://mcp.character.app/mcp","auth":"OAuth consent inside the app — the config file has no remote-URL field.","headless":"browser-only","notes":"Same on claude.ai: Settings → Connectors → Add custom connector. A config-file MCP registration only covers local stdio servers here."},{"id":"cursor","label":"Cursor","mechanism":"deeplink","snippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"url\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","deeplink":"cursor://anysphere.cursor-deeplink/mcp/install?name=charactr&config=eyJ1cmwiOiJodHRwczovL21jcC5jaGFyYWN0ZXIuYXBwL21jcCJ9","fileHint":"~/.cursor/mcp.json","auth":"OAuth on first use — the client registers itself (DCR), no sign-up step.","headless":"bearer-header","notes":"Headless: add \"headers\": { \"Authorization\": \"Bearer $CHARACTR_TOKEN\" } to the same entry."},{"id":"devin","label":"Devin CLI","mechanism":"cli","snippet":"devin mcp add charactr -s user --transport http --scopes email https://mcp.character.app/mcp\ndevin mcp login charactr --scopes email","fileSnippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"url\": \"https://mcp.character.app/mcp\",\n      \"transport\": \"http\"\n    }\n  }\n}","fileHint":"~/.config/devin/mcp_config.json","login":"devin mcp login charactr --scopes email","auth":"devin mcp add writes the config and immediately opens the browser sign-in — its OAuth callback listens on the fixed port 8765, so the browser must run on the same machine.","headless":"bearer-header","notes":"Windsurf's Devin Local agent (the default for new tabs) reads this same Devin config — no separate Windsurf setup needed there. Headless/CI: \"headers\": { \"Authorization\": \"Bearer $CHARACTR_TOKEN\" } on the same entry, or .devin/mcp_config.local.json for one project."},{"id":"gemini","label":"Gemini CLI","mechanism":"config-file","snippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"httpUrl\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","fileHint":"~/.gemini/settings.json","auth":"Browser OAuth on first use — no browserless OAuth flow is documented.","headless":"bearer-header","notes":"The remote key is \"httpUrl\", not \"url\". Headless: \"headers\": { \"Authorization\": \"Bearer $CHARACTR_TOKEN\" } on the same entry. A workspace .gemini/settings.json overrides the user file."},{"id":"vscode","label":"VS Code","mechanism":"deeplink","snippet":"{\n  \"servers\": {\n    \"charactr\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","deeplink":"https://vscode.dev/redirect/mcp/install?name=charactr&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.character.app%2Fmcp%22%7D","fileHint":"User mcp.json — Command Palette → \"MCP: Open User Configuration\"","auth":"Browser OAuth on first connect.","headless":"bearer-header","notes":"The root key is \"servers\", not \"mcpServers\". Also works: code --add-mcp '{\"name\":\"charactr\",\"type\":\"http\",\"url\":\"https://mcp.character.app/mcp\"}'. Agent Host never forwards ${input:…} variables — use a literal \"headers\" bearer there."},{"id":"windsurf","label":"Windsurf","mechanism":"config-file","snippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"serverUrl\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","fileHint":"~/.codeium/windsurf/mcp_config.json","auth":"OAuth on first use.","headless":"bearer-header","notes":"This file configures the legacy Cascade agent only. New Windsurf tabs run the Devin Local agent, which reads the Devin CLI config — use the Devin CLI entry above for them."},{"id":"zed","label":"Zed","mechanism":"config-file","snippet":"{\n  \"context_servers\": {\n    \"charactr\": {\n      \"url\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","fileHint":"~/.config/zed/settings.json under \"context_servers\"","auth":"OAuth on first use.","headless":"browser-only","notes":"No verified static-header path for remote servers — plan on one browser sign-in."},{"id":"chatgpt","label":"ChatGPT","mechanism":"ui","snippet":"Settings → Connectors → Developer Mode → New app → URL: https://mcp.character.app/mcp → auth: OAuth","auth":"OAuth only — there is no bearer-header field, so a browser sign-in is mandatory.","headless":"browser-only","notes":"Needs ChatGPT developer mode. Refresh tokens keep the connection alive past access-token expiry."},{"id":"any-client","label":"Any other MCP client","mechanism":"config-file","snippet":"{\n  \"mcpServers\": {\n    \"charactr\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.character.app/mcp\"\n    }\n  }\n}","auth":"The client runs its own OAuth prompt and consent screen.","headless":"bearer-header","notes":"Any client that speaks streamable HTTP. If it accepts a static \"Authorization: Bearer …\" header, a fresh Supabase access token serves headless for about an hour."}],"headless_note":"OAuth 2.1 is the only door — Character App does not issue a long-lived API key yet. Clients that take a static Authorization bearer header can run headless with a fresh Supabase access token, but that token lives about an hour: fine for CI smoke checks, not a durable install. Claude Code has a true no-browser OAuth path (claude mcp login charactr --no-browser); every other harness needs one browser sign-in on the same machine the callback listens on."}