Skip to main content
Glama
README.md
# symm-mcp

Symm is a lightweight asynchronous MCP channel for handing work between independent agents and
re-entering it with fresh attention.

> The work persists. The viewpoint changes.

Any MCP client can dispatch a task to another agent, keep working, and later observe the
result and record a resolution: **Dispatch → Observe → Resolve → Repeat**. Symm does not decide
who implements and who reviews; that is expressed in the prompt.

## Status

Pre-release (`0.1.0.dev0`). The v0.1 task tools are implemented; publishing to PyPI and the
MCP Registry is not done yet, so install from Git for now.

## Tools

| Tool | What it does |
|---|---|
| `spawn_task` | Dispatch a prompt to a registered agent. Returns as soon as the agent process is running. |
| `get_task` | Current state: execution `status`, `exit_code`, `resolution`, timestamps. |
| `get_events` | Events after `after_seq` plus a `cursor` to pass next time, and the current `status`. |
| `resolve_task` | Record `accepted`, `rejected`, `needs_followup`, or `superseded` for a finished task. No side effects; may be revised. |
| `cancel_task` | Terminate a running agent's whole process group. A finished task is returned unchanged. |

Execution status (`running`, `succeeded`, `failed`, `cancelled`) says what happened to the
process. Resolution says what a caller concluded about the result. `succeeded` never implies
`accepted`.

Registered agents: `claude_code` (Claude Code in print mode, streaming JSON output). Its
`options` are limited to `model`, `effort`, `permission_mode`, and `allowed_tools`. Symm adds
no permission flags of its own: an agent that must edit files or run commands without a human
at the keyboard needs you to pass, for example, `{"permission_mode": "acceptEdits"}` or an
`allowed_tools` list.

Errors are tool errors whose text contains `<code>: <message>`, with codes `unknown_agent`,
`invalid_request`, `task_not_found`, and `invalid_transition`.

## Use

Requires [uv](https://docs.astral.sh/uv/), and the `claude` CLI on `PATH` for the
`claude_code` agent. Register Symm with an MCP client, for example Claude Code:

```bash
claude mcp add symm -- uvx --from git+https://github.com/tacticaldoll/symm-mcp symm-mcp
```

Or in a client's JSON configuration:

```json
{
  "mcpServers": {
    "symm": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/tacticaldoll/symm-mcp", "symm-mcp"]
    }
  }
}
```

A typical loop, as the calling agent sees it:

1. `spawn_task(agent="claude_code", prompt="Review the authentication changes in this
   workspace and list concrete flaws.", workspace="/path/to/repo")` returns a `task_id` while
   the reviewer starts working.
2. Continue with other work.
3. `get_events(task_id, after_seq=<cursor>)` to follow progress; `get_task(task_id)` once
   `status` is terminal.
4. `resolve_task(task_id, resolution="needs_followup", note="two findings to fix")`, then
   dispatch the next task, possibly with the reviewer and implementer roles swapped.

Agents run in the given workspace (default: the server's working directory) with the server's
environment. Symm does not copy, isolate, or clean workspaces.

## v0.1 Scope and Limitations

- **stdio only, process-local task ledger.** Each MCP client launches its own Symm server, and
  each server sees only the tasks it dispatched. `stdio + in-memory = process-local task
  ledger`.
- **In memory only.** Task state is lost when the server process exits. There is no recovery.
- **No output caps or retention policy yet.** Every output line is kept as an event; long,
  high-output tasks grow server memory.
- **Tools only.** No MCP resources or subscriptions yet; observe by polling `get_events`
  with its cursor.
- **No orphans.** When the client disconnects or the server receives SIGTERM, SIGINT, or
  SIGHUP, every running agent's process group is terminated before the server exits.
- **Your environment, your permissions.** Symm never escalates an agent's permissions;
  dependencies, secrets, sandboxing, and workspace cleanliness are the caller's
  responsibility.
- **POSIX only.** Process groups and signals; Windows is not supported.

Rationale: [ADR 0003](docs/adr/0003-v0-1-runtime-boundaries.md).

## Run Locally

From a checkout:

```bash
uv run symm-mcp
```

The command speaks MCP over stdio, so it is meant to be launched by an MCP client rather than
used interactively.

## Development

This project uses OpenSpec; read [AGENTS.md](AGENTS.md) before changing anything. The
Definition of Done:

```bash
uv sync
uv run python -m compileall -q src tests
uv run python -m pytest
uv run ruff check .
uv run ruff format --check .
./scripts/changelog-guard.sh
```

## License

Licensed under either of [Apache-2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT), at your option.

Maintenance

ActivityMaintained
ResponsivenessNo issues