MCP

Connect AI agents like Claude Code, Codex, and Cursor to your GalaxyBrain workspace. Read, write, search, and monitor your pages, templates, and layout in real time.

Setup

Prerequisites

  • Bun runtime installed
  • GalaxyBrain open in a Chromium-based browser (Chrome, Edge, Brave)

Install

Ask your AI assistant to install the GalaxyBrain MCP server (package: galaxybrain-mcp). Most AI tools can configure MCP servers automatically.

Or install manually. Add to your tool's MCP settings:

{
  "mcpServers": {
    "galaxybrain": {
      "command": "npx",
      "args": ["-y", "galaxybrain-mcp"]
    }
  }
}

The MCP server starts a local API server automatically if one isn't already running. It communicates with GalaxyBrain browser tabs over a local WebSocket connection (default port 1924).

Port override

{
  "mcpServers": {
    "galaxybrain": {
      "command": "npx",
      "args": ["-y", "galaxybrain-mcp"],
      "env": { "GB_API_PORT": "3000" }
    }
  }
}

If you override the port, also pass ?gb_port=3000 in the GalaxyBrain browser URL.

How It Works

AI Tool (Claude Code, Cursor, etc.) โ†• MCP protocol (stdio) GalaxyBrain MCP Server โ†• WebSocket (localhost:1924) GalaxyBrain API Server โ†• WebSocket GalaxyBrain Browser Tab(s)

The MCP server is a thin translation layer. It receives tool calls from your AI assistant, converts them to WebSocket commands, sends them to the API server, and formats the responses.

Multiple MCP server processes can connect simultaneously. The API server is started automatically if not already running. When the MCP session that spawned the API server exits, it terminates the API server. Other connected MCP sessions will automatically re-spawn it on their next command.

Version Checking

The MCP server performs two version checks:

  1. Protocol compatibility — Before connecting to an API server, the MCP server checks the API server's protocol version (from the HTTP health check response "GalaxyBrain API Server/{version}"). If the versions don't match, it returns an error with instructions to stop the old server. This also applies after spawning a new API server, as a belt-and-suspenders check for npm dependency mismatches.
  2. npm update check — On startup, the MCP server checks the npm registry for newer versions of galaxybrain-mcp. If an update is available, it logs a warning to stderr and prepends the update notice to galaxybrain_status, galaxybrain_orient, and galaxybrain_help responses. The raw galaxybrain_status output also exposes a structured mcp.updateState field so agents can detect the update programmatically and call galaxybrain_update to warm the npx cache.

Tools Overview

The MCP server provides 13 tools. Use galaxybrain_help to look up detailed schemas for complex nested payloads.

galaxybrain_status

Check whether the API server is running and list connected browser tabs. Shows each tab's state, project, and connection details. Use this first to confirm connectivity.

The raw output of galaxybrain_status is MCP-enriched (not a pure pass-through of the API response). Two top-level blocks are injected:

  • mcp{ version, updateState }. updateState is one of "checking", "up-to-date", "available", or "failed". When the state is "available", the block also includes latestKnown and updateAvailable: true.
  • api{ protocolVersion, port }. The MCP ↔ API protocol version in use and the bound port.

Agents can gate offers of galaxybrain_update on mcp.updateAvailable === true.

galaxybrain_project

Manage the project lifecycle: list available folders and demos, open_folder by ID, open_demo by name, close the current project, or remove_folder from recents.

galaxybrain_orient

Get a structural overview of the open project — page and template counts, hub structure (link hierarchy), and currently open tabs. Call this after opening a project.

galaxybrain_read_pages

Read full serialized content of pages or templates. Select by ID or read all open tabs. Control returned fields with icon, title, subtitle, blocks flags. Use blockIds to read specific blocks. Supports scope: "templates".

galaxybrain_query

Search and filter pages with text search, error search, references search, graph filters, count filters, field projection, sorting, and pagination. Returns lightweight results by default — use fields to include additional data. Call galaxybrain_help("query") for full filter docs.

