trackmcp
Back to directory

Wormhole MCP: Collaborative AI Workflow ManagerπŸŒ€

11 stars TypeScriptOthers Updated Jul 19, 2026
agentic-workflowagentsclaude-codeclaude-code-skillsgithub-copilotmcp-server

Documentation

Wormhole πŸŒ€

Collaborative AI Workflow Manager

Keep your AI coding agents in sync. Wormhole gives Claude Code, GitHub Copilot, and Cursor a shared memory layerβ€”so when you switch tools mid-task, nothing gets lost.

Works across:

  • πŸ”€ Multiple subagents within the same tool (e.g., parallel Claude tasks)
  • πŸ”„ Different AI tools entirely (Claude ↔ Copilot ↔ Cursor)

⚠️ *Disclaimer*: Wormhole is an early-stage project. APIs and behavior may change, and there may be rough edges. It’s built in the open and evolving fast based on real developer feedback.

Features

  • Universal Logging - Single `log` tool for any action type
  • Event Tagging - Categorize events with tags for better organization
  • Session Management - Named work sessions with isolation
  • Token Optimized - Compact output, delta queries, relevance filtering
  • Conflict Detection - Know when agents touch the same files
  • Stale Event Rejection - Automatically filters out file edits that no longer exist in the current project state
  • Web UI Visualization - View sessions, timeline events, and insights with `npx wormhole ui`
  • Knowledge Capture & Search - Save decisions/pitfalls and surface them with intent-aware search

Quick Start

Try instantly with npx (no installation required):

bash
npx wormhole-mcp

Minimal Workflow (token-optimized)

1) `start_session`

2) Pull context: `search_project_knowledge` + `get_recent`

3) Before edits: `check_conflicts`

4) During work: `log` every file_edit/cmd_run/decision/test_result/todos

5) Capture learnings: `save_knowledge` (decision/pitfall/convention/constraint)

6) Finish: `end_session` with summary

javascript
start_session({ project_path: ".", agent_id: "copilot", name: "fix-auth" })
search_project_knowledge({ project_path: ".", intent: "debugging", query: "auth" })
get_recent({ project_path: "." })
check_conflicts({ project_path: ".", files: ["src/auth.ts"] })
log({ action: "file_edit", agent_id: "copilot", project_path: ".", content: { file_path: "src/auth.ts", description: "Fix timeout" } })
save_knowledge({ project_path: ".", knowledge_type: "decision", title: "Use async DB client", content: "Prevents blocking" })
end_session({ session_id: "abc-123", summary: "Auth fixed; tests green" })

Web UI

Visualize your agent activity with the built-in web interface:

bash
# Start the UI server (default port: 3000)
npx wormhole ui

# Or specify a custom port
npx wormhole ui 8080

Then open http://localhost:3000 in your browser to see:

  • πŸ“Š Dashboard - Stats on events, sessions, and agents
  • ⏱️ Timeline - Visual event stream with filtering
  • πŸ“‹ Sessions - All work sessions with details
  • πŸ“ˆ Insights - Action types and tag analytics

Installation

Claude Code β€” Add to `~/.claude/claude_code_config.json`:

json
{
  "mcpServers": {
    "wormhole": {
      "command": "npx",
      "args": ["-y", "wormhole-mcp"]
    }
  }
}

GitHub Copilot β€” Add to `.vscode/mcp.json` in your project:

json
{
  "servers": {
    "wormhole": {
      "command": "npx",
      "args": ["-y", "wormhole-mcp"]
    }
  }
}

Option 2: Global Install

bash
npm install -g wormhole-mcp

Then use `"command": "wormhole-mcp"` in your config.

Option 3: From Source

bash
git clone https://github.com/fatmali/wormhole.git
cd wormhole
npm install
npm run build

Use `"command": "node"` with `"args": ["/path/to/wormhole/dist/server.js"]`.

code
### Claude Code Plugin

For Claude Code users, there's an optional plugin that bundles the MCP server config with a skill:

Install the plugin

claude /install-plugin ./node_modules/wormhole-mcp/plugins/wormhole

code
Or test locally:

claude --plugin-dir ./node_modules/wormhole-mcp/plugins/wormhole

code
Then invoke with `/wormhole:wormhole` in Claude Code.

**Standalone skill** (simpler):

cp -r node_modules/wormhole-mcp/skills/wormhole .claude/skills/

code
## MCP Tools

### `log`

Universal logging for any action type:

// Log a command

log({

action: "cmd_run",

agent_id: "claude-code",

project_path: "/path/to/project",

content: { command: "npm test", exit_code: 0 },

tags: ["testing", "ci"] // Optional: categorize events

})

// Log a file edit

log({

action: "file_edit",

agent_id: "claude-code",

project_path: "/path/to/project",

content: { file_path: "src/auth.ts", description: "Added JWT validation" },

tags: ["bugfix", "auth"]

})

// Log a decision

log({

action: "decision",

agent_id: "claude-code",

project_path: "/path/to/project",

content: { decision: "Use Zod for validation", rationale: "Already in deps" }

})

