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

Campaign orchestration MCP server for AI agents — dependency DAGs, parallel
fan-out, failure policies, and embedded notes.

Think `make` for AI agent workflows, where the LLM is the planner that
generates and adapts the DAG at runtime.

## Install

```bash
pip install sortie-mcp
```

Or with [uv](https://docs.astral.sh/uv/):

```bash
uv add sortie-mcp
```

## Quick Start

### 1. Set up PostgreSQL

sortie-mcp requires PostgreSQL 15+ with [pgvector](https://github.com/pgvector/pgvector).

```bash
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
export SORTIE_SCHEMA="sortie"  # default
```

### 2. Run the MCP server

```bash
sortie-mcp
# or: python -m sortie_mcp.server
```

The server runs on stdio transport. Configure it in your MCP client:

```json
{
  "sortie": {
    "command": ["sortie-mcp"],
    "env": {
      "DATABASE_URL": "postgresql://..."
    }
  }
}
```

### 3. Run the campaign runner

```bash
sortie-runner
# or: python -m sortie_mcp.runner
```

Add to cron for autonomous operation:

```
*/15 * * * * /path/to/venv/bin/sortie-runner
```

## Architecture

One MCP server, three perspectives:

- **Coordinator** (e.g. a dispatcher agent): create, list, steer, pause/cancel campaigns
- **Worker** (specialist agents): get context, add notes, complete/fail steps, spawn subtasks
- **Runner** (cron): capacity-aware watchdog that dispatches ready steps and consults the planner LLM

### Step Types

| Type | Description |
|------|-------------|
| `atomic` | Single task executed by one agent |
| `parallel_group` | Fan-out: children run concurrently |
| `sequence` | Pipeline: each step depends on the previous |
| `for_each` | Map: apply a template to each item in a list |

### Key Features

- **DAG splice** (`spawn_and_continue`): agents can split work into subtasks + continuation
- **Branch abort** (`abort_branch`): scoped early return from an ancestor step
- **Skip cascade**: transitive propagation through the dependency graph
- **Priority scheduling**: urgent / high / normal / low / background
- **Advisory dedup**: fingerprinting warns the planner of duplicate steps
- **Depth limits**: `spawn_and_continue` hidden from agents at max depth
- **Embedded notes**: pgvector semantic search across campaign findings

## Configuration

| Env Var | Default | Description |
|---------|---------|-------------|
| `DATABASE_URL` | `postgresql://localhost/sortie` | PostgreSQL connection string |
| `SORTIE_SCHEMA` | `sortie` | Database schema name |
| `SORTIE_MAX_CONCURRENT` | `4` | Max parallel running steps |
| `SORTIE_ZOMBIE_TIMEOUT` | `30` | Minutes before a stuck step is reset |
| `LITELLM_URL` | `http://localhost:4000` | LiteLLM proxy URL (for planner) |
| `LITELLM_KEY` | | LiteLLM API key |
| `SORTIE_PLANNER_MODEL` | `qwen3.5:9b` | Model for the planner LLM |
| `OPENCLAW_RUNTIME_URL` | `http://localhost:3000` | Agent runtime API |

## Development

```bash
uv sync
uv run pytest
uv run ruff check .
uv run mypy src tests
```

## License

GPL-3.0-or-later. See [LICENSE](LICENSE).

TDQS

A4/5.0

Scored across 21 tools

Disambiguation5/5

Each tool targets a distinct action in the campaign lifecycle (e.g., create_campaign vs. cancel_campaign, abort_branch vs. spawn_and_continue). While some tools like get_campaign and get_updates overlap in scope, their purposes (full state vs. delta) are clearly differentiated.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case (e.g., abort_branch, create_campaign, complete_step). The naming is predictable and makes the function of each tool immediately understandable.

Tool Count4/5

21 tools is slightly high but justified for a comprehensive workflow orchestration system. Each tool serves a clear purpose in campaign management, step execution, branching, and monitoring. No obvious bloat, though a few tightly related tools (e.g., get_notes, search_notes) could potentially be merged.

Completeness5/5

The tool set covers the full lifecycle of campaigns and steps: creation, cancellation, pausing, resumption, steering, step execution with branching, input/decision handling, heartbeat monitoring, and comprehensive state retrieval. There are no obvious gaps for the intended domain of long-running multi-step work.

Maintenance

ActivityInactive
ResponsivenessNo issues