Skip to content

For developers

Plug your agents into the same graph as your plans

Project Orchestrator exposes everything the app does as MCP tools, a REST API and two WebSocket streams. A Rust server keeps code, plans, decisions and notes in a Neo4j graph and in Meilisearch.

MCP tools
31
MCP tools
actions across them
402
actions across them
languages parsed
17
languages parsed
WebSocket streams
3
WebSocket streams

Looking for the product itself? Go back to the home page.

project(action: "sync", slug: "my-app")

code(
  action: "analyze_impact",
  target: "src/session.rs",
  project_slug: "my-app"
)

plan(action: "run", plan_id: "<uuid>")

Connect

Plug PO into an MCP client

The desktop app or the server must be running. Then one command registers PO in Claude Code, or you add the entry by hand for any other MCP client.

Install and start the server

The server needs Neo4j and Meilisearch. NATS is optional. The repository ships a docker-compose.yml for all three.

orchestrator serve

# needs Neo4j and Meilisearch: docker compose up -dbrew install this-rs/tap/project-orchestratororchestrator serve --port 8080

Register PO in Claude Code

This writes the MCP entry in stdio mode, with this server URL and its auth secret, and pre-approves the tools.

orchestrator setup-claude

orchestrator setup-claude --port 8080

setup-claude also adds mcp__project-orchestrator__* to the allowed tools of ~/.claude/settings.json, so Claude Code does not ask before every call.

Check that it works

In Claude Code, run /mcp: project-orchestrator should be listed. Then ask for the list of projects: Claude calls project(action: "list").

Claude Code

# in Claude Code/mcp# then ask: "List all registered projects"# Claude calls: project(action: "list")

Any MCP client, stdio

mcp_server is a thin proxy: it speaks MCP on stdio and forwards each call to the REST API. It never connects to Neo4j itself. Set PO_AUTH_TOKEN, or PO_JWT_SECRET to let it generate a token at startup.

~/.claude/mcp.json

{  "mcpServers": {    "project-orchestrator": {      "command": "/path/to/mcp_server",      "env": {        "PO_SERVER_URL": "http://127.0.0.1:8080",        "PO_AUTH_TOKEN": "<jwt-session-token>"      }    }  }}

Remote clients, Streamable HTTP

The server also answers MCP at POST /mcp, behind the same authentication as the REST API. A session id is returned in the Mcp-Session-Id header and must be echoed on each request.

Claude Code

claude mcp add --transport http project-orchestrator http://127.0.0.1:8080/mcp \  --header "Authorization: Bearer <token>"

HTTP

POST /mcpAuthorization: Bearer <token>Content-Type: application/json{"jsonrpc":"2.0","id":1,"method":"tools/list"}

MCP tools

31 tools, one call shape

Every tool takes an action parameter and dispatches to one operation. Search by tool, action or parameter, then copy the exact call.

31 tools

plan

Plans with dependency graph, waves, critical path, and the autonomous runner.

Planning and delivery 27 actions

Example call

plan(  action: "create",  title: "Migrate session store to Redis",  priority: 8)

Actions

+21 more

Parameters

plan_idproject_idtitledescriptionpriorityconstraintsstatussearchlimitoffsetsort_bysort_orderpriority_minpriority_maxcwdproject_slugtrigger_idtrigger_typeconfigcooldown_secsrun_idrun_idstask_idparent_session_idcustom_sections

Argument values such as <uuid> are placeholders. The action and parameter names are read from the server source.

Architecture

One Rust server, three stores, any client

Clients never touch the databases. They talk to the server, which parses code, serves the API and streams events.

  • MCP clients

    Claude Code, Cursor or any MCP client. They talk MCP to mcp_server over stdio, or to POST /mcp over HTTP.

  • Desktop app

    The Tauri 2 app embeds the interface and starts the server. It manages the Neo4j and Meilisearch containers through Docker.

  • WebSocket clients

    Anything that opens /ws/chat/{session_id}, /ws/events or /ws/run/{run_id}.

  • mcp_server

    Binary mcp_server: MCP on stdio in, REST calls out. Holds no state.

  • orchestrator

    The orchestrator binary (axum). REST API, chat manager, plan runner, tree-sitter parser, event bus.

  • Neo4j

    The graph: code, plans, tasks, decisions, notes, skills, protocols, chat sessions.

  • Meilisearch

    Full-text search over code, notes, decisions and chat messages.

  • NATSoptional

    Syncs events and relays chat between several server instances. Without it, the server runs local-only.

  • Claude

    The chat manager drives Claude through the nexus-claude SDK.

