Skip to main content
Glama
BuckG71

Momentum

by BuckG71
README.md
# Momentum

An MCP server that answers *"what should I work on right now?"* across a
portfolio of workstreams — clients, projects, initiatives — with a **score you
can audit**, not a guess.

Point Claude (or any MCP client) at it and ask "what now?". It returns a ranked
board where every position is explained: *stale 11 days past a weekly cadence;
deadline in 2 days; revenue-bearing.* The ranking is computed in deterministic
Python. No language model is in the scoring path.

---

## Why this exists

Most "AI productivity" tooling asks a model to rank your priorities. That's the
wrong job for a model. Ranking needs to be **consistent** (the same inputs
produce the same order every time) and **explainable** (you can see exactly why
something is #1). Language models are neither by construction — they're
non-deterministic and their reasoning isn't inspectable.

So Momentum splits the labor the way it should be split:

- **Code decides the ranking.** Four weighted factors, computed from your data,
  fully reproducible.
- **The model handles language and judgment.** It decides *when* to call a tool,
  interprets your shorthand ("just wrapped the ACME spec"), and presents the
  result conversationally.

This is the same principle behind well-designed agent systems generally: keep
the deterministic hot path in code, and reserve the model for the parts that
genuinely need judgment. It's easier to trust, easier to debug, and it doesn't
drift.

---

## How the score works

Each active workstream is scored 0–100 from four factors, combined by weights
you set in config:

| Factor | What it measures |
| --- | --- |
| **staleness** | How far past its review cadence a workstream has drifted. A weekly workstream untouched for 11 days is stale; touched today resets it to zero. |
| **deadline_pressure** | Proximity of the nearest goal or task deadline, ramping up as the date approaches and maxing out once overdue. |
| **revenue_weight** | Configurable emphasis for revenue-bearing work, with an optional weekday/weekend split so billable client work outranks internal work during the work week. |
| **cascade_risk** | Risk propagated from **stale upstream dependencies**. If workstream A feeds workstream B with a `strong` edge and A goes stale, B's risk rises — because B is about to be blocked. |

A **daily capacity check-in** (energy 1–5, available focus hours) applies a state
modifier on top. On low-energy days the engine biases toward workstreams you've
flagged as low-effort-compatible, so a depleted afternoon surfaces the
proposal-follow-up instead of the hardest build on the board.

Everything — the weights, the tier thresholds, the cadence definitions, the
per-workstream revenue and low-capacity values — lives in a JSON config and is
hot-reloadable. Re-tuning the ranking never requires touching code.

---

## The tools

| Tool | Purpose |
| --- | --- |
| `get_now` | The headline read: overdue tasks, due-today tasks, top 5 ranked workstreams with next actions and reasons. |
| `compute_priorities` | Force a re-rank. Pass `energy_override` to preview how a capacity level would reshuffle the board. |
| `quick_update` | Log progress on a workstream and set its next action. Re-ranks and reports the new position. |
| `write_checkin` | Record daily capacity/energy; trips low-capacity mode when energy ≤ 2. |
| `list_workstreams` | The portfolio, filterable by status. |
| `workstream_status` | Full report on one workstream: state, log, goals, dependencies, tasks, priority history. |
| `workstream_manage` | Create / pause / archive / re-cadence a workstream. |
| `sync_tasks` | Upsert external tasks (from a task-tool MCP) into a workstream's cache. |
| `mark_task_disposition` | Record a task outcome and return routing for Claude to push the change upstream. |
| `reload_config` | Re-read config without restarting. |

### The cross-MCP brokering pattern

An MCP server can't call another MCP server directly. Momentum needs live task
data from a task tool (TickTick, ClickUp) but stays dependency-free by making
**Claude the broker**:

1. `sync_tasks` takes rows Claude has already read from the task-tool MCP and
   caches them locally, so deadlines factor into the score.
2. `mark_task_disposition` updates the local cache **and returns a `routing`
   block** naming the exact downstream MCP tool and params to call. Claude then
   executes that call.

The server never reaches across the boundary; it hands Claude a precise
instruction and lets the model bridge the two servers. This keeps Momentum
self-contained and portable across whatever task tool a given workstream uses.

---

## Quick start

```bash
python -m venv .venv && source .venv/bin/activate
pip install fastmcp

# create and seed a demo database (a small consulting portfolio)
MOMENTUM_DB_PATH=./momentum.db python init_db.py

# create your config from the example
cp config.example.json config.json

# run the server
MOMENTUM_DB_PATH=./momentum.db MOMENTUM_CONFIG_PATH=./config.json python server.py
```

Then register it with your MCP client. Example Claude Desktop config
(`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "momentum": {
      "command": "/path/to/.venv/bin/python",
      "args": ["/path/to/momentum-mcp/server.py"],
      "env": {
        "MOMENTUM_DB_PATH": "/path/to/momentum.db",
        "MOMENTUM_CONFIG_PATH": "/path/to/config.json"
      }
    }
  }
}
```

**Replace every `/path/to/` with the real absolute path on your machine** — the
interpreter, `server.py`, the database, and your config. Use full paths starting
with `/Users/...`; `~` is not reliably expanded here. A leftover placeholder is
the most common cause of a "Failed to spawn process" error in the logs.

Restart your MCP client, then ask Claude: *"What should I focus on right now?"*
→ it calls `get_now` and walks you through the ranked board.

### Tuning the ranking

`config.json` is where you customize weights, tier thresholds, revenue rules,
and low-capacity fit — edit it to match your own workstreams. Every key is
optional; anything you omit falls back to the engine defaults, so a minimal
config file works fine. `config.json` is gitignored so your real tuning never
lands in the repo. Use the `reload_config` tool to apply edits without
restarting.

---

## Design notes

- **Config over code.** No user- or business-specific value is hardcoded.
  Weights, thresholds, cadences, and per-workstream rules are all external and
  hot-reloadable. The default config runs sensibly with no file at all.
- **Fail fast on config.** Required paths come from environment variables set by
  the MCP client. A missing `MOMENTUM_DB_PATH` is a hard error at import rather
  than a silent fallback that breaks subtly on another machine.
- **Tools never raise.** Every tool returns `{"status": "ok" | "error", ...}`.
  A bad input surfaces as a structured error the model can read and relay, not a
  stack trace that kills the session.
- **SQLite in WAL mode**, foreign keys on. Durable, concurrent-read-friendly,
  zero-infrastructure.
- **Tool descriptions are written for the model.** Each docstring states plainly
  when to call the tool and disambiguates likely confusions (e.g. "workstreams"
  are your tracked areas of effort, not DNS domains) — because a tool the model
  can't reliably select is a tool that doesn't work.

## Provenance

Momentum is the open, generalized core of a private personal-operating-system
MCP server the author built to run several businesses and a research project in
parallel. The scoring engine, the cross-MCP brokering pattern, and the
config-driven architecture are lifted directly from that system and reframed for
a professional workstream portfolio. The same engine could be configured to rank any set of things, personal or professional, competing for finite attention and resources.

## License

MIT.