Wormhole

Registra ediciones de archivos, decisiones y comandos para que los agentes se mantengan sincronizados, eviten conflictos y retomen el trabajo donde otros lo dejaron.

Documentación

Wormhole 🌀

Gestor de Flujo de Trabajo de IA Colaborativo

Mantén tus agentes de codificación de IA sincronizados. Wormhole proporciona a Claude Code, GitHub Copilot y Cursor una capa de memoria compartida, de modo que cuando cambies de herramienta a mitad de tarea, nada se pierda.

Funciona con:

  • 🔀 Múltiples subagentes dentro de la misma herramienta (p. ej., tareas paralelas de Claude)
  • 🔄 Diferentes herramientas de IA por completo (Claude ↔ Copilot ↔ Cursor)

⚠️ Aviso: Wormhole es un proyecto en etapa temprana. Las API y el comportamiento pueden cambiar, y puede haber asperezas. Está construido en abierto y evoluciona rápidamente basándose en comentarios reales de desarrolladores.

Características

  • Registro Universal - Herramienta única log para cualquier tipo de acción
  • Etiquetado de Eventos - Categoriza eventos con etiquetas para una mejor organización
  • Gestión de Sesiones - Sesiones de trabajo nombradas con aislamiento
  • Optimizado en Tokens - Salida compacta, consultas delta, filtrado por relevancia
  • Detección de Conflictos - Saber cuándo los agentes tocan los mismos archivos
  • Rechazo de Eventos Obsoletos - Filtra automáticamente las ediciones de archivos que ya no existen en el estado actual del proyecto
  • Visualización Web UI - Ver sesiones, eventos de línea de tiempo y perspectivas con npx wormhole ui
  • Captura y Búsqueda de Conocimiento - Guarda decisiones/errores y muéstralos con búsqueda consciente de intención

Inicio Rápido

Prueba al instante con npx (sin necesidad de instalación):

npx wormhole-mcp

Flujo de Trabajo Mínimo (optimizado en tokens)

  1. start_session
  2. Obtener contexto: search_project_knowledge + get_recent
  3. Antes de editar: check_conflicts
  4. Durante el trabajo: log cada file_edit/cmd_run/decision/test_result/todos
  5. Captura aprendizajes: save_knowledge (decision/pitfall/convention/constraint)
  6. Finalizar: end_session con resumen
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" })

Interfaz Web

Visualiza la actividad de tus agentes con la interfaz web integrada:

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

# Or specify a custom port
npx wormhole ui 8080

Luego abre http://localhost:3000 en tu navegador para ver:

  • 📊 Panel - Estadísticas sobre eventos, sesiones y agentes
  • ⏱️ Línea de tiempo - Flujo de eventos visual con filtrado
  • 📋 Sesiones - Todas las sesiones de trabajo con detalles
  • 📈 Perspectivas - Tipos de acción y análisis de etiquetas

Instalación

Opción 1: npx (Recomendado)

Claude Code — Añade a ~/.claude/claude_code_config.json:

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

GitHub Copilot — Añade a .vscode/mcp.json en tu proyecto:

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

Opción 2: Instalación Global

npm install -g wormhole-mcp

Luego usa "command": "wormhole-mcp" en tu configuración.

Opción 3: Desde el Código Fuente

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

Usa "command": "node" con "args": ["/path/to/wormhole/dist/server.js"].


### Claude Code Plugin

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

```bash
# Install the plugin
claude /install-plugin ./node_modules/wormhole-mcp/plugins/wormhole

O prueba localmente:

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

Luego invoca con /wormhole:wormhole en Claude Code.

Habilidad independiente (más simple):

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

Herramientas MCP

log

Registro universal para cualquier tipo de acción:

// 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..."
  }
})

Tipos de Acción:

  • cmd_run - Ejecuciones de comandos
  • file_edit - Modificaciones de archivos
  • decision - Decisiones de diseño con justificación
  • test_result - Resultados de pruebas
  • feedback - Aceptación/rechazo del usuario
  • todos - Elementos de tarea con seguimiento de estado
  • plan_output - Artefactos de planificación (diseño, arquitectura, tareas)
  • Cualquier tipo personalizado que necesites

get_recent

Obtén actividad reciente (compacta por defecto):

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

Salida:

[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

Opciones:

  • limit - Máximo de eventos (por defecto: 5)
  • detail - minimal | normal | full
  • since_cursor - Solo eventos nuevos (consulta delta)
  • related_to - Filtrar por rutas de archivo
  • action_types - Filtrar por tipos de acción
  • tags - Filtrar por etiquetas (p. ej., ["bugfix", "feature"])

get_tags

Obtén todas las etiquetas únicas usadas en un proyecto con recuentos:

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

Búsqueda consciente de intención del conocimiento almacenado. Prefiere tipos que coincidan con tu intención.

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)


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

### `check_conflicts`

Detect concurrent file edits:

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

Rechazo de Eventos Obsoletos

Wormhole rastrea y valida automáticamente las ediciones de archivos para asegurar que los agentes nunca actúen sobre información obsoleta. Cuando se registra un evento file_edit con un diff, Wormhole:

  1. Extrae el parche completo - Almacena todas las líneas añadidas/eliminadas del diff
  2. Valida en la consulta - Cuando los eventos se recuperan mediante get_recent o detección de conflictos, cada edición de archivo se verifica contra el estado actual del archivo
  3. Coincidencia difusa - Utiliza coincidencia inteligente para manejar código que cambió de posición, rechazando solo ediciones realmente obsoletas
  4. Auto-filtrado - Los eventos rechazados se excluyen automáticamente de los resultados

Cómo funciona

Cuando registras una edición de archivo:

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;
 }`
  }
})

