@sudosandwich/limps 2.5.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,296 +1,174 @@
1
1
  # limps
2
2
 
3
- **L**ocal **I**ntelligent **M**CP **P**lanning **S**erver - limps your Local Intelligent MCP Planning Server across AI assistants. No subscriptions, no cloud—run it locally. Version control your planning docs in git. No more context drift—one shared source of truth for planning docs, tasks, and decisions across Claude Desktop, Cursor, GitHub Copilot, and any MCP tool.
3
+ **L**ocal **I**ntelligent **M**CP **P**lanning **S**erver 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.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@sudosandwich/limps)](https://www.npmjs.com/package/@sudosandwich/limps)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- ![Tests](https://img.shields.io/badge/Tests-817%20passing-brightgreen)
7
+ ![Tests](https://img.shields.io/badge/Tests-899%20passing-brightgreen)
8
8
  ![Coverage](https://img.shields.io/badge/Coverage-%3E70%25-brightgreen)
9
9
 
10
- ![limps in action](https://github.com/paulbreuler/limps/blob/main/.github/assets/limps-in-action.gif?raw=true)
10
+ ![limps in action](https://github.com/paulbreuler/limps/blob/main/.github/assets/limps-a-lol-longer.gif?raw=true)
11
11
 
12
- *Claude Desktop accessing the planning MCP, talking to Runi project docs*
12
+ ## Quick Start
13
13
 
14
- ## The Problem limps Solves
14
+ ```bash
15
+ # Install globally
16
+ npm install -g @sudosandwich/limps
15
17
 
16
- **Context drift between LLM providers** — Each AI assistant (Claude, ChatGPT, Cursor, GitHub Copilot, etc.) maintains its own separate context. Without a shared source of truth, planning documents, task status, and decisions get fragmented across different conversations and sessions.
18
+ # Initialize a project
19
+ limps init my-project --docs-path ~/Documents/my-planning-docs
17
20
 
18
- limps solves this by providing a **standardized MCP interface** that any MCP-compatible tool can access. Your planning documents, tasks, and decisions live in one place, accessible to:
21
+ # Add to your AI assistant (picks up all registered projects)
22
+ limps config sync-mcp --client cursor
23
+ limps config sync-mcp --client claude-code
24
+ ```
19
25
 
20
- - **Claude Desktop** Full access to search, read, update, create documents, and more
21
- - **Cursor** — Integrated planning and task management via MCP tools
22
- - **GitHub Copilot** — When MCP support is enabled
23
- - **Any MCP-compatible tool** — Standard protocol means universal access
26
+ Run this in the folder where you want to keep the docs and that's it. Your AI assistant now has access to your documents and nothing else. The folder can be anywhere—local, synced, or in a repo; limps does not require a git repository or a `plans/` directory.
24
27
 
25
- ### Deployment Options
28
+ ### What to know before you start
26
29
 
27
- - **Local (Default)** — Run limps locally for secure, private access
28
- - **Deployed** — You can deploy the MCP server for global access, but **research AUTH** to protect your endpoint and documents
30
+ - **Local only** — Your data stays on disk (SQLite index + your files). No cloud, no subscription.
31
+ - **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.
32
+ - **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.
33
+ - **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.
29
34
 
30
- ## Used In Production
35
+ ## How I Use limps
31
36
 
32
- limps is actively used to build [runi](https://github.com/paulbreuler/runi) - managing planning documents and task tracking across the development lifecycle.
37
+ 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.
33
38
 
34
- ### How runi Uses limps
39
+ Typical flow:
35
40
 
36
- The [runi](https://github.com/paulbreuler/runi) project uses a separate git repository ([runi-planning-docs](https://github.com/paulbreuler/runi-planning-docs)) for version-controlled planning documents. Custom Cursor commands in `.cursor/commands/` integrate with limps tools:
41
+ 1. Point limps at a docs directory (any folder, local or synced).
42
+ 2. Use CLI + MCP tools to create plans/docs, read the current status, update tasks, and close work when done.
43
+ 3. Sync MCP configs so Cursor/Claude/Codex all see the same plans.
37
44
 
38
- **Core Commands:**
45
+ Commands and tools I use most often:
39
46
 
40
- | Command | Description | MCP Tools Used |
41
- |---------|-------------|----------------|
42
- | `/create-feature-plan` | Generate TDD plan with docs and agent files | `create_plan`, `create_doc`, `list_docs` |
43
- | `/list-feature-plans` | List all plans with clickable file paths | `list_docs`, `process_doc` |
44
- | `/run-agent` | Start work on next agent task | `process_doc`, `update_task_status` |
45
- | `/close-feature-agent` | Verify completion, sync status | `process_doc`, `update_doc`, `update_task_status` |
46
- | `/update-feature-plan` | Regenerate agents from updated plan | `process_doc`, `create_doc`, `process_docs` |
47
- | `/plan-list-agents` | Show all agents with status | `list_docs`, `process_docs` |
47
+ - **Create**: `limps init`, `create_plan`, `create_doc`
48
+ - **Read**: `list_plans`, `list_agents`, `list_docs`, `search_docs`, `get_plan_status`
49
+ - **Update**: `update_doc`, `update_task_status`, `manage_tags`
50
+ - **Close**: `update_task_status` (e.g., `PASS`), `delete_doc` if needed
48
51
 
49
- **Example: `/create-feature-plan` using MCP tools:**
52
+ Full lists are below in "CLI Commands" and "MCP Tools."
50
53
 
51
- ```typescript
52
- // 1. Find next plan number
53
- const plans = await list_docs({ path: 'plans/', pattern: '*' });
54
- const nextNum = Math.max(...plans.map(p => parseInt(p.name))) + 1;
54
+ ## How You Can Use It
55
55
 
56
- // 2. Create plan structure
57
- await create_plan({ name: `${nextNum}-my-feature`, description: '...' });
56
+ `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.
58
57
 
59
- // 3. Create planning documents
60
- await create_doc({ path: `plans/${nextNum}-my-feature/plan.md`, content: '...' });
61
- await create_doc({ path: `plans/${nextNum}-my-feature/interfaces.md`, content: '...' });
62
- ```
58
+ Common setups:
63
59
 
64
- **Example: `/run-agent` using process_doc:**
60
+ - **Single project**: One docs folder for a product.
61
+ - **Multi-project**: Register multiple folders and switch with `limps config use`.
62
+ - **Shared team folder**: Put plans in a shared location and review changes like code.
63
+ - **Local-first**: Keep everything on disk, no hosted service required.
65
64
 
66
- ```typescript
67
- // Extract next GAP feature from plan
68
- const nextGap = await process_doc({
69
- path: `plans/${planName}/plan.md`,
70
- code: `
71
- const features = extractFeatures(doc.content);
72
- const gaps = features.filter(f => f.status === 'GAP');
73
- return gaps.sort((a, b) => a.priority - b.priority)[0];
74
- `,
75
- });
76
- ```
65
+ Key ideas:
77
66
 
78
- **Project Structure:**
67
+ - **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`).
68
+ - **One source of truth** — MCP tools give structured access; multiple clients share the same docs.
79
69
 
80
- ```
81
- runi/ # Main codebase
82
- ├── .cursor/commands/ # Cursor slash commands
83
- │ ├── create-feature-plan.md
84
- │ ├── list-feature-plans.md
85
- │ ├── run-agent.md
86
- │ ├── close-feature-agent.md
87
- │ └── update-feature-plan.md
88
- └── .claude/commands/ # Claude Code commands
89
- └── pr.md
90
-
91
- runi-planning-docs/ # Separate git repo for plans
92
- ├── plans/
93
- │ ├── 0004-datagrid/ # Feature plan
94
- │ │ ├── plan.md # Full specifications
95
- │ │ ├── interfaces.md # Interface contracts
96
- │ │ ├── README.md # Status index
97
- │ │ ├── gotchas.md # Discovered issues
98
- │ │ └── agents/ # Agent task files
99
- │ └── ...
100
- └── decisions/ # Decision log
101
- ```
70
+ ## Why limps?
102
71
 
103
- ## Installation
72
+ **The problem:** Each AI assistant maintains its own context. Planning documents, task status, and decisions get fragmented across Claude, Cursor, ChatGPT, and Copilot conversations.
73
+
74
+ **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.
75
+
76
+ ### Supported Clients
104
77
 
105
- ### Global Install (Recommended)
78
+ | Client | Config Location | Command |
79
+ |--------|----------------|---------|
80
+ | **Cursor** | `.cursor/mcp.json` (local) | `limps config sync-mcp --client cursor` |
81
+ | **Claude Code** | `.mcp.json` (local) | `limps config sync-mcp --client claude-code` |
82
+ | **Claude Desktop** | Global config | `limps config sync-mcp --client claude --global` |
83
+ | **OpenAI Codex** | `~/.codex/config.toml` | `limps config sync-mcp --client codex --global` |
84
+ | **ChatGPT** | Manual setup | `limps config sync-mcp --client chatgpt --print` |
85
+
86
+ > **Note:** By default, `sync-mcp` writes to local/project configs. Use `--global` for user-level configs.
87
+
88
+ ## Installation
106
89
 
107
90
  ```bash
108
91
  npm install -g @sudosandwich/limps
109
92
  ```
110
93
 
111
- ### Quick Setup
94
+ ## Project Setup
95
+
96
+ ### Initialize a New Project
112
97
 
113
98
  ```bash
114
- limps init my-project --docs-path ~/Documents/my-project
99
+ limps init my-project --docs-path ~/Documents/my-planning-docs
115
100
  ```
116
101
 
117
- This creates a config and outputs the Cursor/Claude Desktop configuration snippets with full paths.
118
-
119
- ## CLI Commands
102
+ This creates a config file and outputs setup instructions.
120
103
 
121
- limps provides a full CLI for managing projects and viewing plans without needing an MCP client.
104
+ ### Register an Existing Directory
122
105
 
123
106
  ```bash
124
- limps --help # Show all commands
125
- limps <command> --help # Show command help
107
+ limps config add my-project ~/Documents/existing-docs
126
108
  ```
127
109
 
128
- ### Project Management
110
+ If the directory contains a `plans/` subdirectory, limps uses it. Otherwise, it indexes the entire directory.
129
111
 
130
- | Command | Description |
131
- |---------|-------------|
132
- | `limps init <name>` | Initialize a new project |
133
- | `limps serve` | Start the MCP server |
134
-
135
- ### Plan Commands
136
-
137
- | Command | Description |
138
- |---------|-------------|
139
- | `limps list-plans` | List all plans with status |
140
- | `limps list-agents <plan>` | List agents in a plan |
141
- | `limps next-task <plan>` | Get the highest-priority available task |
142
- | `limps status <plan>` | Show plan status summary |
143
-
144
- ### Configuration
145
-
146
- | Command | Description |
147
- |---------|-------------|
148
- | `limps config list` | Show all registered projects |
149
- | `limps config use <name>` | Switch to a different project |
150
- | `limps config show` | Display resolved configuration |
151
- | `limps config path` | Print the config file path |
152
- | `limps config add <name> <path>` | Register an existing config |
153
- | `limps config remove <name>` | Unregister a project |
154
- | `limps config set <path>` | Set current from config path |
155
- | `limps config discover` | Find configs in default locations |
156
- | `limps config update <name>` | Update project paths |
157
- | `limps config sync-mcp` | Add projects to MCP client configs |
158
-
159
- ### Multi-Project Workflow
112
+ ### Multiple Projects
160
113
 
161
114
  ```bash
162
115
  # Register multiple projects
163
- limps init project-a --docs-path ~/Documents/project-a
164
- limps init project-b --docs-path ~/Documents/project-b
116
+ limps init project-a --docs-path ~/docs/project-a
117
+ limps init project-b --docs-path ~/docs/project-b
165
118
 
166
- # Switch between projects
119
+ # Switch between them
167
120
  limps config use project-a
168
- limps list-plans
169
-
170
- limps config use project-b
171
- limps list-plans
172
121
 
173
- # Use environment variable
174
- LIMPS_PROJECT=project-a limps list-plans
122
+ # Or use environment variable
123
+ LIMPS_PROJECT=project-b limps list-plans
175
124
  ```
176
125
 
177
- ### Example: Git-based Document Versioning
126
+ ## Client Setup
178
127
 
179
- Point limps at a git repository to version control your planning documents:
128
+ ### Automatic (Recommended)
180
129
 
181
130
  ```bash
182
- # Create a dedicated docs repo
183
- mkdir ~/Documents/GitHub/my-planning-docs
184
- cd ~/Documents/GitHub/my-planning-docs
185
- git init
186
-
187
- # Initialize limps with your docs repo
188
- limps init my-project --docs-path ~/Documents/GitHub/my-planning-docs
189
- ```
190
-
191
- This approach gives you:
192
- - **Version history** for all plans and decisions
193
- - **Branching** for experimental planning
194
- - **Collaboration** via pull requests
195
- - **Backup** through remote repositories
196
-
197
- ### Manual Configuration
198
-
199
- The server automatically finds configuration at OS-specific locations:
200
-
201
- | OS | Config Location |
202
- |----|-----------------|
203
- | macOS | `~/Library/Application Support/limps/config.json` |
204
- | Linux | `~/.config/limps/config.json` |
205
- | Windows | `%APPDATA%\limps\config.json` |
131
+ # Add all projects to a client's local config
132
+ limps config sync-mcp --client cursor
206
133
 
207
- ## Configuration
134
+ # Preview changes without writing
135
+ limps config sync-mcp --client cursor --print
208
136
 
209
- Create a `config.json` at the OS-specific location or specify a path:
137
+ # Write to global config instead of local
138
+ limps config sync-mcp --client cursor --global
210
139
 
211
- ```json
212
- {
213
- "plansPath": "~/Documents/my-plans",
214
- "docsPaths": ["~/Documents/my-plans"],
215
- "fileExtensions": [".md"],
216
- "dataPath": "~/Library/Application Support/limps/data",
217
- "extensions": ["@sudosandwich/limps-radix"],
218
- "@sudosandwich/limps-radix": {
219
- "cacheDir": "~/Library/Application Support/limps-radix",
220
- "featureFlags": {
221
- "enableRadix": true
222
- }
223
- },
224
- "scoring": {
225
- "weights": {
226
- "dependency": 40,
227
- "priority": 30,
228
- "workload": 30
229
- },
230
- "biases": {}
231
- }
232
- }
140
+ # Custom config path
141
+ limps config sync-mcp --client cursor --path ./custom-mcp.json
233
142
  ```
234
143
 
235
- ### Config Resolution Priority
236
-
237
- The server finds configuration in this order:
238
-
239
- 1. **CLI argument**: `limps serve --config /path/to/config.json`
240
- 2. **Environment variable**: `MCP_PLANNING_CONFIG=/path/to/config.json`
241
- 3. **Project environment**: `LIMPS_PROJECT=my-project` (looks up in registry)
242
- 4. **Registry current project**: Set via `limps config use <name>`
243
- 5. **OS-specific default**: See table above
244
-
245
- > **Note:** If no config exists at the resolved path, limps auto-creates a default config file.
246
-
247
- ### Config Options
248
-
249
- | Option | Type | Default | Description |
250
- |--------|------|---------|-------------|
251
- | `plansPath` | string | `./plans` | Primary directory for structured plans (contains `NNNN-name/` directories with agents, tasks, status tracking) |
252
- | `docsPaths` | string[] | `[]` | Additional directories to index for search (any markdown, no structure required) |
253
- | `fileExtensions` | string[] | `[".md"]` | File types to index |
254
- | `dataPath` | string | `./data` | SQLite database location |
255
- | `scoring` | object | required | Task scoring configuration for `get_next_task` (weights and biases) |
256
- | `extensions` | string[] | `[]` | Extension package names to load (e.g., `["@sudosandwich/limps-radix"]`) |
144
+ ### Manual Setup
257
145
 
258
- ### Path Options
146
+ <details>
147
+ <summary><b>Cursor</b></summary>
259
148
 
260
- - **Tilde expansion**: `~/Documents/plans` `/Users/you/Documents/plans`
261
- - **Absolute paths**: `/Users/john/Documents/plans`
262
- - **Relative paths**: `./plans` (relative to config file location)
263
-
264
- ### Extensions
265
-
266
- Extensions are loaded by package name from `node_modules` and can register MCP tools/resources.
267
- Per-extension configuration lives under a top-level key matching the package name.
268
-
269
- Security note: extensions execute local code. Only install extensions you trust. Extensions should never log prompts or model outputs; keep logs to metadata only.
149
+ Add to `.cursor/mcp.json` in your project:
270
150
 
271
151
  ```json
272
152
  {
273
- "extensions": ["@sudosandwich/limps-radix"],
274
- "@sudosandwich/limps-radix": {
275
- "cacheDir": "~/Library/Application Support/limps-radix",
276
- "featureFlags": {
277
- "enableRadix": true
153
+ "mcpServers": {
154
+ "limps": {
155
+ "command": "limps",
156
+ "args": ["serve", "--config", "/path/to/config.json"]
278
157
  }
279
158
  }
280
159
  }
281
160
  ```
282
161
 
283
- ## MCP Client Setup
162
+ </details>
284
163
 
285
- > **Important:** MCP clients must use the `serve` subcommand. Run `limps init my-project` first to generate a config.
164
+ <details>
165
+ <summary><b>Claude Code</b></summary>
286
166
 
287
- ### Cursor
288
-
289
- Add to settings (`Cmd+Shift+P` → "Preferences: Open User Settings (JSON)"):
167
+ Add to `.mcp.json` in your project root:
290
168
 
291
169
  ```json
292
170
  {
293
- "mcp.servers": {
171
+ "mcpServers": {
294
172
  "limps": {
295
173
  "command": "limps",
296
174
  "args": ["serve", "--config", "/path/to/config.json"]
@@ -299,9 +177,12 @@ Add to settings (`Cmd+Shift+P` → "Preferences: Open User Settings (JSON)"):
299
177
  }
300
178
  ```
301
179
 
302
- ### Claude Desktop
180
+ </details>
303
181
 
304
- Claude Desktop runs in a macOS sandbox—use `npx` instead of global binaries.
182
+ <details>
183
+ <summary><b>Claude Desktop</b></summary>
184
+
185
+ Claude Desktop runs in a sandbox—use `npx` instead of global binaries.
305
186
 
306
187
  Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
307
188
 
@@ -316,290 +197,329 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
316
197
  }
317
198
  ```
318
199
 
319
- ### Claude Code
200
+ </details>
320
201
 
321
- Add to `~/.claude/.mcp.json`:
202
+ <details>
203
+ <summary><b>OpenAI Codex</b></summary>
322
204
 
323
- ```json
324
- {
325
- "mcpServers": {
326
- "limps": {
327
- "command": "npx",
328
- "args": ["-y", "@sudosandwich/limps", "serve", "--config", "/path/to/config.json"]
329
- }
330
- }
331
- }
332
- ```
205
+ Add to `~/.codex/config.toml`:
333
206
 
334
- ### Automatic MCP Client Configuration
207
+ ```toml
208
+ [mcp_servers.limps]
209
+ command = "limps"
210
+ args = ["serve", "--config", "/path/to/config.json"]
211
+ ```
335
212
 
336
- Instead of manually editing config files, use the CLI:
213
+ </details>
337
214
 
338
- ```bash
339
- # Add all registered projects to all MCP clients
340
- limps config sync-mcp
215
+ <details>
216
+ <summary><b>ChatGPT</b></summary>
341
217
 
342
- # Add to specific client only
343
- limps config sync-mcp --client claude
344
- limps config sync-mcp --client cursor
345
- limps config sync-mcp --client claude-code
218
+ ChatGPT requires a remote MCP server over HTTPS. Deploy limps behind an MCP-compatible HTTP/SSE proxy.
346
219
 
347
- # Add specific projects
348
- limps config sync-mcp --projects my-project,other-project
220
+ In ChatGPT → Settings → Connectors → Add custom connector:
349
221
 
350
- # Preview without writing
351
- limps config sync-mcp --print
222
+ - **Server URL**: `https://your-domain.example/mcp`
223
+ - **Authentication**: Configure as needed
352
224
 
353
- # Show a JSON Patch diff before writing (confirm prompt)
354
- limps config sync-mcp
225
+ Print setup instructions:
355
226
 
356
- # Skip diff/confirmation and write directly
357
- limps config sync-mcp -f
227
+ ```bash
228
+ limps config sync-mcp --client chatgpt --print
358
229
  ```
359
230
 
360
- ## Features
361
-
362
- ### MCP Tools (15 Tools)
231
+ </details>
363
232
 
364
- #### Document Operations
233
+ ## CLI Commands
365
234
 
366
- | Tool | Description |
367
- |------|-------------|
368
- | `process_doc` | Process a document with JavaScript code (read, filter, transform, extract) |
369
- | `process_docs` | Process multiple documents with JavaScript for cross-document analysis |
370
- | `create_doc` | Create new documents |
371
- | `update_doc` | Update with overwrite, append, or prepend modes |
372
- | `delete_doc` | Delete documents |
373
- | `list_docs` | List files and directories |
374
- | `search_docs` | Full-text search with frontmatter support, excerpts, and match counts |
375
- | `manage_tags` | Add, remove, or list tags (frontmatter and inline `#tag` format) |
376
- | `open_document_in_cursor` | Open files in Cursor editor |
235
+ ### Viewing Plans
377
236
 
378
- #### Plan Management
237
+ ```bash
238
+ limps list-plans # List all plans with status
239
+ limps list-agents <plan> # List agents in a plan
240
+ limps status <plan> # Show plan progress summary
241
+ limps next-task <plan> # Get highest-priority available task
242
+ ```
379
243
 
380
- | Tool | Description |
381
- |------|-------------|
382
- | `create_plan` | Create feature plans with directory structure and agent files |
383
- | `list_plans` | List all plans with status, workType, and overview |
384
- | `list_agents` | List agents for a plan with status, persona, and file counts |
385
- | `get_plan_status` | Get plan progress with completion %, blocked/WIP agents |
244
+ ### Project Management
386
245
 
387
- #### Task Management
246
+ ```bash
247
+ limps init <name> # Initialize new project
248
+ limps serve # Start MCP server
249
+ limps config list # Show registered projects
250
+ limps config use <name> # Switch active project
251
+ limps config show # Display current config
252
+ limps config sync-mcp # Add projects to MCP clients
253
+ ```
388
254
 
389
- | Tool | Description |
390
- |------|-------------|
391
- | `get_next_task` | Get highest-priority task with detailed score breakdown |
392
- | `update_task_status` | Update task status (GAP → WIP → PASS/BLOCKED) |
255
+ ## Configuration
393
256
 
394
- #### Task Scoring Algorithm
257
+ Config location varies by OS:
395
258
 
396
- When using `get_next_task` with a `planId`, returns a detailed score breakdown:
259
+ | OS | Path |
260
+ |----|------|
261
+ | macOS | `~/Library/Application Support/limps/config.json` |
262
+ | Linux | `~/.config/limps/config.json` |
263
+ | Windows | `%APPDATA%\limps\config.json` |
397
264
 
398
- | Score Component | Max Points | Description |
399
- |----------------|------------|-------------|
400
- | Dependency Score | 40 | All dependencies satisfied = 40, otherwise 0 |
401
- | Priority Score | 30 | Based on agent number (lower = higher priority) |
402
- | Workload Score | 30 | Based on file count (fewer files = higher score) |
403
- | **Total** | **100** | Sum of all components |
265
+ ### Config Options
404
266
 
405
- Example response:
406
267
  ```json
407
268
  {
408
- "taskId": "0001-feature#002",
409
- "title": "Implement API endpoints",
410
- "totalScore": 85,
411
- "dependencyScore": 40,
412
- "priorityScore": 24,
413
- "workloadScore": 21,
414
- "reasons": ["All 2 dependencies satisfied", "Agent #2 priority: 24/30", "3 files to modify: 21/30"],
415
- "otherAvailableTasks": 3
269
+ "plansPath": "~/Documents/my-plans",
270
+ "docsPaths": ["~/Documents/my-plans"],
271
+ "fileExtensions": [".md"],
272
+ "dataPath": "~/Library/Application Support/limps/data",
273
+ "extensions": ["@sudosandwich/limps-radix"],
274
+ "scoring": {
275
+ "weights": { "dependency": 40, "priority": 30, "workload": 30 },
276
+ "biases": {}
277
+ }
416
278
  }
417
279
  ```
418
280
 
419
- #### Scoring Biases
281
+ | Option | Description |
282
+ |--------|-------------|
283
+ | `plansPath` | Directory for structured plans (`NNNN-name/` with agents) |
284
+ | `docsPaths` | Additional directories to index |
285
+ | `fileExtensions` | File types to index (default: `.md`) |
286
+ | `dataPath` | SQLite database location |
287
+ | `extensions` | Extension packages to load |
288
+ | `scoring` | Task prioritization weights and biases |
420
289
 
421
- Biases are numeric adjustments added to the final score. Use them to promote or demote specific plans, personas, or statuses.
290
+ ## MCP Tools
422
291
 
423
- Supported bias keys:
292
+ limps exposes 15 MCP tools for AI assistants:
424
293
 
425
- | Bias Key | Description | Example |
426
- |---------|-------------|---------|
427
- | `plans` | Per-plan bias keyed by plan folder name | `"plans": { "0030-limps-scoring-weights": 20 }` |
428
- | `personas.coder` | Bias for coder tasks | `"personas": { "coder": 10 }` |
429
- | `personas.reviewer` | Bias for reviewer tasks | `"personas": { "reviewer": -10 }` |
430
- | `personas.pm` | Bias for PM tasks | `"personas": { "pm": 5 }` |
431
- | `personas.customer` | Bias for customer tasks | `"personas": { "customer": 5 }` |
432
- | `statuses.GAP` | Bias for GAP tasks | `"statuses": { "GAP": 5 }` |
433
- | `statuses.WIP` | Bias for WIP tasks | `"statuses": { "WIP": -5 }` |
434
- | `statuses.BLOCKED` | Bias for BLOCKED tasks | `"statuses": { "BLOCKED": 10 }` |
294
+ | Category | Tools |
295
+ |----------|-------|
296
+ | **Documents** | `process_doc`, `process_docs`, `create_doc`, `update_doc`, `delete_doc`, `list_docs`, `search_docs`, `manage_tags`, `open_document_in_cursor` |
297
+ | **Plans** | `create_plan`, `list_plans`, `list_agents`, `get_plan_status` |
298
+ | **Tasks** | `get_next_task`, `update_task_status` |
299
+
300
+ ## Extensions
301
+
302
+ Extensions add MCP tools and resources. Install from npm:
303
+
304
+ ```bash
305
+ npm install -g @sudosandwich/limps-radix
306
+ ```
307
+
308
+ Add to config:
435
309
 
436
- Example:
437
310
  ```json
438
311
  {
439
- "scoring": {
440
- "weights": {
441
- "dependency": 40,
442
- "priority": 30,
443
- "workload": 30
444
- },
445
- "biases": {
446
- "plans": { "0030-limps-scoring-weights": 20 },
447
- "personas": { "reviewer": -10, "coder": 5 },
448
- "statuses": { "GAP": 5 }
449
- }
312
+ "extensions": ["@sudosandwich/limps-radix"],
313
+ "@sudosandwich/limps-radix": {
314
+ "cacheDir": "~/Library/Application Support/limps-radix"
450
315
  }
451
316
  }
452
317
  ```
453
318
 
454
- ### RLM (Recursive Language Model) Support
319
+ **Available extensions:**
455
320
 
456
- Implements the [RLM pattern from MIT CSAIL](https://arxiv.org/abs/2512.24601) for programmatic document examination and recursive processing:
321
+ - `@sudosandwich/limps-radix` Radix UI contract extraction and semantic analysis
457
322
 
458
- - **Sandbox execution** - Secure JavaScript via QuickJS
459
- - **Recursive sub-calls** - Depth-limited processing
460
- - **Parallel execution** - Cross-document analysis
461
- - **Document extractors** - Markdown, YAML, Gherkin parsing
323
+ ## Obsidian Compatibility
462
324
 
463
- #### Sub-query LLM Gating
325
+ limps works with Obsidian vaults. Open your `plans/` directory as a vault for visual editing:
464
326
 
465
- `process_doc` and `process_docs` only invoke LLM sub-queries when explicitly enabled. This keeps local workflows deterministic by default and avoids token spend unless requested.
327
+ - Full YAML frontmatter support
328
+ - Tag management (frontmatter and inline `#tag`)
329
+ - Automatic exclusion of `.obsidian/`, `.git/`, `node_modules/`
466
330
 
467
- - **Opt-in:** `allow_llm: true` is required to run `sub_query`
468
- - **Policy:** `llm_policy: "auto"` (default) skips small results (under 800 bytes); `"force"` always runs
469
- - **Skip metadata:** when skipped, responses include `sub_query_skipped` and `sub_query_reason`
331
+ ![Obsidian vault with limps plans](https://github.com/paulbreuler/limps/blob/main/.github/assets/obsidian-vault.png?raw=true)
470
332
 
471
- Example:
472
- ```typescript
473
- await process_doc({
474
- path: 'plans/0001-feature/plan.md',
475
- code: 'extractFeatures(doc.content)',
476
- sub_query: 'Summarize each feature',
477
- allow_llm: true,
478
- llm_policy: 'force'
479
- });
333
+ ## Development
334
+
335
+ ```bash
336
+ git clone https://github.com/paulbreuler/limps.git
337
+ cd limps
338
+ npm install
339
+ npm run build
340
+ npm test
480
341
  ```
481
342
 
482
- ### Obsidian Vault Compatibility
343
+ This is a monorepo with:
483
344
 
484
- limps is compatible with Obsidian vaults. Simply open your `plans/` directory as an Obsidian vault to get a visual editor for your planning documents:
345
+ - `packages/limps` Core MCP server
346
+ - `packages/limps-radix` — Radix UI extension
485
347
 
486
- ![Obsidian vault with limps plans](https://github.com/paulbreuler/limps/blob/main/.github/assets/obsidian-vault.png?raw=true)
348
+ ## Used in Production
487
349
 
488
- **Features:**
489
- - **Frontmatter parsing** - Full YAML frontmatter support via `gray-matter`
490
- - **Tag management** - Both frontmatter `tags:` arrays and inline `#tag` format
491
- - **Path filtering** - Automatically excludes `.obsidian/`, `.git/`, `node_modules/`
492
- - **Frontmatter search** - Search within YAML properties with `searchFrontmatter: true`
350
+ limps manages planning for [runi](https://github.com/paulbreuler/runi), using a separate folder (in this case a git repo) for plans.
493
351
 
494
- > **Tip:** The `.obsidian/` folder is automatically excluded from indexing and should be added to `.gitignore` to keep local settings out of version control.
352
+ ---
495
353
 
496
- #### Enhanced Search Features
354
+ ## Creating a feature plan
497
355
 
498
- ```typescript
499
- // Search with frontmatter and excerpts
500
- await search_docs({
501
- query: 'status PASS',
502
- searchFrontmatter: true, // Search in YAML frontmatter
503
- searchContent: true, // Search in body content
504
- caseSensitive: false, // Case-insensitive (default)
505
- prettyPrint: true // Human-readable output
506
- });
356
+ This flow is used by the **create-feature-plan** command you can find in [claude/commands](/.claude/commands/) along with other useful commands and skills. These can be followed manually with MCP tools. The docs path is whatever folder limps is pointed at (any directory, not necessarily a repo).
357
+
358
+ 1. **Gather context** — Project name and scope, work type (`refactor` | `overhaul` | `features`), tech stack, prototype/reference docs, known gotchas.
359
+ 2. **Create planning docs** — Use MCP:
360
+ - `list_docs` on `plans/` to get the next plan number (max existing + 1).
361
+ - `create_plan` with name `NNNN-descriptive-name` and a short description.
362
+ - `create_doc` for: `{plan-name}-plan.md` (full specs), `interfaces.md`, `README.md`, `gotchas.md` (template). Use template `none` for plan/interfaces/README, `addendum` for gotchas if available.
363
+ 3. **Assign features to agents** — Group by file ownership and dependencies; 2–4 features per agent; minimize cross-agent conflicts.
364
+ 4. **Distill agent files** — For each agent, `create_doc` at `plans/NNNN-name/agents/NNN_agent_descriptive-name.agent.md` (template `none`). Extract from the plan: feature IDs + TL;DRs, interface contracts, files to create/modify, test IDs, TDD one-liners, brief gotchas. Target ~200–400 lines per agent.
365
+ 5. **Validate** — Agent files self-contained; interfaces consistent; dependency graph and file ownership correct; each agent file <500 lines.
507
366
 
508
- // Returns: path, title, excerpt (with context), matchCount, lineNumber
367
+ Resulting layout:
368
+
369
+ ```
370
+ NNNN-descriptive-name/
371
+ ├── README.md
372
+ ├── {plan-name}-plan.md
373
+ ├── interfaces.md
374
+ ├── gotchas.md
375
+ └── agents/
376
+ ├── 000_agent_infrastructure.agent.md
377
+ ├── 001_agent_....agent.md
378
+ └── ...
509
379
  ```
510
380
 
511
- #### Write Modes for update_doc
381
+ ### Why the prefixes?
512
382
 
513
- ```typescript
514
- // Append content (preserves existing, merges frontmatter)
515
- await update_doc({
516
- path: 'notes/meeting.md',
517
- content: '\n## Action Items\n- Task 1',
518
- mode: 'append'
519
- });
383
+ I chose this to keep things lexicographically ordered and easier to reference in chat. "Show me the next agent or agents we can run now in plan 25", and the MCP will run the tool to process the agents applying weights and biases to choose the next best task or tasks that can run in parallel.
520
384
 
521
- // Prepend content
522
- await update_doc({
523
- path: 'notes/log.md',
524
- content: '## 2024-01-26\nNew entry\n',
525
- mode: 'prepend'
526
- });
385
+ ## Deep Dive
386
+
387
+ <details>
388
+ <summary><b>Plan Structure</b></summary>
389
+
390
+ ```
391
+ plans/
392
+ ├── 0001-feature-name/
393
+ │ ├── 0001-feature-name-plan.md # Main plan with specs
394
+ │ ├── interfaces.md # Interface contracts
395
+ │ ├── README.md # Status index
396
+ │ └── agents/ # Task files
397
+ │ ├── 000-setup.md
398
+ │ ├── 001-implement.md
399
+ │ └── 002-test.md
400
+ └── 0002-another-feature/
401
+ └── ...
527
402
  ```
528
403
 
529
- #### Tag Management
404
+ Agent files use frontmatter to track status:
530
405
 
531
- ```typescript
532
- // List all tags (frontmatter + inline #tags)
533
- await manage_tags({ path: 'notes/project.md', operation: 'list' });
406
+ ```yaml
407
+ ---
408
+ status: GAP | WIP | PASS | BLOCKED
409
+ persona: coder | reviewer | pm | customer
410
+ depends_on: ["000-setup"]
411
+ files:
412
+ - src/components/Feature.tsx
413
+ ---
414
+ ```
415
+
416
+ </details>
417
+
418
+ <details>
419
+ <summary><b>Task Scoring Algorithm</b></summary>
420
+
421
+ `get_next_task` returns tasks scored by:
534
422
 
535
- // Add tags to frontmatter
536
- await manage_tags({ path: 'notes/project.md', operation: 'add', tags: ['active', 'priority'] });
423
+ | Component | Max Points | Description |
424
+ |-----------|------------|-------------|
425
+ | Dependency | 40 | All dependencies satisfied = 40, else 0 |
426
+ | Priority | 30 | Based on agent number (lower = higher priority) |
427
+ | Workload | 30 | Based on file count (fewer = higher score) |
537
428
 
538
- // Remove tags
539
- await manage_tags({ path: 'notes/project.md', operation: 'remove', tags: ['draft'] });
429
+ **Biases** adjust final scores:
430
+
431
+ ```json
432
+ {
433
+ "scoring": {
434
+ "biases": {
435
+ "plans": { "0030-urgent-feature": 20 },
436
+ "personas": { "coder": 5, "reviewer": -10 },
437
+ "statuses": { "GAP": 5, "WIP": -5 }
438
+ }
439
+ }
440
+ }
540
441
  ```
541
442
 
542
- ### Resources (Progressive Disclosure)
443
+ </details>
543
444
 
544
- - `plans://index` — List of all plans (minimal)
545
- - `plans://summary` Plan summaries (key info)
546
- - `plans://full` — Full plan documents
547
- - `decisions://log` — Decision log entries
548
- - `agents://status` — Agent status and tasks
445
+ <details>
446
+ <summary><b>RLM (Recursive Language Model) Support</b></summary>
549
447
 
550
- ## Development
448
+ `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.
551
449
 
552
- ```bash
553
- git clone https://github.com/paulbreuler/limps.git
554
- cd limps
555
- npm install # Install dependencies
556
- npm run build # Build TypeScript
557
- npm test # Run tests
558
- npm run dev # Watch mode
559
- npm run lint # ESLint check
560
- npm run format # Prettier format
450
+ ```typescript
451
+ await process_doc({
452
+ path: 'plans/0001-feature/plan.md',
453
+ code: `
454
+ const features = extractFeatures(doc.content);
455
+ return features.filter(f => f.status === 'GAP');
456
+ `
457
+ });
561
458
  ```
562
459
 
563
- Pre-commit hooks run lint-staged, build, and tests automatically.
460
+ **Available extractors:**
564
461
 
565
- ## Releasing
462
+ - `extractSections()` — Markdown headings
463
+ - `extractFrontmatter()` — YAML frontmatter
464
+ - `extractFeatures()` — Plan features with status
465
+ - `extractAgents()` — Agent metadata
466
+ - `extractCodeBlocks()` — Fenced code blocks
566
467
 
567
- ```bash
568
- # Update version in package.json, then:
569
- git tag v0.2.1
570
- git push origin v0.2.1
468
+ **LLM sub-queries** (opt-in):
469
+
470
+ ```typescript
471
+ await process_doc({
472
+ path: 'plans/0001/plan.md',
473
+ code: 'extractFeatures(doc.content)',
474
+ sub_query: 'Summarize each feature',
475
+ allow_llm: true,
476
+ llm_policy: 'force' // or 'auto' (skips small results)
477
+ });
571
478
  ```
572
479
 
573
- GitHub Actions automatically builds, tests, and creates releases with changelogs.
480
+ </details>
481
+
482
+ <details>
483
+ <summary><b>MCP Resources</b></summary>
574
484
 
575
- ## Architecture
485
+ Progressive disclosure via resources:
576
486
 
577
- ![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)
578
- ![React](https://img.shields.io/badge/React-19-61dafb)
579
- ![Ink](https://img.shields.io/badge/Ink-6-green)
580
- ![SQLite](https://img.shields.io/badge/SQLite-FTS5-003B57)
581
- ![Zod](https://img.shields.io/badge/Zod-4-3068b7)
487
+ | Resource | Description |
488
+ |----------|-------------|
489
+ | `plans://index` | List of all plans (minimal) |
490
+ | `plans://summary` | Plan summaries with key info |
491
+ | `plans://full` | Full plan documents |
492
+ | `decisions://log` | Decision log entries |
493
+ | `agents://status` | Agent status and tasks |
582
494
 
583
- - Full-text search with auto-indexing and frontmatter support
584
- - Real-time file watching (Chokidar) with path filtering
585
- - RLM sandbox (QuickJS)
586
- - Obsidian-compatible frontmatter (gray-matter)
495
+ </details>
587
496
 
588
- ### Principles
497
+ <details>
498
+ <summary><b>Example: Custom Cursor Commands</b></summary>
589
499
 
590
- 1. Simplicity over complexity
591
- 2. Local-first, no external dependencies
592
- 3. Progressive disclosure (index → summary → full)
593
- 4. Optimistic concurrency
594
- 5. Scoring-based task selection
500
+ Create `.cursor/commands/run-agent.md`:
501
+
502
+ ```markdown
503
+ # Run Agent
504
+
505
+ Start work on the next available task.
506
+
507
+ ## Instructions
508
+
509
+ 1. Use `get_next_task` to find the highest-priority task
510
+ 2. Use `process_doc` to read the agent file
511
+ 3. Use `update_task_status` to mark it WIP
512
+ 4. Follow the agent's instructions
513
+ ```
595
514
 
596
- ## Adapting for Other Uses
515
+ This integrates with limps MCP tools for seamless task management.
516
+ </details>
597
517
 
598
- The server is designed for planning documents but the core is generic. For wikis or knowledge bases: configure `plansPath`/`docsPaths`/`fileExtensions` to point at your content, and optionally customize extractors in `src/rlm/extractors.ts`.
518
+ ---
599
519
 
600
520
  ## What is MCP?
601
521
 
602
- **MCP (Model Context Protocol)** is a standardized protocol for AI applications to connect to external systems. Launched by Anthropic (Nov 2024), now part of the Linux Foundation's Agentic AI Foundation.
522
+ **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.
603
523
 
604
524
  - [MCP Specification](https://modelcontextprotocol.io/)
605
525
  - [MCP Documentation](https://modelcontextprotocol.io/docs)