References searchsearch: { references: <target>, sections?: ["subtitle","blocks"] } finds structural references to a single target across subtitles, block items, var formulas, and block linkOrder keys. Targets:

  • { imageId: "<64hex>" } or { imageId: "<64hex>.<ext>" } — image items only
  • { varName: "...", prefix?: true } — var defs + V refs + PLCV refs + linkOrder keys (V refs use live name lookup; prefix: true enables trailing-* match)
  • { metaRef: { head, pageId?, blockId?, varId?, type?, derivation?, varName?, format? } }head must be "CT", "CA", "UA", "V", "PLCV", or "M"
  • { pageLink: { pageId } } — both standalone page link items and inline pageLink units
  • { webLinkUrl: "..." } — exact URL match on webLink units

galaxybrain_traverse

Build a recursive page-link tree starting from a root page:

  • down (MAP) — walks outbound links. limits is optional: pass null for auto mode (~200 page budget) or [] for leaf only.
  • up (ANCESTORS) — walks inbound links. limits is required (e.g. [10, 5, 3] for per-layer budgets) — there is no auto mode.

Optionally include subtitle text and block text previews.

galaxybrain_write_pages

Create, update, or delete pages or templates. Supports full replacement, surgical block-level edits, and image uploads via base64.

galaxybrain_create_from_template

Create a page from a template with automatic value resolution: nextNumber, nextDay, dateToday. A page link is inserted into the specified source block.

galaxybrain_items

Push (insert) or pop (remove) items from specific blocks. More precise than full page updates — useful for appending tasks, inserting links, or removing items.

galaxybrain_workspace

Read or write the workspace tab layout — which tabs are open, their widths, scroll positions, and navigation paths. Supports optimistic concurrency via readVersion.

galaxybrain_watch

Start watching for real-time events. Returns a shell command to run with your AI tool's process monitor. Supports event-type filters, content-derived filters, and hooks. See Event Watching.

galaxybrain_update

Warm the npx cache for galaxybrain-mcp@latest so the next MCP host restart picks up the new version. Input schema is empty. Check galaxybrain_status.mcp.updateAvailable first; offer this tool when it is true. On success, returns a message instructing the user to restart their MCP host. No-op for non-npx installs. Process timeout is 120 seconds.

galaxybrain_help

Look up detailed documentation on a specific topic during a session. Available topics:

TopicDescription
commandsOverview of all tools and workflow guidance
querySearch filters, fields, sorting, pagination
meta_refsMeta reference format strings
stylesText item style values
link_orderLink order format and sort keys
unitsUnit types, fields, and context restrictions
imagesImage ID format and images map
versionsVersion semantics and conflict detection
instancesInstance states and routing
templatesTemplate pages and value types
workspaceWorkspace layout and validation rules
anchor_offsetPush/pop anchor and offset semantics
page_bodyFull page body schema
surgical_updateSurgical update fields and behavior
read_shapesSerialized schemas from read commands
watchWatch system: events, content filters, hooks
errorsCommon error codes
troubleshootingVersion mismatches, updating, common errors
docsLinks to full online documentation

Typical Workflow

1. galaxybrain_status → check connectivity, see open instances 2. galaxybrain_orient → understand the project structure 3. galaxybrain_read_pages → read content galaxybrain_query → search and filter galaxybrain_traverse → explore link structure 4. galaxybrain_write_pages → create / update / delete pages galaxybrain_items → insert / remove items galaxybrain_create_from_template → create from template

If no project is open, use galaxybrain_project to list and open one first. Most of the time, a project is already open in the browser.

Data Model

GalaxyBrain organizes content in a hierarchy: Pages → Blocks → Items → Units.

Pages

FieldDescription
pageId20-character alphanumeric ID (e.g. AbcDef1234567890GhIj)
iconSingle emoji
titleArray of title units (text and template values only)
subtitleArray of units (all types)
blocksArray of blocks

Read-only fields: blockOrder, createdAt, updatedAt, templateValues, counts.

Blocks

