Developers
One key, ten actions, plain Markdown. The MCP server and REST API are the same product the app uses.
Carbon is built to be used by AI tools, so this is the whole product surface: an MCP server for AI clients and a REST API for scripts. Both work on one workspace of folders and Markdown documents, and both attribute every change to the connection that made it.
Get a key
In a workspace, open Connect AI tools, pick a tool (or "Scripts and the REST API"), and Carbon creates a connection and shows a key once. Keys look like carb_…. Tick Read-only if the connection should only read and search. Claude and ChatGPT connect with OAuth instead and never see a key.
Send the key as a bearer token on every request:
Authorization: Bearer carb_…
The MCP server
https://www.carbon.app/api/mcp
Streamable HTTP, stateless, JSON responses. Any MCP client that supports remote servers can use it; Claude Code, for example:
claude mcp add --transport http carbon https://www.carbon.app/api/mcp --header "Authorization: Bearer carb_…"
Every connection gets the same ten tools:
| Tool | Does |
|---|---|
carbon_overview | the workspace README, the full folder tree, and recent changes. Start here. |
carbon_list | folders and documents in a folder |
carbon_read | one or more documents, with their version |
carbon_search | full-text search with snippets |
carbon_write | create or replace a document; folders are created on demand |
carbon_edit | replace one exact passage |
carbon_append | add to the end of a document |
carbon_move | move or rename a document or folder |
carbon_delete | delete a document or folder (restorable by a person) |
carbon_history | list versions, or read an older one |
Paths look like projects/atlas/decisions.md; .md is added when you leave it off. carbon_write accepts the expected_version you read, and refuses a stale write, so two tools editing the same file cannot silently overwrite each other. On a read-only connection the five writing tools return an error that says so.
OAuth-capable clients discover the flow on their own: a 401 carries WWW-Authenticate pointing at /.well-known/oauth-protected-resource, dynamic registration is open, and PKCE is required.
The REST API
Base URL https://www.carbon.app/api/v1. JSON in and out; PUT also accepts a text/markdown body.
| Route | Does |
|---|---|
GET /overview | the same orientation as carbon_overview |
GET /tree | nested folders and documents |
GET /files | the root listing |
GET /files/{path} | a document (add ?raw=1 for plain Markdown with the version in X-Document-Version), or a folder listing (?recursive=1) |
PUT /files/{path} | create or replace: {content, message?, expected_version?} |
PATCH /files/{path} | {old_text, new_text, replace_all?, message?} or {append, message?} |
DELETE /files/{path} | delete a document or folder |
POST /move | {from, to} |
GET /search?q=&folder=&limit= | search |
GET /history?path=&version= | versions, or one version's content |
For example:
curl https://www.carbon.app/api/v1/files/README.md?raw=1 -H "Authorization: Bearer carb_…"
curl -X PUT https://www.carbon.app/api/v1/files/notes/today.md \
-H "Authorization: Bearer carb_…" -H "Content-Type: application/json" \
-d '{"content":"# Today\n\nShipped the thing.","message":"daily note"}'
Errors come back as {error, kind}: 400 invalid, 402 plan limit, 403 read-only, 404 not found, 409 conflict or stale version, 429 rate limited (with Retry-After).
Limits
Each connection gets 120 requests a minute and 10,000 a day on the free plan; every response carries X-RateLimit-* headers. Documents are plain text up to 1 MB. Everything a workspace holds can be exported as a zip from Settings.