// Log test results

log({

action: "test_result",

agent_id: "claude-code",

project_path: "/path/to/project",

content: { test_suite: "auth.test.ts", status: "passed" }

})

// Log user feedback

log({

action: "feedback",

agent_id: "claude-code",

project_path: "/path/to/project",

content: { agent_suggestion: "Use async/await", user_response: "rejected", user_note: "Legacy code" }

})

// Log todos

log({

action: "todos",

agent_id: "claude-code",

project_path: "/path/to/project",

content: {

items: [

{ task: "Add input validation", status: "pending", priority: "high" },

{ task: "Write unit tests", status: "done" },

{ task: "Update README", status: "pending" }

],

context: "Auth refactor"

}

})

// Log plan output

log({

action: "plan_output",

agent_id: "claude-code",

project_path: "/path/to/project",

content: {

title: "API Authentication Design",

type: "architecture",

content: "Use JWT with refresh tokens, store in httpOnly cookies..."

}

})

code
**Action Types:**
- `cmd_run` - Command executions
- `file_edit` - File modifications  
- `decision` - Design decisions with rationale
- `test_result` - Test outcomes
- `feedback` - User acceptance/rejection
- `todos` - Task items with status tracking
- `plan_output` - Planning artifacts (design, architecture, tasks)
- Any custom type you need

### `get_recent`

Get recent activity (compact by default):

get_recent({ project_path: "/path/to/project" })

code
**Output:**

[5m] claude: npm test β†’ βœ“

[8m] cursor: edit auth.ts "Add JWT"

[12m] copilot: decided "Use Zod for validation"

[15m] claude: auth.test.ts βœ“

cursor: evt_123

code
**Options:**
- `limit` - Max events (default: 5)
- `detail` - `minimal` | `normal` | `full`
- `since_cursor` - Only new events (delta query)
- `related_to` - Filter by file paths
- `action_types` - Filter by action types
- `tags` - Filter by tags (e.g., `["bugfix", "feature"]`)

### `get_tags`

Get all unique tags used in a project with counts:

get_tags({ project_path: "/path/to/project" })

// Output:

// tags:

// bugfix (12)

`save_knowledge`

Persist decisions, pitfalls, conventions, or constraints so agents don’t repeat mistakes.

javascript
save_knowledge({
  project_path: "/path/to/project",
  knowledge_type: "pitfall",
  title: "Avoid fs.readFileSync in handlers",
  content: "Blocks event loop; causes timeouts",
  confidence: 0.9
})

`search_project_knowledge`

Intent-aware lookup of stored knowledge. Prefers types that match your intent.

javascript
search_project_knowledge({
  project_path: "/path/to/project",
  intent: "debugging",
  query: "auth"
})
// β†’ [{ type: "pitfall", summary: "Avoid fs.readFileSync", confidence: 0.9 }]

// feature (8)

// testing (5)

// auth (3)

code
**Options:**
- `with_counts` - Include event counts per tag (default: true)

### `check_conflicts`

Detect concurrent file edits:

check_conflicts({ project_path: "/path/to/project" })

code
---

## Stale Event Rejection

Wormhole automatically tracks and validates file edits to ensure agents never act on stale information. When a `file_edit` event is logged with a `diff`, Wormhole:

1. **Extracts the full patch** - Stores all added/removed lines from the diff
2. **Validates on query** - When events are retrieved via `get_recent` or conflict detection, each file edit is checked against the current file state
3. **Fuzzy matching** - Uses intelligent matching to handle code that moved positions, only rejecting truly stale edits
4. **Auto-filters** - Rejected events are automatically excluded from results

### How it works

When you log a file edit:

log({

action: "file_edit",

agent_id: "claude-code",

project_path: "/path/to/project",

content: {

file_path: "src/auth.ts",

description: "Added JWT validation",

diff: `--- a/src/auth.ts

+++ b/src/auth.ts

@@ -10,6 +10,7 @@

function validateToken(token: string) {

+ const decoded = jwt.verify(token, SECRET);

return decoded;

}`

}

})

code
Wormhole stores the full diff in the payload. Later, when another agent queries recent events:
- **File still has the change** β†’ Event is included
- **Code was removed or changed** β†’ Event is silently filtered out
- **Code moved to different location** β†’ Still recognized (fuzzy match)

**Note:** The `diff` field is NOT truncated (unlike other content fields), ensuring accurate validation even for large changes.

This ensures agents always work with accurate context about what's currently in the codebase.

### Validation Algorithm

The patch validation uses intelligent fuzzy matching:

**For Added Lines (`+`):**
- Checks if the added code exists anywhere in the current file
- Uses normalized comparison (trimmed whitespace)
- Accepts partial matches (code that contains or is contained by the search)
- Requires 60% of added lines to match for validation

**For Removed Lines (`-`):**
- If a "removed" line still exists in the file β†’ patch is stale
- This catches cases where a deletion was reverted

