Cowork

io.github.slashman413由 GitHub 帳號 slashman413 發布v1.0.1更新於 Oct 27, 2026

Self-hosted MCP task inbox shared by Claude Code, Codex, Gemini CLI and local LLMs.

概覽

AI 產生的概覽

自架的 MCP 任務收件匣與儀表板,讓多個 AI 程式開發代理共用一個任務佇列,並支援模型路由與容錯切換。

可以做什麼
  • 註冊與管理代理:註冊用戶端及其可執行的模型、取消註冊代理、送出心跳,並查詢約 285 個代理、19 個部門的名冊
  • 處理任務收件匣:為其他代理或平台建立任務、認領待處理任務、提交結果完成任務,並依狀態或平台篩選列出任務
  • 檢視運作概況:取得包含作用中代理與收件匣統計的完整儀表板資料
  • 調度與編排:把任務分派給具名模型,支援備援鏈、依部門覆寫與單一任務指定,並提供宣告式工作流程與產出物管理
適用情境
適合在一台或多台機器上執行多個程式開發代理或命令列工具,希望用一個共用佇列讓代理彼此交接任務,並在模型觸發速率限制時自動切換。也適合想要自架儀表板觀察代理活動的團隊。
執行需求
以本機程序或容器方式執行。原始碼安裝需要 Node.js 20 以上與 npm 10 以上,僅作中樞的映像需要 Docker。agency-agents 儲存庫以 git 子模組形式隨附。API 與 MCP 端點需要 COWORK_API_KEY 作為 Bearer 金鑰;未設定時首次啟動會產生並只列印一次。Antigravity 配額計量可選地需要 Google OAuth 用戶端參數。
安裝前請注意
API 與 MCP 端點受金鑰保護:持有金鑰者,或在關閉驗證時能連上該連接埠的人,都能為你的模型建立任務。綁定所有網路介面會讓儀表板暴露在網路上。被分派的任務會在環境變數中取得該 API 金鑰。README 提到付費的 Pro 方案與組合包。伺服器會把任務、產出物與設定檔寫入磁碟,並可在已連線的機器上執行任務。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Cowork,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

🤝 Cowork — one task inbox for Claude Code, Codex, Gemini CLI & Hermes agents

A self-hosted MCP server + web dashboard that lets different AI coding agents share one task queue. Dispatch a task from any of them (or from the UI); a dispatcher routes it to a named brain (model × CLI × machine), runs it, verifies the result, and falls back to the next brain on rate limits. Workflows, artifacts, remote machines and cost/usage meters are built in.

  • Mixed-vendor agents, one inbox: Claude Code, Codex, Gemini CLI / Antigravity, Hermes, Ollama.
  • Brain routing with fallback chains: route by role, pin by task, fail over on quota errors.
  • Plain files on disk: the task store is files. No database to run.
  • Remote brains: another machine joins with one command and offers its models (JOIN-AS-A-BRAIN.md): COWORK_URL=http://<host>:6868 HOST=<you> node cowork/deploy/remote-brain-client.mjs

Jump to: Quick Start · Connecting agents · Dispatcher · Brains · Workflows · MCP tools

Screenshots

One dark-themed single pane of glass for the whole operation: live host metrics (CPU / GPU / memory / temp), open-task and Agencies counters, the dispatcher's current role → model chains, and a real-time activity feed.

[Cowork dashboard — metrics, counters, dispatcher chains, and live activity]

The Workflows, Task Inbox, Brains, Connections, and Chat views are shown in context throughout this README.

Supported Platforms

PlatformAgentsFormat
Claude Code~285.md with YAML frontmatter
Antigravity (AGY)Built-in + skillsSKILL.md
Hermes Agent39 skillsSKILL.md + triggers
Gemini CLIConverted from source.md subagents
GitHub CopilotSame as Claude.md agents
CodexConverted.toml agents
CursorConverted.mdc rules
+ 7 moreSee agency-agents repoVarious formats

Quick Start

Prerequisites

  • Node.js ≥ 20 (tested with v22)

  • npm ≥ 10

  • The agency-agents repo — bundled as a git submodule at cowork/agency-agents (the Agencies — 285 agents). Clone with submodules:

    bash
    git clone --recurse-submodules https://github.com/slashman413/cowork# already cloned without it? initialise the submodule:git submodule update --init

Fast path — two scripts (recommended)

From the repo root, after cloning with submodules (above):

bash
# 1. Build + launch the server (installs deps, builds, starts a systemd user service)deploy/install-server.sh
# 2. Drop the coordination skill + MCP connection into your agent clients on this boxdeploy/install-skill.sh            # auto-detects Claude Code / Hermes / Antigravity

install-server.sh generates a systemd unit with this machine's real node path and working dir (nothing to hand-edit), or pass --foreground to launch in the terminal and --build-only to stop after building. install-skill.sh copies the right per-client skill into place and, for Claude Code, merges mcpServers.cowork into ~/.claude.json non-destructively (add --url http://<host>:6868 for a remote server; --client claude|hermes|agy|all to target one). The numbered steps below are the same thing, broken out for when you want to do it by hand.

Container (hub only)

bash
docker run -d -p 6868:6868 -v cowork-data:/data ghcr.io/slashman413/cowork:1.0.1docker logs <container>   # first start prints the generated API key once

The image (amd64 + arm64) runs the MCP server, dashboard and task inbox with the local dispatcher off: agents connect to http://<host>:6868/mcp, and machines offer their brains with deploy/remote-brain-client.mjs (see JOIN-AS-A-BRAIN.md). Config and all state live in the /data volume. /api and /mcp always require a key: pass your own with -e COWORK_API_KEY=…, or the server generates one on first start, saves it to /data/api-key and prints it once. Clients send Authorization: Bearer <key> (the brain client reads COWORK_API_KEY); open http://<host>:6868/?apiKey=<key> once to log the dashboard in. Images are built from v* tags by .github/workflows/release.yml on a digest-pinned base.

1. Install Dependencies

bash
cd cowork/servernpm install

2. Configure Settings

Config lives outside the repo. The tracked cowork/config.json is a sanitized template only. On first run the server copies it to ~/.cowork/config.json — your real per-server config (host binding, registered brains, chains). Edit that copy, not the template; the server also persists all live dashboard/API edits there, so your personal host/brain settings never touch the repo. Override the location with the COWORK_CONFIG env var.

Edit ~/.cowork/config.json to match your environment:

json
{  "server": {    "port": 6868,          // ← Change the port here    "host": "0.0.0.0",     // ← Bind address (0.0.0.0 = all interfaces)    "name": "cowork-mcp",    "version": "1.0.0",    "apiKey": null          // ← Set a string to require API key auth (see below for null)  },  "paths": {    "agencyAgents": "./agency-agents",  // ← Path to agency-agents repo    "inbox": "./inbox",    "status": "./.status",    "decisions": "./decisions",    "workflows": "./workflows",    "artifacts": "./artifacts",    "inputs": "./inputs"  }}

All paths are relative to cowork/ (the parent of server/). Use ~ for home directory paths (e.g., ~/.claude/agents).

Key Settings
SettingDefaultDescription
server.port6868HTTP port for MCP endpoint + Web UI
server.host0.0.0.0Bind address (127.0.0.1 for local-only)
server.apiKeynullAPI key for /api and /mcp. When null and host is not loopback, a key is generated into api-key beside the config and printed once
server.allowUnauthenticatedfalseServe a non-loopback host with no key (also COWORK_ALLOW_NO_AUTH=1). Only for a trusted, firewalled network
paths.agencyAgents./agency-agentsPath to the agency-agents repo
platforms.*.enabledtrueEnable/disable individual platforms
platforms.*.agentsDirvariesWhere platform-specific agents live on disk
services.*.enabledfalseEnable/disable service health monitoring

3. Start the Server

bash
# Development mode (with hot-reload)cd cowork/servernpm run dev
# Production modenpm run buildnpm start

You should see:

🤝 Cowork MCP Server running at http://0.0.0.0:6868   MCP endpoint: http://0.0.0.0:6868/mcp   Web Dashboard: http://0.0.0.0:6868/   REST API: http://0.0.0.0:6868/api/   Agencies loaded: 285 agents across 19 divisions

4. Open the Dashboard

Open http://localhost:6868 in your browser.


Connecting AI Agents

The fastest way to talk to any connected model is the dashboard's Chat view: pick a brain, optionally scope it to a division and a specific agent, and your message is dispatched as a task — the reply is the task result.

🎙 Voice assistant (Chat → Voice)

Talk a new idea through, hands-free if you like. Each turn runs on the best brain that is enabled and not cooling down on a rate limit (claude › codex › agy › hermes/dsh › ollama; pin an order with orchestration.voice.brains). If that brain gets rate-limited, the turn moves to the next one.

  1. Grill: it uses the grill-me skill (/grilling): one question at a time, each with a recommended answer, until nothing is ambiguous. Open questions are listed as it goes.
  2. Plan: it proposes a plan: a yes/no success criterion and a few ordered phases.
  3. Execute (only with your permission): tap Approve & execute, or say "go ahead" while the plan is on screen. The plan becomes an active Goal that the Achiever/Judger loop drives through tasks until the success criterion is met. Phase progress is read aloud as it happens.

Speech-to-text and text-to-speech run in the browser (Web Speech API: Chrome, Edge or Safari). The mic needs HTTPS or localhost. You can always type instead. Turns are tasks tagged voice with context.conversational, so a question back to you counts as a finished reply and is never parked on wait-input. REST: /api/voice/brains and /api/voice/sessions[/:id[/turn|/execute]]. Sessions are stored in voice-sessions/.

For programmatic access, wire the MCP connection into your agent clients:

Scripted (recommended): deploy/install-skill.sh installs the cowork coordination skill and wires the MCP connection for every agent client detected on the box — one command instead of hand-editing each config:

bash
deploy/install-skill.sh                          # auto-detect all clients, localhost serverdeploy/install-skill.sh --client claude          # just Claude Codedeploy/install-skill.sh --client all --url http://cowork-host:6868   # remote server, every client

It drops the per-client skill (canonical copies in deploy/skills/) into the client's live skill dir and, for Claude Code, merges the mcpServers.cowork entry into ~/.claude.json without disturbing your other servers. The manual per-client config is below for reference.

Claude Code

Add to your MCP configuration (~/.claude.json or project-level):

json
{  "mcpServers": {    "cowork": {      "url": "http://localhost:6868/mcp",      "transport": "streamable-http"    }  }}

Then in Claude Code, the agent can call:

Use the cowork MCP tools: register_agent, create_task, get_roster, etc.

Antigravity (AGY)

Add to your AGY MCP settings:

json
{  "mcpServers": {    "cowork": {      "url": "http://localhost:6868/mcp"    }  }}

agy quota meter / token refresh. To mint Antigravity access tokens, the usage probe and deploy/remote-brain-client.mjs need Google OAuth client values. These are the public values that ship with the agy and Gemini CLIs. They are not committed. Copy .env.example to ~/.cowork/oauth-clients.env, fill it in, and run chmod 600. Alternatively, export the same variables in the service environment; process env takes precedence. If no values are set, the agy meter only works while a cached CLI access token is still valid.

Hermes Agent

Configure the MCP endpoint in Hermes:

json
{  "mcp_endpoints": {    "cowork": "http://localhost:6868/mcp"  }}

Any MCP-Compatible Client

The server speaks standard MCP over Streamable HTTP. Any client that supports MCP can connect to http://localhost:6868/mcp.


Task Execution — the Dispatcher

The server includes a dispatcher that turns queued tasks into real agent runs. Output becomes the task result; the full transcript is saved as result.md in the task's artifacts dir.

Every task lands in the Task Inbox, tagged with the division/agent that ran it and the brain it ran on, with its output artifacts attached and filterable by status (done · in-progress · pending · wait-input · failed).

[Task Inbox — tasks tagged with division/agent, brain, and downloadable artifacts]

Two-stage routing

An unassigned task is routed in two stages by an orchestrator/classifier brain (default qwen3.8-27b via Hermes, orchestration.classifier):

  1. Division — pick 1 of 19 divisions (testing, engineering, security, …).
  2. Agent — pick 1 of ~285 agents in that division. The chosen agent's full .md persona becomes the system prompt.

The agent then runs on a brain fallback chain (below). Skip the classifier by targeting directly: context.agent: "<agent-slug>" or a special-executor name. Tag a task manual to never auto-execute.

Executors: special agents + the Agencies

  • Special executors (config.json → orchestration.agents) — only orchestrator, generalist, video; each is {description, brains: [...]} with its own chain. video runs the ComfyUI LTX pipeline (deploy/video-pipeline.sh; LTX only — never Wan/Hunyuan/SVD).
  • Agencies agents — the ~285 personas in the agency-agents submodule, grouped into 19 divisions. They have no chain of their own; they run on the division's chain if one is set, else the global default.

Brain fallback chains (GET /api/chains)

  • Global default — orchestration.defaultChain; drag-reorder in the Brains view (PUT /api/chains/default).
  • Per-division override — orchestration.divisionChains[<division>]; set/clear in the Agents view (PUT /api/chains/division/:division; empty = use default).

A chain runs top → bottom: the task runs on chain[0]; on failure the dispatcher hands over to chain[1], then [2]… recording the failed brain on the task each attempt, until success or the chain is exhausted. Pin a single task to one brain with context.brain: "<id>".

The Agents view exposes the per-division chain for every division — drag to reorder, + add brain…, or reset to the global default. No template edits, no restart.

[Agents view — per-division brain fallback chains, editable inline]

Brains — named execution identities (model × platform × location)

config.json → orchestration.brains (GET /api/brains) names each brain a chain can reference. The Brains view lists every registered brain — its platform (claude / agy / hermes), underlying model, location, and whether it was auto-registered by a connecting client — with one-click deregister:

[Brains view — every registered execution identity, model, and location]

AliasLocationRuns
local-hermes-qwen3.8-27blocalHermes on that model
local-dsh-qwen3-8-27blocalDeepSeek Harness (dsh) on that model
local-cc-opus-5-5 / -sonnet-5-5 / -fable-5-1localClaude Code on that model
local-agy-* / local-comfy-ltxlocalAntigravity/Gemini / ComfyUI-LTX video
remote-codex-gpt-5-6-terra / -luna / -defaultremoteCodex, claimed by the codex client (on this host)
remote-ai-code-gen-cc-opus-4-8 / -sonnet-5 / -fable-5remoteClaude Code on the ai-code-gen machine
remote-<host>-cc-sonnet-5-5remoteClaude Code on another machine

Brain ids carry the model version (local-cc-opus-5-5, not local-cc-opus) so the model a brain runs is readable from its id; only -default brains, which follow the account default, are unversioned. The local-/remote- prefix must match the brain's location, which means who runs it (local = the dispatcher spawns it; remote = a client claims it from the inbox), not which machine it is on. DeepSeek brains are retired — any id matching /deepseek/i is scrubbed from the registry on load (see DENYLISTED_BRAIN_RE), so never put deepseek in a new id.

Renamed ids keep working. BRAIN_ID_ALIASES in server/src/config.ts (plus an optional orchestration.brainAliases in config) maps retired ids to their canonical id. Old ids in an on-disk config, a task's context.brain pin, or a client's registration all resolve to the canonical brain. A client that still declares an old id keeps receiving its tasks under that id (clientId on the brain), until it re-declares the canonical one. Renamed on 2026-10-07:

Retired idCanonical id
local-ha-qwen3-8-27b, local-ha-qwen38-27b, local-ha-qwen3.8-27blocal-hermes-qwen3.8-27b
local-codex-default / -gpt-5-6-terra / -gpt-5-6-lunaremote-codex-default / -gpt-5-6-terra / -gpt-5-6-luna
remote-ai-code-gen-cc-opus / -sonnet / -fableremote-ai-code-gen-cc-opus-4-8 / -sonnet-5 / -fable-5

Local brains the dispatcher spawns here. Remote brains it leaves pending and publishes the brain id onto the task's context.brain so that machine's client can discover and claim it (the client filters list_inbox for tasks whose context.brain is one of its own ids). If no client claims a remote rung within orchestration.remoteGraceMs (default 60 s), the dispatcher advances to the next brain in the chain, so a clientless remote rung never stalls a task.

Artifacts work for both: local brains save files to $COWORK_ARTIFACTS_DIR (the dispatcher collects them from disk); remote brains save to the same env dir and the client uploads each file via POST /api/artifacts/:taskId/:file. Either way they land in artifacts/<task-id>/ and become downloadable from the Inbox. Outputs (the task's final deliverables) go in the outputs/ subfolder ($COWORK_OUTPUTS_DIR; remote clients upload via POST /api/outputs/:taskId/:file) and get their own OUTPUTS section on the card, after RESULT and before ARTIFACTS.

Input files flow the other way — a person attaches files for the brain to read. Attach them in the Chat composer (📎) or on any Inbox card ("+ Attach files"); they are stored under inputs/<task-id>/ and mirrored onto context.inputFiles. The dispatcher points a local brain at their absolute paths in the prompt; a remote brain client downloads them (GET /api/inputs/:taskId) before running and lists their local paths in the prompt. Inputs survive a re-run.

Failed tasks & re-run. When a task exhausts its whole fallback chain (every brain failed verification) it finishes flagged failed: true. The Inbox groups these under a red "failed" filter (kept out of the green "done" count) and offers a confirm-gated ↻ Re-run that resets the task to pending from the top of its chain (POST /api/inbox/:id/rerun) — preserving its brief and attached inputs.

Auto-registered brains (clients-capability protocol)

A connecting MCP client DECLARES the brains it can run via the register_agent tool's brains field; the server auto-adds them to the registry (marked dynamic, owned by that client). One machine can offer several models at once. Auto-registered brains persist and are removed only by deregister_agent or the Brains view (never on heartbeat timeout); removal cascades out of the default chain, every division chain, and every special agent. Manage all of this from the dashboard's Agents and Brains views.

Wiring a remote brain machine

deploy/remote-brain-client.mjs is a zero-dependency (Node 18+) Cowork MCP client that does exactly that loop. Its header comment documents every env var.

Quickest — run it directly (foreground; good for a first test). One brain:

bash
git clone https://github.com/slashman413/coworkCOWORK_URL=http://<cowork-host>:6868 EXEC=claude MODEL=claude-sonnet-5-5 \  BRAIN_ID=remote-<host>-cc-sonnet-5-5 \  node cowork/deploy/remote-brain-client.mjs

Several brains from one machine (declares them all; each becomes a targetable brain):

bash
COWORK_URL=http://<cowork-host>:6868 EXEC=claude HOST=<host> \  BRAINS='[{"id":"remote-<host>-cc-opus-5-5","model":"claude-opus-5-5"},           {"id":"remote-<host>-cc-sonnet-5-5","model":"claude-sonnet-5-5"}]' \  node cowork/deploy/remote-brain-client.mjs

As a boot service (recommended for permanent machines):

bash
mkdir -p ~/.config/cowork-remote-braincp cowork/deploy/remote-brain-client.env.example ~/.config/cowork-remote-brain/aicodegen.env# edit: COWORK_URL, BRAINS (or BRAIN_ID), EXEC, HOST, COWORK_CLIENT_JScp cowork/deploy/[email protected] ~/.config/systemd/user/systemctl --user daemon-reload && systemctl --user enable --now cowork-remote-brain@aicodegen

It connects to COWORK_URL/mcp, register_agents (declaring its BRAINS, which auto-register into the registry), then polls and claims only tasks whose context.brain is one of its brain ids, runs the matching EXEC/MODEL, and complete_tasks with its result and uploaded artifacts — appearing in Connections like any other client. Flexible: the same script serves any brain by changing env only. Scalable: add machines/brains by adding <name>.env files; claims are atomic (single-process compare-and-set) so even multiple clients on the same brain id never double-run a task — first claim wins.

Every connected client shows up live in the Connections view — grouped by platform, listing the brains it offers, its idle/busy state, and a per-session tally of how many tasks each brain has run vs. submitted:

[Connections view — live MCP clients, the brains they offer, and per-brain invocation counters]

The always-on coordinator agent shown in Connections as cowork/orchestrator polls the inbox, two-stage-routes unassigned tasks, reclaims orphans, and dispatches; transient per-task workers appear as e.g. testing / Workflow Optimizer · local-hermes-qwen3.8-27b or video · local-comfy-ltx while running.

CEO flow: tell Hermes (e.g. via Discord) an idea → Hermes creates ONE task with context.agent: "orchestrator" → the orchestrator decomposes it into subtasks via POST /api/inbox → each subtask is two-stage-routed to an agent on its brain chain → results and artifacts appear live on the dashboard.

LLM classifier — no task left behind

An unassigned task (e.g. a free-text idea filed straight from Discord) no longer stalls: the dispatcher runs the two-stage LLM router (default qwen3.8-27b via Hermes, orchestration.classifier in config.json) that reads the task, picks a division, then an agent, which then dispatches normally on that agent's brain chain. Tag a task manual to skip both routing and dispatch.

Stale-claim reclaim

orchestration.staleClaimMs (default 30 min) reclaims any in-progress task whose claiming agent has disappeared — a crashed/exited live agent or a dispatcher killed mid-run — back to pending so the work is retried. A task still owned by a heartbeating agent is never touched.

Dispatcher status: GET /api/dispatcher. Tune orchestration.maxConcurrent / taskTimeoutMs / pollIntervalMs / classifier / staleClaimMs in config.

Deployment (systemd) & Remote Access

Easiest — deploy/install-server.sh generates and enables the user service with this machine's resolved node path and working dir:

bash
deploy/install-server.sh          # build + install & start the cowork-mcp user service

Manual equivalent (the tracked deploy/cowork-mcp.service has /home/USER placeholders you must edit first — the script fills them in for you):

bash
cp deploy/cowork-mcp.service ~/.config/systemd/user/   # then edit the USER/paths insidesystemctl --user daemon-reloadsystemctl --user enable --now cowork-mcp

With server.host: "0.0.0.0" the dashboard is reachable from other machines at http://<host-ip>:6868/ (LAN or Tailscale IP — 0.0.0.0 itself is a bind address, not a URL). A non-loopback host always requires a key: set server.apiKey (or COWORK_API_KEY), or use the one generated into api-key beside the config on first start. Log the dashboard in once with http://<host-ip>:6868/?apiKey=<key> (it sets a same-site cookie). server.allowUnauthenticated: true opts out; anyone who can reach the port can then create tasks for your brains.

Moving a running open hub to a key without locking anyone out: set the key and keep allowUnauthenticated: true. That is soft (migration) mode: a valid key is accepted, a wrong key gets 401, and keyless requests still pass but are listed at GET /api/auth/keyless (key required). Give the key to every client (brain clients: COWORK_API_KEY; MCP configs: an Authorization: Bearer <key> header, e.g. deploy/install-skill.sh --key <key>; dashboards: /?apiKey=<key> once). Dispatched tasks get COWORK_API_KEY in their env automatically. When /api/auth/keyless stays empty, drop allowUnauthenticated and restart to enforce.

Switching from HTTP to HTTPS

By default the server listens over plain http://. That is fine over localhost, but a browser only exposes the microphone (the New-task Dictate speech-to-text button) in a secure context — https:// or http://localhost. Reach the dashboard over http://<lan-or-tailscale-ip>:6868 and navigator.mediaDevices is undefined, so Dictate can't start. Serving over HTTPS fixes it.

When server.tls points at valid cert/key files, Cowork runs a multiplexed dual-protocol listener on port 6868 that accepts both HTTP and HTTPS simultaneously:

  • Localhost in Chrome (http://localhost:6868/): Chrome and modern browsers natively treat http://localhost as a W3C-standard Secure Context (window.isSecureContext === true). The New-task Dictate mic button and clipboard work out of the box with zero certificate warnings.
  • Remote / Mobile on Tailscale (https://<machine>.tailXXXX.ts.net:6868/): Remote connections use the valid Let's Encrypt TLS certificate provisioned via Tailscale. Chrome shows a verified, trusted green lock.
  • Automatic IP/Domain HTTP-to-HTTPS Redirection: Requests arriving over plain HTTP for external hostnames or IPs are automatically redirected (302) to the trusted HTTPS domain.
  • SNI Fallback: Multi-domain TLS SNI callback routes domain traffic to the trusted certificate and loopback TLS traffic to the local fallback certificate.

Migrate in this order:

  1. Obtain or Generate a TLS Certificate:

    • Tailscale Let's Encrypt (Recommended, Zero Warnings):
      bash
      deploy/update-tailscale-cert.sh
      This fetches a genuine Let's Encrypt certificate via tailscale cert and installs it to ~/.cowork/tls/cert.pem and ~/.cowork/tls/key.pem.
    • Self-Signed (Alternative):
      bash
      server/gen-tls-cert.sh ~/.cowork/tls cowork-host 100.80.243.33 cowork.tailXXXX.ts.net
  2. Point the config at the files. Add a tls block under server in ~/.cowork/config.json (the live config — the repo config.json is only the default template and ships "tls": null):

    jsonc
    "server": {  "host": "0.0.0.0",  "port": 6868,  "tls": { "certFile": "~/.cowork/tls/cert.pem", "keyFile": "~/.cowork/tls/key.pem" }}

    ~ and repo-relative paths are resolved for you. This is the step most often missed: generating the cert alone does nothing — without this block the server stays on http://.

  3. Restart the server so the new scheme takes effect. A plain systemctl --user restart cowork-mcp run from inside a task SIGKILLs that task (it is a child of the unit it's restarting), so use the idle-safe redeploy, which waits until no task is in flight:

    bash
    systemd-run --user --collect --unit=cowork-server-redeploy \  deploy/redeploy-server-when-idle.sh

    Confirm it came up:

    bash
    journalctl --user -u cowork-mcp -n 10 | grep -E 'Trusted HTTPS|Local HTTP|API:'curl -s http://localhost:6868/api/status | jq .uptime
  4. Accessing the Dashboard in Chrome:

    • On the host machine: Open http://localhost:6868/ (Secure Context active, 0 SSL warnings).
    • From remote devices or mobile: Open https://<tailscale-domain>:6868/ (Trusted Let's Encrypt SSL lock).
  5. Updating Agent Clients and Skills: Run deploy/install-skill.sh, which automatically detects your Tailscale domain or localhost configuration:

    bash
    deploy/install-skill.sh --client all

Server-side self-dispatch is loopback-optimized — local subtask dispatch runs over http://localhost:6868 through the multiplexed listener, avoiding TLS handshake overhead and certificate hostname mismatch errors entirely.

To roll back, set server.tls to null (or remove the block) and redeploy — the server returns to http://.

MCP Tools Reference

Once connected, agents have access to these tools:

ToolDescription
register_agentRegister this client; optionally DECLARE the brains it can run
deregister_agentRemove this client and cascade-remove every brain it registered
heartbeatUpdate status and current task
get_rosterSearch ~285 agents across 19 divisions
create_taskCreate a task for another agent/platform
claim_taskClaim a pending inbox task
complete_taskMark a task as done with results
list_inboxList inbox tasks with status/platform filters
get_dashboardGet full dashboard data (active agents, inbox stats, etc.)

Example: Cross-Platform Task Dispatch

You: "Review the auth code in saas-starter"
AGY Agent calls:  create_task(    title: "Review auth middleware",    from_platform: "antigravity",    from_agent: "self",    to_platform: "claude",    to_agent: "engineering-code-reviewer",    priority: "normal"  )
→ Task appears in dashboard inbox→ Claude Code picks it up, runs review→ Claude calls complete_task(...) with its result + artifacts→ Result + artifacts appear on the task card

Workflows — declarative pipelines, two execution modes

A workflow is a version-controlled template (workflows/<id>.json). It runs in one of two modes, chosen per template with "mode":

The Workflows view renders each template as a live graph — sequential fan-through pipelines and parallel fan-out/fan-in diamonds alike — with every step pinned to a division or agent, plus Dry run (inspect the resolved plan) and Run controls:

build-and-ship — a 5-step engineering pipelineexpand-perspectives — parallel multi-lens fan-out → synthesis
[Build & Ship workflow — architect → build → CI → review → push][Expand Perspectives and Feedback → Roadmap workflows]
  • dag (default) — static & deterministic. The steps form a DAG wired by dependsOn; the whole graph is expanded into inbox tasks up front and the dispatcher walks it in dependency order. No new execution engine: expansion just pre-wires the tasks the dispatcher runs anyway. A multi-step job becomes reusable and inspectable instead of an LLM re-planning from scratch every time.
  • orchestrated — adaptive & orchestrator-driven. The steps are a library of candidate moves; nothing is planned up front. After each step finishes, the orchestrator brain decides the next step automatically from the goal + the results so far — or answers DONE. The path taken adapts to what comes back. Every decision (the step it chose + its rationale) is logged to workflow-runs/<runId>.json and rendered as a decision log in the dashboard.

DAG mode

A template is a list of steps; each step is a task with a stable key that other steps reference in dependsOn (resolved to real task ids at run time):

json
{  "id": "content-pipeline",  "params": ["topic"],  "steps": [    { "key": "research", "title": "Research: {{topic}}", "division": "marketing" },    { "key": "draft",    "title": "Draft {{topic}}", "division": "marketing", "dependsOn": ["research"] },    { "key": "review",   "title": "Review {{topic}}", "agent": "code-reviewer", "dependsOn": ["draft"] },    { "key": "publish",  "title": "Publish {{topic}}", "division": "marketing", "dependsOn": ["review"] }  ]}

Run it (or dry-run to inspect the resolved plan without creating anything):

bash
curl -s -X POST localhost:6868/api/workflows/content-pipeline/run \  -H 'content-type: application/json' -d '{"params":{"topic":"RISC-V laptops"}}'

Every task a run creates carries context.workflowId, context.workflowRunId, and context.stepKey so the Workflows tab in the dashboard can group a run and render its DAG with per-node live status. Templates are validated on load (unique keys, deps exist, and the graph is acyclic — a cycle would deadlock dependsOn forever); a template that fails validation is skipped rather than crashing the list, and the reason is surfaced in the dashboard (and at GET /api/workflows-invalid) so a malformed template is easy to fix. Steps can pin an agent, division, or brain, or leave them off and let the router pick.

Orchestrated (adaptive) mode

Set "mode": "orchestrated", give the template a goal, and list the steps as a candidate library (dependsOn becomes an optional hint used to wire a step's inputs when its upstream has already run). Running it writes a run record and creates no tasks — the dispatcher's orchestrator loop makes the first decision on its next tick, then one more after each step completes:

json
{  "id": "adaptive-research",  "mode": "orchestrated",  "goal": "Produce a decision-ready brief answering: {{question}}",  "params": ["question"],  "steps": [    { "key": "scope",     "title": "Scope the question", "division": "operations" },    { "key": "survey",    "title": "Broad survey", "division": "operations" },    { "key": "deep-dive", "title": "Deep dive on the crux" },    { "key": "counter",   "title": "Steelman the opposing view" },    { "key": "brief",     "title": "Write the decision brief" }  ]}

The orchestrator brain (the router model — orchestration.classifier, else the first local runnable brain in the orchestrator/default chain) is prompted with the goal, the completed steps and their results, and the remaining candidates; it replies with one step key or DONE. orchestration.maxWorkflowSteps (default 12) force-finishes a run whose orchestrator never says DONE.

Both modes stamp every task with context.workflowId, context.workflowRunId, and context.stepKey so the Workflows tab groups a run and renders it live — a DAG for static runs, a decision timeline for adaptive ones. Templates are validated on load (unique keys, deps exist, and — for DAG mode — the graph is acyclic); a template that fails validation is skipped rather than crashing the list, and the reason is surfaced in the dashboard (and at GET /api/workflows-invalid).

The engine (validation, cycle detection, topological expansion, DAG wiring, run reconstruction, and the orchestrated decision loop) is covered by a test suite — cd server && npm test.

Shipped company workflows

The workflows/ directory ships a set of realistic, cross-functional company pipelines. Each step pins a division or agent (never a brain), so the brain fallback chain for every role stays editable from the dashboard's Agents view (orchestration.agents[*].brains for special agents; divisionChains[*] / defaultChain for agents) — change who runs a step without touching the template.

WorkflowModeWhat it does
idea-to-launchdagThe flagship. CEO brief → market research + perspectives → PM spec → architecture → engineers build the real product & push to GitHub with GH Actions → marketing promos + email auto-replies → sales enablement → finance model → Chief-of-Staff go/no-go review. params: idea
product-specdagPM writes a build-ready PRD, fed by user research + engineering feasibility, then cut into a shippable first sprint. params: idea
build-and-shipdagTake a spec → architect → dispatch engineers to build real code → wire the GitHub Actions CI pipeline → code review → push & verify the pipeline is green. params: spec
feedback-to-roadmapdagRaw feedback from an employee/customer → triage → synthesize into themes → PM initiatives → prioritized roadmap → dispatch the "Now" items as real work. params: feedback
gtm-campaigndagMarketing + sales wire a launch: offer & promo angles → email sequences + inbound auto-reply rules → content → sales enablement → success metrics. params: product
finance-closedagThe accounting cycle: bookkeeper reconciles → FP&A variance → forward model → CFO sign-off + board summary. params: period
expand-perspectivesdagResearchers deep-dive an idea from four independent lenses (first-principles, precedent, contrarian, second-order) in parallel, then synthesize a decision-ready perspective map. params: idea
adaptive-researchorchestratedAdaptive deep research — the orchestrator drills only where the goal needs it. params: question
plan-executionorchestratedTurns a plan into dispatched jobs and drives them to verified completion. params: plan
content-pipelinedagResearch → draft → review → publish. params: topic
product-briefdagMarket + tech + risk fan-out → one-page go/no-go brief. params: idea
bash
# Run the flagship end-to-end company workflow:curl -s -X POST localhost:6868/api/workflows/idea-to-launch/run \  -H 'content-type: application/json' -d '{"params":{"idea":"a self-hosted receipts scanner"}}'

REST API

The Web UI uses these endpoints (also available for scripts/integrations):

MethodPathDescription
GET/api/statusDashboard overview data
GET/api/agentsAll active agents (id → name)
GET/api/connectionsLive MCP clients (heartbeat) + per-brain ran/submitted counters
GET/api/inbox?status=pendingInbox tasks (filterable)
POST/api/inboxCreate a new task; optional inputs: [{token,name}] attaches uploaded files
PATCH/api/inbox/:idClaim or complete a task
POST/api/inbox/:id/rerunRe-queue a FAILED (chain-exhausted) task — reset to pending from the top of its chain, keep its inputs
GET/POST/api/inbox/:id/inputsList / attach input files to an existing task ({inputs:[{token,name}]})
POST/api/uploads?name=<file>Stage an uploaded file (raw body) → {token} to pass as a task input
GET/api/inputs/:taskId, /:taskId/:fileList / download a task's attached input files
GET/api/workflows / /api/workflows/:idDeclarative workflow templates (validated)
GET/api/workflows-invalidTemplates that failed to load, with the reason (JSON/validation errors)
POST/api/workflows/:id/runStart a run: expand a DAG template into tasks, or begin an orchestrated run; { params, dryRun }
GET/api/workflow-runs / /api/workflow-runs/:runIdRuns for the run view (DAG grouped from tasks; orchestrated from run records + decision log)
GET/api/roster?division=engineeringAgencies (filterable)
GET/api/roster-divisionsAgencies grouped by division (for the Agents view)
GET/api/dispatcherSpecial agents + brains + defaultChain + divisionChains + running
GET/PUT/api/chains, /chains/default, /chains/division/:divRead/edit brain fallback chains
GET/PUT/DELETE/api/brains, /api/brains/:idBrain registry (cascades on delete)
GET/PUT/DELETE/api/agents-config, /api/agents-config/:nameSpecial-executor chains
GET/POST/api/artifacts/:taskId, /:taskId/:fileList/download; POST (raw body) uploads a file from a remote brain
GET/api/configCurrent configuration
GET/api/eventsSSE event stream

Directory Structure

cowork/├── config.json              # TEMPLATE only — real config at ~/.cowork/config.json├── README.md                # This file├── PROTOCOL.md              # Protocol specification├── JOIN-AS-A-BRAIN.md       # Onboarding for a remote brain client├── agency-agents/           # git SUBMODULE — the Agencies (~285 agents)├── workflows/               # Workflow templates (*.json) — DAG + orchestrated├── workflow-runs/           # Orchestrated run records + decision logs (gitignored)├── server/                  # MCP Server + Web UI│   ├── src/                 # TypeScript source│   └── public/              # Web UI (HTML/CSS/JS)├── deploy/                  # systemd units, remote-brain client, presets, skills├── inbox/                   # Task queue (JSON files, auto-managed)├── artifacts/               # Per-task OUTPUT files (audio/video/md), downloadable├── inputs/                  # Per-task INPUT files a person attached for the brain (gitignored)├── decisions/               # Decision log└── .status/                 # Runtime state (auto-managed)

Debugging

MCP Inspector

Test the MCP endpoint with the official inspector:

bash
npx @modelcontextprotocol/inspector http://localhost:6868/mcp

This opens a web UI at http://localhost:6274 where you can browse and test all MCP tools interactively.

curl Examples

bash
# Check server statuscurl http://localhost:6868/api/status | jq
# List active agentscurl http://localhost:6868/api/agents | jq
# List pending inbox taskscurl "http://localhost:6868/api/inbox?status=pending" | jq
# Browse engineering agents in Agenciescurl "http://localhost:6868/api/roster?division=engineering" | jq
# Watch real-time eventscurl -N http://localhost:6868/api/events

Test MCP Tool Calls

bash
# Register a test agentcurl -X POST http://localhost:6868/mcp \  -H "Content-Type: application/json" \  -d '{    "jsonrpc": "2.0",    "method": "tools/call",    "params": {      "name": "register_agent",      "arguments": {        "platform": "antigravity",        "agent_name": "test-agent",        "current_task": "Testing MCP connection"      }    },    "id": 1  }'
# Get dashboard datacurl -X POST http://localhost:6868/mcp \  -H "Content-Type: application/json" \  -d '{    "jsonrpc": "2.0",    "method": "tools/call",    "params": {      "name": "get_dashboard",      "arguments": {}    },    "id": 2  }'

Configuration Reference

Full config.json Example

json
{  "server": {    "port": 6868,    "host": "0.0.0.0",    "name": "cowork-mcp",    "version": "1.0.0",    "apiKey": null  },  "paths": {    "agencyAgents": "./agency-agents",    "inbox": "./inbox",    "status": "./.status",    "decisions": "./decisions",    "workflows": "./workflows",    "artifacts": "./artifacts",    "inputs": "./inputs"  },  "platforms": {    "claude": {      "enabled": true,      "agentsDir": "~/.claude/agents",      "color": "#D97757"    },    "hermes": {      "enabled": true,      "skillsDir": "../hermes-agent/skills",      "color": "#7C3AED"    },    "antigravity": {      "enabled": true,      "skillsDir": "~/.gemini/config/skills",      "color": "#0EA5E9"    }  },  "inbox": {    "autoArchiveDays": 30,    "maxRetries": 3  }}

Portal launcher cards live in their own file, portal.json (live copy ~/.cowork/portal.json, hot-reloaded) — see docs/dashboard.md#portal.

Environment-Specific Overrides

The real config is read from ~/.cowork/config.json by default. Point at a different file with the COWORK_CONFIG env var (and override the port / API key without editing any file):

bash
COWORK_CONFIG=~/.cowork/config.staging.json COWORK_PORT=6900 npm start

The Agencies catalog is cached in memory and rescanned at most once per COWORK_ROSTER_TTL_MS (default 30000). New agents / a submodule bump propagate within that window with no restart; set 0 to rescan on every query, or a larger value to reduce disk work.


Cowork Pro

Cowork Pro ($59) is the production package: advanced workflows, priority support and lifetime updates. It is also part of the AI Developer Stack Bundle ($79).

License

MIT © 2026 slashman413. The core server, dashboard and remote-brain client are free and open source; Cowork Pro (above) is the separate paid add-on.

來源:README.md,提交 f6fc28d

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

2
  1. v1.0.1最新Oct 18, 2026
  2. v1.0.0Oct 17, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分