Calliope MCP Server
The Calliope MCP Server lets you read and edit the prose body (sections) of plan nodes. It provides four tools:
read_body: Retrieve all prose sections for a given node, returned as a sorted list of{ id, text, orderKey }objects. Nodes with no body return an empty list.write_body: Fully replace all sections of a node's body with a new ordered array of text sections. The substrate handles order keys and copy-on-write for changed prose.append_section: Add a single new prose section to the end of a node's body without affecting any other sections.edit_section: Update the prose of one specific section (bysection_id) in place using copy-on-write, leaving all other sections and their positions untouched.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Calliope MCP Serverread the body of node 'my-note'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@forge/calliope — the prose/body-facet constellation star
Calliope stores and serves node bodies behind an MCP server — since
the Git for Ideas arc (2026-08-16), as git's factoring: immutable
content-deduped blobs in Calliope's own Postgres, tree/commit/history as
facts in the chaos graph, one save = one transaction, history = a read
at an earlier transaction. It is the peer of clotho (the work/graph
facet): clotho owns graph structure (parent, dependsOn, status, …);
Calliope owns every body, prose notes and work-node plan prose alike
[Rob, 2026-07-04]. The same engine ships twice: the fleet star, and the
Grace desktop sidecar running a bundled PostgreSQL + the real chaosstore
binary (baby chaos, F13).
The Muse shed its UI (2026-07-04). Through spec 001-muse-sheds-ui, the
ProseMirror editor component that used to live here moved to @forge/aglaia.
This repo is now service-only: the body-model types, three body-store
backends (pg/hades/urania, plus an in-memory fixture for tests), and
an MCP server exposed over stdio and streamable-HTTP. If you're looking for
the editor UI, it's in aglaia.
The repo is a turbo monorepo (2026-07-10). Adopted onto the
frontend-repo-template (chore/adopt-frontend-template, flat → monorepo):
the package now lives at apps/calliope/ (workspaces: apps/*, currently
just this one app; packages/* is reserved by the template, unused so far).
Root package.json scripts (lint/typecheck/test/build) delegate to
turbo run <task>, which fans out to each workspace's own script. All src/
paths below are relative to apps/calliope/, not the repo root.
Body model — the blob store and the tree (Git for Ideas, 039–047)
Since 2026-08-16 the store IS git's factoring (specs 039–047, the
Git for Ideas master-plan (vault), all fourteen features landed in one arc):
Blobs (
apps/calliope/src/blob-store.ts, tableblobsin calliope-db): immutable, content-deduped prose —id bigint identity, text, identity enforced by a unique expression index over an IMMUTABLE sha256 wrapper (blob_content_hash). Mint returns the existing id on a duplicate; identical prose anywhere in the system is ONE row.The tree (facts in the
chaosgraph, per-tenant): a container node holdstree_memberedges to kind-Blockslot nodes; each slot holds a fractionaltree_positionliteral and atree_contentedge into the blob store (chaos's third object domain,o_blob). Container+position is identity — an edit repoints ONE slot, a reorder rewrites ONE position.A save is one commit (
container-write.ts): the client computes the op batch (aglaia's diff), blobs mint first, and the surviving tree facts ride a single admitted graph transaction. Byte-identical content nets out — a save whose ops all net to nothing writes nothing.History is not a feature (
container-read.ts+ chaos'shistoryverb): every save carries a transaction id, so any past state is the same tree read withas_of_tx, and the history listing is the graph's own transaction log. No revision tables.Blob GC (
blob-census.ts): an inverted census — chaos reports the LOG of blob ids each tenant graph has ever named (held_blobs), calliope reaps only on a complete roster of reports, mark-and-sweep across two complete censuses.
The old model — the sections table with copy-on-write lineage,
supersessions, comments_on — was migrated (7,416 containers, full
two-sided parity; report at specs/043-migrate-tree/parity-report.json)
and then dropped from production (the gated cut, spec 047). A fresh
install bootstraps the blob store only; the legacy DDL exists solely
behind ensureSchema({ legacy: true }), which the migration suite uses to
simulate an old store. src/order-key.ts still mints the fractional
position keys (COLLATE "C", compared as raw bytes).
Related MCP server: memory-mcp
Backends
Backend selection (src/mcp/backend.ts) reads the environment, in order:
| Condition | Client | Store |
|
|
| sovereign store |
|
|
| gateway-auth path; writes carry |
| fallback |
| direct |
| explicit only |
| in-memory — dev/test |
The pg and fixture backends additionally provide a document store
(C3, the internal dissolve sink — its verbs retired in F12), a revision
store (C4), and the container facet (blobs + the chaos dial — the
write path) off the same pool/memory; the substrate-direct backends
(urania, hades) do not. Both fleet entries pass the container facet to
the server explicitly (an F12 audit finding: it was wired in the backend
since F4 but served by neither entry until the cut — the production-shape
regression pin in __tests__/mcp-http.test.ts keeps it that way).
The desktop is its own backend (F13/F14, specs 045/046): the Grace
sidecar (src/mcp/sidecar.ts) boots a bundled PostgreSQL + the real
chaosstore binary (src/mcp/babychaos.ts) and serves everything from
ONE LocalEngineStore (src/local-store.ts) — node identity is the
markdown path, the container is the graph node labelled by it, the
markdown directory is a projected WORKING TREE (external edits ingest
like git add), and admits translate in-process without themis
(src/local-admit.ts, a port of go-court ToWire held by the court's own
pinned constants). Payloads are assembled by
scripts/fetch-babychaos-payload.ts (zonky embedded-postgres + a go
build of chaosstore, linux and windows).
MCP tools — the post-cut surface (F12)
The fleet serves sixteen verbs, pinned (names AND annotations) by an
executable fence in __tests__/mcp-http.test.ts — change the surface only
alongside the plan that licenses it:
The container surface (the ONE write path):
write_container(container, ops, tenant?)— the tree-native save: one graph transaction, blob-first, identical content nets outread_container(container, as_of_tx?)— ordered blocks (slot, position, blobId, text); dangling blobs surfaced, never fabricatedcontainer_history(container)— the container's transactions (history IS the graph)blob_census()— the F7 GC (roster-gated mark-and-sweep)
The note-native verbs (C8/F10): create_note, dissolve_note,
export_note, materialize_note. Findability: search, list_tags,
list_by_tag, copy_reference. Attention: look, unpin. The frozen
git-for-ideas archive (read-only): file_revisions, revision_deltas.
Retired by the F12 cut (2026-08-16) — the body family (read_body,
write_body, has_body, read_body_revisions, read_body_at), the
section family (apply_section_ops, append_section, edit_section),
the block family (create/read/update/delete/split/merge_block,
list_blocks, coalesce_block_writes), the document/plan verbs
(write_document, read_documents, read_plan), and the comments pair.
Charon's /body allowlist moved with the surface; the fleet-wide caller
sweep ran first (theia's clients were repointed in the same feature).
The desktop exception: the sidecar's loopback /mcp additionally
serves path-addressed body verbs (read_body/write_body/
apply_section_ops/read_body_revisions/read_body_at/has_body)
behind the pathBodies server option ONLY it passes — those are the F14
engine-backed surface sharing the old wire spellings, not the old model.
Transports
Two bins, same server (src/mcp/server.ts, four-to-nine tools depending on
which facet stores the backend supplies), reused unforked:
calliope-mcp(src/mcp/main.ts) — stdio, for local/CLI use.calliope-mcp-http(src/mcp/http.ts) — streamable-HTTP,POST /mcpon$PORT(else$CALLIOPE_MCP_PORT, else8204). Stateless: a fresh server+transport per request over a long-lived backend. This is the constellation-star form — the Hades MCP gateway fronts it east-west athttp://calliope-mcp:8204/mcp.
Deploy (nas01 star)
Deploy is no longer local to this repo. The repo used to ship its own
compose.yaml + .forgejo/workflows/deploy.yml; both are retired
("services lane owns deploy now" / "state lives in the services lane") —
there is no infra/ and no local deploy.yml here anymore. What remains in
this repo:
Dockerfile— the image build only (see below), no deploy step.star.toml— the conformance target the shared admission gate reads (image ref, entrypointapps/calliope/src/mcp/http.ts, the governance policy bundle). Derived by the Hephaestus foundry — do not hand-edit..forgejo/workflows/build.yml— a caller stub (pushtomain, non-docs/non-infra paths) delegating to the shared, language-agnosticfoundry/foundry-stocksreusable build workflow (docker build ., the Dockerfile does the rest)..forgejo/workflows/ci.yml— a caller stub (onpull_request) delegating to the sharedfrontend-ci.ymlreusable workflow (bun install +bun run gate+ audit + opengrep).
The image itself: oven/bun-based multi-stage build on
stellar_core:bun-mcp (digest-pinned, not a floating tag); the runtime stage
ships only the bun build --target=bun-bundled server.js — no source
tree, no node_modules, no bun install in the deployed image (see
Dockerfile). Publish/sign/scan/deploy mechanics now live in the shared
foundry-stocks workflows and the services-lane deploy pipeline, not in this
repo — read star.toml + the two .forgejo/workflows/*.yml caller stubs for
what this repo actually controls, not this README, if those diverge.
Project structure
Turbo monorepo root — the package lives under apps/calliope/:
apps/calliope/
src/
types.ts Section / SectionInput / BodyClient contract (capability
methods REQUIRED since the F14 interface collapse)
index.ts public package exports (@forge/calliope)
order-key.ts fractional order-key scheme (COLLATE "C")
blob-store.ts BlobStore / FixtureBlobStore / PgBlobGc — F1/F7
tree.ts tree vocabulary + slot op builders + readTree — F3
container-write.ts writeContainer: ops -> blobs -> ONE admit — F4
container-read.ts readContainer (HEAD / as-of) + containerHistory — F5
blob-census.ts the inverted-census GC — F7
chaos-client.ts ChaosDial (Live/Fixture) — the graph wire
local-admit.ts LocalChaosDial — themis-free desktop admit (F13)
local-store.ts LocalEngineStore — the desktop backend: engine +
working-tree projection/ingestion + tags + FTS (F14)
search-types.ts the search seam types (SearchProvider et al.)
eros-provider.ts the fleet's search arm (eros-routed)
fixture-client.ts FixtureBodyClient — in-memory, dev/test
urania-client.ts UraniaBodyClient — substrate-triple mapping (legacy reads)
pg-client.ts PgBodyClient — blob-store DDL; the legacy sections DDL
only behind ensureSchema({legacy: true}) (migration suite)
document-store.ts DocumentStore (C3) — the internal dissolve sink
revision-store.ts RevisionStore (C4) — frozen archive, read-only
plan-blocks.ts plan block-addressing (C7; its verb retired in F12)
mcp/
backend.ts env -> BackendKind -> BodyClient + facet stores
server.ts createServer() — the 16-verb fleet surface;
pathBodies option adds the desktop's body dialect
tools.ts tool handler functions (pure over a BodyClient)
main.ts calliope-mcp bin (stdio)
http.ts calliope-mcp-http bin (streamable-HTTP, :8204)
sidecar.ts the Grace desktop sidecar — engine-backed (F13/F14)
babychaos.ts payload resolve + engine boot/stop (F13)
drop-old-tables.ts the F12 gated drop (parity report + frozen-store check)
migrate-tree.ts the F6 migration engine (retry armor, crash recovery,
carrier fallback) — the old store's replay
index-push.ts IndexingBodyClient — similarity-index push decorator
backfill-index.ts one-off index backfill CLI
heartbeat.ts op-contract heartbeat -> Pontus
hades-capture.ts / live-capture.ts legacy substrate transports
migrate.ts / migrate-documents.ts / migrate-revisions.ts /
migrate-dissolution-archive.ts the C2-C5 era migrations (historical)
scripts/
fetch-babychaos-payload.ts assemble the desktop engine payload (F13)
__tests__/ vitest specs (49 files; engine suites gated on
CALLIOPE_BABYCHAOS_DIR / CALLIOPE_CHAOSSTORE_BIN)
docs/body-facet.md C2 ownership record (historical; superseded by 039-047)
specs/ spec-kit feature dirs — 039-047 are the Git for Ideas
arc; 043 carries the production parity reportDevelop
From the repo root (turbo fans out to the one workspace, apps/calliope):
bun install
bun run lint # turbo run lint -> eslint .
bun run typecheck # turbo run typecheck -> tsc --noEmit
bun run test # turbo run test -> vitest run
bun run format # prettier --write "**/*.{ts,tsx,json,css}"
bun run format:check
bun run gate # format:check && turbo run lint typecheck test buildOr from apps/calliope/ directly (same scripts, plus dev/run):
bun run test:watch # vitest
bun run start # calliope-mcp over stdio
bun run start:http # calliope-mcp-http, :8204
bun run dev # bun run --watch src/mcp/http.ts
bun run build # bun build src/mcp/http.ts --target=bun --outfile dist/server.jsbun runs the TypeScript directly in dev/test — no build step, no dist/,
until you explicitly bun run build (or the Dockerfile does, for the
deployed image). Requires Node >=22.13 (.nvmrc: 22) and the pinned
bun@1.3.14 (packageManager in the root package.json).
Status
Version 0.1.0, Apache-2.0, single-author (Rob Fischer). The Git for
Ideas arc is complete (2026-08-16, specs 039–047): the blob store
(F1), the tree + container write/read/history (F3–F5), blob GC (F7), the
ferry + editor + consumer repoints (F8–F11), the full production
migration to two-sided parity (F6 — 7,416 containers, report archived in
specs/043-migrate-tree/), the desktop engine (F13 baby chaos), the
deletion of the parallel fs implementation (F14), and the cut (F12 — the
old verb families retired and sections/supersessions/comments_on
dropped from production behind the gated tool). The C2–C5/A8/A11/C7 era
described in docs/body-facet.md and the older spec dirs is historical
context: its storage model and most of its verb surface no longer exist.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceExposes the Nodus orchestration runtime as MCP tools for memory management, goal/workflow execution, and sandboxed code execution.MIT
- AlicenseNot gradedqualityAmaintenanceEnables reading, writing, and searching a local markdown-based memory store using MCP tools, with safety checks and index consistency.MIT
- AlicenseNot gradedqualityFmaintenanceEnables MCP-based operations on an Obsidian vault, including reading, editing, and custom script tools.BSD Zero Clause
- AlicenseAqualityAmaintenanceProvides a single-writer MCP server for a governance-grade knowledge base of markdown documents with version control and query capabilities.918Apache 2.0
Related MCP Connectors
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
MCP-native collaborative markdown editor with real-time AI document editing
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/robfischer1/calliope'
If you have feedback or need assistance with the MCP directory API, please join our Discord server