@sudosandwich/limps 3.0.0 → 3.1.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.
Files changed (64) hide show
  1. package/README.md +587 -136
  2. package/dist/cli/config-cmd.d.ts +4 -17
  3. package/dist/cli/config-cmd.d.ts.map +1 -1
  4. package/dist/cli/config-cmd.js +22 -157
  5. package/dist/cli/config-cmd.js.map +1 -1
  6. package/dist/cli/init-project.d.ts.map +1 -1
  7. package/dist/cli/init-project.js +15 -33
  8. package/dist/cli/init-project.js.map +1 -1
  9. package/dist/cli/mcp-client-adapter.d.ts +17 -48
  10. package/dist/cli/mcp-client-adapter.d.ts.map +1 -1
  11. package/dist/cli/mcp-client-adapter.js +29 -194
  12. package/dist/cli/mcp-client-adapter.js.map +1 -1
  13. package/dist/cli/mcp-clients.d.ts +2 -40
  14. package/dist/cli/mcp-clients.d.ts.map +1 -1
  15. package/dist/cli/mcp-clients.js +31 -91
  16. package/dist/cli/mcp-clients.js.map +1 -1
  17. package/dist/commands/config/index.js +1 -1
  18. package/dist/commands/config/index.js.map +1 -1
  19. package/dist/commands/config/{sync-mcp.d.ts → print.d.ts} +2 -6
  20. package/dist/commands/config/print.d.ts.map +1 -0
  21. package/dist/commands/config/print.js +51 -0
  22. package/dist/commands/config/print.js.map +1 -0
  23. package/dist/commands/index.d.ts.map +1 -1
  24. package/dist/commands/index.js +1 -1
  25. package/dist/commands/index.js.map +1 -1
  26. package/dist/commands/start.d.ts.map +1 -1
  27. package/dist/commands/start.js +26 -23
  28. package/dist/commands/start.js.map +1 -1
  29. package/dist/commands/status-server.d.ts.map +1 -1
  30. package/dist/commands/status-server.js +113 -52
  31. package/dist/commands/status-server.js.map +1 -1
  32. package/dist/commands/stop.d.ts.map +1 -1
  33. package/dist/commands/stop.js +3 -2
  34. package/dist/commands/stop.js.map +1 -1
  35. package/dist/pidfile.d.ts +30 -4
  36. package/dist/pidfile.d.ts.map +1 -1
  37. package/dist/pidfile.js +66 -6
  38. package/dist/pidfile.js.map +1 -1
  39. package/dist/server-http.d.ts.map +1 -1
  40. package/dist/server-http.js +30 -3
  41. package/dist/server-http.js.map +1 -1
  42. package/dist/utils/app-paths.d.ts +15 -0
  43. package/dist/utils/app-paths.d.ts.map +1 -0
  44. package/dist/utils/app-paths.js +37 -0
  45. package/dist/utils/app-paths.js.map +1 -0
  46. package/dist/utils/config-resolver.d.ts +1 -0
  47. package/dist/utils/config-resolver.d.ts.map +1 -1
  48. package/dist/utils/config-resolver.js +29 -0
  49. package/dist/utils/config-resolver.js.map +1 -1
  50. package/dist/utils/http-client.d.ts +72 -0
  51. package/dist/utils/http-client.d.ts.map +1 -0
  52. package/dist/utils/http-client.js +160 -0
  53. package/dist/utils/http-client.js.map +1 -0
  54. package/dist/utils/port-checker.d.ts +23 -0
  55. package/dist/utils/port-checker.d.ts.map +1 -0
  56. package/dist/utils/port-checker.js +56 -0
  57. package/dist/utils/port-checker.js.map +1 -0
  58. package/dist/utils/version-state.d.ts.map +1 -1
  59. package/dist/utils/version-state.js +1 -19
  60. package/dist/utils/version-state.js.map +1 -1
  61. package/package.json +1 -1
  62. package/dist/commands/config/sync-mcp.d.ts.map +0 -1
  63. package/dist/commands/config/sync-mcp.js +0 -232
  64. package/dist/commands/config/sync-mcp.js.map +0 -1
package/README.md CHANGED
@@ -19,12 +19,15 @@
19
19
  - [How You Can Use It](#how-you-can-use-it)
20
20
  - [Why limps?](#why-limps)
21
21
  - [Installation](#installation)
22
+ - [Upgrading from v2](#upgrading-from-v2)
22
23
  - [Project Setup](#project-setup)
23
24
  - [Client Setup](#client-setup)
24
25
  - [Transport](#transport)
26
+ - [Daemon Management](#daemon-management)
25
27
  - [CLI Commands](#cli-commands)
26
28
  - [Configuration](#configuration)
27
29
  - [Environment Variables](#environment-variables)
30
+ - [Troubleshooting](#troubleshooting)
28
31
  - [MCP Tools](#mcp-tools)
29
32
  - [Skills & Commands](#skills--commands)
30
33
  - [Extensions](#extensions)
@@ -33,7 +36,6 @@
33
36
  - [Used in Production](#used-in-production)
34
37
  - [Creating a feature plan](#creating-a-feature-plan)
35
38
  - [Deep Dive](#deep-dive)
36
- - [Instructions](#instructions)
37
39
  - [What is MCP?](#what-is-mcp)
38
40
  - [License](#license)
39
41
 
@@ -43,15 +45,24 @@
43
45
  # Install globally
44
46
  npm install -g @sudosandwich/limps
45
47
 
46
- # Initialize a project
47
- limps init my-project --docs-path ~/Documents/my-planning-docs
48
+ # Initialize in your project
49
+ cd ~/Documents/my-planning-docs
50
+ limps init
48
51
 
49
- # Add to your AI assistant (picks up all registered projects)
50
- limps config sync-mcp --client cursor
51
- limps config sync-mcp --client claude-code
52
+ # Start the HTTP daemon
53
+ limps start
54
+ # Daemon starts on http://127.0.0.1:4269/mcp
55
+ # → PID file written to OS-standard location
56
+ # → Ready for MCP client connections
57
+
58
+ # Generate MCP client config
59
+ limps config print --client claude-code
60
+ # Copy the output to your MCP client config file
52
61
  ```
53
62
 
54
- 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.
63
+ 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.
64
+
65
+ **Tip:** `limps status-server` shows the status of the current project if a config is found in the working directory (or passed via `--config`). Run it from a directory where no limps config can be resolved to list all running limps daemons on your system.
55
66
 
56
67
  ## Features
57
68
 
@@ -59,7 +70,7 @@ Run this in the folder where you want to keep the docs and that's it. Your AI as
59
70
  - **Plan + agent workflows** with status tracking and task scoring
60
71
  - **Next-task suggestions** with score breakdowns and bias tuning
61
72
  - **Sandboxed document processing** via `process_doc(s)` helpers
62
- - **Multi-client sync** for Cursor, Claude, Codex, and more
73
+ - **Multi-client support** for Cursor, Claude, Codex, and more
63
74
  - **Extensions** for domain-specific tooling (e.g., limps-headless)
64
75
  - **Knowledge graph** — Entity extraction, hybrid retrieval, conflict detection, and graph-based suggestions
65
76
  - **Health automation** — Staleness detection, code drift checks, status inference, and auto-fix proposals
@@ -70,6 +81,7 @@ Run this in the folder where you want to keep the docs and that's it. Your AI as
70
81
 
71
82
  - **Local only** — Your data stays on disk (SQLite index + your files). No cloud, no subscription.
72
83
  - **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.
84
+ - **Daemon management** — The HTTP server runs as a background process. Use `limps start`, `limps stop`, and `limps status-server` to manage the daemon lifecycle. PID files are stored in OS-standard directories for system-wide awareness.
73
85
  - **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.
74
86
  - **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.
75
87
 
@@ -81,7 +93,7 @@ Typical flow:
81
93
 
82
94
  1. Point limps at a docs directory (any folder, local or synced).
83
95
  2. Use CLI + MCP tools to create plans/docs, read the current status, update tasks, and close work when done.
84
- 3. Sync MCP configs so Cursor/Claude/Codex all see the same plans.
96
+ 3. Add the limps MCP entry to each client config so Cursor/Claude/Codex all see the same plans.
85
97
 
86
98
  Commands and tools I use most often:
87
99
 
@@ -100,7 +112,7 @@ Full lists are below in "CLI Commands" and "MCP Tools."
100
112
  Common setups:
101
113
 
102
114
  - **Single project**: One docs folder for a product.
103
- - **Multi-project**: Register multiple folders and switch with `limps config use`.
115
+ - **Multi-project**: Each project gets its own `.limps/config.json`; pass `--config` to target a specific one.
104
116
  - **Shared team folder**: Put plans in a shared location and review changes like code.
105
117
  - **Local-first**: Keep everything on disk, no hosted service required.
106
118
 
@@ -115,75 +127,96 @@ Key ideas:
115
127
 
116
128
  **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.
117
129
 
118
- ### Supported Clients
119
-
120
- | Client | Config Location | Command |
121
- | ------------------ | -------------------------- | ------------------------------------------------ |
122
- | **Cursor** | `.cursor/mcp.json` (local) | `limps config sync-mcp --client cursor` |
123
- | **Claude Code** | `.mcp.json` (local) | `limps config sync-mcp --client claude-code` |
124
- | **Claude Desktop** | Global config | `limps config sync-mcp --client claude --global` |
125
- | **OpenAI Codex** | `~/.codex/config.toml` | `limps config sync-mcp --client codex --global` |
126
- | **ChatGPT** | Manual setup | `limps config sync-mcp --client chatgpt --print` |
127
-
128
- > **Note:** By default, `sync-mcp` writes to local/project configs. Use `--global` for user-level configs.
129
-
130
130
  ## Installation
131
131
 
132
132
  ```bash
133
133
  npm install -g @sudosandwich/limps
134
134
  ```
135
135
 
136
+ ## Upgrading from v2
137
+
138
+ v3 introduces major changes:
139
+
140
+ ### HTTP Transport (Breaking Change)
141
+
142
+ v3 uses **HTTP transport exclusively**. stdio transport has been removed.
143
+
144
+ **Migration steps:**
145
+
146
+ 1. **Start the HTTP daemon** for each project:
147
+ ```bash
148
+ limps start --config /path/to/.limps/config.json
149
+ ```
150
+
151
+ 2. **Update MCP client configs** — Replace stdio configs with HTTP transport:
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "limps-planning-myproject": {
156
+ "transport": {
157
+ "type": "http",
158
+ "url": "http://127.0.0.1:4269/mcp"
159
+ }
160
+ }
161
+ }
162
+ }
163
+ ```
164
+ Use `limps config print` to generate the correct snippet.
165
+
166
+ ### Per-Project Configs (Breaking Change)
167
+
168
+ v3 removes the centralized project registry. If you previously used `limps config add`, `config use`, or the `--project` flag:
169
+
170
+ 1. **Run `limps init`** in each project directory to create `.limps/config.json`.
171
+ 2. **Update MCP client configs** — Replace `--project <name>` with HTTP transport config (see above).
172
+ 3. **Remove environment variable** — `LIMPS_PROJECT` no longer exists. Use `MCP_PLANNING_CONFIG` to override config path.
173
+
174
+ **Removed commands:** `config list`, `config use`, `config add`, `config remove`, `config set`, `config discover`, `config migrate`, `config sync-mcp`, `serve`.
175
+
176
+ **Replaced by:** `limps init` + `limps start` + `limps config print`.
177
+
136
178
  ## Project Setup
137
179
 
138
180
  ### Initialize a New Project
139
181
 
140
182
  ```bash
141
- limps init my-project --docs-path ~/Documents/my-planning-docs
183
+ cd ~/Documents/my-planning-docs
184
+ limps init
142
185
  ```
143
186
 
144
- This creates a config file and outputs setup instructions.
187
+ This creates `.limps/config.json` in the current directory and prints MCP client setup instructions.
145
188
 
146
- ### Register an Existing Directory
189
+ You can also specify a path:
147
190
 
148
191
  ```bash
149
- limps config add my-project ~/Documents/existing-docs
192
+ limps init ~/Documents/my-planning-docs
150
193
  ```
151
194
 
152
195
  If the directory contains a `plans/` subdirectory, limps uses it. Otherwise, it indexes the entire directory.
153
196
 
154
197
  ### Multiple Projects
155
198
 
156
- ```bash
157
- # Register multiple projects
158
- limps init project-a --docs-path ~/docs/project-a
159
- limps init project-b --docs-path ~/docs/project-b
160
-
161
- # Switch between them
162
- limps config use project-a
199
+ Each project has its own `.limps/config.json`. Use `--config` to target a specific project:
163
200
 
164
- # Or use environment variable
165
- LIMPS_PROJECT=project-b limps list-plans
201
+ ```bash
202
+ limps list-plans --config ~/docs/project-b/.limps/config.json
166
203
  ```
167
204
 
168
205
  ## Client Setup
169
206
 
170
- ### Automatic (Recommended)
207
+ 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:
171
208
 
172
209
  ```bash
173
- # Add all projects to a client's local config
174
- limps config sync-mcp --client cursor
175
-
176
- # Preview changes without writing
177
- limps config sync-mcp --client cursor --print
210
+ limps config print --client cursor
211
+ limps config print --client claude-code
212
+ limps config print --client claude
213
+ ```
178
214
 
179
- # Write to global config instead of local
180
- limps config sync-mcp --client cursor --global
215
+ The output tells you exactly what JSON (or TOML) to add and where the config file lives.
181
216
 
182
- # Custom config path
183
- limps config sync-mcp --client cursor --path ./custom-mcp.json
184
- ```
217
+ ### Per-Client Examples
185
218
 
186
- ### Manual Setup
219
+ All clients connect to the HTTP daemon. Start the daemon first with `limps start`, then configure your client.
187
220
 
188
221
  <details>
189
222
  <summary><b>Cursor</b></summary>
@@ -193,9 +226,11 @@ Add to `.cursor/mcp.json` in your project:
193
226
  ```json
194
227
  {
195
228
  "mcpServers": {
196
- "limps": {
197
- "command": "limps",
198
- "args": ["serve", "--config", "/path/to/config.json"]
229
+ "limps-planning-myproject": {
230
+ "transport": {
231
+ "type": "http",
232
+ "url": "http://127.0.0.1:4269/mcp"
233
+ }
199
234
  }
200
235
  }
201
236
  }
@@ -211,9 +246,11 @@ Add to `.mcp.json` in your project root:
211
246
  ```json
212
247
  {
213
248
  "mcpServers": {
214
- "limps": {
215
- "command": "limps",
216
- "args": ["serve", "--config", "/path/to/config.json"]
249
+ "limps-planning-myproject": {
250
+ "transport": {
251
+ "type": "http",
252
+ "url": "http://127.0.0.1:4269/mcp"
253
+ }
217
254
  }
218
255
  }
219
256
  }
@@ -224,48 +261,16 @@ Add to `.mcp.json` in your project root:
224
261
  <details>
225
262
  <summary><b>Claude Desktop</b></summary>
226
263
 
227
- Claude Desktop runs in a sandbox—use `npx` instead of global binaries.
228
-
229
264
  Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
230
265
 
231
266
  ```json
232
267
  {
233
268
  "mcpServers": {
234
- "limps": {
235
- "command": "npx",
236
- "args": [
237
- "-y",
238
- "@sudosandwich/limps",
239
- "serve",
240
- "--config",
241
- "/path/to/config.json"
242
- ]
243
- }
244
- }
245
- }
246
- ```
247
-
248
- </details>
249
-
250
- <details>
251
- <summary><b>Windows (npx)</b></summary>
252
-
253
- On Windows, use `cmd /c` to run `npx`:
254
-
255
- ```json
256
- {
257
- "mcpServers": {
258
- "limps": {
259
- "command": "cmd",
260
- "args": [
261
- "/c",
262
- "npx",
263
- "-y",
264
- "@sudosandwich/limps",
265
- "serve",
266
- "--config",
267
- "C:\\path\\to\\config.json"
268
- ]
269
+ "limps-planning-myproject": {
270
+ "transport": {
271
+ "type": "http",
272
+ "url": "http://127.0.0.1:4269/mcp"
273
+ }
269
274
  }
270
275
  }
271
276
  }
@@ -279,9 +284,9 @@ On Windows, use `cmd /c` to run `npx`:
279
284
  Add to `~/.codex/config.toml`:
280
285
 
281
286
  ```toml
282
- [mcp_servers.limps]
283
- command = "limps"
284
- args = ["serve", "--config", "/path/to/config.json"]
287
+ [mcp_servers.limps-planning-myproject.transport]
288
+ type = "http"
289
+ url = "http://127.0.0.1:4269/mcp"
285
290
  ```
286
291
 
287
292
  </details>
@@ -289,67 +294,336 @@ args = ["serve", "--config", "/path/to/config.json"]
289
294
  <details>
290
295
  <summary><b>ChatGPT</b></summary>
291
296
 
292
- ChatGPT requires a remote MCP server over HTTPS. Deploy limps behind an MCP-compatible HTTP/SSE proxy.
297
+ ChatGPT requires a remote MCP server over HTTPS. Deploy limps behind an MCP-compatible HTTPS reverse proxy (nginx, Caddy, etc.) with authentication.
293
298
 
294
299
  In ChatGPT → Settings → Connectors → Add custom connector:
295
300
 
296
301
  - **Server URL**: `https://your-domain.example/mcp`
297
- - **Authentication**: Configure as needed
302
+ - **Authentication**: Configure as needed for your proxy
298
303
 
299
304
  Print setup instructions:
300
305
 
301
306
  ```bash
302
- limps config sync-mcp --client chatgpt --print
307
+ limps config print --client chatgpt
303
308
  ```
304
309
 
305
310
  </details>
306
311
 
307
312
  ## Transport
308
313
 
309
- ### stdio (default)
310
-
311
- Your MCP client spawns `limps serve` as a child process. No daemon required.
314
+ 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.
312
315
 
313
- ### HTTP (persistent daemon)
314
-
315
- Run limps as a long-lived HTTP server that multiple clients can connect to:
316
+ ### Start the HTTP daemon
316
317
 
317
318
  ```bash
318
319
  # Start the daemon
319
- limps start --config /path/to/config.json
320
+ limps start
320
321
 
321
- # Check status
322
+ # Check status (shows uptime, sessions, PID)
322
323
  limps status-server
323
324
 
324
325
  # Stop the daemon
325
326
  limps stop
326
327
  ```
327
328
 
328
- Configure your MCP client to use HTTP transport:
329
+ The daemon runs at `http://127.0.0.1:4269/mcp` by default. Use `limps config print` to generate the correct MCP client configuration:
330
+
331
+ ```bash
332
+ limps config print --client claude-code
333
+ ```
334
+
335
+ See [Daemon Management](#daemon-management) for detailed lifecycle documentation.
336
+
337
+ ### MCP Client Configuration
338
+
339
+ All clients use HTTP transport. Example config:
329
340
 
330
341
  ```json
331
342
  {
332
343
  "mcpServers": {
333
- "limps": {
334
- "transport": { "type": "http", "url": "http://127.0.0.1:4269/mcp" }
344
+ "limps-planning-myproject": {
345
+ "transport": {
346
+ "type": "http",
347
+ "url": "http://127.0.0.1:4269/mcp"
348
+ }
335
349
  }
336
350
  }
337
351
  }
338
352
  ```
339
353
 
340
- Server config options (set in `config.json` under `"server"`):
354
+ ### Server Config Options
355
+
356
+ Customize the HTTP server by adding a `"server"` section to your `config.json`:
357
+
358
+ | Option | Default | Description |
359
+ | ------------------ | ---------------------- | ---------------------------------------- |
360
+ | `port` | `4269` | HTTP listen port |
361
+ | `host` | `127.0.0.1` | Bind address |
362
+ | `maxSessions` | `100` | Maximum concurrent MCP sessions |
363
+ | `sessionTimeoutMs` | `1800000` | Session idle timeout in ms (30 min) |
364
+ | `corsOrigin` | `""` (none) | CORS origin (`""`, `"*"`, or a URL) |
365
+ | `maxBodySize` | `10485760` | Max request body in bytes (10 MB) |
366
+ | `rateLimit` | `100 req/min` | Rate limit per client IP |
367
+
368
+ Example custom server config:
369
+
370
+ ```json
371
+ {
372
+ "server": {
373
+ "port": 8080,
374
+ "host": "0.0.0.0"
375
+ }
376
+ }
377
+ ```
378
+
379
+ **Note:** PID files are stored in OS-standard application directories:
380
+ - **macOS**: `~/Library/Application Support/limps/pids/`
381
+ - **Linux**: `$XDG_DATA_HOME/limps/pids/` or `~/.local/share/limps/pids/`
382
+ - **Windows**: `%APPDATA%/limps/pids/`
383
+
384
+ This enables `limps status-server` to perform system-wide daemon discovery when no project configuration can be resolved; when a limps config is found for the current directory, the CLI runs in project mode and reports status for that project instead.
385
+
386
+ - **Remote clients**: Use an MCP-compatible HTTPS proxy for remote clients (e.g., ChatGPT).
387
+
388
+ ## Daemon Management
389
+
390
+ 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.
391
+
392
+ ### PID File Locations
393
+
394
+ PID files are stored in platform-specific application data directories:
395
+
396
+ **macOS:**
397
+ ```
398
+ ~/Library/Application Support/limps/pids/
399
+ ```
400
+
401
+ **Linux:**
402
+ ```
403
+ $XDG_DATA_HOME/limps/pids/
404
+ # or if XDG_DATA_HOME is not set:
405
+ ~/.local/share/limps/pids/
406
+ ```
407
+
408
+ **Windows:**
409
+ ```
410
+ %APPDATA%/limps/pids/
411
+ ```
412
+
413
+ Each PID file is named by port number (`limps-{port}.pid`) to enable system-wide discovery. Example PID file structure:
414
+
415
+ ```json
416
+ {
417
+ "pid": 12345,
418
+ "port": 4269,
419
+ "host": "127.0.0.1",
420
+ "startedAt": "2026-02-08T12:00:00.000Z",
421
+ "configPath": "/path/to/project/.limps/config.json"
422
+ }
423
+ ```
424
+
425
+ This port-based naming allows `limps status-server` to find all running daemons across different projects without needing a config file.
426
+
427
+ ### Starting the Daemon
428
+
429
+ **Background mode (default):**
430
+
431
+ ```bash
432
+ limps start
433
+ # → Daemon starts on http://127.0.0.1:4269/mcp
434
+ # → PID file written to OS-standard location
435
+ # → Process detaches and runs in background
436
+ ```
437
+
438
+ **Foreground mode (debugging):**
439
+
440
+ ```bash
441
+ limps start --foreground
442
+ # → Runs in foreground (blocks terminal)
443
+ # → Logs appear in stderr
444
+ # → Useful for debugging startup issues
445
+ # → Still creates PID file for discovery
446
+ ```
447
+
448
+ **Custom port/host (via config):**
449
+
450
+ Configure `server.port` and `server.host` in your `.limps/config.json`:
451
+
452
+ ```json
453
+ {
454
+ "server": {
455
+ "port": 8080,
456
+ "host": "0.0.0.0"
457
+ }
458
+ }
459
+ ```
460
+
461
+ Then start normally:
462
+
463
+ ```bash
464
+ limps start
465
+ # → Starts using server.port/server.host from config
466
+ # → PID file: limps-8080.pid
467
+ ```
468
+
469
+ 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:
470
+
471
+ - **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 start --foreground` to see logs.
472
+ - **NETWORK_ERROR** — Cannot connect to daemon. Port may be blocked or already in use by another process.
473
+ - **NON_200_STATUS** — Health endpoint returned a non-200 status code. Check daemon logs with foreground mode.
474
+ - **INVALID_RESPONSE** — Health endpoint responded, but the response was invalid or could not be parsed as expected (for example, malformed or missing required fields).
475
+
476
+ ### Checking Daemon Status
477
+
478
+ **Project mode (when config is found):**
479
+
480
+ ```bash
481
+ # From within a project directory with .limps/config.json
482
+ limps status-server
483
+ # limps server is running
484
+ # PID: 12345 | 127.0.0.1:4269
485
+ # Uptime: 2h 15m
486
+ # Sessions: 3
487
+
488
+ # Or specify config explicitly
489
+ limps status-server --config /path/to/.limps/config.json
490
+ ```
491
+
492
+ **System-wide discovery (when no config is found):**
493
+
494
+ ```bash
495
+ # From a directory without a limps config
496
+ cd /tmp
497
+ limps status-server
498
+ # Found 2 running daemons:
499
+ # 127.0.0.1:4269 (PID 12345)
500
+ # Uptime: 2h 15m | Sessions: 3
501
+ # 127.0.0.1:8080 (PID 67890)
502
+ # Uptime: 45m 30s | Sessions: 1
503
+ ```
504
+
505
+ When `limps status-server` cannot resolve a config file in the current directory (and no `--config` is provided), it scans the system PID directory and reports all running limps daemons. When a config is found, it shows only that project's daemon status.
506
+
507
+ ### Stopping the Daemon
508
+
509
+ ```bash
510
+ # From the project directory (where your .limps config lives):
511
+ limps stop
512
+ # → Gracefully shuts down daemon
513
+ # → Closes all MCP sessions
514
+ # → Stops file watchers
515
+ # → Removes PID file
516
+ # → Process exits
517
+
518
+ # Or from any directory, by specifying the config explicitly:
519
+ limps stop --config /path/to/.limps/config.json
520
+ ```
521
+
522
+ The `stop` command is project-specific and resolves the config to determine which daemon to stop. The daemon performs a graceful shutdown by:
523
+ 1. Closing all active MCP sessions
524
+ 2. Shutting down file watchers
525
+ 3. Removing the PID file
526
+ 4. Exiting the process
341
527
 
342
- | Option | Default | Description |
343
- | ------------------ | -------------- | ---------------------------------------- |
344
- | `port` | `4269` | HTTP listen port |
345
- | `host` | `127.0.0.1` | Bind address |
346
- | `maxSessions` | `100` | Maximum concurrent MCP sessions |
347
- | `sessionTimeoutMs` | `1800000` | Session idle timeout in ms (30 min) |
348
- | `corsOrigin` | `""` (none) | CORS origin (`""`, `"*"`, or a URL) |
349
- | `maxBodySize` | `10485760` | Max request body in bytes (10 MB) |
350
- | `rateLimit` | `100 req/min` | Rate limit per client IP |
528
+ ### Port Conflicts
351
529
 
352
- - **Remote clients**: Use an MCP-compatible proxy for HTTPS clients (e.g., ChatGPT).
530
+ If you try to start a daemon on a port that's already in use, limps will detect the conflict and provide resolution guidance:
531
+
532
+ ```bash
533
+ limps start
534
+ # Error: Port 4269 is already in use.
535
+ # Process using port: node (PID 12345)
536
+ # Command: /usr/local/bin/node /usr/local/bin/limps start
537
+ #
538
+ # To stop the process: kill 12345
539
+ # Or use a different port: limps start --port <port>
540
+ ```
541
+
542
+ 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.
543
+
544
+ ### Foreground Mode
545
+
546
+ Use foreground mode for debugging, Docker deployments, or CI/CD pipelines:
547
+
548
+ ```bash
549
+ limps start --foreground
550
+ ```
551
+
552
+ **Use cases:**
553
+ - **Debugging** — See server logs in real-time to diagnose startup issues
554
+ - **Docker** — Keep container alive with the daemon as the main process
555
+ - **CI/CD** — Run tests against a limps daemon without background processes
556
+
557
+ **Behavior differences from background mode:**
558
+ - Logs to stderr instead of being silent
559
+ - Blocks the terminal (press Ctrl+C to stop)
560
+ - Still creates a PID file for discovery by other processes
561
+ - Responds to SIGINT (Ctrl+C) and SIGTERM for graceful shutdown
562
+
563
+ ### Health Endpoint
564
+
565
+ The HTTP daemon exposes a `/health` endpoint for monitoring and health checks:
566
+
567
+ ```bash
568
+ curl http://127.0.0.1:4269/health
569
+ ```
570
+
571
+ **Example response:**
572
+
573
+ ```json
574
+ {
575
+ "status": "ok",
576
+ "sessions": 3,
577
+ "uptime": 8145,
578
+ "pid": 12345,
579
+ "sessionTimeoutMs": 1800000
580
+ }
581
+ ```
582
+
583
+ **HTTP status codes:**
584
+ - **200** — Daemon is healthy and accepting connections
585
+ - **429** — Rate limit exceeded (rate limiter may return this before the request reaches `/health`)
586
+
587
+ Use this endpoint for:
588
+ - Monitoring daemon health in scripts or dashboards
589
+ - Verifying daemon is running before connecting MCP clients
590
+ - Automated health checks in orchestration tools (Kubernetes, Docker Compose)
591
+
592
+ ### Multiple Daemons
593
+
594
+ You can run multiple limps daemons on different ports for different projects by configuring different ports in each project's config:
595
+
596
+ ```bash
597
+ # Project A with default port (4269)
598
+ cd ~/projects/project-a
599
+ # .limps/config.json has server.port: 4269 (or uses default)
600
+ limps start
601
+ # → Running on http://127.0.0.1:4269/mcp
602
+
603
+ # Project B with custom port (8080)
604
+ cd ~/projects/project-b
605
+ # .limps/config.json has server.port: 8080
606
+ limps start
607
+ # → Running on http://127.0.0.1:8080/mcp
608
+ ```
609
+
610
+ Each daemon has its own PID file:
611
+ - `limps-4269.pid` — Project A
612
+ - `limps-8080.pid` — Project B
613
+
614
+ Discover all running daemons (run from a directory without a limps config):
615
+
616
+ ```bash
617
+ cd /tmp
618
+ limps status-server
619
+ # Found 2 running daemons:
620
+ # 127.0.0.1:4269 (PID 12345)
621
+ # Uptime: 2h 15m | Sessions: 3
622
+ # 127.0.0.1:8080 (PID 67890)
623
+ # Uptime: 45m 30s | Sessions: 1
624
+ ```
625
+
626
+ Each MCP client can connect to different daemons by configuring different URLs in their config files.
353
627
 
354
628
  ## CLI Commands
355
629
 
@@ -365,15 +639,13 @@ limps next-task <plan> # Get highest-priority available task
365
639
  ### Project Management
366
640
 
367
641
  ```bash
368
- limps init <name> # Initialize new project
369
- limps serve # Start MCP server (stdio)
370
- limps start # Start persistent HTTP daemon
642
+ limps init [path] # Initialize new project
643
+ limps start # Start HTTP daemon (background by default)
644
+ limps start --foreground # Start in foreground (debugging mode)
371
645
  limps stop # Stop HTTP daemon
372
- limps status-server # Show HTTP daemon status
373
- limps config list # Show registered projects
374
- limps config use <name> # Switch active project
646
+ limps status-server # Show daemon status (current project or all daemons)
375
647
  limps config show # Display current config
376
- limps config sync-mcp # Add projects to MCP clients
648
+ limps config print # Print MCP client config snippets
377
649
  ```
378
650
 
379
651
  ### Health & Automation
@@ -412,22 +684,16 @@ limps repair-plans [--fix] # Check/fix agent frontmatter
412
684
 
413
685
  ## Configuration
414
686
 
415
- Config location varies by OS:
416
-
417
- | OS | Path |
418
- | ------- | ------------------------------------------------- |
419
- | macOS | `~/Library/Application Support/limps/config.json` |
420
- | Linux | `~/.config/limps/config.json` |
421
- | Windows | `%APPDATA%\limps\config.json` |
687
+ Config lives at `.limps/config.json` in your project directory, created by `limps init`.
422
688
 
423
689
  ### Config Options
424
690
 
425
691
  ```json
426
692
  {
427
- "plansPath": "~/Documents/my-plans",
428
- "docsPaths": ["~/Documents/my-plans"],
693
+ "plansPath": "./plans",
694
+ "docsPaths": ["."],
429
695
  "fileExtensions": [".md"],
430
- "dataPath": "~/Library/Application Support/limps/data",
696
+ "dataPath": ".limps/data",
431
697
  "extensions": ["@sudosandwich/limps-headless"],
432
698
  "tools": {
433
699
  "allowlist": ["list_docs", "search_docs"]
@@ -456,12 +722,197 @@ Config location varies by OS:
456
722
 
457
723
  | Variable | Description | Example |
458
724
  | ---------------------- | ---------------------------------------------------------- | ------------------------------------------------- |
459
- | `LIMPS_PROJECT` | Select active project for CLI commands | `LIMPS_PROJECT=project-b limps list-plans` |
725
+ | `MCP_PLANNING_CONFIG` | Path to config file (overrides default discovery) | `MCP_PLANNING_CONFIG=./my-config.json limps serve`|
460
726
  | `LIMPS_ALLOWED_TOOLS` | Comma-separated allowlist; only these tools are registered | `LIMPS_ALLOWED_TOOLS="list_docs,search_docs"` |
461
727
  | `LIMPS_DISABLED_TOOLS` | Comma-separated denylist; tools to hide | `LIMPS_DISABLED_TOOLS="process_doc,process_docs"` |
462
728
 
463
729
  **Precedence:** `config.tools` overrides env vars. If allowlist is set, denylist is ignored.
464
730
 
731
+ ## Troubleshooting
732
+
733
+ ### Daemon Won't Start
734
+
735
+ **"Port already in use" error:**
736
+
737
+ If you see this error, another process is using the port:
738
+
739
+ ```bash
740
+ limps start
741
+ # Error: Port 4269 is already in use.
742
+ # Process using port: node (PID 12345)
743
+ ```
744
+
745
+ **Resolution:**
746
+ 1. **Kill the existing process**: `kill 12345`
747
+ 2. **Or use a different port**: `limps start --port 8080`
748
+ 3. **Check if it's another limps daemon**: `limps status-server` (if so, use `limps stop` first)
749
+
750
+ **"Daemon may have failed to start" error:**
751
+
752
+ If the daemon starts but doesn't respond to health checks:
753
+
754
+ ```bash
755
+ limps start
756
+ # Error: Daemon may have failed to start. Check logs or try: limps start --foreground
757
+ ```
758
+
759
+ **Resolution:**
760
+ 1. **Run in foreground to see logs**: `limps start --foreground`
761
+ 2. **Check for permission issues**: Ensure you have write access to the PID directory
762
+ 3. **Verify port is accessible**: Try `curl http://127.0.0.1:4269/health`
763
+ 4. **Enable debug logging**: `DEBUG=1 limps start --foreground`
764
+
765
+ **Permission issues with PID directory:**
766
+
767
+ If you can't create PID files:
768
+
769
+ ```bash
770
+ # macOS
771
+ ls -la ~/Library/Application\ Support/limps/pids/
772
+
773
+ # Linux
774
+ ls -la ~/.local/share/limps/pids/
775
+
776
+ # Windows
777
+ dir %APPDATA%\limps\pids
778
+ ```
779
+
780
+ Ensure the directory exists and you have write permissions. If not, create it manually:
781
+
782
+ ```bash
783
+ # macOS
784
+ mkdir -p ~/Library/Application\ Support/limps/pids
785
+
786
+ # Linux
787
+ mkdir -p ~/.local/share/limps/pids
788
+
789
+ # Windows
790
+ mkdir %APPDATA%\limps\pids
791
+ ```
792
+
793
+ ### Health Check Failures
794
+
795
+ **TIMEOUT error:**
796
+
797
+ The daemon did not respond within the configured timeout. Each health-check request has its own timeout (for example, 1000ms during the final `limps start` check and 3000ms for `status-server`), and during startup limps will poll for up to about 5 seconds before reporting "Daemon may have failed to start".
798
+
799
+ **Common causes:**
800
+ - System resource constraints (high CPU/memory usage)
801
+ - Slow filesystem (especially for index initialization)
802
+ - Large document corpus requiring time to index
803
+
804
+ **Resolution:**
805
+ 1. Check system resources: `top` or Activity Monitor
806
+ 2. Wait a bit longer and retry: `limps status-server`
807
+ 3. Run in foreground to see progress: `limps start --foreground`
808
+
809
+ **NETWORK_ERROR:**
810
+
811
+ Cannot establish connection to the daemon.
812
+
813
+ **Common causes:**
814
+ - Port is blocked by firewall
815
+ - Daemon crashed after starting
816
+ - Incorrect host/port configuration
817
+
818
+ **Resolution:**
819
+ 1. Verify daemon is running: `limps status-server`
820
+ 2. Check firewall settings for port 4269
821
+ 3. Try `curl http://127.0.0.1:4269/health` manually
822
+ 4. Check daemon logs: `limps start --foreground`
823
+
824
+ ### Stale PID Files
825
+
826
+ limps automatically cleans up stale PID files when:
827
+ - Running `limps status-server` (discovers and removes stale files)
828
+ - Running `limps start` (removes stale file for the target port)
829
+ - The daemon shuts down gracefully with `limps stop`
830
+
831
+ If you need to manually clean up PID files:
832
+
833
+ ```bash
834
+ # macOS
835
+ rm ~/Library/Application\ Support/limps/pids/limps-*.pid
836
+
837
+ # Linux
838
+ rm ~/.local/share/limps/pids/limps-*.pid
839
+
840
+ # Windows
841
+ del %APPDATA%\limps\pids\limps-*.pid
842
+ ```
843
+
844
+ **When to manually clean up:**
845
+ - After a system crash or forced shutdown
846
+ - If `limps start` reports a daemon is running but it's not
847
+ - Before uninstalling limps
848
+
849
+ ### Multiple Daemons Conflict
850
+
851
+ If you accidentally try to start a second daemon on the same port:
852
+
853
+ ```bash
854
+ limps start
855
+ # Error: limps daemon already running (PID 12345 on 127.0.0.1:4269). Run 'limps stop' first.
856
+ ```
857
+
858
+ This is expected behavior — limps prevents multiple daemons on the same port using PID-based locking.
859
+
860
+ **Resolution:**
861
+ 1. **Check all running daemons**: `limps status-server`
862
+ 2. **Stop the existing daemon**: `limps stop`
863
+ 3. **Or start on a different port**: `limps start --port 8080`
864
+
865
+ ### Debugging Connection Issues
866
+
867
+ If MCP clients can't connect to the daemon, verify connectivity step by step:
868
+
869
+ **1. Check daemon status:**
870
+
871
+ ```bash
872
+ limps status-server
873
+ # Should show daemon running with healthy status
874
+ ```
875
+
876
+ **2. Verify health endpoint:**
877
+
878
+ ```bash
879
+ curl http://127.0.0.1:4269/health
880
+ # Should return JSON with status "ok"
881
+ ```
882
+
883
+ **3. Verify MCP endpoint:**
884
+
885
+ ```bash
886
+ curl -X POST http://127.0.0.1:4269/mcp \
887
+ -H "Content-Type: application/json" \
888
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
889
+ # Should return MCP initialize response
890
+ ```
891
+
892
+ **4. Enable debug logging:**
893
+
894
+ ```bash
895
+ DEBUG=1 limps start --foreground
896
+ # Watch for connection attempts and errors
897
+ ```
898
+
899
+ **5. Check MCP client config:**
900
+
901
+ Ensure the URL in your client config matches the daemon:
902
+
903
+ ```json
904
+ {
905
+ "mcpServers": {
906
+ "limps-planning-myproject": {
907
+ "transport": {
908
+ "type": "http",
909
+ "url": "http://127.0.0.1:4269/mcp"
910
+ }
911
+ }
912
+ }
913
+ }
914
+ ```
915
+
465
916
  ## MCP Tools
466
917
 
467
918
  limps exposes MCP tools for AI assistants: