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 a persistent, interactive plan panel — rendered inline in the chat.

Sits beside you. Doesn't fly the plane.

PyPI Python License: MIT MCP Apps


Wingman demo



What is Wingman?

Long Claude conversations lose track of what you were doing, what's done, and what's next. Wingman fixes that.

It gives every Claude conversation a persistent, interactive plan panel — rendered inline as a live UI widget. You click checkboxes. Claude ticks tasks after completing work. Either of you can add, reorder, or rename tasks at any time. The plan survives conversation restarts and lives in local SQLite on your machine.

Think of it as Cursor's plan agent, generalized to any Claude conversation and any goal.



Install

pip install wingman-mcp

Works on Windows, macOS, and Linux. Requires Python 3.10+.



Configure

Add Wingman to your MCP host config and restart. One block, one restart.

Claude Desktop

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json

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

Cursor

.cursor/mcp.json in your project root, or ~/.cursor/mcp.json globally:

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

VS Code Copilot Chat

.vscode/mcp.json:

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

Note: The interactive panel requires a host with MCP Apps support (SEP-1865). Claude Desktop and MCPJam render it fully. Cursor and VS Code Copilot Chat receive a clean text fallback — all tools still work.



How it works

1. Build a plan with Claude

Just describe what you're working on. Claude creates the plan and renders the panel inline:

You: I want to ship Wingman this weekend — README, PyPI, GitHub, launch post.
     Create a plan.

Claude: [calls create_plan → panel mounts with tasks already populated]

2. Start with an empty plan, let Claude fill it

You: Create an empty plan called "Wingman launch"

Claude: [panel mounts showing the empty state]

Hit Build from our conversation → in the panel. Claude scans your chat history and populates tasks from what you've already discussed.

3. Work through it together

  • Click a checkbox to tick a task manually
  • Click ▶ Run on any task to send it back to Claude as a framed prompt — Claude works on it and ticks it when done
  • Drag the ⋮⋮ handle to reorder tasks as priorities shift
  • Click the title to rename the plan inline
  • Tasks persist in local SQLite — survive restarts, survive new conversations


Screenshots

Empty state — ready to build

The panel mounts with a feather icon and a single CTA. One click scans your conversation and populates tasks.

Populated plan

Progress card, task list with checkboxes, drag handles, and run buttons. Always visible, never hover-only.

Empty state

Populated plan

Task ticked — progress updates live

Checkbox turns green, strikethrough applied, progress bar advances. State syncs via live polling across any open panels.

3-dot menu

Rename plan, Clear completed, Build from conversation, Clear all tasks, Export as markdown, and Delete plan.

Task ticked

Menu



Tool reference

Wingman exposes 12 tools to Claude. You don't call these directly — just describe what you want and Claude picks the right one.

Tool What it does
create_plan Create a new named plan with optional initial tasks
show_plan Render the interactive panel inline in chat
show_plans Render a clickable plan picker inline in chat
get_plan Return plan state as formatted text (no panel)
add_task Append a single task to a plan
add_tasks Append multiple tasks in one call
tick_task Mark a task done (Claude calls this after completing work)
update_task_status Set status: pending / in_progress / done / blocked
rename_plan Rename a plan
reorder_tasks Reorder tasks by ID list
list_plans List all plans with task counts
delete_plan Delete a plan and all its tasks

There are also 14 internal _ui_* tools used by the panel itself — hidden from Claude, not part of the public API.



Architecture

┌─────────────────────────────────────────────────────┐
│  MCP Host  (Claude Desktop / Cursor / MCPJam)        │
│                                                      │
│  ┌──────────────┐     ┌──────────────────────────┐  │
│  │  Claude LLM  │────▶│  Wingman MCP Server       │  │
│  └──────────────┘     │  (stdio transport)        │  │
│         ▲             │                            │  │
│         │             │  12 LLM-visible tools      │  │
│  sendMessage()        │  14 UI-only tools          │  │
│         │             │  ui:// resource (panel)    │  │
│  ┌──────────────┐     │  SQLite store              │  │
│  │  Wingman     │◀────│                            │  │
│  │  Panel       │     └──────────────────────────┘  │
│  │  (iframe)    │  JSON-RPC over postMessage         │
│  └──────────────┘                                    │
└─────────────────────────────────────────────────────┘
                              │
               platformdirs.user_data_dir()
                              │
                         plans.db (SQLite)