FieldDescription
blockIdNon-negative integer, unique within the page
itemsNon-empty array of items
linkOrderOptional sort rule for page-link items (e.g. A.M.tt for title A-Z)

Items

TypeDescription
textStyled text content with a style and content units
varNamed variable with a formula that evaluates to a value
imageImage, referenced by content-addressed ID
pageLinkStandalone link to another page
Text item styles
StyleMeaning
""Body text
"#"Heading 1
"##"Heading 2
"###"Heading 3
"*"Bullet list
"[ ]"Unchecked checkbox
"[X]"Checked checkbox
"ol"Ordered list

Text items also support indentLevel (0-8) for nesting.

Units

TypeDescription
textPlain or styled text (unitStyle: bold, italic, boldItalic)
webLinkHyperlink with display text and URL
pageLinkInline reference to another page
metaRefLive computed value (timestamps, counts, variables)
templateValuePlaceholder resolved when creating from a template
Context restrictions: Titles only allow unstyled text and templateValue. Formulas only allow text, metaRef, and templateValue. Subtitles and text item content allow all types.

Templates

Templates are special pages that serve as blueprints. They use the same structure as regular pages but can contain templateValue units resolved at creation time. Access templates by passing scope: "templates" to read, write, and items tools.

Writing Content

Creating a Page

Pass a full page body to galaxybrain_write_pages with action: "create":

{
  "action": "create",
  "pages": [{
    "icon": "📝",
    "title": [{ "type": "text", "text": "My Page" }],
    "subtitle": [],
    "blocks": [{
      "blockId": 0,
      "items": [{
        "type": "text",
        "style": "",
        "content": [{ "type": "text", "text": "Hello world" }]
      }]
    }]
  }]
}

Pass null in the pages array to create a default blank page.

Updating a Page

For a full replacement, pass the complete page body with a pageId:

{
  "action": "update",
  "pages": [{
    "pageId": "AbcDef1234567890GhIj",
    "icon": "🔥",
    "title": [{ "type": "text", "text": "Updated Title" }],
    "subtitle": [],
    "blocks": [{ "blockId": 0, "items": [...] }]
  }]
}

Surgical Updates

Modify specific blocks without replacing the entire page:

{
  "action": "update",
  "pages": [{
    "pageId": "AbcDef1234567890GhIj",
    "title": [{ "type": "text", "text": "New Title" }],
    "updateBlocks": [{ "blockId": 0, "items": [...] }],
    "insertBlocks": [{ "blockId": 5, "items": [...] }],
    "deleteBlockIds": [2, 3]
  }]
}

blocks (full replacement) and surgical fields are mutually exclusive.

Push and Pop

Use galaxybrain_items for targeted insertions and removals:

Push (insert items)
{
  "action": "push",
  "operations": [{
    "pageId": "AbcDef1234567890GhIj",
    "blockId": 0,
    "anchor": "bottom", "offset": 0,
    "items": [{
      "type": "text", "style": "[ ]",
      "content": [{ "type": "text", "text": "New task" }]
    }]
  }]
}
Pop (remove items)
{
  "action": "pop",
  "operations": [{
    "pageId": "AbcDef1234567890GhIj",
    "blockId": 0,
    "anchor": "bottom", "offset": 0,
    "count": 1
  }]
}
Position reference
PositionMeaning
top + 0Beginning of the block
bottom + 0End of the block
top + 2After the second item
bottom + 1Before the last item

Batch Semantics

Create, update, delete, push, and pop all accept arrays. Each entry succeeds or fails independently. Responses include a results array aligned to input order.

Normalization

Written content is normalized automatically: adjacent compatible units are merged, lone pageLink units in unstyled text items are promoted to standalone items. Content may look different on read.

Output Modes

ModeDescription
summaryHuman-readable formatted text
rawFull JSON response from the API
fullSummary text with raw JSON appended
Defaults by tool
DefaultTools
summarygalaxybrain_status, galaxybrain_orient, galaxybrain_query, galaxybrain_traverse
fullgalaxybrain_read_pages, galaxybrain_write_pages, galaxybrain_create_from_template, galaxybrain_items, galaxybrain_workspace, galaxybrain_project