Wormhole almacena el diff completo en el payload. Más tarde, cuando otro agente consulta eventos recientes:

  • El archivo aún tiene el cambio → El evento se incluye
  • El código fue eliminado o cambiado → El evento se filtra silenciosamente
  • El código se movió a otra ubicación → Aún se reconoce (coincidencia difusa)

Nota: El campo diff NO se trunca (a diferencia de otros campos de contenido), asegurando una validación precisa incluso para cambios grandes.

Esto asegura que los agentes siempre trabajen con contexto preciso sobre lo que está actualmente en el código base.

Algoritmo de Validación

La validación del parche utiliza coincidencia difusa inteligente:

Para Líneas Añadidas (+):

  • Verifica si el código añadido existe en cualquier parte del archivo actual
  • Utiliza comparación normalizada (espacios en blanco recortados)
  • Acepta coincidencias parciales (código que contiene o está contenido por la búsqueda)
  • Requiere que el 60% de las líneas añadidas coincidan para la validación

Para Líneas Eliminadas (-):

  • Si una línea "eliminada" aún existe en el archivo → el parche está obsoleto
  • Esto detecta casos donde se revirtió una eliminación

Casos Límite Manejados:

  • Archivo eliminado: El parche falla la validación
  • Código refactorizado: La coincidencia difusa aún encuentra la lógica si existe
  • Cambios de espacios en blanco: La comparación normalizada ignora el formato
  • Movimientos de línea: Busca en todo el archivo, no solo en la posición original
  • Sin parche almacenado: El evento se mantiene (compatibilidad hacia atrás)
  • Ya rechazado: El evento se omite en consultas posteriores

Rendimiento

  • La validación se ejecuta solo cuando se consultan eventos (evaluación perezosa)
  • La E/S de archivos se almacena en caché por el sistema operativo para lecturas repetidas
  • Sobrecarga mínima: ~1-5ms por evento file_edit
  • La base de datos almacena diffs completos eficientemente como columnas TEXT

cleanup

Limpia eventos con ámbitos:

// 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 })

Gestión de Sesiones

start_session

Inicia una sesión de trabajo nombrada:

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)

Las sesiones aíslan automáticamente el contexto: los eventos anteriores se ocultan de las consultas.

end_session

Finaliza una sesión con resumen:

end_session({
  session_id: "abc-123-def",
  summary: "Fixed timeout by optimizing DB query"
})

list_sessions

Ver sesiones:

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

Salida:

● bugfix-auth (2h) by claude
○ feature-payment (1d) by cursor

switch_session

Reanuda una sesión anterior:

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

Configuración

Archivo de configuración: ~/.wormhole/config.json

{
  "retention_hours": 24,
  "max_payload_chars": 200,
  "auto_cleanup": true,
  "default_detail": "minimal",
  "default_limit": 5
}

Nota: El ajuste max_payload_chars trunca la mayoría de los campos de contenido para la visualización, pero los campos diff en eventos file_edit siempre se almacenan completos para permitir una validación precisa de eventos obsoletos.

Optimización de Tokens

Wormhole minimiza el uso de tokens para las respuestas get_recent mediante cuatro estrategias clave:

1. Formato de Salida Compacto (Por Defecto)

En lugar de devolver JSON crudo, los eventos se formatean como resúmenes de una sola línea:

# 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"}

El parámetro detail controla la verbosidad:

  • minimal (por defecto) — Resúmenes de una línea con símbolos (✓/✗)
  • normal — Multi-línea con detalles clave
  • full — Payloads JSON completos

2. Truncamiento de Payload

Los campos de contenido se truncan a 200 caracteres por defecto (config max_payload_chars):

// Stored/displayed as:
"Added authentication middleware with JWT validation and refresh token..."

// Instead of full 2000+ char description

Excepción: Los campos diff en eventos file_edit nunca se truncan; son necesarios para la validación de eventos obsoletos.

3. Consultas Delta

Usa since_cursor para obtener solo eventos desde tu última consulta:

// 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

Esto evita reenviar el mismo contexto repetidamente.

4. Límites Bajos por Defecto

  • default_limit: 5 — Devuelve solo los 5 eventos más recientes
  • Los agentes pueden aumentar con el parámetro limit cuando sea necesario

Comparación de Tokens

EscenarioSin OptimizaciónCon Optimización
5 eventos, primera consulta~500-1000 tokens~100 tokens
5 eventos, consulta delta (2 nuevos)~500-1000 tokens~40 tokens
10 eventos, detalle completo~2000+ tokens~800 tokens

Configuración

Ajusta en ~/.wormhole/config.json:

{
  "max_payload_chars": 200,
  "default_detail": "minimal",
  "default_limit": 5
}

Arquitectura

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ Claude Code │  │  Copilot    │  │   Cursor    │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │
       └────────────────┼────────────────┘
                        │
                ┌───────▼───────┐
                │   Wormhole    │
                │  MCP Server   │
                └───────┬───────┘
                        │
                ┌───────▼───────┐
                │    SQLite     │
                │  timeline.db  │
                └───────────────┘

Almacenamiento de Datos

  • Base de datos: ~/.wormhole/timeline.db
  • Configuración: ~/.wormhole/config.json
  • Archivos: ~/.wormhole/archives/

Licencia

MIT