MCP planning server for AI agents — plan management, full-text search, and task lifecycle
io.github.paulbreuler/limps (MCP Planning Server)
The MCP server “io.github.paulbreuler/limps” is a planning server for AI agents that provides plan management, full-text search, and task lifecycle. It includes a document and planning layer for AI assistants and is described as local-only (no subscriptions, no cloud).
🛠️ Key Features
Plan management
Full-text search
Task lifecycle
Document and planning layer for AI assistants
Points at any folder (local, synced, or in git)
🚀 Use Cases
Shared source of truth across AI assistants and MCP-compatible tools
Planning and organizing work for AI agents
Searching and tracking tasks within a folder-based workspace
⚡ Developer Benefits
MCP integration for planning workflows
Folder-based shared documentation and plans
Use with Claude, Cursor, Codex, and other MCP-compatible tools
⚠️ Limitations
Source material does not describe additional setup, hosting constraints, or tool schema details beyond being local-only.
Local Intelligent MCP Planning Server — A document and planning layer for AI assistants. No subscriptions, no cloud. Point limps at any folder (local, synced, or in git). One shared source of truth across Claude, Cursor, Codex, and any MCP-compatible tool.
# Install globally
npm install -g @sudosandwich/limps
# Initialize in your projectcd ~/Documents/my-planning-docs
limps init
# Start the HTTP daemon
limps server start
# → Daemon starts on http://127.0.0.1:4269/mcp# → PID file written to OS-standard location# → Ready for MCP client connections# Generate MCP client config
limps config print --client claude-code
# Copy the output to your MCP client config file
That's it. Your AI assistant now has access to your documents via HTTP transport. The folder can be anywhere—local, synced, or in a repo; limps does not require a git repository or a plans/ directory.
Tip:limps server status always includes system-wide daemon discovery. If a project config is found (or passed via --config), it also reconciles the configured project target against that global list.
Features
Document CRUD + full-text search across any folder of Markdown files
Plan + agent workflows with status tracking and task scoring
Next-task suggestions with score breakdowns and bias tuning
Sandboxed document processing via process_doc(s) helpers
Multi-client support for Cursor, Claude, Codex, and more
Extensions for domain-specific tooling (e.g., limps-headless)
Health automation — Staleness detection, code drift checks, status inference, and auto-fix proposals
Advanced task scoring — Dependency-aware prioritization with per-plan/agent weight overrides
MCP Registry — Published to the official MCP Registry (registry.modelcontextprotocol.io)
What to know before you start
Local only — Your data stays on disk (SQLite index + your files). No cloud, no subscription.
Restart after changes — If you change the indexed folder or config, restart the MCP server (or rely on the file watcher) so the index and tools reflect the current state.
Daemon management — The HTTP server runs as a background process. Use limps server start, limps server stop, and limps server status to manage the daemon lifecycle. PID files are stored in OS-standard directories for system-wide awareness.
Sandboxed user code — process_doc and process_docs run your JavaScript in a QuickJS sandbox with time and memory limits; no network or Node APIs.
One optional network call — limps version --check fetches from the npm registry to compare versions. All other commands (serve, init, list, search, create/update/delete docs, process_doc, etc.) do not contact the internet. Omit version --check if you want zero external calls.
How I Use limps
I use limps as a local planning layer across multiple AI tools, focused on create → read → update → closure for plans and tasks. The MCP server points at whatever directory I want (not necessarily a git repo), so any client reads and updates the same source of truth.
Typical flow:
Point limps at a docs directory (any folder, local or synced).
Use CLI + MCP tools to create plans/docs, read the current status, update tasks, and close work when done.
Add the limps MCP entry to each client config so Cursor/Claude/Codex all see the same plans.
Close: update_task_status (e.g., PASS), delete_doc if needed
Analyze: graph health, graph search, graph check, health check
Full lists are below in "CLI Commands" and "MCP Tools."
How You Can Use It
limps is designed to be generic and portable. Point it at any folder with Markdown files and use it from any MCP-compatible client. No git repo required.Not limited to planning—planning (plans, agents, task status) is one use case; the same layer gives you document CRUD, full-text search, and programmable processing on any indexed folder.
Common setups:
Single project: One docs folder for a product.
Multi-project: Each project gets its own .limps/config.json; pass --config to target a specific one.
Shared team folder: Put plans in a shared location and review changes like code.
Local-first: Keep everything on disk, no hosted service required.
Key ideas:
Any folder — You choose the path; if there’s no plans/ subdir, the whole directory is indexed. Use generic tools (list_docs, search_docs, create_doc, update_doc, delete_doc, process_doc, process_docs) or plan-specific ones (create_plan, list_plans, list_agents, get_plan_status, update_task_status, get_next_task).
One source of truth — MCP tools give structured access; multiple clients share the same docs.
Why limps?
The problem: Each AI assistant maintains its own context. Planning documents, task status, and decisions get fragmented across Claude, Cursor, ChatGPT, and Copilot conversations.
The solution: limps provides a standardized MCP interface that any tool can access. Your docs live in one place—a folder you choose. Use git (or any sync) if you want version control; limps is not tied to a repository.
Installation
bash
npm install -g @sudosandwich/limps
Upgrading from v2
v3 introduces major changes:
HTTP Transport (Breaking Change)
v3 uses HTTP transport exclusively. stdio transport has been removed.
Migration steps:
Start the HTTP daemon for each project:
bash
limps server start --config /path/to/.limps/config.json
This creates .limps/config.json in the current directory and prints MCP client setup instructions.
You can also specify a path:
bash
limps init ~/Documents/my-planning-docs
If the directory contains a plans/ subdirectory, limps uses it. Otherwise, it indexes the entire directory.
Multiple Projects
Each project has its own .limps/config.json. Use --config to target a specific project:
bash
limps plan list --config ~/docs/project-b/.limps/config.json
Client Setup
After running limps init, you need to add a limps entry to your MCP client's config file. Use limps config print to generate the correct snippet for your client, then paste it into the appropriate config file:
ChatGPT requires a remote MCP server over HTTPS. Deploy limps behind an MCP-compatible HTTPS reverse proxy (nginx, Caddy, etc.) with authentication.
In ChatGPT → Settings → Connectors → Add custom connector:
Server URL: https://your-domain.example/mcp
Authentication: Configure as needed for your proxy
Print setup instructions:
bash
limps config print --client chatgpt
Transport
limps v3 uses HTTP transport exclusively via a persistent daemon. This allows multiple MCP clients to share a single server instance, avoiding file descriptor bloat from multiple stdio processes.
Start the HTTP daemon
bash
# Start the daemon
limps server start
# Check status (shows uptime, sessions, PID)
limps server status
# Stop the daemon
limps server stop
The daemon runs at http://127.0.0.1:4269/mcp by default. Use limps config print to generate the correct MCP client configuration:
Customize the HTTP server by adding a "server" section to your config.json:
Option
Default
Description
port
4269
HTTP listen port
host
127.0.0.1
Bind address
maxSessions
100
Maximum concurrent MCP sessions
sessionTimeoutMs
1800000
Session idle timeout in ms (30 min)
corsOrigin
"" (none)
CORS origin ("", "*", or a URL)
maxBodySize
10485760
Max request body in bytes (10 MB)
rateLimit
100 req/min
Rate limit per client IP
Example custom server config:
json
{"server":{"port":8080,"host":"0.0.0.0"}}
Note: PID files are stored in OS-standard application directories:
macOS: ~/Library/Application Support/limps/pids/
Linux: $XDG_DATA_HOME/limps/pids/ or ~/.local/share/limps/pids/
Windows: %APPDATA%/limps/pids/
This enables limps server status to perform system-wide daemon discovery from any directory. When a limps config is found for the current directory (or passed via --config), the CLI also reports and reconciles that project's configured target.
Remote clients: Use an MCP-compatible HTTPS proxy for remote clients (e.g., ChatGPT).
Daemon Management
limps v3 uses a persistent HTTP daemon with system-wide awareness. PID files are stored in OS-standard directories, allowing you to manage and discover daemons from any directory on your system.
PID File Locations
PID files are stored in platform-specific application data directories:
macOS:
code
~/Library/Application Support/limps/pids/
Linux:
code
$XDG_DATA_HOME/limps/pids/
# or if XDG_DATA_HOME is not set:
~/.local/share/limps/pids/
Windows:
code
%APPDATA%/limps/pids/
Each PID file is named by port number (limps-{port}.pid) to enable system-wide discovery. Example PID file structure:
This port-based naming allows limps server status to find all running daemons across different projects without needing a config file.
Daemon logs are written to OS-standard application log directories:
macOS:
code
~/Library/Application Support/limps/logs/
Linux:
code
$XDG_DATA_HOME/limps/logs/
# or if XDG_DATA_HOME is not set:
~/.local/share/limps/logs/
Windows:
code
%APPDATA%/limps/logs/
Daemon logs are intentionally operational-only: limps redacts uncaught exception/rejection payloads and does not persist raw AI prompt/response content.
Daemon log files are append-only and are not auto-rotated; if you run long-lived daemons, rotate or truncate these files with your system tooling.
Starting the Daemon
Background mode (default):
bash
limps server start
# → Daemon starts on http://127.0.0.1:4269/mcp# → PID file written to OS-standard location# → Logs written to OS-standard log file (append mode)# → Process detaches and runs in background
Foreground mode (debugging):
bash
limps server start --foreground
# → Runs in foreground (blocks terminal)# → Logs appear in stderr# → Useful for debugging startup issues# → Still creates PID file for discovery
Custom port/host (via config):
Configure server.port and server.host in your .limps/config.json:
json
{"server":{"port":8080,"host":"0.0.0.0"}}
Then start normally:
bash
limps server start
# → Starts using server.port/server.host from config# → PID file: limps-8080.pid
The start command performs health verification by polling the /health endpoint for up to 5 seconds, issuing repeated HTTP requests. Each individual health-check request has its own shorter timeout (for example, ~1000ms). If any request fails during this window, you'll see one of these error codes:
TIMEOUT — A single health-check HTTP request exceeded its per-request timeout (e.g., ~1000ms). The daemon may be slow to start or system resources may be constrained. Try limps server start --foreground to see logs.
NETWORK_ERROR — Cannot connect to daemon. Port may be blocked or already in use by another process.
NON_200_STATUS — Health endpoint returned a non-200 status code. Check daemon logs with foreground mode.
INVALID_RESPONSE — Health endpoint responded, but the response was invalid or could not be parsed as expected (for example, malformed or missing required fields).
Checking Daemon Status
With project config (reconciled with global discovery):
bash
# From within a project directory with .limps/config.json
limps server status
# Project target:# limps server is running# PID: 12345 | 127.0.0.1:4269# Uptime: 2h 15m# Sessions: 3# Log: /Users/you/Library/Application Support/limps/logs/limps-4269.log# Project target is present in system-wide daemon discovery.# System-wide daemons:# 127.0.0.1:4269 (PID 12345) [project target]# Uptime: 2h 15m | Sessions: 3# Log: /Users/you/Library/Application Support/limps/logs/limps-4269.log# Or specify config explicitly
limps server status --config /path/to/.limps/config.json
Without project config (global discovery only):
bash
# From a directory without a limps configcd /tmp
limps server status
# Found 2 running daemons:# 127.0.0.1:4269 (PID 12345)# Uptime: 2h 15m | Sessions: 3# Log: /Users/you/Library/Application Support/limps/logs/limps-4269.log# 127.0.0.1:8080 (PID 67890)# Uptime: 45m 30s | Sessions: 1# Log: /Users/you/Library/Application Support/limps/logs/limps-8080.log
When limps server status cannot resolve a config file in the current directory (and no --config is provided), it reports global daemon discovery only. When a config is found, it reports both the configured project target and the global daemon list.
Stopping the Daemon
bash
# From the project directory (where your .limps config lives):
limps server stop
# → Gracefully shuts down daemon# → Closes all MCP sessions# → Stops file watchers# → Removes PID file# → Process exits# Or from any directory, by specifying the config explicitly:
limps server stop --config /path/to/.limps/config.json
The stop command is project-specific and resolves the config to determine which daemon to stop. The daemon performs a graceful shutdown by:
Closing all active MCP sessions
Shutting down file watchers
Removing the PID file
Exiting the process
Port Conflicts
If you try to start a daemon on a port that's already in use, limps will detect the conflict and provide resolution guidance:
bash
limps server start
# Error: Port 4269 is already in use.# Process using port: node (PID 12345)# Command: /usr/local/bin/node /usr/local/bin/limps server start## To stop the process: kill 12345# Or use a different port: limps server start --port <port>
On systems with lsof available (macOS, Linux), limps can identify which process is using the port and show its command line. If lsof is not available, you'll see a simpler error message suggesting a different port.
Foreground Mode
Use foreground mode for debugging, Docker deployments, or CI/CD pipelines:
bash
limps server start --foreground
Use cases:
Debugging — See server logs in real-time to diagnose startup issues
Docker — Keep container alive with the daemon as the main process
CI/CD — Run tests against a limps daemon without background processes
Behavior differences from background mode:
Logs to stderr instead of being silent
Blocks the terminal (press Ctrl+C to stop)
Still creates a PID file for discovery by other processes
Responds to SIGINT (Ctrl+C) and SIGTERM for graceful shutdown
Health Endpoint
The HTTP daemon exposes a /health endpoint for monitoring and health checks:
429 — Rate limit exceeded (rate limiter may return this before the request reaches /health)
Session Management & Reconnection
Sessions automatically expire after 30 minutes of inactivity (configurable via sessionTimeoutMs). When a session expires, MCP clients receive a specific error response indicating they should reconnect.
Session Expiration Response:
When a session expires or is closed, subsequent requests with that session ID return:
json
{"error":"Session expired","code":"SESSION_EXPIRED","message":"Session expired due to timeout. Please reconnect without session ID.","expiredAt":"2026-02-11T10:30:00.000Z"}
Set to 0 to disable timeout (sessions persist until server restart).
Expired Session Tracking:
The server tracks expired sessions for 24 hours to help clients distinguish between "session expired" vs "session never existed":
SESSION_EXPIRED — Session previously existed but timed out (client should reconnect)
SESSION_NOT_FOUND — Session ID was never valid (possible server restart or invalid ID)
Use this endpoint for:
Monitoring daemon health in scripts or dashboards
Verifying daemon is running before connecting MCP clients
Automated health checks in orchestration tools (Kubernetes, Docker Compose)
Multiple Daemons
You can run multiple limps daemons on different ports for different projects by configuring different ports in each project's config:
bash
# Project A with default port (4269)cd ~/projects/project-a
# .limps/config.json has server.port: 4269 (or uses default)
limps server start
# → Running on http://127.0.0.1:4269/mcp# Project B with custom port (8080)cd ~/projects/project-b
# .limps/config.json has server.port: 8080
limps server start
# → Running on http://127.0.0.1:8080/mcp
Each daemon has its own PID file:
limps-4269.pid — Project A
limps-8080.pid — Project B
Discover all running daemons (run from a directory without a limps config):
bash
cd /tmp
limps server status
# Found 2 running daemons:# 127.0.0.1:4269 (PID 12345)# Uptime: 2h 15m | Sessions: 3# 127.0.0.1:8080 (PID 67890)# Uptime: 45m 30s | Sessions: 1
Each MCP client can connect to different daemons by configuring different URLs in their config files.
CLI Commands
Recommended Grouped Commands
bash
limps plan list # List all plans with status
limps plan agents <plan> # List agents in a plan
limps plan status <plan> # Show plan progress summary
limps plan next <plan> # Get highest-priority available task
limps plan score --plan <plan> --agent <n> # Score a single task
limps plan scores --plan <plan> # Score all available tasks in a plan
limps docs list [path] # List files/directories
limps docs search <query> # Search indexed docs
limps docs process [path] --code "<js>"# Process docs with JavaScript
limps server start # Start HTTP daemon
limps server status # Show daemon status
limps server stop # Stop HTTP daemon
Project Management
bash
limps init [path] # Initialize new project
limps config show # Display current config
limps config print# Print MCP client config snippets
limps completion zsh # Generate Zsh tab-completion script
Health & Automation
bash
limps health check # Aggregate all health signals
limps health staleness [plan] # Find stale plans/agents
limps health inference [plan] # Suggest status updates
limps proposals [plan] # List auto-fix proposals
limps proposals apply <id> # Apply a proposal
limps proposals apply-safe # Apply all safe proposals
limps plan scores --plan <plan> # Score all agents in a plan
limps plan score --plan <plan> --agent <n> # Score a single task
limps plan repair [--fix] # Check/fix agent frontmatter
Configuration
Config lives at .limps/config.json in your project directory, created by limps init.
The daemon did not respond within the configured timeout. Each health-check request has its own timeout (for example, 1000ms during the final limps server start check and 3000ms for limps server status), and during startup limps will poll for up to about 5 seconds before reporting "Daemon may have failed to start".
Common causes:
System resource constraints (high CPU/memory usage)
Slow filesystem (especially for index initialization)
Large document corpus requiring time to index
Resolution:
Check system resources: top or Activity Monitor
Wait a bit longer and retry: limps server status
Run in foreground to see progress: limps server start --foreground
NETWORK_ERROR:
Cannot establish connection to the daemon.
Common causes:
Port is blocked by firewall
Daemon crashed after starting
Incorrect host/port configuration
Resolution:
Verify daemon is running: limps server status
Check firewall settings for port 4269
Try curl http://127.0.0.1:4269/health manually
Check daemon logs: see Log: path in limps server status output
Stale PID Files
limps automatically cleans up stale PID files when:
Running limps server status (discovers and removes stale files)
Running limps server start (removes stale file for the target port)
The daemon shuts down gracefully with limps server stop
If you need to manually clean up PID files:
bash
# macOSrm ~/Library/Application\ Support/limps/pids/limps-*.pid
# Linuxrm ~/.local/share/limps/pids/limps-*.pid
# Windows
del %APPDATA%\limps\pids\limps-*.pid
When to manually clean up:
After a system crash or forced shutdown
If limps server start reports a daemon is running but it's not
Before uninstalling limps
Multiple Daemons Conflict
If you accidentally try to start a second daemon on the same port:
bash
limps server start
# Error: limps daemon already running (PID 12345 on 127.0.0.1:4269). Run 'limps server stop' first.
This is expected behavior — limps prevents multiple daemons on the same port using PID-based locking.
Resolution:
Check all running daemons: limps server status
Stop the existing daemon: limps server stop
Or start on a different port: limps server start --port 8080
Debugging Connection Issues
If MCP clients can't connect to the daemon, verify connectivity step by step:
1. Check daemon status:
bash
limps server status
# Should show daemon running with healthy status
2. Verify health endpoint:
bash
curl http://127.0.0.1:4269/health
# Should return JSON with status "ok"
3. Verify MCP endpoint:
bash
curl -X POST http://127.0.0.1:4269/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'# Should return MCP initialize response
4. Enable debug logging:
bash
DEBUG=1 limps server start --foreground
# Watch for connection attempts and errors
5. Check MCP client config:
Ensure the URL in your client config matches the daemon:
Environment variable set: Check if MCP_PLANNING_CONFIG is set in your shell or IDE. This takes priority over local config files.
bash
# Check if setecho$MCP_PLANNING_CONFIG# Unset if neededunset MCP_PLANNING_CONFIG
Wrong working directory: Config search starts from your current working directory. Make sure you're in the right directory when running limps commands.
bash
# Check current directorypwd# Navigate to your projectcd /path/to/your/project
Missing .limps/config.json: The config file must be in a .limps subdirectory, not at the project root.
bash
# Correct location
/path/to/project/.limps/config.json
# Wrong - won't be found
/path/to/project/config.json
Quick fixes:
bash
# Override with explicit path
limps plan list --config /path/to/project/.limps/config.json
# Or set environment variableexport MCP_PLANNING_CONFIG=/path/to/project/.limps/config.json
# Or initialize a new config in current directory
limps init
The knowledge graph builds a structured, queryable representation of your planning documents. It extracts 6 entity types (plan, agent, feature, file, tag, concept) and their relationships (ownership, dependency, modification, tagging, conceptual links). Use it to find conflicts, trace dependencies, and get graph-based suggestions.
bash
# Build the graph from plan files
limps graph reindex
# Check graph health and conflicts
limps graph health --json
# Search entities
limps graph search "auth" --json
# Trace relationships
limps graph trace plan:0042 --direction down
# Detect conflicts (file contention, circular deps, stale WIP)
limps graph check --json
# Get graph-based suggestions
limps graph suggest dependency-order
Claude Code commands (available automatically when limps is your working directory):
Command
Description
/create-feature-plan
Create a full TDD plan with agents
/run-agent
Pick up and execute the next agent
/close-feature-agent
Mark an agent PASS and clean up
/update-feature-plan
Revise an existing plan
/audit-plan
Audit a plan for completeness
/list-feature-plans
List all plans with status
/plan-list-agents
List agents in a plan
/plan-check-status
Check plan progress
/pr-create
Create a PR from the current branch
/pr-check-and-fix
Fix CI failures and update PR
/pr-comments
Review and respond to PR comments
/review-branch
General code review of current branch
/review-mcp
Review code for MCP/LLM safety
/attack-cli-mcp
Stress-test CLI + MCP for robustness
Vercel Skills (for other AI IDEs):
Install the limps planning skill to get AI-powered guidance for plan creation, agent workflows, and task management:
bash
# Install only the limps planning skill (recommended for consumers)
npx skills add https://github.com/sudosandwich/limps/tree/main/.claude/skills/limps-plan-operations
# Or install all available skills
npx skills add sudosandwich/limps
Available Skills:
Skill
Description
limps-plan-operations
Plan identification, artifact loading, distillation rules, and lifecycle guidance using limps MCP tools
mcp-code-review
Security-focused code review for MCP servers and LLM safety
branch-code-review
General code review for design, maintainability, and correctness
git-commit-best-practices
Conventional commits and repository best practices
See skills.yaml for the complete manifest of the .claude/skills packages installed via npx skills add above; the separate skills/limps-planning/ package in this repo is a legacy distribution and new consumers should prefer the .claude/skills method.
Extensions
Extensions add MCP tools and resources. Install from npm:
limps manages planning for runi, using a separate folder (in this case a git repo) for plans.
Creating a feature plan
The fastest way is the /create-feature-plan slash command (Claude Code) — it handles numbering, doc creation, and agent distillation automatically via MCP tools. See .claude/commands/create-feature-plan.md for the full spec.
You can also run the same steps manually with MCP tools:
list_plans → determine next plan number
create_plan → scaffold the plan directory
create_doc → add plan, interfaces, README, and agent files
Numbered prefixes keep plans and agents lexicographically ordered. get_next_task uses the agent number (plus dependency and workload scores) to suggest what to work on next.
Deep Dive
Plan Structure
code
plans/
├── 0001-feature-name/
│ ├── 0001-feature-name-plan.md # Main plan with specs
│ ├── interfaces.md # Interface contracts
│ ├── README.md # Status index
│ └── agents/ # Task files
│ ├── 000-setup.md
│ ├── 001-implement.md
│ └── 002-test.md
└── 0002-another-feature/
└── ...
process_doc and process_docs execute JavaScript in a secure QuickJS sandbox. User-provided code is statically validated and cannot use require, import, eval, fetch, XMLHttpRequest, WebSocket, process, timers, or other host/network APIs—so it cannot make external calls or access the host.
awaitprocess_doc({
path: "plans/0001/plan.md",
code: "extractFeatures(doc.content)",
sub_query: "Summarize each feature",
allow_llm: true,
llm_policy: "force", // or 'auto' (skips small results)
});
MCP Resources
Progressive disclosure via resources:
Resource
Description
plans://index
List of all plans (minimal)
plans://summary
Plan summaries with key info
plans://full
Full plan documents
decisions://log
Decision log entries
Example: Custom Cursor Commands
Create .cursor/commands/run-agent.md:
markdown
# Run Agent
Start work on the next available task.
## Instructions1. Use `get_next_task` to find the highest-priority task
2. Use `process_doc` to read the agent file
3. Use `update_task_status` to mark it WIP
4. Follow the agent's instructions
This integrates with limps MCP tools for seamless task management.
What is MCP?
Model Context Protocol is a standardized protocol for AI applications to connect to external systems. Originally from Anthropic (Nov 2024), now part of the Linux Foundation's Agentic AI Foundation.