io.github.vish288/mcp-coda

Registre officiel Productivité

Coda MCP server (MCP 2026-07-28): docs, pages, tables, rows, automations; writes or read-only

Installation

Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).

PYPI package mcp-coda
Claude Code
claude mcp add mcp-coda -e 'CODA_API_TOKEN=<your coda_api_token>' -e 'CODA_READ_ONLY=<CODA_READ_ONLY>' -e 'MCP_READ_ONLY=<MCP_READ_ONLY>' -e 'CODA_HTTP_BEARER_TOKEN=<your coda_http_bearer_token>' -- uvx mcp-coda==0.12.3
Configuration JSON (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "mcp-coda": {
            "command": "uvx",
            "args": [
                "mcp-coda==0.12.3"
            ],
            "env": {
                "CODA_API_TOKEN": "<your coda_api_token>",
                "CODA_READ_ONLY": "<CODA_READ_ONLY>",
                "MCP_READ_ONLY": "<MCP_READ_ONLY>",
                "CODA_HTTP_BEARER_TOKEN": "<your coda_http_bearer_token>"
            }
        }
    }
}

Variables d'environnement

  • CODA_API_TOKEN obligatoire secret Coda API token (also accepts CODA_TOKEN or CODA_PAT)
  • CODA_READ_ONLY Alias for MCP_READ_ONLY. Any value other than false/0/no/off/empty locks the server read-only; --read-only can only raise the lock
  • MCP_READ_ONLY Locks the server read-only: write tools and write-workflow prompts are not listed and nothing lifts the lock at runtime. Shared name across the mcp-* servers; set it in the deployer's env
  • CODA_HTTP_BEARER_TOKEN secret Bearer token (min 16 chars) required to bind an HTTP transport to a non-loopback host; clients send it as 'Authorization: Bearer <token>'

Documentation

Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.

Sommaire
  1. mcp-coda
  2. 1-Click Installation
  3. Configuration
  4. Compatibility
  5. Protocol support
  6. Tools (54)
  7. Resources (12)
  8. Prompts (5)
  9. Usage Examples
  10. Security Considerations
  11. Upgrading to 0.9.0
  12. Rate Limits & Permissions
  13. CLI & Transport Options
  14. Docker
  15. FAQ
  16. Related MCP Servers
  17. Development
  18. License

mcp-coda

Install: uvx mcp-coda | PyPI | MCP Registry | Changelog

uvx mcp-coda                          # with writes
MCP_READ_ONLY=true uvx mcp-coda       # locked read-only: write tools are not listed

mcp-coda is a Model Context Protocol (MCP) server for Coda. It lets an AI assistant read and write Coda docs, pages, tables, and rows through the Coda API. It also runs formulas, manages permissions and folders, publishes docs, and triggers automations. The server exposes 54 tools, 12 resources, and 5 prompts. It supports the MCP 2026-07-28 specification (often called MCP 2.0) and stays compatible with 2025-11-25 clients. It works with Claude Desktop, Claude Code, Cursor, Windsurf, VS Code Copilot, and any MCP-compatible client. Runs in one of two modes: with writes, or locked read-only (MCP_READ_ONLY=true) so the 20 write tools are never offered to the model.

mcp-coda uses FastMCP, httpx, and Pydantic.

1-Click Installation

Tip: For other AI assistants (Claude Code, Windsurf, IntelliJ, Gemini CLI), visit the Coda MCP Installation Gateway.

Manual Setup Guides (Click to expand)

Prerequisite: Install uv first (required for all uvx install flows). Install uv.

Claude Code
# with writes
claude mcp add coda -e CODA_API_TOKEN=your-token-here -- uvx mcp-coda
# locked read-only
claude mcp add coda -e MCP_READ_ONLY=true -e CODA_API_TOKEN=your-token-here -- uvx mcp-coda
Windsurf & IntelliJ

Windsurf: Add to ~/.codeium/windsurf/mcp_config.json IntelliJ: Add to Settings | Tools | MCP Servers

Note: The actual server config starts at coda inside the mcpServers object. Remove MCP_READ_ONLY to allow writes.

{
  "mcpServers": {
    "coda": {
      "command": "uvx",
      "args": ["mcp-coda"],
      "env": {
        "CODA_API_TOKEN": "your-token-here",
        "MCP_READ_ONLY": "true"
      }
    }
  }
}
Gemini CLI
# with writes
gemini mcp add -s user -e CODA_API_TOKEN=your-token-here coda uvx mcp-coda
# locked read-only
gemini mcp add -s user -e MCP_READ_ONLY=true -e CODA_API_TOKEN=your-token-here coda uvx mcp-coda
VS Code

Add to .vscode/mcp.json:

{
  "servers": {
    "coda": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-coda"],
      "env": { "CODA_API_TOKEN": "your-token-here", "MCP_READ_ONLY": "true" }
    }
  }
}
Codex
# with writes
codex mcp add coda --env CODA_API_TOKEN=your-token-here -- uvx mcp-coda
# locked read-only
codex mcp add coda --env MCP_READ_ONLY=true --env CODA_API_TOKEN=your-token-here -- uvx mcp-coda
pip / uv
uv pip install mcp-coda

Drop MCP_READ_ONLY to allow writes. On a shared or hosted server put it in the deployer's env, not the client config.

Configuration

VariableRequiredDefaultDescription
CODA_API_TOKENYes-Coda API token (get one here)
MCP_READ_ONLYNofalseShared name across the mcp-* servers. Any value other than false/0/no/off/empty locks the server read-only: the 20 write tools and write-workflow prompts are not listed, and nothing can turn it back off at runtime
CODA_READ_ONLYNofalsePer-server alias for MCP_READ_ONLY; either one locks the server read-only. --read-only can only raise the lock
CODA_BASE_URLNohttps://coda.io/apis/v1API base URL
CODA_TIMEOUTNo30Request timeout in seconds
CODA_HTTP_BEARER_TOKENNo-Required to bind an HTTP transport to a non-loopback host. Clients send Authorization: Bearer <token>. Minimum 16 characters
Supported Token Types

The server checks these environment variables in order — first match wins:

  1. CODA_API_TOKEN
  2. CODA_TOKEN
  3. CODA_PAT

Generate tokens at coda.io/account#apiSettings. Tokens grant access to all docs accessible by the token owner. Tokens have no scope restrictions. Coda's sharing settings control doc-level access.

Compatibility

ClientSupportedInstall Method
Claude DesktopYesclaude_desktop_config.json
Claude CodeYesclaude mcp add
CursorYesOne-click deeplink or .cursor/mcp.json
VS Code CopilotYesOne-click deeplink or .vscode/mcp.json
WindsurfYes~/.codeium/windsurf/mcp_config.json
Any MCP clientYesstdio or HTTP transport

Protocol support

mcp-coda implements the Model Context Protocol 2026-07-28 specification, often called MCP 2.0. It also stays compatible with 2025-11-25 clients. A FastMCP client pinned to 2026-07-28 and a legacy client both list all tools and reach the Coda API over stdio. The companion code PR adds a regression test that checks tools/list with an in-memory client pinned to 2026-07-28.

  • Spec version: MCP 2026-07-28 (MCP 2.0), backward compatible with 2025-11-25.
  • Built on: FastMCP 4.x and the MCP Python SDK 2.x.
  • Transports: stdio (default) and streamable-http (recommended for remote). sse (HTTP+SSE) still works, but the 2026-07-28 specification deprecates it, so the server prints a warning.
  • Capabilities: tools, resources, and prompts. The server uses no Roots, Sampling, Logging, elicitation, or resource subscriptions, so the 2026-07-28 deprecations do not affect it.
Error results

An expected failure — a 404, a 401, a rate limit, or a write that reaches the read-only guard — comes back as a tool result with isError: true rather than a value the caller must inspect for an error key. (In locked read-only mode the write tools are hidden, so calling one returns an Unknown tool error; the error envelope below is the guard's own response, returned only when a client reaches a write tool anyway.) The result body is the text content: a JSON object with error, an actionable hint, and, where relevant, status_code, body, and retry_after. The result carries no structuredContent — the TypeScript MCP SDK validates structuredContent against the tool's output schema even when isError is true, so an error payload there would make strict clients reject the whole result. Unexpected exceptions (a bug in a tool) are also isError: true, their text is TypeName: message, and the server logs them with a traceback.

A successful result carries the Coda JSON object as structuredContent beside the pretty-printed text, and tools advertise no outputSchema: payloads pass the upstream fields through untyped, so strict clients validate nothing and receive the object directly rather than a double-encoded {"result": "<json>"} wrapper. A typed schema is opt-in per tool via @mcp.tool(output_schema=…).

Tools (54)

CategoryCountTools
Account3whoami, resolve browser link, mutation status
Docs5list, get, create, update, delete
Pages9list, get, create, update, delete, get content, delete content, export, export status
Tables4list tables, get table, list columns, get column
Rows7list, get, insert/upsert, update, delete, bulk delete, push button
Permissions6sharing metadata, list, add, delete, search principals, ACL settings
Folders5list, get, create, update, delete
Misc8formulas (list, get), controls (list, get), publishing (list categories, publish, unpublish), trigger automation
Analytics7doc analytics, doc summary, page analytics, pack analytics, pack summary, formula analytics, analytics updated

Full tool reference (click to expand)

Account
ToolDescription
coda_whoamiGet current user info
coda_resolve_browser_linkConvert browser URL to API IDs
coda_get_mutation_statusCheck async write status
Docs
ToolDescription
coda_list_docsList accessible docs
coda_get_docGet doc metadata
coda_create_docCreate a new doc
coda_update_docUpdate doc title/icon
coda_delete_docDelete a doc
Pages
ToolDescription
coda_list_pagesList pages in a doc
coda_get_pageGet page metadata
coda_create_pageCreate a page
coda_update_pageUpdate page name/content
coda_delete_pageDelete a page
coda_get_page_contentRead page content
coda_delete_page_contentClear page content
coda_export_pageExport page as HTML or markdown
coda_get_export_statusPoll an export started by coda_export_page
Tables
ToolDescription
coda_list_tablesList tables and views
coda_get_tableGet table metadata
coda_list_columnsList columns in a table
coda_get_columnGet column metadata
Rows
ToolDescription
coda_list_rowsList and filter rows
coda_get_rowGet a single row
coda_insert_rowsInsert or upsert rows
coda_update_rowUpdate a row
coda_delete_rowDelete a row
coda_delete_rowsBulk delete rows by filter
coda_push_buttonPush a button column value
Formulas
ToolDescription
coda_list_formulasList named formulas
coda_get_formulaGet formula value
Controls
ToolDescription
coda_list_controlsList controls
coda_get_controlGet control value
Permissions
ToolDescription
coda_get_sharing_metadataGet sharing config
coda_list_permissionsList ACL entries
coda_add_permissionGrant access
coda_delete_permissionRevoke access
coda_search_principalsSearch users/groups
coda_get_acl_settingsGet ACL settings
Publishing
ToolDescription
coda_list_categoriesList publishing categories
coda_publish_docPublish a doc
coda_unpublish_docUnpublish a doc
Folders
ToolDescription
coda_list_foldersList folders
coda_get_folderGet folder details
coda_create_folderCreate a folder
coda_update_folderRename a folder
coda_delete_folderDelete a folder
Automations
ToolDescription
coda_trigger_automationTrigger an automation rule
Analytics
ToolDescription
coda_list_doc_analyticsDoc usage metrics
coda_get_doc_analytics_summaryAggregated doc metrics
coda_list_page_analyticsPage usage metrics
coda_list_pack_analyticsPack usage metrics
coda_get_pack_analytics_summaryAggregated pack metrics
coda_list_pack_formula_analyticsFormula-level metrics
coda_get_analytics_updatedAnalytics freshness timestamp

Resources (12)

The server exposes MCP resources that provide ambient context and do not consume tool calls.

Data Resources (live API)
URINameDescription
coda://docsCoda DocsList of docs accessible to the current API token
coda://docs/{doc_id}/schemaCoda Doc SchemaTable and column definitions for a doc
Rules (static knowledge)
URINameDescription
resource://rules/coda-doc-structureCoda Doc StructureDoc/page hierarchy, page types, naming, when to split docs vs folders
resource://rules/coda-table-designCoda Table DesignColumn types, relations, display columns, row limits, table vs view
resource://rules/coda-permissionsCoda Permission ModelDoc-level vs page-level locking, ACL, domain sharing, principal types
resource://rules/coda-automationsCoda Automation PatternsWebhooks, button triggers, rate limits, payload design, idempotency
resource://rules/coda-api-patternsCoda API Best PracticesRate limits, pagination, async mutations, error handling, retry
Guides (how-to)
URINameDescription
resource://guides/row-operationsRow Operations GuideInsert vs upsert, bulk ops, key columns, cell formats, delete strategies
resource://guides/page-contentPage Content GuideHTML vs markdown, insert modes, export workflows
resource://guides/formula-controlsFormulas & Controls GuideNamed formulas, control types, reading values
resource://guides/publishing-analyticsPublishing & Analytics GuidePublishing categories, gallery settings, analytics date filtering
resource://guides/folder-organizationFolder Organization GuideFolder CRUD, doc-folder relationships, hierarchy, bulk organization

Prompts (5)

The server provides MCP prompts — reusable task templates that clients can invoke.

PromptParametersDescription
analyze_doc_structuredoc_idAnalyze a doc's page hierarchy, table layout, and organization
design_table_schemadescriptionDesign a table schema from a natural language description
migrate_spreadsheetdoc_id, source_formatGuide for migrating CSV/Excel/Sheets data into Coda
setup_automationdoc_id, trigger_typeSet up a webhook/button/time automation with error handling
audit_permissionsdoc_idAudit sharing and permissions, suggest tightening

Usage Examples

Docs & Pages
"List all my Coda docs"
→ coda_list_docs(is_owner=True)

"Get the content of page 'Sprint Planning' in doc d1"
→ coda_list_pages(doc_id="d1") → find page ID
→ coda_get_page_content(doc_id="d1", page_id_or_name="canvas-abc")

"Create a new doc from a template"
→ coda_create_doc(title="Q1 Planning", source_doc="template-doc-id")
Tables & Rows
"List all tables in doc d1"
→ coda_list_tables(doc_id="d1")

"Find rows where Status is 'Done'"
→ coda_list_rows(doc_id="d1", table_id_or_name="Tasks", query="Done")

"Insert a new row into the Tasks table"
→ coda_insert_rows(doc_id="d1", table_id_or_name="Tasks", rows=[{"cells": [{"column": "Name", "value": "New task"}]}])

"Update a row's status"
→ coda_update_row(doc_id="d1", table_id_or_name="Tasks", row_id_or_name="i-abc", row={"cells": [{"column": "Status", "value": "In Progress"}]})
Formulas & Controls
"Get the value of the TotalBudget formula"
→ coda_get_formula(doc_id="d1", formula_id_or_name="TotalBudget")

"Check the current value of the DateFilter control"
→ coda_get_control(doc_id="d1", control_id_or_name="DateFilter")
Permissions & Sharing
"Share a doc with a teammate"
→ coda_add_permission(doc_id="d1", access="write", principal_email="alice@example.com")

"List who has access to a doc"
→ coda_list_permissions(doc_id="d1")

Security Considerations

  • Token scope: Coda API tokens grant access to all docs the token owner can access. Use a dedicated service account for production deployments to limit exposure.
  • Read-only mode: Set MCP_READ_ONLY=true (or CODA_READ_ONLY=true) in the launch you control and the server starts locked: the 20 write tools and the write-workflow prompts are not listed, a call to one returns "Unknown tool", and the guard refuses any write that still reaches it. Nothing lifts the lock at runtime — not a false from another source, not a .env file, not tool arguments; any value other than false/0/no/off/empty locks, and --read-only can only raise it. The lock is only as strong as the launch: set it where users cannot edit it (a managed MCP config such as Claude Code managed-mcp.json, a container, k8s or systemd env, or a hosted HTTP deployment). A user who starts the server themselves controls its environment. A Coda token has no scopes, so this lock is the only read-only control.
  • MCP tool annotations: Each tool declares readOnlyHint, destructiveHint, and idempotentHint for client-side permission prompts.
  • No credential storage: The server does not persist tokens. It reads credentials from environment variables at startup.
  • HTTP transport auth: Host/Origin protection is not authentication. Binding an HTTP transport to a non-loopback host requires CODA_HTTP_BEARER_TOKEN (min 16 chars); clients send Authorization: Bearer <token> and anything else gets a 401. Without it the server refuses to start on a non-loopback host.

Upgrading to 0.9.0

Two defaults changed. Both are breaking for callers that relied on the old behaviour:

  • coda_publish_doc no longer lists docs in the public gallery by default. discoverable now defaults to False — publishing alone makes a doc reachable by URL; pass discoverable=True to list it in the Coda gallery. mode is now restricted to view, play, or edit.
  • An HTTP transport on a non-loopback host now requires a bearer token. uvx mcp-coda --transport streamable-http --host 0.0.0.0 (or any non-loopback host) exits with an error unless CODA_HTTP_BEARER_TOKEN (min 16 chars) is set; clients then send Authorization: Bearer <token>. Binding to 127.0.0.1 is unchanged.

Rate Limits & Permissions

Rate Limits

Coda enforces per-token rate limits (varies by plan). When Coda rate-limits a request, the tool returns a 429 error with retry_after seconds. The client retries a 429 once when its Retry-After is ≤ 5s (GET only, with jitter, also covering 502/503/504); otherwise it surfaces retry_after without retrying — wait that many seconds, then retry. Writes are never retried. Most paginated endpoints default to 50 results per page (coda_list_docs 25, coda_list_columns 100). Use limit to adjust.

Async Mutations

Coda processes write operations (insert, update, delete rows) asynchronously. Tools return a requestId. Check it with coda_get_mutation_status to confirm completion.

Required Permissions
OperationMinimum Coda Doc Role
List docs, read pages, tables, rows, formulas, controlsViewer
Read permissions, analyticsViewer (doc owner for analytics)
Create/update pages, insert/update/delete rowsEditor
Create/delete docs, manage foldersEditor (or doc owner)
Add/remove permissions, publish/unpublishDoc Owner
Trigger automationsEditor
Access Control
LayerMechanism
Server-levelCODA_READ_ONLY=true / MCP_READ_ONLY=true hides every write tool (deployer-owned launch required)
MCP annotationsreadOnlyHint, destructiveHint, idempotentHint for client-side prompts
Coda tokenDoc-level access enforced by Coda's sharing settings

CLI & Transport Options

# Default: stdio transport (for MCP clients)
uvx mcp-coda

# HTTP transport (SSE or streamable-http)
uvx mcp-coda --transport sse --host 127.0.0.1 --port 8000
uvx mcp-coda --transport streamable-http --port 9000

# Binding to a non-loopback host requires a bearer token
CODA_HTTP_BEARER_TOKEN=$(openssl rand -hex 32) \
  uvx mcp-coda --transport streamable-http --host 0.0.0.0 --port 9000
# Clients authenticate with the token:
#   curl -H "Authorization: Bearer $CODA_HTTP_BEARER_TOKEN" http://host:9000/mcp

# Config comes from env vars
CODA_API_TOKEN=your-token uvx mcp-coda --read-only

--coda-token still works but is deprecated and hidden from --help: it exposes the token to ps and shell history. Use CODA_API_TOKEN.

The server loads .env files from the working directory automatically via python-dotenv.

Docker

The image is a minimal, non-root python:3.13-slim build. The image defaults to locked read-only (MCP_READ_ONLY=true); pass -e MCP_READ_ONLY=false to allow writes.

docker build -t mcp-coda .

# stdio (default), locked read-only
docker run -i --rm -e CODA_API_TOKEN=your-token mcp-coda

# HTTP transport on a non-loopback host requires a bearer token (min 16 chars);
# clients then send Authorization: Bearer <token>
BEARER=$(openssl rand -hex 32)
docker run --rm -p 9000:9000 \
  -e CODA_API_TOKEN=your-token \
  -e CODA_HTTP_BEARER_TOKEN="$BEARER" \
  mcp-coda --transport streamable-http --host 0.0.0.0 --port 9000

FAQ

Does mcp-coda support MCP 2.0 (the 2026-07-28 spec)?

Yes. mcp-coda implements the MCP 2026-07-28 specification, commonly called MCP 2.0. It also works with 2025-11-25 clients.

Which transports does mcp-coda support?

The server supports stdio (the default) and streamable-http. It also supports sse, but the 2026-07-28 specification deprecates it. Prefer streamable-http for remote connections.

Can I run mcp-coda read-only so the assistant cannot change anything?

Yes. Start it with MCP_READ_ONLY=true (or CODA_READ_ONLY=true). The 20 write tools and the write-workflow prompts are then not listed at all, so the model never sees them; a call to one returns "Unknown tool", and nothing can turn writes back on while the process runs. Set it in a launch you control — a managed MCP config, a container or systemd env, or a hosted deployment — because a user who starts the server themselves can start it without the variable. A Coda token has no scopes, so this lock is the only read-only control.

What token scopes does mcp-coda need?

Coda tokens have no scopes. A token reaches every doc its owner can reach. Coda's sharing settings control doc-level access. Use a dedicated service account to limit exposure.

Does mcp-coda work with self-hosted Coda?

Coda is a hosted service, so there is no self-hosted deployment. Set CODA_BASE_URL only to target a proxy or a non-default API base.

Which clients work with mcp-coda?

mcp-coda works with Claude Desktop, Claude Code, Cursor, Windsurf, VS Code Copilot, and any MCP-compatible client over stdio or HTTP.

How many tools, resources, and prompts does it provide?

mcp-coda provides 54 tools, 12 resources, and 5 prompts. They cover docs, pages, tables, rows, formulas, controls, permissions, folders, publishing, automations, and analytics.

  • mcp-gitlab — GitLab integration (83 tools, 7 resources, 6 prompts)
  • mcp-atlassian-extended — Jira + Confluence integration (22 tools, 15 resources, 5 prompts)
  • mcp-argocd — Argo CD integration (37 tools, 7 resources, 7 prompts)

Development

git clone https://github.com/vish288/mcp-coda.git
cd mcp-coda
uv sync --all-extras

uv run pytest --cov
uv run ruff check .
uv run ruff format --check .

License

MIT

Questions fréquentes

Qu'est-ce que io.github.vish288/mcp-coda ?

Coda MCP server (MCP 2026-07-28): docs, pages, tables, rows, automations; writes or read-only

Comment installer io.github.vish288/mcp-coda ?

Il s'exécute sur votre machine. Dans Claude Code : claude mcp add mcp-coda -e 'CODA_API_TOKEN=<your coda_api_token>' -e 'CODA_READ_ONLY=<CODA_READ_ONLY>' -e 'MCP_READ_ONLY=<MCP_READ_ONLY>' -e 'CODA_HTTP_BEARER_TOKEN=<your coda_http_bearer_token>' -- uvx mcp-coda==0.12.3. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.

Faut-il une clé API pour io.github.vish288/mcp-coda ?

Oui. Il attend CODA_API_TOKEN, CODA_HTTP_BEARER_TOKEN, à renseigner dans sa configuration.

io.github.vish288/mcp-coda est-il open source ?

Oui. Son code est sur GitHub sous licence MIT.

Qui maintient io.github.vish288/mcp-coda ?

Il est publié par vish288. AI.tn le référence sans le maintenir ni le recommander.

Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.