Stack: Python 3.10+, FastMCP, SQLite + platformdirs, vanilla HTML/CSS/JS, Sortable.js. No external runtime network calls anywhere.



Security & privacy

  • No telemetry. No phone-home. No network calls anywhere. Wingman is a local state-tracking server. Zero outbound connections on any tool path — audited and tested.
  • Local-only by default. stdio transport. Your plans live on your machine.
  • Sandboxed UI. The panel runs in a host-sandboxed iframe with a strict CSP (connect-src 'self'). No cross-origin access.
  • Parameterized SQL throughout. No string-built queries. Validated via full test suite.
  • Path-traversal safe. Plan names are allow-list validated — letters, digits, space, hyphen, underscore, apostrophe, period, colon, parentheses. Slashes, backslashes, .. sequences, null bytes, newlines, and tabs are blocked.


vs. alternatives

Wingman text-only MCP todos Cursor plan agent
Interactive UI panel ✅ inline iframe ✅ code-only
Works in Claude Desktop
One-click Run task
Build from conversation
Drag-to-reorder
Persists across restarts ✅ SQLite varies
Any goal / domain ❌ code only
No telemetry varies


Known limitations in v0.2

  • Live polling runs every 2.5s (10s after 30s idle). Server-pushed updates via MCP notifications are v0.3.
  • Mobile Claude (claude.ai mobile) requires a hosted HTTP/SSE server. Local stdio can't reach mobile clients. Wingman Cloud addresses this.


Roadmap

v0.2 — shipped

Plan-picker panel (show_plans) · per-plan task position (1..N display) · wider plan-name regex · smarter polling backoff · re-enabled clear-all / export / delete-plan menu actions · "Build from conversation" in 3-dot menu.

v0.3 — next

Server-pushed updates (replace polling via MCP notifications) · sub-tasks · priorities · due dates.

Wingman Cloud — hosted SaaS

HTTP/SSE transport · OAuth 2.1 · Postgres with user scoping · Fly.io / Railway hosting · mobile Claude support · cross-device plan access

v1.0 — after Cloud

React UI rewrite · multi-plan tabs · search across plans · plan sharing · optional cloud sync for local users



Development troubleshooting

Panel doesn't appear after code changes: The served HTML is cached in memory for the subprocess lifetime. Restart Claude Desktop fully (quit from tray, don't just close the window) after any change to ui/static/*. Hard-refresh the host webview (Ctrl+Shift+R in MCPJam) after restart. The build timestamp in the panel footer confirms which build is live.

Tools don't appear after config change: Quit Claude Desktop fully — closing the window leaves the MCP subprocess running with the old config.

wingman --help shows an MCP protocol error: Expected. Wingman is an MCP server, not a CLI tool. It speaks JSON-RPC over stdio — running it directly in a terminal produces a protocol handshake error. Use it via your MCP host config.



Contributing

Issues, PRs, and feedback welcome. This is v0.2 — rough edges exist and are documented above.

If you hit a host-specific rendering quirk (especially on Cursor or VS Code Copilot Chat), open an issue with your host version and what you observed. Host-side MCP Apps behavior varies and real-world reports are the fastest way to track it.



License

MIT — © 2026 Adeolu Adesina


Built with FastMCP · Powered by MCP Apps (SEP-1865) · Published on PyPI

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.2.0.tar.gz (138.4 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.2.0-py3-none-any.whl (133.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: wingman_mcp-0.2.0.tar.gz
  • Upload date:
  • Size: 138.4 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.2.0.tar.gz
Algorithm Hash digest
SHA256 f06694cd5e1452bc0a55b3dde860e4983d29bc0c5a268d223c95e3d428610cb5
MD5 53f58a09c994881269bf11937e5ab3ab
BLAKE2b-256 ace15f75cc3e18abf072a7c82f565fe6cef7c972756879691c42e5afffe7ad61

See more details on using hashes here.

File details

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

File metadata

  • Download URL: wingman_mcp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 133.9 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2447ed98d34f4256c5640009668cef5b2a445bd72d055f34ed03c9dd1204e0c8
MD5 ba5a947d92d02d086f8470c8efc41b91
BLAKE2b-256 1b0355cda9c1f8fb2060b718e51c0e3ad5827e24510efb5cc8ffb26242bc5a80

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