claude-openmax
This server gives an agent the full OpenMax/CWS workspace toolset — task management, knowledge base, artifacts, communication, directory/identity, and connection credentials — via six dispatch tools plus a direct reply tool, and it pushes workspace messages into Claude Code's context so the agent can act on them.
tm— Task management: create/browse projects, issues, tasks, blueprints, comments, and attempts; run the issue lifecycle (create → submit plan → accept plan → deliver → accept delivery), claim/start/transition tasks, and write comments on issues/tasks.kb— Knowledge base: browse and create KBs, folders and pages, read/write page content and revisions, run full-text search, and upload files.as— Artifact store: upload/download media, resolveartifact://URIs, and get presigned URLs.comm— Communication: list conversations, open DMs, read message history and single messages, send, and sync/mark-read.core— Directory & identity: look up your own identity (me), members, agents, orgs, roles and invitations, read agent profiles/capabilities, rename yourself, and browse projects.conn— Connection credentials: list, acquire, proxy through, and inspect workspace connections.comm_send— Reply directly: send a message into a conversation using the wake notice'sendpoint, with optionalreplyToandorgId.Inbound wake: workspace messages are injected into the agent's visible context via the experimental
claude/channelMCP push (withok:trueonly when the wake truly landed), so the agent can respond to DMs and @-mentions.
Click on "Deploy 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., "@claude-openmax create a task 'update docs' in workspace"
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.
claude-openmax
The Claude Code runtime adapter for OpenMax / CWS. A thin Category-B
(bare runtime) adapter: it owns none of the CWS protocol — that all comes from
@openmaxai/openmax-agent-sdk (CwsAgentBridge) — and does
only the two runtime-specific translations plus capability exposure:
Inbound — bring a workspace message into Claude Code's visible context via an experimental
claude/channelMCP push (raft-channel-wake.v1).Outbound — send Claude's reply back to cws-core via the SDK's
CommService.Capability exposure — the SDK's six service clients (
tm/kb/as/comm/core/conn) as MCP tools, so the agent can operate the workspace (create issues/tasks, query the KB, upload files, reply).
It follows the proven reference implementation,
raft-external-agents v0.3.1
— the only one of the four external runtimes with a shipped Claude Code plugin —
and the claude-openmax adapter design.
Architecture
Layer 1 @openmaxai/openmax-agent-sdk (CWS HTTP/WS contract only)
CwsAgentBridge: per-org WS lifecycle · auth/heartbeat/reconnect · atomic dedupe
· /sync + inbox-ledger · frame dispatch · access-policy · normalized InboundMessage
services: tm / kb / as / comm / core / conn (one CwsHttpClient)
providers: StorageProvider · RuntimeStateProvider · InboundDelivery(★) · Logger
▲ import + inject
Layer 2 claude-openmax (this repo)
┌ bridge host (Node) ────────────────┐ ┌ Claude Code (agent) ──────────┐
│ new CwsAgentBridge({providers,cbs}) │ │ MCP `openmax` server: │
│ providers.inbound.deliver ─────────┼─wake──▶│ experimental claude/channel │
│ = derive WakeRequest → push │ │ → pushes notice into context │
│ storage=local data dir · logger │ │ MCP tools: tm kb as comm core │
│ holds 6 SDK service clients ◀──────┼─call───┤ conn + comm_send │
└─────────────────────────────────────┘ └───────────────────────────────┘
│ CommService.send() / bridge.send() → cws-core
▼
cws-core REST ◀── cws-comm WS (inbound frames) ── COCO Workspace (user)Topologies
In-process (MVP, default) — one Node process is both the stdio MCP server (
claude/channel+ tools) and the host ofCwsAgentBridge.InboundDeliverypushes wakes straight to the channel; the/wakeHTTP hop is skipped but theWakeRequestwire shape is preserved. Run: Claude Code loads the plugin.Split (design topology 1,
CLAUDE_OPENMAX_MODE=channel-only) — the MCP plugin runs only the channel + an HTTPPOST /wakeserver; a separate residentbridge.jsholds the WS and POSTs wakes. The bridge survives Claude Code session restarts and redelivers via the SDK's/sync+ inbox-ledger.
Related MCP server: Slack MCP Server
The ok:true delivery invariant
The single most important rule (from the SDK's wake-result schema and
CwsAgentBridge): ok:true MUST mean the message genuinely entered the
runtime's visible context. On ok:true the SDK commits dedupe + ledger +
read markers and stops /sync retry for that message — so a false ok:true
loses the message forever.
This adapter returns ok:true only when the wake injection resolved
(ClaudeChannel.notifyWake / POST /wake succeeded). Anything else —
channel not connected, notification write failed, malformed inbound — returns
{ok:false, failureClass, retryAfterMs}, so the SDK holds all markers and
redelivers on the next /sync sweep. See src/inbound-delivery.js and its
tests.
Files
File | Purpose |
| MCP channel plugin entrypoint (Claude Code loads this over stdio); default in-process bridge host. |
| Standalone resident bridge for the split topology; POSTs wakes over HTTP |
| MCP |
| Pure |
|
|
| Debounced wake coalescing (raft EAB-8): leading-edge inject + window merge. |
| HTTP |
| Wraps the six SDK service clients as MCP tools (one dispatch tool per service + |
| Loads adapter config; builds |
| Assembles |
| Channel activation ( |
| One-shot onboarding: config, register + accept, permission rules, launch the channel session. |
| First channel session after onboarding catches up the new inbox from seq 0 instead of seeking past it. |
| File-backed |
| stderr logger + empty |
| Registers the |
|
|
| Agent-facing instructions: how wakes arrive, how to read/reply, tool map. |
|
|
Session / context management
Uses Claude Code's built-in autocompact (and /clear / /compact). This
adapter implements no extra compression logic — by design.
Installation
Install as a Claude Code plugin from this repo's marketplace:
claude plugin marketplace add openmaxai/claude-openmax # register the marketplace (once)
claude plugin install openmax-channel@openmax # install the pluginClaude Code fetches the plugin, installs it into its managed plugin directory,
and keeps it updated — no manual git clone needed. Then create your config
(see Configuration) and start Claude Code.
Experimental wake — one caveat. The MCP tools (
tm/kb/as/comm/core/conn+comm_send) work from a plain plugin install with no flags. The inbound wake (claude/channel, how workspace messages reach the agent) is still an experimental Claude Code capability and currently requires launching with the development-channels flag:claude --dangerously-load-development-channels plugin:openmax-channel@openmaxReference the plugin, not a bare server name. When installed via
claude plugin install, Claude Code namespaces this MCP server —/mcpshows it asplugin:openmax-channel:openmax, notopenmax. So the bare--dangerously-load-development-channels server:openmaxdoes not match a plugin install (it only works if you register the server directly in a.mcp.jsonunder the literal nameopenmax); use theplugin:…@…form above. If in doubt, run/mcpand reference the exact server name it prints. Onceclaude/channelgraduates from experimental, install alone will be enough.
One-shot onboarding (scripts/onboard.js)
An OpenMax invitation prompt runs the whole onboarding as one Bash call — one approval for the user — and then starts the channel session itself:
export CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1
claude plugin marketplace add https://github.com/openmaxai/claude-openmax.git#openmax-channel--v<version> \
&& claude plugin install openmax-channel@openmax --scope user \
&& node "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins/cache/openmax/openmax-channel/<version>/scripts/onboard.js" --launch <<'JSON'
{ …the invitation's config JSON… }
JSONonboard.js writes the config (0600), registers the agent and accepts the
invitation (per-request timeouts under a 45 s budget; registration is retried only
when the request provably never reached the server, so no orphan identity is
created), appends the OpenMax
tool rules to permissions.allow, and with --launch starts
CLAUDE_OPENMAX_CHANNEL=1 claude --dangerously-load-development-channels plugin:openmax-channel@openmax -- "<greeting>"
in tmux — a new window if you are already in tmux, otherwise a detached session
openmax (tmux attach -t openmax); without tmux it prints the command. (The --
matters: the channel flag takes several values, so without it Claude Code reads the
greeting as a second channel and exits.) A new window/session is reported as
launched only if it is still running 3 s after it was started; if it has exited by
then, the script prints launch: FAILED … with the exit status and output and
LAUNCH: manual. This catches start-up failures (bad arguments, missing binary);
a session that dies LATER than 3 s (for example after the dev-channel dialog) is
not detected and still counts as launched. You then
confirm Claude Code's dev-channel warning dialog yourself (the script never answers
it). Output ends with ONBOARD OK / LAUNCH: / NEXT: / RESTART_COMMAND: on
success or ONBOARD FAILED: <step>: <reason> on failure; exit codes are 0 (ok, also
"already onboarded"), 1 (failed — nothing is launched), 2 (bad usage / input).
Re-running it is safe. A running openmax tmux session is reused only if this run
kept the same agent identity; after a new registration it prints LAUNCH: manual
and asks you to close the old session first. node scripts/onboard.js --help
prints the usage.
Which session receives messages
The plugin's MCP server starts in every Claude Code session, but Claude Code
delivers channel pushes only to a session launched with the channel flag, and drops
them silently anywhere else. So the workspace connection (WS) is opened only when
the session is channel-active — CLAUDE_OPENMAX_CHANNEL=1 in its environment (the
command above sets it; =0 forces it off). If the variable is unset, the plugin
falls back to checking whether its parent claude process was started with
--dangerously-load-development-channels/--channels naming openmax-channel.
Only one channel-active session holds the connection at a time
(<data dir>/channel.lock); a second one gets the tools only and a notice. Every
other session still has all MCP tools (comm_send works over REST), stays offline,
and never acknowledges a message it cannot show — the message waits for /sync
redelivery to the channel session.
Startup and network errors: if the config has no agent.api_key yet when the
server starts (the onboarding command is still registering), it waits up
to 120 s for the key to appear instead of running the whole session on an empty key;
the tools answer "waiting for the API key — run the onboarding command if you
haven't" meanwhile. Workspace HTTP calls time out
after 15 s waiting for a response, errors name the request and its cause
(fetch failed: POST /auth/ws-ticket → ECONNRESET), and the token / ws-ticket calls
are retried twice on network errors.
Group messages: with the default access policy written by the invitation
(groupPolicy: "allowlist", no groups listed), a group message reaches the agent
only when the owner @-mentions it; anything else in a group is dropped without a
reply. Direct messages from the owner always come through. This is intentional and
unchanged — @-mention the agent in groups.
Security
What installing and onboarding this plugin does on your machine, so you can check it before approving:
Installs: this repository (public,
openmaxai/claude-openmax) into Claude Code's plugin cache. Claude Code runsdist/index.mjsas a local MCP server (stdio) andhooks/session-hook.jsonSessionStart. Plugins run with your user's permissions — only install from a tag/commit you trust.Files written:
~/.config/claude-openmax/config.json(or$CLAUDE_OPENMAX_CONFIG), mode 0600 — server URLs, the agent's api_key, optional CF-Access service-token pair, and the one-time invite (removed once accepted). A replaced config is kept asconfig.json.bak-openmax-<ts>(0600).${CLAUDE_CONFIG_DIR:-~/.claude}/settings.json— five entries appended topermissions.allow; nothing else is changed, the previous file is saved assettings.json.bak-openmax-<ts>first, and a file that is not valid JSON is refused.~/.local/share/claude-openmax/(or$CLAUDE_OPENMAX_DATA_DIR) — token cache, sync cursors, dedupe ledger, downloaded media,channel.lock, and after a new registrationfirst-sync.json(api_key fingerprint + the onboarded org ids); files 0600.A log file only if you set
CLAUDE_OPENMAX_LOG_FILE(0600, secrets scrubbed).
Endpoints called (only the workspace server in your config —
server.bff_url/server.ws_url):POST /auth/register/agent,POST /auth/agent/token,POST /api/v1/invitations/<id>/acceptduring onboarding; then the agent token / ws-ticket endpoints, the workspace REST API (/api/v1/...) for the MCP tools, and the cws-comm WebSocket — the WebSocket only from the channel-active session. No other hosts, no telemetry.Permissions added:
mcp__plugin_openmax-channel_openmax__comm,…__comm_send,…__tm,…__kb,…__core. Theas(file upload/download) andconn(connection credentials) tools are not allowed and keep prompting per call. Remove the entries frompermissions.allowto undo.Verify what you run:
Tag ↔ commit:
git ls-remote https://github.com/openmaxai/claude-openmax.git refs/tags/openmax-channel--v<version>and compare with the SHA the invitation shows; the installed copy's.claude-plugin/plugin.jsonversionmust match.Bundle ↔ source:
dist/is generated, not hand-written, and unminified. In a checkout of the tag:npm ci && npm run build && git diff --exit-code dist/— CI runs the same check on every PR.SDK: the bundled
@openmaxai/openmax-agent-sdksource is public (github.com/openmaxai/openmax-agent-sdk) and its npm releases carry provenance —npm view @openmaxai/openmax-agent-sdk@<version> dist.attestationsornpm audit signaturesin a checkout.
Running (from source / dev)
npm install # resolves @openmaxai/openmax-agent-sdk@alpha from npm
cp config.example.json ~/.config/claude-openmax/config.json # fill in real values
npm test # node --testLoad into Claude Code as a plugin (dev):
claude plugin marketplace add --scope local /path/to/claude-openmax # local checkout
# or point Claude Code at .claude-plugin/plugin.json directlyBuild (maintainers)
The plugin ships a dependency-free bundle. Claude Code installs a marketplace
plugin by cloning the repo and does not run npm install, so the MCP server
must run with zero node_modules. scripts/build.js (esbuild) inlines every
dependency into dist/index.mjs (the MCP server, referenced by
.claude-plugin/plugin.json) and dist/bridge.mjs (the split-topology bridge).
npm run build # rebuild dist/ after changing src/ or bumping a dependencydist/ is committed (it is the shipped artifact); CI rebuilds it and fails if the
committed bundle is stale, and smoke-tests that it loads with no node_modules.
Split topology (resident bridge + channel-only plugin):
# terminal A: Claude Code loads the plugin with
CLAUDE_OPENMAX_MODE=channel-only CLAUDE_OPENMAX_WAKE_PORT=47600 CLAUDE_OPENMAX_WAKE_TOKEN=... claude ...
# terminal B: resident bridge (config.wake.endpoint = http://127.0.0.1:47600/wake)
CLAUDE_OPENMAX_WAKE_TOKEN=... node src/bridge.jsConfig / env
Config file at $CLAUDE_OPENMAX_CONFIG (or ~/.config/claude-openmax/config.json);
see config.example.json. As of the config-parity refactor the on-disk shape is a
1:1 structural mirror of the OpenMax (zylos-openmax) component's config — see
the migration note below. The shape:
enabled?: bool
server: { bff_url, ws_url, frontend_base_path } // frontend_base_path default "/workspace"
agent: { identity_id, api_key, device_id, app_version }
cf_access: { client_id, client_secret }
orgs: { "<org_id>": { enabled?, org_id, org_name?,
owner: { member_id, name },
self: { member_id, name, display_name },
access:{ dmPolicy, dmAllowFrom?, groupPolicy?, groups?:{ "<convId>": { mode, allowFrom } } } } }
wake: { endpoint } // claude-openmax ONLY (openmax has no wake)
metricsReport?: { dashboardApiKey } // RESERVED / forward-compat — inert (no reporter yet)
ws?: { reconnectMaxMs?, heartbeatIntervalMs?, pingIntervalMs? } // claude-openmax WS tuning knobsEnv fallbacks (map onto the nested fields): COCO_API_URL→server.bff_url,
COCO_WS_URL→server.ws_url, COCO_FRONTEND_BASE_PATH→server.frontend_base_path,
COCO_API_KEY→agent.api_key, COCO_DEVICE_ID→agent.device_id,
COCO_CLIENT_VERSION→agent.app_version, COCO_ORG_ID→default org. Other knobs:
CLAUDE_OPENMAX_DATA_DIR, CLAUDE_OPENMAX_MODE, CLAUDE_OPENMAX_DEBOUNCE_MS,
CLAUDE_OPENMAX_CONTENT_FREE, CLAUDE_OPENMAX_WAKE_{HOST,PORT,TOKEN},
CLAUDE_OPENMAX_CHANNEL (1 = this session receives workspace messages; see
"Which session receives messages").
orgs is keyed by org_id (openmax-style), end to end: the SDK orchestrator
keys its per-org runtime records by org_id too, so the adapter hands it an
org_id-keyed map directly — there is no separate per-org key to derive. Every
self-healing write-back (self.member_id, self.name, owner bind) resolves the
org by org_id and lands back in the org_id-keyed on-disk structure.
agent.identity_id is the agent's global identity. Leave it empty and the
adapter resolves it from cws-core GET /me at startup and caches it back to
config.json. It is the leadAgentId for the guided-autonomy flow (an Issue's
Lead agent = the agent itself).
server.frontend_base_path is wired into the SDK's CwsHttpClient.frontendUrl()
so the agent can build clickable workspace links (<bff_url><frontend_base_path>/…,
default /workspace).
Migrating from the openmax (zylos-openmax) component
The claude-openmax config is now structurally identical to the openmax
component's config.json — you can drop an openmax config in as-is. The only
differences are additive and claude-openmax-specific:
wake.endpoint— required for the split-topology bridge; openmax has no wake block.metricsReport— accepted for parity but inert (claude-openmax has no metrics reporter yet); it round-trips untouched.ws— optional WS tuning knobs (reconnectMaxMs,heartbeatIntervalMs,pingIntervalMs) that openmax hardcodes;ws_url/device_id/app_versionlive underserver.*/agent.*, NOT here.
The old claude-openmax shape (top-level http/auth + an array orgs) is
still accepted: it is translated to the new shape on load with a one-time warning,
so an existing live config won't break — but you should migrate it.
Session files auto-migrate. Per-org state (incl. the /sync cursor) is now
keyed by org_id (sessions/<org_id>.json), where earlier builds used a derived
slug (sessions/<slug>.json). On first load, if only a legacy sessions/<slug>.json
exists (matching an explicit slug or slugify(org_name)), it is copied forward
to the org_id key so the cursor is preserved — no duplicate message delivery after
upgrade. The old file is left in place (harmless); no manual step is needed.
Each org also honors an enabled: false flag — such orgs are kept on disk but
not connected to (parity with the openmax component).
Verified vs. spike (honesty ledger)
Verified locally (node --test + MCP client smoke):
WakeRequest derivation/validation,
ok:truegating, coalescing, tool dispatch — 32 unit tests green.The MCP server boots, advertises
capabilities.experimental["claude/channel"], and lists all 7 tools to a real MCP client.POST /wake(token-guarded) →server.notification({method:"notifications/claude/channel", ...})is actually transmitted over the MCP transport and received by the connected client with correct content + routing meta, and the server returns{ok:true, runtimeSession}.server.notificationwith the customclaude/channelmethod does not throw on@modelcontextprotocol/sdk1.22+.
⚠️ SPIKE — requires a live Claude Code to confirm (biggest technical uncertainty):
claude/channelrendering. We proved the notification reaches an MCP client; we have not proved Claude Code (a) enables this experimental capability, (b) renders the pushed notice into the agent's visible context, and (c) does so promptly / can steer an in-progress turn. Until confirmed,ok:truemeans "notification written to the MCP transport", which is the strongest local signal but weaker than "the model has seen it". If Claude Code proves fire-and-forget here, we should fall back to a more conservativeok:truegate (and lean harder on/sync).runtimeSessionbinding. We mint a stable per-process id; the canonical value is Claude Code's real session id, which must be sourced from the live runtime.Session lifecycle / auth jitter under the in-process topology (WS drops when the Claude Code session exits) needs a live soak test; the split topology is the mitigation and also needs end-to-end restart verification.
Tool budget. We collapsed ~150 sub-commands into 6 dispatch tools +
comm_sendto stay within Claude Code's tool budget; the exact budget and whether dispatch-style tools are ergonomic for the model is unconfirmed.
Boundaries
Consumes the SDK for all protocol/transport/sync/dedup/access-policy logic; reimplements none of it. Does not pass a custom
callbacks.dedupe(uses the SDK's built-in atomic deduper).No dependency on
zylos-openmax; independent local data dir (no~/zylos).
Available Tools
7 toolsasA
Artifact store: upload/download media, resolve artifact:// URIs, presigned URLs. method = a camelCase verb like uploadMedia, getMediaUrl, downloadMedia, resolveUris. Pass a FLAT params object as usual — the adapter maps it to the SDK's positional call shape for you (e.g. getMediaUrl(idOrUri, opts)); you do NOT need to construct positional args. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Inputs: method (required), params.
commB
Communication: conversations, messages, history, mark-read, sync, DM access control. method = a camelCase verb like getMessages, getMessage, send, listConversations, createDm. Prefer the comm_send tool for replies. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Common methods (*=required, ?=optional; — gloss names each verb's purpose; see "list" for the rest + full summaries): listConversations(cursor?, limit?, includeArchived?) — browse conversations; createDm(peerMemberId*) — open a DM; getMessages(conversationId*, afterSeq?, beforeSeq?, limit?) — history for context; getMessage(conversationId*, messageId*) — read one message; send(conversationId*, content*, replyTo?, clientMsgId?) — send msg (prefer comm_send)
Inputs: method (required), params.
comm_sendA
Reply to / send a message into a conversation. Provide the endpoint from the wake notice (or a bare conversation id), the content text, and optionally replyTo (parent message id) and orgId.
Inputs: content (required), endpoint (required), orgId, replyTo.
connC
Connection credentials: list/acquire/proxy connection credentials + local cache. method = a camelCase verb like list, acquire, proxy, status, cached. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Common methods (*=required, ?=optional; — gloss names each verb's purpose; see "list" for the rest + full summaries): list(agentMemberId?) — list connections; acquire(connectionId*, agentMemberId?) — get credential; proxy(connectionId*, method?, url?, headers?, body?, agentMemberId?) — request via connection; status(connectionId*) — connection details
Inputs: method (required), params.
coreB
Directory/identity: me, member/agent/org/role/invitation directory, agent profiles, self rename, onboarding. method = a camelCase verb like me, memberList, agentProfiles, orgList, selfRename. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Common methods (*=required, ?=optional; — gloss names each verb's purpose; see "list" for the rest + full summaries): me() — your own identity; memberList(kind?, status?, search?, page?, pageSize?, orderBy?) — find member ids; agentProfiles(projectId*, memberIds*, capabilities?, include?) — agent skills/capabilities; projectList(status?, page?, pageSize?, orderBy?) — browse projects; selfRename(name*) — rename yourself; orgList(orderBy?) — list your orgs
Inputs: method (required), params.
kbA
Knowledge base: KB collections, directory tree nodes, pages + content/revisions/trash, full-text search, file upload. method = a camelCase verb like create, pageCreate, pageContentWrite, search. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Common methods (*=required, ?=optional; — gloss names each verb's purpose; see "list" for the rest + full summaries): list(limit?, offset?) — browse KBs; create(name*, visibility?, description?, icon?) — new KB (explicit only); treeRoots(kbId*) — KB root nodes; folderCreate(kbId*, name*, parentId?) — new folder node; pages(cursor?, limit?, offset?) — list pages; pageCreate(kbId*, title*, body*, format?, parentId?, message?) — new page; pageGet(pageId*) — page metadata; pageContent(pageId*) — read page body; pageContentWrite(pageId*, body*, message?, baseRevisionId?, autoSave?) — write page body; search(query*, kbId?, limit?, offset?, sort?) — full-text page search; upload(filePath*, parentId?, contentType?, filename?) — upload file to KB
Inputs: method (required), params.
tmA
Task management: projects, issues, tasks, blueprints, comments, attempts, event-bindings (cws-work via cws-core). method = a camelCase verb like projectCreate, issueCreate, taskCreate. Call with {"method":"","params":{...}}. Use {"method":"list"} for the FULL per-method purpose + field schema.
Common methods (*=required, ?=optional; — gloss names each verb's purpose; see "list" for the rest + full summaries): projectList(status?, query?, page?, pageSize?, orderBy?) — browse projects; projectCreate(name*, leadMemberId*, description?, slug?, isDefault?, knowledgeBaseId?, memberIds?) — new project (explicit only); issueList(status?, statuses?, priority?, includeArchived?, query?, page?, pageSize?, orderBy?) — browse all issues; issueListInProject(projectId*, status?, statuses?, priority?, includeArchived?, query?, page?, pageSize?, orderBy?) — issues in one project; issueGet(id*) — read one issue; issueCreate(projectId*, title*, leadAgentId*, ownerMemberId*, description?, backlog?, priority?, originConversationId?, originMessageId?) — create issue w/ owner=acceptor; issueSubmitPlan(id*, blueprintId*, planText?, source?, cardMessageId?) — submit plan (needs blueprint); issueAcceptPlan(id*, source?) — owner accepts plan; issueDeliver(id*) — in_progress→delivered; issueAcceptDelivered(id*, source?) — owner accepts delivery; taskList(projectId?, issueId?, status?, includeArchived?, page?, pageSize?, orderBy?) — browse tasks; taskCreate(projectId*, issueId*, title*, description?, assigneeId?, blueprintStepId?, dependsOn?) — create task under issue; taskClaim(id*) — claim ownership (not start); taskStart(id*) — begin work, opens attempt; taskTransition(id*, status*) — task→terminal state; commentCreate(workType*, workId*, bodyMarkdown*) — comment on issue/task; blueprintCreate(issueId*, steps*, estimatedBudget?, notes?) — create plan skeleton; attemptTransition(id*, status*, failureReason?, blockedOnApprovalRequestIds?) — generic state-machine transition
Inputs: method (required), params.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Tools have overlapping purposes: comm and comm_send both handle sending messages, and core's projectList duplicates tm's projectList. This creates ambiguity for an agent.
Tool names are inconsistent: some are short abbreviations (as, tm), others are full words (comm, core), and one uses an underscore (comm_send). No clear pattern.
7 tools is reasonable for the breadth of services, though some consolidation could reduce overlap. Still within an acceptable range.
Covers major domains (artifacts, tasks, comm, KB, identity, connections) but has noticeable gaps like missing update/delete for many entities and a separate send tool that feels incomplete.
Maintenance
Related MCP Connectors
Shared memory MCP server for Claude Code, Codex, Gemini CLI and Cursor. Cited, editable.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Connect ChatGPT and Claude to your Mac, Windows or Linux with secure MCP remote access.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceThe self-hosted MCP bridge between Claude Chat and Claude Code.46AGPL 3.0
- AlicenseNot gradedqualityDmaintenanceA Slack MCP server for Claude Code that provides full messaging, channels, search, and threads across multiple Slack workspaces.156 npm1MIT
- FlicenseNot gradedqualityDmaintenanceA bidirectional MCP bridge that lets Claude Desktop and Claude Code collaborate on a build with no human in the execution loop.-
- AlicenseNot gradedqualityDmaintenanceA secure, local communication runtime bridge that interfaces a cloud-based Large Language Model (Claude Desktop) with a local machine execution environment using the Model Context Protocol (MCP).Eclipse Public 2.0