Coda

Lightweight, dependency-free, in-memory fake of the Coda API v1 for testing code that talks to the Coda /v1 REST surface.

Default port: 4796

Auth is Authorization: Bearer <token>. Collections carry { items, href }.

Quick start

import { CodaServer } from "./services/coda/src/server.js";

const server = new CodaServer(4796);
await server.start();
// ... run your app/tests ...
await server.stop();
const res = await fetch(
  "http://127.0.0.1:4796/v1/docs/<docId>/tables/<tableId>/rows",
  {
    method: "POST",
    headers: { Authorization: "Bearer coda_xxx", "Content-Type": "application/json" },
    body: JSON.stringify({ rows: [{ cells: [{ column: "Name", value: "Task 1" }] }] }),
  }
);
// => 202 { requestId, addedRowIds: [...] }

Access via MCP / preview URL

Point your MCP server / agent tooling at the preview URL printed by the parlel pool (defaults to http://127.0.0.1:4796). Set CODA_BASE_URL to that URL and supply any non-empty CODA_API_TOKEN; the fake accepts any Bearer token.

Implemented operations

All /v1/* routes require an Authorization: Bearer <token> header.

Docs

Tables

Rows

Account

Service & inspection

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Doc list / create / get✅ Supported
Table list / get✅ Supported
Row list / insert (upsertRows)✅ Supported
{ items, href } collection envelope✅ Supported
202 Accepted + addedRowIds on row insert✅ Supported
Columns, formulas, controls, pages, automations⟳ Roadmap
Row update / delete◐ Insert + list only
Async mutation status polling◐ Inserts are applied immediately
Table create◐ Default table only
Token validity / scope enforcement✓ By design — Any non-empty credential is accepted — no real secrets needed

Error shapes

Errors use the Coda envelope { statusCode, statusMessage, message }.

StatusWhen
401no Authorization: Bearer header
404unknown doc / table / endpoint
405method not allowed

Manifest

See services/coda/manifest.json:

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

CODA_API_TOKEN=coda_parlel
CODA_BASE_URL=http://parlel-bridge:4796
<!-- parlel:testenv:end -->