galaxybrain_help, galaxybrain_watch, and galaxybrain_update do not use output modes.

Instances

A GalaxyBrain instance is a browser tab connected to the API server.

StateDescription
pickerNo project is open
folderA folder-backed project is open
demoA demo project is open
Routing rules
  • One instance connectedinstance is optional; auto-routed.
  • Multiple instancesinstance is required. Use galaxybrain_status to list them.
  • No instances — commands fail with NO_INSTANCES. Open GalaxyBrain in a browser.

Versions & Conflict Detection

Each page has an independent integer version that increments on every mutation. Pass readVersion with mutations for optimistic concurrency:

  • Match — mutation proceeds.
  • MismatchCONFLICT error. Re-read and retry.
  • Omitted — conflict check is skipped.
Where readVersion goes
CommandLocation
Page updatesInside each page object in the pages array
Push/pop operationsInside each operation object
Workspace writesTop-level readVersion parameter
Create and deleteNot used

Event Watching

The galaxybrain_watch tool sets up real-time event monitoring. It returns a shell command to run with your AI tool's process monitor. Each matching event prints a line to stdout.

Note: At least one event subscription or content filter must be specified when calling galaxybrain_watch.

Event Types

Page events
EventDescriptionFilters
pages_createdPages were createdtemplateId, titlePattern
pages_deletedPages were deleted
pages_updatedPage content changedpageIds, scope, role, source
Workspace events
EventDescriptionFilters
workspace_tab_openedTab openedpageId
workspace_tab_closedTab closedpageId
workspace_tab_navigatedTab changed pagesnewPageId
workspace_tab_resizedTab resized
workspace_scrolledWorkspace scrolledpageId
workspace_changedLayout changed
Project events

project_opened, project_closed, concurrent_access_detected

File events

files_changed โ€” fires for each filesystem change produced by an active FILES_WATCH subscription (see File Watching below).

File Watching

File watching lets you drive agents off filesystem activity inside your GalaxyBrain project folder, not just app-internal mutations. It's a thin wrapper around Chromium's FileSystemObserver, exposed through the same monitor script as everything else in galaxybrain_watch.

Typical uses:

  • Inbox processing. Drop a PDF into inbox/, have the agent OCR it, write a page, move the file to inbox/processed/.
  • External edit sync. Watch a subfolder you also edit outside GalaxyBrain and reconcile changes back into pages.
  • Attachment pipelines. React when images, audio, or exports land in a known drop folder โ€” e.g. transcribe voice memos, tag screenshots, thumbnail photos.
  • Cleanup / audit. Alert on unexpected deletions or moves inside critical folders.

Pass files_subscriptions to galaxybrain_watch to start one or more folder watches when the monitor connects. Each entry fires a FILES_WATCH against the open instance before the monitor subscribes to the event stream:

{
  "files_subscriptions": [
    { "subpath": "inbox", "recursive": true }
  ]
}

subpath is forward-slash-delimited and must resolve to an existing directory under the project root. Leading /, backslashes, Windows-absolute paths, .., ., and empty segments are rejected. recursive defaults to false โ€” without it you only see direct children of the folder.

Each change produces one files_changed stdout line carrying subscriptionId, subpath, recursive, changeType, path (array, relative to subpath), and movedFrom (array on moved, null otherwise). Change types mirror the platform API:

changeTypeMeaning
appearedA file or directory was created or moved into the watched subtree.
disappearedA file or directory was removed from the watched subtree.
modifiedA file's contents or metadata changed.
movedA file or directory was renamed within the same directory. movedFrom carries the previous path.
unknownThe OS dropped events โ€” state may have diverged; rescan if correctness matters.
erroredThe observation is dead. GalaxyBrain removes the subscription automatically; issue files_subscriptions again on the next monitor run.

Use files_change_types to narrow the stream to the records you care about:

{
  "files_subscriptions": [{ "subpath": "inbox", "recursive": true }],
  "files_change_types": ["appeared", "moved"]
}

File watches fail with specific wire errors you may need to handle:

  • FOLDER_UNAVAILABLE โ€” the open project is a demo / in-memory, so there's no real folder to observe.
  • UNSUPPORTED_BROWSER โ€” the browser doesn't expose FileSystemObserver (currently Chromium-only).
  • FOLDER_NOT_FOUND โ€” the subpath doesn't resolve to an existing directory under the project root.
  • NO_PROJECT โ€” no project is open.
Lifetime: Subscriptions live on the GalaxyBrain instance (the open browser tab), not on the MCP monitor. The monitor performs best-effort FILES_UNWATCH on graceful exit and on reconnect (so duplicates don't accumulate). A hard kill leaves watches running on the instance until the project is closed, the folder is switched, the app is reloaded, or Chrome emits an errored record.

Built-in filter: files_changed events whose last path segment is .DS_Store are dropped before emission โ€” macOS metadata noise is never forwarded to the agent.

Other sharp edges: Windows reports cross-directory moves as a disappeared+appeared pair rather than a single moved record. File events are not file-readiness events โ€” a large file copy produces appeared (and possibly modified) before the writer has finished, so use temp-then-rename or wait for size/mtime stability if completion matters. Per-origin observation limits are OS-dependent and surface as errored.

Content Filters

Content filters detect specific changes within pages_updated events by comparing before/after state. Each filter has a required type field and optional scoping.

Block-level filters

Support pageIds and blockId scoping:

FilterDetectsExtra fields
block_changedAny modification to a block
checkbox_count_changedTotal checkbox count changed
checked_count_changedChecked checkbox count changed
image_count_changedImage item count changed
page_link_item_count_changedPage link count changedtargetPageId (optional)
item_style_changedText item style changed
web_link_unit_added / removedWeb link units added/removed
meta_ref_unit_added / removedMeta ref units added/removed
Page-level filters

Support pageIds scoping:

FilterDetectsExtra fields
page_link_unit_added / removedInline page link unitstargetPageId (optional)
var_value_changedVariable value changedpageId (required), varId (optional)
var_added / var_removedVariable items added/removed
title_changedPage title changed
subtitle_changedPage subtitle changed
icon_changedPage icon changed
block_created / block_deletedBlocks created/deleted
Tip: Content filter output includes full before/after data by default. Set include_diffs: false to reduce token usage and only receive change metadata.

Hooks

Hooks are optional JavaScript/TypeScript modules that run on each matched event before it reaches the agent. They can perform side effects, suppress events (return false), or replace the output (return a string).

// update-subtitle-hook.ts
export default async function(match, context) {
  if (match.output.filter === "checked_count_changed"
      && match.output.afterChecked > match.output.beforeChecked) {
    await context.sendCommand("UPDATE_PAGES", {
      pages: [{ pageId: match.output.pageId,
        subtitle: [{ type: "text", text: "Processing..." }] }]
    });
  }
}
Return values
  • undefined — event passes through normally
  • false — event is suppressed (agent is not woken)
  • string — replaces the default output (agent sees your string)

Use hook_debug: true for verbose tracing of all hook calls.

Tip: When your hook sends API commands, use source: ["user"] in your filter spec to prevent infinite loops. Commands from context.sendCommand have source "api".

Error Reference

Routing errors
CodeMeaning
NO_INSTANCESNo GalaxyBrain browser tabs connected
INSTANCE_REQUIREDMultiple tabs connected; specify instance
UNKNOWN_INSTANCESpecified instance ID not found
Command errors
CodeMeaning
NO_PROJECTCommand requires an open project
CONFLICTreadVersion mismatch — re-read and retry
PARSE_ERRORInvalid payload shape or field types
PAGE_NOT_FOUNDPage or template does not exist
TEMPLATE_PAGERegular-page command sent to a template
NOT_TEMPLATE_PAGETemplate command sent to a regular page
LAST_PAGECannot delete the last remaining page
NO_REMAINING_ITEMSPop would remove every item from a block
SELF_LINKPage link points to itself
PERMISSION_REQUIREDBrowser requires user gesture for folder access
BLOCK_NOT_FOUNDBlock ID doesn't exist
BLOCK_ALREADY_EXISTSInserted block ID already exists
NO_UPDATESSurgical update contained no changes
DUPLICATE_BLOCK_OPSame block in multiple surgical operations
BLOCK_ORDER_MISMATCHblockOrder doesn't match final block set
UNEXPECTED_ITEM_TYPEPop expectedItemType mismatch
INVALID_TEMPLATE_IDTemplate ID doesn't exist
NO_ITEMSEmpty items array
DUPLICATE_VAR_IDDuplicate variable ID within a page

Troubleshooting

Prerequisites

GalaxyBrain MCP requires Bun. Install:

  • macOS/Linux: curl -fsSL https://bun.sh/install | bash
  • Windows: powershell -c "irm bun.sh/install.ps1 | iex"

After installing, fully quit your MCP host and relaunch it from a fresh terminal where bun --version works — the host inherits PATH from the terminal that launched it, not from ~/.zshrc or ~/.bashrc.

If Bun is installed at an unusual path, set GB_BUN_PATH to its absolute path in the host's environment.

Recommended Setup

Configure your MCP client with:

{ "command": "npx", "args": ["-y", "galaxybrain-mcp"] }

The -y flag auto-confirms the install prompt. Without it, npx may hang waiting for confirmation since MCP servers have no interactive terminal.

Updating

The MCP server checks for updates on startup and re-checks lazily during long sessions. When an update is available, the notice is prepended to galaxybrain_status, galaxybrain_orient, and galaxybrain_help output; agents can also detect it programmatically via galaxybrain_status raw output (mcp.updateAvailable === true).

Agents should prefer calling galaxybrain_update — it warms the npx cache without requiring the user to drop to a shell. After it reports success, the user must restart their MCP host for the new version to take effect. The shell equivalent is:

npx -y galaxybrain-mcp@latest

To update the API server:

npx -y galaxybrain-api@latest

If an old API server is still running, stop it first:

lsof -ti :1924 | xargs kill

npx Caching

npx caches packages locally. Running npx -y galaxybrain-mcp uses the cached version without checking for updates — this keeps startup fast. To force an update, run npx -y galaxybrain-mcp@latest once. Subsequent runs use the updated cache.

Do not use @latest in your MCP client configuration — it causes a network request to the npm registry on every startup, adding latency.

Version Mismatches

The browser app, API server, and MCP server share a protocol version. When versions don't match:

  • MCP ↔ API server — The MCP server checks protocol compatibility before connecting. Incompatible versions produce a clear error with update instructions.
  • Browser app ↔ API server — The app checks on WebSocket connect. Incompatible versions show a warning toast with update instructions.

Common Errors

ErrorCauseFix
GalaxyBrain MCP requires BunBun not installed or not findable from the MCP host's PATHInstall Bun (see Prerequisites above); if already installed, relaunch the host from a terminal where bun --version works
env: bun: No such file or directoryHost launched from a shell without Bun on PATHQuit the host, open a fresh terminal where bun --version works, relaunch the host from there
"incompatible version"MCP/API protocol versions don't matchUpdate both: npx -y galaxybrain-api@latest and npx -y galaxybrain-mcp@latest
"Port in use by another process"Non-GalaxyBrain process on port 1924Stop it: lsof -ti :1924 | xargs kill
"No GalaxyBrain browser tabs connected"No browser tab connected to the API serverOpen GalaxyBrain in Chrome, or check for version mismatch
"No project is open"Browser tab is on the folder pickerOpen a folder or demo via galaxybrain_project

Further Reading

  • GalaxyBrain API Reference — full WebSocket API with transport details, data model schemas, and all command specifications.
  • galaxybrain_help tool — call it from your AI tool for detailed, contextual documentation during a session.