**Edge Cases Handled:**
- **File deleted**: Patch fails validation
- **Code refactored**: Fuzzy matching still finds the logic if it exists
- **Whitespace changes**: Normalized comparison ignores formatting
- **Line movements**: Searches entire file, not just original position
- **No patch stored**: Event is kept (backward compatibility)
- **Already rejected**: Event is skipped on subsequent queries

### Performance

- Validation runs only when events are queried (lazy evaluation)
- File I/O is cached by OS for repeated reads
- Minimal overhead: ~1-5ms per file_edit event
- Database stores full diffs efficiently as TEXT columns

### `cleanup`

Clean up events with scopes:

// Clean entire project

cleanup({ scope: "project", project_path: "/path/to/project" })

// Clean specific session

cleanup({ scope: "session", session_id: "abc-123" })

// Clean everything

cleanup({ scope: "all", force: true })

code
---

## Session Management

### `start_session`

Start a named work session:

start_session({

project_path: "/path/to/project",

agent_id: "claude-code",

name: "bugfix-auth",

description: "Fixing login timeout issue"

})

// β†’ session started: bugfix-auth (abc-123-def)

code
Sessions automatically isolate contextβ€”previous events hidden from queries.

### `end_session`

End a session with summary:

end_session({

session_id: "abc-123-def",

summary: "Fixed timeout by optimizing DB query"

})

code
### `list_sessions`

View sessions:

list_sessions({ project_path: "/path/to/project" })

code
**Output:**

● bugfix-auth (2h) by claude

β—‹ feature-payment (1d) by cursor

code
### `switch_session`

Resume a previous session:

switch_session({ session_id: "xyz-789" })

code
---

## Configuration

Config file: `~/.wormhole/config.json`

{

"retention_hours": 24,

"max_payload_chars": 200,

"auto_cleanup": true,

"default_detail": "minimal",

"default_limit": 5

}

code
**Note:** The `max_payload_chars` setting truncates most content fields for display, but `diff` fields in `file_edit` events are always stored in full to enable accurate stale-event validation.

## Token Optimization

Wormhole minimizes token usage for `get_recent` responses through four key strategies:

### 1. Compact Output Format (Default)

Instead of returning raw JSON, events are formatted as single-line summaries:

Compact (default) - ~35 chars per event

[5m] claude: npm test β†’ βœ“

vs Full JSON - ~200+ chars per event

{"id":42,"agent_id":"claude-code","action":"cmd_run","payload":"{\"command\":\"npm test\",\"exit_code\":0}","timestamp":1706621234567,"project_path":"/path/to/project","session_id":"abc-123"}

code
The `detail` parameter controls verbosity:
- `minimal` (default) β€” Single-line summaries with symbols (βœ“/βœ—)
- `normal` β€” Multi-line with key details
- `full` β€” Complete JSON payloads

### 2. Payload Truncation

Content fields are truncated to 200 characters by default (`max_payload_chars` config):

// Stored/displayed as:

"Added authentication middleware with JWT validation and refresh token..."

// Instead of full 2000+ char description

code
**Exception:** `diff` fields in `file_edit` events are never truncatedβ€”they're needed for stale event validation.

### 3. Delta Queries

Use `since_cursor` to fetch only events since your last query:

// First call returns events + cursor

get_recent({ project_path: "." })

// β†’ [5 events] + cursor: evt_42

// Subsequent call returns only NEW events

get_recent({ project_path: ".", since_cursor: "evt_42" })

// β†’ [0-2 events] instead of repeating all 5

code
This prevents re-sending the same context repeatedly.

### 4. Low Default Limits

- `default_limit: 5` β€” Returns only 5 most recent events
- Agents can increase with `limit` param when needed

### Token Comparison

| Scenario | Without Optimization | With Optimization |
|----------|---------------------|-------------------|
| 5 events, first query | ~500-1000 tokens | ~100 tokens |
| 5 events, delta query (2 new) | ~500-1000 tokens | ~40 tokens |
| 10 events, full detail | ~2000+ tokens | ~800 tokens |

### Configuration

Adjust in `~/.wormhole/config.json`:

{

"max_payload_chars": 200,

"default_detail": "minimal",

"default_limit": 5

}

code
## Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”

β”‚ Claude Code β”‚ β”‚ Copilot β”‚ β”‚ Cursor β”‚

β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜

β”‚ β”‚ β”‚

β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”‚

β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”

β”‚ Wormhole β”‚

β”‚ MCP Server β”‚

β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜

β”‚

β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”

β”‚ SQLite β”‚

β”‚ timeline.db β”‚

β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

code
## Data Storage

- Database: `~/.wormhole/timeline.db`
- Config: `~/.wormhole/config.json`
- Archives: `~/.wormhole/archives/`

## License

MIT

Frequently asked questions

What is wormhole?

wormhole is Wormhole MCP: Collaborative AI Workflow ManagerπŸŒ€

How do I install wormhole?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is wormhole open source?

Yes β€” it is hosted on GitHub at https://github.com/fatmali/wormhole and has 11 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP