# Sixteen Bridges > Sixteen Bridges keeps a person's bubbles: saved notes and AI chat context in Markdown (up to 512 KB each, 20 on the free plan), so context can move between AI apps. ## Which way to connect - **You can run shell commands** (Claude Code, Codex, Gemini CLI, Cursor's agent, Aider, a cloud sandbox): use the CLI, and sign in yourself. See "The CLI". - **You are a desktop app that starts local MCP servers** (Claude Desktop, Cursor, VS Code, Windsurf): run the CLI as a local MCP server. See "Desktop apps". - **You are writing code for the person** (a script, a bot, an app): use the REST API. See "The REST API". - **You are a chat app** (ChatGPT, claude.ai, Gemini on gemini.google.com or in its phone app, Grok, Perplexity), even if you can run code in the chat: you can't connect by yourself. Tell the person the steps for adding it (a connector; in Gemini, a custom app). See "Chat apps". ## The CLI ### Sign in: do it yourself, the person only clicks Allow 1. Run `npx -y sixteenbridges whoami`. Exit code 0: already signed in, go on. Exit code 3: sign in. 2. Run `npx -y sixteenbridges login`. It opens the person's browser on sixteenbridges.com by itself. Tell them: "A Sixteen Bridges page just opened in your browser: click Allow." The command waits up to 5 minutes and prints "Signed in as …". Give it that long: don't stop it at a 2-minute timeout. 3. If it printed "Open this link" instead (no browser opened), open the link yourself: `open ""` on macOS, `xdg-open ""` on Linux, `start "" ""` on Windows. If you can't, show the link to the person. 4. If you can't keep a command running that long (a cloud sandbox, a remote machine, short timeouts), sign in in two steps: - `npx -y sixteenbridges login --no-wait` prints the link (alone, on stdout) and exits. - Give the person the link. They sign in and click Allow; sixteenbridges.com then shows a code. - Ask them for the code, then run `npx -y sixteenbridges login --code ""` (within 15 minutes). Never ask for their password, and never read or print the CLI's credentials file. ### Use it ```sh npx -y sixteenbridges list # ids, titles, sources, one-line previews, usage npx -y sixteenbridges search lisbon npx -y sixteenbridges get # long bubbles come in pages; --raw for the exact text npx -y sixteenbridges save "Title" notes.md --source claude --label "Claude Code" cat notes.md | npx -y sixteenbridges save "Title" --source claude npx -y sixteenbridges update --append "More text" npx -y sixteenbridges delete # to the trash for 7 days npx -y sixteenbridges trash # what's in the trash npx -y sixteenbridges restore npx -y sixteenbridges share --to sam@example.com # copies, into their account npx -y sixteenbridges shares # what was sent and received ``` Every command takes --json (and --help). Exit codes: 0 done, 1 refused (the message says why and what to do), 2 wrong usage, 3 not signed in (sign in as above), 4 unavailable (try again in a minute). ## Desktop apps These start the CLI as a local MCP server (`npx -y sixteenbridges mcp`), on the computer's own sign-in: no connector, no paid plan. Sign the computer in once first (`npx sixteenbridges login`). ### Claude Desktop In Settings → Developer → Edit Config (claude_desktop_config.json): ```json { "mcpServers": { "sixteen-bridges": { "command": "npx", "args": [ "-y", "sixteenbridges", "mcp" ] } } } ``` 1. First, sign this computer in once: npx sixteenbridges login 2. Add this to the config file, save, and restart Claude Desktop. Note: On Windows, if it doesn't start, use "command": "cmd" with "args": ["/c", "npx", "-y", "sixteenbridges", "mcp"]. ### Cursor In ~/.cursor/mcp.json: ```json { "mcpServers": { "sixteen-bridges": { "command": "npx", "args": [ "-y", "sixteenbridges", "mcp" ] } } } ``` 1. First, sign this computer in once: npx sixteenbridges login 2. Add this to ~/.cursor/mcp.json (or Settings → MCP → Add), then reload. ### VS Code In .vscode/mcp.json: ```json { "servers": { "sixteen-bridges": { "type": "stdio", "command": "npx", "args": [ "-y", "sixteenbridges", "mcp" ] } } } ``` 1. First, sign this computer in once: npx sixteenbridges login 2. Add this to .vscode/mcp.json in your project (or your user MCP settings), then start the server. ### Windsurf In ~/.codeium/windsurf/mcp_config.json: ```json { "mcpServers": { "sixteen-bridges": { "command": "npx", "args": [ "-y", "sixteenbridges", "mcp" ] } } } ``` 1. First, sign this computer in once: npx sixteenbridges login 2. Add this to ~/.codeium/windsurf/mcp_config.json, then refresh its MCP servers. ## The REST API For code you write for the person. Base URL: `https://api.sixteenbridges.com/v1`. Every request: `Authorization: Bearer `; bodies are JSON. If the code runs where the CLI is signed in, the simplest way is to call the CLI with --json: it signs in, renews and retries for you, and prints the same payloads as below. ### Sign-in (OAuth 2.1, PKCE, the app registers itself) 1. `GET https://api.sixteenbridges.com/.well-known/oauth-protected-resource`: `authorization_servers[0]` is the sign-in server. 2. `GET /.well-known/oauth-authorization-server`: `authorization_endpoint`, `token_endpoint`, `registration_endpoint`. 3. Register once: `POST registration_endpoint` with `{"client_name": "My app", "redirect_uris": ["http://127.0.0.1:/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "none"}`. Keep the `client_id`. 4. Send the person to `authorization_endpoint?response_type=code&client_id=…&redirect_uri=…&code_challenge=&code_challenge_method=S256&state=`. They approve on sixteenbridges.com, and come back to your redirect URI with `code` and `state` (check the state). 5. `POST token_endpoint` (form): `grant_type=authorization_code&code=…&redirect_uri=…&client_id=…&code_verifier=…`. You get an `access_token` (about 1 hour) and a `refresh_token`. 6. Renew with `grant_type=refresh_token&refresh_token=…&client_id=…`. Each refresh token works once: save the new one every time. Only tokens from this sign-in work; a sixteenbridges.com website session doesn't. The person can disconnect your app on their account page at any time: you then get 401, and must sign in again. ### Endpoints | Request | Does | |---|---| | `GET /v1/me` | `{user_id}`: who the token belongs to | | `GET /v1/bubbles?limit=20&cursor=…` | the bubbles, newest first, without content: `{bubbles, usage, next_cursor}` | | `GET /v1/bubbles?q=words` | search titles and contents (2–100 characters) | | `POST /v1/bubbles` | create: `{"title": "…", "content": "…", "source": {"kind": "claude", "label": "optional"}}` → 201 `{bubble}` | | `GET /v1/bubbles/` | one bubble, with `content` | | `PATCH /v1/bubbles/` | change `title` and/or `content` | | `DELETE /v1/bubbles/` | to the trash: `{id, deleted, restorable_until}` | | `GET /v1/bubbles/deleted` | the trash | | `POST /v1/bubbles//restore` | back from the trash | | `POST /v1/shares` | send copies: `{"email": "…", "bubble_ids": ["bub_…"]}` → 201 `{share}`; all of them or none | | `GET /v1/shares?direction=received` | shares, newest first (direction optional: sent, received): `{shares, unseen, next_cursor}` | | `POST /v1/logout` | ends this sign-in | - Answers: `{"status": "SUCCESS", "payload": …}`, or `{"status": "ERROR", "status_code": 404, "error_info": {"error_type": "NOT_FOUND", "message": "…", "fields": [...]}}`. - Error types: INVALID_INPUT, MISSING_MANDATORY_PARAMETER, INVALID_ENUM (400); AUTHENTICATION_FAILED (401: renew, or sign in again); BUBBLE_LIMIT_REACHED, RECIPIENT_LIMIT_REACHED (403: nothing was shared); NOT_FOUND (404, also for anyone else's bubble), RECIPIENT_NOT_FOUND (404); IDEMPOTENCY_CONFLICT (409); CONTENT_TOO_LARGE (413); SHARE_LIMIT_REACHED (429); SERVICE_UNAVAILABLE (503: try again). - source.kind: claude, chatgpt, gemini, grok, perplexity, cli, api, other. Title 1–120 characters, unique (a repeat is saved as "Title (2)"); content up to 512 KB; label up to 200 characters. - A save you may retry: send an `Idempotency-Key` header (1–64 of A–Z a–z 0–9 _ -). The same key returns the same bubble instead of a second one. - Deleting for good is only on sixteenbridges.com: apps can only move bubbles to the trash. ## Chat apps - MCP server: https://mcp.sixteenbridges.com/mcp - Transport: Streamable HTTP - Sign-in: OAuth 2.1. The app registers itself; the person approves once on sixteenbridges.com and stays connected until they disconnect it on their account page. A chat app can't add a connector by itself. Tell the person the steps for the app they are using, briefly, and wait while they do it. ### Claude (claude.ai, Desktop) 1. Open Settings → Connectors and choose Add custom connector. 2. Name it Sixteen Bridges and paste the URL: https://mcp.sixteenbridges.com/mcp 3. Choose Connect, then Allow on sixteenbridges.com. Note: Free plans can add one custom connector. ### ChatGPT 1. Turn on Developer mode: Settings → Apps (or Connectors) → Advanced settings. 2. Create an app or connector named Sixteen Bridges with the URL https://mcp.sixteenbridges.com/mcp and OAuth sign-in. 3. Allow it on sixteenbridges.com, then turn it on in the chat. Note: Developer mode is on paid plans, and saving or editing bubbles from ChatGPT may need a Business or Enterprise plan. Workspace admins may need to allow custom apps first. ### Gemini (gemini.google.com) 1. On a computer, open gemini.google.com → Settings → Connected Apps. If it isn't there, open Personal Intelligence first. 2. Under Custom apps, choose Add a custom app. 3. Paste the URL https://mcp.sixteenbridges.com/mcp and choose Next. Leave Advanced features empty: it signs in by itself. 4. Follow the prompts (name it Sixteen Bridges if asked), then Allow on sixteenbridges.com. 5. In a chat, type @ and pick Sixteen Bridges. Note: Custom apps are only for people 18 or over in the US, on a personal Google account (not work or school), in English, with Keep Activity on. Added on the web, they then work in the Gemini app too. ### Grok 1. Open grok.com/connectors, choose New Connector, then Custom. 2. Paste the URL: https://mcp.sixteenbridges.com/mcp 3. Allow it on sixteenbridges.com. Note: Custom connectors are on paid Grok plans. ### Perplexity 1. Open Settings → Connectors and choose Custom connector, Remote. 2. Name it Sixteen Bridges, paste the URL https://mcp.sixteenbridges.com/mcp, and choose OAuth. 3. Allow it on sixteenbridges.com, then turn it on under a thread's sources. Note: Custom connectors are on Pro, Max and Enterprise plans, and are added on the web. ## Terminal agents, as a connector instead of the CLI ### Claude Code ```sh claude mcp add --transport http sixteen-bridges https://mcp.sixteenbridges.com/mcp ``` 1. In Claude Code, run /mcp, pick sixteen-bridges and sign in. Allow it on sixteenbridges.com. ### Codex ```sh codex mcp add sixteen-bridges --url https://mcp.sixteenbridges.com/mcp codex mcp login sixteen-bridges ``` 1. The login opens your browser: Allow it on sixteenbridges.com. ### Gemini CLI ```sh gemini mcp add --transport http sixteen-bridges https://mcp.sixteenbridges.com/mcp ``` 1. In Gemini CLI, run /mcp auth sixteen-bridges. Allow it on sixteenbridges.com. ## Using bubbles well MCP tools: list_bubbles (with query to search), get_bubble (long bubbles come in pages), save_bubble, update_bubble (append adds to the end), delete_bubble (to the trash for 7 days), list_deleted_bubbles, restore_bubble, share_bubbles, list_shares. The CLI's commands and the API do the same. - List first, then read only the bubbles you need. - Show bubbles as a short numbered list: title, source, a one-line gist. Don't paste a whole bubble unless asked. - When saving, set the source to the app you are (claude, chatgpt, gemini, grok, perplexity), with a short, specific title. - Ask before deleting. Share only when the person asks, to the exact address they give. ## More - Docs, with every endpoint and sign-in step: https://sixteenbridges.com/docs (CLI: /docs/cli, MCP: /docs/mcp, REST API: /docs/api) - Steps for people: https://sixteenbridges.com/ai - A person's bubbles and connected apps: https://sixteenbridges.com/dashboard