How they talk

  • MCP clients / mcp_serverstdio
  • MCP clients / orchestratorHTTP /mcp
  • mcp_server / orchestratorREST
  • Desktop app / orchestratorREST + WebSocket
  • WebSocket clients / orchestratorWebSocket
  • orchestrator / Neo4jbolt
  • orchestrator / MeilisearchHTTP
  • orchestrator / NATSNATS
  • orchestrator / ClaudeSDK

Code parsing

17 languages, parsed with tree-sitter

Each file is parsed into functions, structs, traits, enums, imports, impl blocks and call edges, then stored in the graph.

17 languages

  • Rust

    Extensions: .rs

    tree-sitter-rust

  • TypeScript / JavaScript

    Extensions: .ts .tsx .js .jsx .mjs .cjs

    tree-sitter-typescript

  • Python

    Extensions: .py .pyi

    tree-sitter-python

  • Go

    Extensions: .go

    tree-sitter-go

  • Java

    Extensions: .java

    tree-sitter-java

  • C

    Extensions: .c .h

    tree-sitter-c

  • C++

    Extensions: .cpp .cc .cxx .hpp .hxx .hh

    tree-sitter-cpp

  • Ruby

    Extensions: .rb .rake .gemspec

    tree-sitter-ruby

  • PHP

    Extensions: .php .phtml .php5 .php7

    tree-sitter-php

  • Kotlin

    Extensions: .kt .kts

    tree-sitter-kotlin-ng

  • Swift

    Extensions: .swift

    tree-sitter-swift

  • Bash

    Extensions: .sh .bash .zsh

    tree-sitter-bash

  • C#

    Extensions: .cs

    tree-sitter-c-sharp

  • Scala

    Extensions: .scala .sc

    tree-sitter-scala

  • Zig

    Extensions: .zig

    tree-sitter-zig

  • HCL (Terraform)

    Extensions: .tf .tfvars

    tree-sitter-hcl

  • Dart

    Extensions: .dart

    tree-sitter-dart

Per file: functions, structs, traits, enums, imports, impl blocks, function calls with a confidence score.

JavaScript files (.js, .jsx, .mjs, .cjs) are read with the TypeScript grammar.

API and events

REST for state, WebSockets for change

Plans, code, notes and the rest are plain JSON over HTTP. Changes are pushed on WebSockets.

Main REST endpoints

Most routes sit behind the auth middleware. When no auth section is configured, the API is open.

GET/healthLiveness
GET/api/versionServer version
GET/api/projectsList projects (POST creates)
POST/api/projects/{slug}/syncParse a project into the graph
GET/api/plans/{plan_id}/wavesParallel waves of a plan
POST/api/plans/{plan_id}/runStart the runner on a plan
GET/api/code/searchSearch code
GET/api/code/impactImpact analysis
GET/api/notes/searchSearch notes
GET/api/decisions/searchSearch decisions
POST/api/reasonReasoning over the graph
POST/mcpMCP over Streamable HTTP

WebSocket streams

  • /ws/events

    Every create, update, delete, link, unlink and status change, as one JSON event. Filter with the entity_types, project_id and layers query parameters.

  • /ws/chat/{session_id}

    Conversation with Claude. Send user_message, interrupt, permission_response and input_response; receive the chat events, replayed from last_event after a reconnect.

  • /ws/run/{run_id}

    One stream for a plan run: runner events (task started, wave started...) plus the chat events of every child session.

Browsers authenticate with a cookie, or with a one-time ticket from POST /auth/ws-ticket passed as the ticket parameter.

A /ws/events message

/ws/events?entity_types=plan,task&project_id=<uuid>

{  "entity_type": "task",  "action": "status_changed",  "entity_id": "<uuid>",  "payload": { "old_status": "pending", "new_status": "in_progress" },  "timestamp": "2026-10-05T10:00:00Z",  "project_id": "<uuid>"}

Extend

Three ways to make PO yours

All three are available through the same MCP tools.

  • Protocols

    Define a finite state machine with states and transitions, start a run, and let agents move it forward with the protocol tool.

  • Skills

    Skills are clusters of notes and code that emerge from use; the skill tool activates, exports and imports them across projects and instances.

  • MCP federation

    mcp_federation connects external MCP servers over stdio, sse or streamable_http, so their tools are reachable through PO.