Skip to main content

An open-source MCP server that gives Claude conversations a persistent, interactive plan/to-do panel.

Project description

Wingman

An open-source MCP server that gives Claude conversations a persistent, interactive plan/to-do panel — rendered inline in the chat via MCP Apps.

Tagline: Sits beside you. Doesn't fly the plane.

Why Wingman?

Long AI conversations lose the plot. You start working on something complex, the thread drifts, and twenty messages later you can't remember what's done and what isn't. Cursor solved this for code with its plan agent. Wingman generalises that experience to any Claude conversation and any MCP host.

You and Claude share a named plan, edit it live, tick tasks off as you go, and one-click "Run" any pending task to send it back to Claude as the next prompt — pre-framed with surrounding context.

What it does

  • Named plans, persistent: Plans live in a local SQLite database keyed by name. They survive restarts, conversation pivots, and entire chat threads.
  • Interactive inline panel: An MCP Apps panel renders right in the chat — checkboxes, drag-to-reorder, three-dot menu, the works. No plain text.
  • Two-way edits: You click checkboxes from the panel. Claude calls tick_task after completing work. State syncs via 2.5s polling.
  • "Run this task": One click sends a pre-framed prompt back to Claude as your next message: the task, surrounding context, and an instruction to tick the box when done.
  • "Build from our conversation": Empty-state CTA that asks Claude to scan the conversation and populate the plan with actionable tasks.
  • Text fallback: Every tool returns clean markdown for hosts without MCP Apps support. Nothing breaks; you just lose the panel.

Install

pip install wingman

Or from source:

git clone https://github.com/adeolu/wingman.git
cd wingman
pip install -e .

Configure

Claude Desktop

Add to your claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows):

{
  "mcpServers": {
    "wingman": { "command": "python", "args": ["-m", "wingman"] }
  }
}

Restart Claude Desktop. Wingman's tools show up in the tool picker.

Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "wingman": { "command": "python", "args": ["-m", "wingman"] }
  }
}

VS Code (Copilot Chat)

Add to your workspace .vscode/mcp.json:

{
  "servers": {
    "wingman": { "type": "stdio", "command": "python", "args": ["-m", "wingman"] }
  }
}

See examples/ for ready-to-copy versions of each.

Usage examples

1. Build a plan with Claude

"Create a plan called 'Launch Footprint' with tasks for writing the spec, building the MVP, and shipping it."

Claude calls create_plan. The panel renders inline.

2. Build from conversation

Create an empty plan, then click "Build from our conversation →" in the empty state. Claude scans the chat, identifies actionable tasks, and calls add_tasks.

3. Run a task end-to-end

Click the ▶ button on any task. The task flips to in-progress, and the next user message is auto-injected: "I'm working on this from my Launch Footprint plan: > Write the spec. Help me complete it...". Claude works on it. When done, Claude calls tick_task and the checkbox flips green.

Tool reference

LLM-visible tools (the model can call these):

Tool What it does
create_plan(name, tasks=[]) Create a new plan
add_task(plan_name, content) Append one task
add_tasks(plan_name, tasks) Append many tasks
show_plan(plan_name) Render the panel inline
get_plan(plan_name) Return plan as text (no panel)
tick_task(plan_name, task_id) Mark a task done
update_task_status(plan_name, task_id, status) pending / in_progress / done / blocked
rename_plan(current_name, new_name) Rename
reorder_tasks(plan_name, ordered_ids) Reorder
list_plans() List all plans with counts
delete_plan(plan_name) Delete a plan and its tasks

The UI panel uses thirteen additional _ui_* tools internally. They're hidden from the model via _meta visibility on hosts that support it.

Architecture

+--------------------------------------------------------------+
|  MCP Host (Claude Desktop / Cursor / VS Code)                |
|                                                              |
|  +----------------+     +------------------------------+    |
|  |  LLM (Claude)  |<--->|  Wingman MCP Server (stdio)  |    |
|  +----------------+     |  - LLM-visible tools         |    |
|       ^                 |  - UI-only tools             |    |
|       | sendMessage     |  - ui:// resource            |    |
|  +----------------+     |  - SQLite store              |    |
|  |    Iframe      |<----| -----------------------------+    |
|  |   (Wingman UI) |     JSON-RPC over postMessage          |
|  +----------------+                                         |
+--------------------------------------------------------------+
                                  |
                                  v
                  ~/.local/share/wingman/plans.db (or equiv)

Security & privacy

  • No telemetry. No phone-home. No network calls anywhere.
  • Local-only stdio transport by default.
  • All tool inputs validated via Pydantic; plan names are regex-restricted to prevent path traversal.
  • All SQL is parameterised. No string-built queries.
  • The UI iframe is sandboxed per the MCP Apps spec and self-contained — no external script sources, no remote fonts, no CDN.

Differentiation

Concern Existing solutions Wingman
Interaction model Type "mark task 3 done" Click a checkbox
Run a task Re-prompt manually One-click "Run" button with framed context
Populate from chat Manual "Build from our conversation" CTA
Visual state Plain text in chat Inline interactive panel with progress card
Reordering Edit text, recreate list Drag-and-drop
MCP Apps native No Yes (SEP-1865, text/html;profile=mcp-app)
Cross-host Limited Anywhere MCP Apps is supported, with text fallback

Host compatibility

Wingman ships an interactive panel via MCP Apps (SEP-1865). Hosts that support MCP Apps render it inline; hosts that don't get a clean markdown text response. You can use Wingman on either tier.

Verified target hosts for v0.1 interactive panel: Claude Desktop (recent versions), Cursor, VS Code Copilot Chat.

Known limitations in v0.1

Three actions in the panel's 3-dot menu are disabled in v0.1 and deferred to v0.2. They appear greyed out with a "Coming in v0.2" tooltip:

  • Clear all tasks
  • Delete plan
  • Export as markdown

These depend on browser capabilities (modal confirmation dialogs and file downloads) that the sandboxed MCP Apps iframe restricts; doing them properly needs an in-panel confirmation flow and a non-download export path, which is v0.2 work.

You can still do all of these through Claude — the LLM-callable tools are unaffected. Ask Claude to delete_plan, or to clear a plan's tasks, or to show the plan as markdown (get_plan). Only the in-panel buttons are deferred, not the underlying capability.

The menu items that work in v0.1: Rename plan and Clear completed tasks.

Roadmap

v0.2 candidates: re-enable the three deferred menu actions (in-panel confirm modal + download-free export), server-pushed updates via MCP notifications, ChatGPT compatibility via dual MIME tagging, sub-tasks, priorities and due dates, plan templates.

v1.0 candidates: React-based UI, multi-plan tabs, search across plans, optional cloud sync, plan sharing.

Contributing

Open a PR. Keep dependencies minimal — mcp, pydantic, platformdirs, plus pytest for dev. Anything else needs a strong justification.

Run tests:

pip install -e ".[dev]"
pytest

Development troubleshooting

If your code changes don't appear in the rendered panel, you're almost certainly hitting one of three caches. Walk them in order:

  1. The Wingman server subprocess is long-lived. An editable install (pip install -e .) makes Python pick up your .py changes only when the next subprocess starts. The MCP host (Claude Desktop, MCPJam, Cursor, etc.) spawns Wingman once and keeps it alive — so after editing anything under src/wingman/, fully quit and relaunch the host so it spawns a fresh subprocess.

  2. The panel HTML is inlined once at server start. ui/static/{app.js, index.html, styles.css, mcp-app.js, sortable.min.js} are read and concatenated by ui/resource.py:_panel_html(), which is wrapped in @lru_cache(maxsize=1). The bundle is computed on the first resources/read and re-used for the lifetime of the subprocess. So iframe-behavior changes (anything in static/) also require a server-subprocess restart — editing app.js without restarting accomplishes nothing.

  3. The host's iframe caches aggressively. Even after a server restart, the host may still display the previous bundle. After restarting the server, hard-refresh the host's webview (Ctrl+Shift+R in MCPJam / browser-based hosts) to force a fresh resources/read.

The build marker is the source of truth. The panel footer shows WINGMAN · MCP plan agent · build <unix-timestamp>. The timestamp is captured at server-subprocess start (ui/resource.py:BUILD_TIMESTAMP). If you edit code, restart the host, refresh the iframe — and the build number hasn't changed — then one of the three caches above is still serving the old code. Don't trust visual inspection of the UI until the build number ticks forward.

A one-shot SDK smoke test that confirms the served HTML, the build marker, and show_plan's _meta.ui.resourceUri lives at tests/manual/smoke_panel.py (gitignored). Run it with python tests/manual/smoke_panel.py after any change to the panel pipeline.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wingman_mcp-0.1.0.tar.gz (136.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wingman_mcp-0.1.0-py3-none-any.whl (132.3 kB view details)

Uploaded Python 3

File details

Details for the file wingman_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: wingman_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 136.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for wingman_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 44bf0a3ea980b16bfee422c84be9172b8134c23a6658d3ab4faa9c90c18c3925
MD5 d2dd8af255e46a45c49c24dc5320ec2e
BLAKE2b-256 335dbe454b28105788e923d8cb07bc04a07fa203e38e50f7c608c64e9e8952b1

See more details on using hashes here.

File details

Details for the file wingman_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wingman_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 132.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for wingman_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0bd7f8659808b754c1d30fc77d240ba48d496f752051926b4f53960f26f6918b
MD5 5312c502ea01f001467070fa98d09119
BLAKE2b-256 c5a295fe9a5af55430bdad4da5389626ae58fd554aa8e3a95380617845747d0d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page