servherd 0.0.1 → 1.0.0

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 (95) hide show
  1. package/CONTRIBUTING.md +250 -0
  2. package/LICENSE +21 -0
  3. package/README.md +653 -29
  4. package/dist/cli/commands/config.d.ts +35 -0
  5. package/dist/cli/commands/config.js +336 -0
  6. package/dist/cli/commands/info.d.ts +37 -0
  7. package/dist/cli/commands/info.js +98 -0
  8. package/dist/cli/commands/list.d.ts +26 -0
  9. package/dist/cli/commands/list.js +86 -0
  10. package/dist/cli/commands/logs.d.ts +46 -0
  11. package/dist/cli/commands/logs.js +292 -0
  12. package/dist/cli/commands/mcp.d.ts +5 -0
  13. package/dist/cli/commands/mcp.js +17 -0
  14. package/dist/cli/commands/refresh.d.ts +20 -0
  15. package/dist/cli/commands/refresh.js +139 -0
  16. package/dist/cli/commands/remove.d.ts +20 -0
  17. package/dist/cli/commands/remove.js +144 -0
  18. package/dist/cli/commands/restart.d.ts +25 -0
  19. package/dist/cli/commands/restart.js +177 -0
  20. package/dist/cli/commands/start.d.ts +37 -0
  21. package/dist/cli/commands/start.js +293 -0
  22. package/dist/cli/commands/stop.d.ts +20 -0
  23. package/dist/cli/commands/stop.js +108 -0
  24. package/dist/cli/index.d.ts +9 -0
  25. package/dist/cli/index.js +160 -0
  26. package/dist/cli/output/formatters.d.ts +117 -0
  27. package/dist/cli/output/formatters.js +454 -0
  28. package/dist/cli/output/json-formatter.d.ts +22 -0
  29. package/dist/cli/output/json-formatter.js +40 -0
  30. package/dist/index.d.ts +15 -0
  31. package/dist/index.js +25 -0
  32. package/dist/mcp/index.d.ts +14 -0
  33. package/dist/mcp/index.js +352 -0
  34. package/dist/mcp/resources/servers.d.ts +14 -0
  35. package/dist/mcp/resources/servers.js +128 -0
  36. package/dist/mcp/tools/config.d.ts +33 -0
  37. package/dist/mcp/tools/config.js +88 -0
  38. package/dist/mcp/tools/info.d.ts +36 -0
  39. package/dist/mcp/tools/info.js +65 -0
  40. package/dist/mcp/tools/list.d.ts +36 -0
  41. package/dist/mcp/tools/list.js +49 -0
  42. package/dist/mcp/tools/logs.d.ts +44 -0
  43. package/dist/mcp/tools/logs.js +55 -0
  44. package/dist/mcp/tools/refresh.d.ts +33 -0
  45. package/dist/mcp/tools/refresh.js +54 -0
  46. package/dist/mcp/tools/remove.d.ts +23 -0
  47. package/dist/mcp/tools/remove.js +43 -0
  48. package/dist/mcp/tools/restart.d.ts +23 -0
  49. package/dist/mcp/tools/restart.js +42 -0
  50. package/dist/mcp/tools/start.d.ts +38 -0
  51. package/dist/mcp/tools/start.js +73 -0
  52. package/dist/mcp/tools/stop.d.ts +23 -0
  53. package/dist/mcp/tools/stop.js +40 -0
  54. package/dist/services/config.service.d.ts +80 -0
  55. package/dist/services/config.service.js +227 -0
  56. package/dist/services/port.service.d.ts +82 -0
  57. package/dist/services/port.service.js +151 -0
  58. package/dist/services/process.service.d.ts +61 -0
  59. package/dist/services/process.service.js +220 -0
  60. package/dist/services/registry.service.d.ts +50 -0
  61. package/dist/services/registry.service.js +157 -0
  62. package/dist/types/config.d.ts +107 -0
  63. package/dist/types/config.js +44 -0
  64. package/dist/types/errors.d.ts +102 -0
  65. package/dist/types/errors.js +197 -0
  66. package/dist/types/pm2.d.ts +50 -0
  67. package/dist/types/pm2.js +4 -0
  68. package/dist/types/registry.d.ts +230 -0
  69. package/dist/types/registry.js +33 -0
  70. package/dist/utils/ci-detector.d.ts +31 -0
  71. package/dist/utils/ci-detector.js +68 -0
  72. package/dist/utils/config-drift.d.ts +71 -0
  73. package/dist/utils/config-drift.js +128 -0
  74. package/dist/utils/error-handler.d.ts +21 -0
  75. package/dist/utils/error-handler.js +38 -0
  76. package/dist/utils/log-follower.d.ts +10 -0
  77. package/dist/utils/log-follower.js +98 -0
  78. package/dist/utils/logger.d.ts +11 -0
  79. package/dist/utils/logger.js +24 -0
  80. package/dist/utils/names.d.ts +7 -0
  81. package/dist/utils/names.js +20 -0
  82. package/dist/utils/template.d.ts +88 -0
  83. package/dist/utils/template.js +180 -0
  84. package/dist/utils/time-parser.d.ts +19 -0
  85. package/dist/utils/time-parser.js +54 -0
  86. package/docs/ci-cd.md +408 -0
  87. package/docs/configuration.md +325 -0
  88. package/docs/mcp-integration.md +411 -0
  89. package/examples/basic-usage/README.md +187 -0
  90. package/examples/ci-github-actions/workflow.yml +195 -0
  91. package/examples/mcp-claude-code/README.md +213 -0
  92. package/examples/multi-server/README.md +270 -0
  93. package/examples/storybook/README.md +187 -0
  94. package/examples/vite-project/README.md +251 -0
  95. package/package.json +123 -6
package/README.md CHANGED
@@ -1,45 +1,669 @@
1
- # servherd
1
+ <p align="center">
2
+ <img src="assets/logo.png" alt="servherd logo" width="180">
3
+ </p>
2
4
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
5
+ <h1 align="center">servherd</h1>
4
6
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
7
+ <p align="center">
8
+ <strong>Herd your development servers</strong>
9
+ </p>
6
10
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/servherd"><img src="https://img.shields.io/npm/v/servherd.svg" alt="npm version"></a>
13
+ <a href="https://github.com/apowers313/servherd/actions/workflows/ci.yml"><img src="https://github.com/apowers313/servherd/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
14
+ <a href="https://codecov.io/gh/apowers313/servherd"><img src="https://codecov.io/gh/apowers313/servherd/branch/main/graph/badge.svg" alt="Coverage"></a>
15
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
16
+ </p>
8
17
 
9
- ## Purpose
18
+ ## The Problem
10
19
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `servherd`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
20
+ When doing AI-driven development across multiple projects, each of which can have multiple git worktrees and multiple development servers (Vite, VitePress, Storybook, logging servers, etc.), you quickly run into resource conflicts:
15
21
 
16
- ## What is OIDC Trusted Publishing?
22
+ - **Port collisions**: Multiple servers fighting for the same ports
23
+ - **Wasted AI time**: Your AI assistant spends cycles hunting for available ports instead of coding
24
+ - **Wrong server errors**: The AI connects to the wrong server instance, causing confusing bugs and failed requests
25
+ - **Lost context**: No easy way to track which servers are running where across your development environment
17
26
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
27
+ ## The Solution
19
28
 
20
- ## Setup Instructions
29
+ **servherd** manages your herd of development servers for AI-driven development. It provides deterministic port assignment, human-readable server names, and an MCP interface so your AI assistant always knows exactly which servers are running and how to reach them.
21
30
 
22
- To properly configure OIDC trusted publishing for this package:
31
+ ## Key Features
23
32
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
33
+ ### Powered by PM2
28
34
 
29
- ## DO NOT USE THIS PACKAGE
35
+ servherd uses [PM2](https://pm2.keymetrics.io) under the hood for robust process management:
30
36
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
37
+ - **Reliable background operation** - Servers run as managed daemon processes
38
+ - **Automatic restarts** - Crashed servers can be automatically restarted
39
+ - **Log management** - Centralized logging with rotation support
40
+ - **Resource monitoring** - Track CPU and memory usage per server
41
+ - **Full lifecycle control** - Start, stop, restart, and remove servers with ease
36
42
 
37
- ## More Information
43
+ ### Intelligent Port Management
38
44
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
45
+ - **Deterministic port assignment** - Same project + command always gets the same port
46
+ - **Automatic conflict resolution** - If a port is busy, servherd finds the next available one
47
+ - **Port availability checking** - Verifies ports are free before starting servers
48
+ - **Configurable port ranges** - Define your own port range (default: 3000-9999)
42
49
 
43
- ---
50
+ ### Developer Experience
44
51
 
45
- **Maintained for OIDC setup purposes only**
52
+ - **Human-readable server names** - Auto-generated names like "brave-tiger" or "calm-panda"
53
+ - **Template variable substitution** - Use `{{port}}`, `{{hostname}}`, `{{url}}` in commands
54
+ - **Environment variable templating** - Pass dynamic values with `-e PORT={{port}}`
55
+ - **JSON output mode** - Machine-readable output with `--json` for scripting
56
+ - **CI/CD friendly** - Automatic CI detection with non-interactive mode
57
+
58
+ ### AI Integration
59
+
60
+ - **MCP server** - Native integration with Claude Code and other MCP-compatible tools
61
+ - **Resource discovery** - AI can query running servers and their status
62
+ - **Log access** - AI can read server logs for debugging
63
+
64
+ ## Quick Start
65
+
66
+ ### Installation
67
+
68
+ ```bash
69
+ npm install -g servherd
70
+ ```
71
+
72
+ ### Replace Your npm Scripts
73
+
74
+ Instead of hunting for available ports, let servherd manage them:
75
+
76
+ ```bash
77
+ # Before: Hardcoded port that might conflict
78
+ npm run dev
79
+
80
+ # After: Automatic port assignment with servherd
81
+ npx servherd start -- npm run dev -- --port {{port}}
82
+ ```
83
+
84
+ ### Basic Usage
85
+
86
+ ```bash
87
+ # Start a server with automatic port assignment
88
+ servherd start -- npx vite --port {{port}}
89
+
90
+ # Start with a custom name
91
+ servherd start --name my-app -- npm run dev -- --port {{port}}
92
+
93
+ # List all servers
94
+ servherd list
95
+
96
+ # View server details
97
+ servherd info my-app
98
+
99
+ # View server logs
100
+ servherd logs my-app
101
+
102
+ # Follow logs in real-time
103
+ servherd logs my-app --follow
104
+
105
+ # Stop a server
106
+ servherd stop my-app
107
+
108
+ # Stop all servers
109
+ servherd stop --all
110
+ ```
111
+
112
+ ## Development Tool Examples
113
+
114
+ ### Vite
115
+
116
+ [Vite](https://vite.dev) accepts the port via `--port` flag:
117
+
118
+ ```bash
119
+ # Using CLI flag
120
+ servherd start --name my-vite-app -- npx vite --port {{port}}
121
+
122
+ # Using environment variable in vite.config.js
123
+ servherd start --name my-vite-app -e VITE_PORT={{port}} -- npx vite
124
+ ```
125
+
126
+ In your `vite.config.js`:
127
+ ```javascript
128
+ export default defineConfig({
129
+ server: {
130
+ port: parseInt(process.env.VITE_PORT) || 5173,
131
+ },
132
+ })
133
+ ```
134
+
135
+ ### VitePress
136
+
137
+ [VitePress](https://vitepress.dev) uses the `--port` flag:
138
+
139
+ ```bash
140
+ servherd start --name my-docs -- npx vitepress dev docs --port {{port}}
141
+ ```
142
+
143
+ ### Storybook
144
+
145
+ [Storybook](https://storybook.js.org) accepts the port via `-p` flag:
146
+
147
+ ```bash
148
+ servherd start --name my-stories -- npx storybook dev -p {{port}}
149
+ ```
150
+
151
+ ### Next.js
152
+
153
+ [Next.js](https://nextjs.org) uses the `-p` or `--port` flag:
154
+
155
+ ```bash
156
+ # Development server
157
+ servherd start --name my-next-app -- npx next dev -p {{port}}
158
+
159
+ # Production server
160
+ servherd start --name my-next-prod -- npx next start -p {{port}}
161
+ ```
162
+
163
+ ### Webpack Dev Server
164
+
165
+ [Webpack Dev Server](https://webpack.js.org/configuration/dev-server/) accepts `--port`:
166
+
167
+ ```bash
168
+ servherd start --name my-webpack-app -- npx webpack serve --port {{port}}
169
+ ```
170
+
171
+ ### Create React App
172
+
173
+ [Create React App](https://create-react-app.dev) reads the `PORT` environment variable:
174
+
175
+ ```bash
176
+ servherd start --name my-react-app -e PORT={{port}} -- npm start
177
+ ```
178
+
179
+ ### Express / Node.js Servers
180
+
181
+ For custom Node.js servers, pass the port as an environment variable:
182
+
183
+ ```bash
184
+ servherd start --name my-api -e PORT={{port}} -- node server.js
185
+ ```
186
+
187
+ In your `server.js`:
188
+ ```javascript
189
+ const port = process.env.PORT || 3000;
190
+ app.listen(port, () => console.log(`Server running on port ${port}`));
191
+ ```
192
+
193
+ ### Python (Flask/FastAPI)
194
+
195
+ ```bash
196
+ # Flask
197
+ servherd start --name my-flask -e FLASK_RUN_PORT={{port}} -- flask run
198
+
199
+ # FastAPI with Uvicorn
200
+ servherd start --name my-fastapi -- uvicorn main:app --port {{port}}
201
+ ```
202
+
203
+ ## CLI Reference
204
+
205
+ ### Global Options
206
+
207
+ These options can be used with any command:
208
+
209
+ | Option | Description |
210
+ |--------|-------------|
211
+ | `--json` | Output results as JSON |
212
+ | `--ci` | Force CI mode behavior |
213
+ | `--no-ci` | Force non-CI mode (override CI detection) |
214
+
215
+ ### `servherd start`
216
+
217
+ Start a new development server or return an existing one.
218
+
219
+ ```bash
220
+ servherd start [options] -- <command>
221
+ ```
222
+
223
+ **Options:**
224
+ | Option | Description |
225
+ |--------|-------------|
226
+ | `-n, --name <name>` | Custom server name (auto-generated if not provided) |
227
+ | `-p, --port <port>` | Override the deterministic port assignment |
228
+ | `--protocol <protocol>` | Protocol to use: `http` or `https` |
229
+ | `-t, --tag <tag...>` | Tags for grouping servers (can use multiple times) |
230
+ | `-d, --description <text>` | Description of the server |
231
+ | `-e, --env <KEY=VALUE...>` | Environment variables (supports templates) |
232
+
233
+ **Template Variables:**
234
+ | Variable | Description | Example |
235
+ |----------|-------------|---------|
236
+ | `{{port}}` | Assigned port number | `8080` |
237
+ | `{{hostname}}` | Configured hostname | `localhost` |
238
+ | `{{url}}` | Full URL | `http://localhost:8080` |
239
+ | `{{https-cert}}` | HTTPS certificate path | `/path/to/cert.pem` |
240
+ | `{{https-key}}` | HTTPS key path | `/path/to/key.pem` |
241
+
242
+ **Examples:**
243
+ ```bash
244
+ # Start with automatic name and port
245
+ servherd start -- npx vite --port {{port}}
246
+
247
+ # Start with custom name and tags
248
+ servherd start --name frontend --tag web --tag dev -- npm run dev -- --port {{port}}
249
+
250
+ # Start with environment variables
251
+ servherd start --name api -e PORT={{port}} -e NODE_ENV=development -- node server.js
252
+
253
+ # Start on a specific port
254
+ servherd start --name fixed-port --port 8080 -- npx vite --port {{port}}
255
+ ```
256
+
257
+ ### `servherd stop`
258
+
259
+ Stop one or more running servers.
260
+
261
+ ```bash
262
+ servherd stop [name] [options]
263
+ ```
264
+
265
+ **Options:**
266
+ | Option | Description |
267
+ |--------|-------------|
268
+ | `-a, --all` | Stop all managed servers |
269
+ | `-t, --tag <tag>` | Stop all servers with this tag |
270
+ | `-f, --force` | Force stop using SIGKILL |
271
+
272
+ **Examples:**
273
+ ```bash
274
+ # Stop by name
275
+ servherd stop brave-tiger
276
+
277
+ # Stop all servers
278
+ servherd stop --all
279
+
280
+ # Force stop a hung server
281
+ servherd stop my-server --force
282
+
283
+ # Stop all servers with a tag
284
+ servherd stop --tag frontend
285
+ ```
286
+
287
+ ### `servherd list`
288
+
289
+ List all managed servers.
290
+
291
+ ```bash
292
+ servherd list [options]
293
+ ```
294
+
295
+ **Options:**
296
+ | Option | Description |
297
+ |--------|-------------|
298
+ | `-r, --running` | Show only running servers |
299
+ | `-s, --stopped` | Show only stopped servers |
300
+ | `-t, --tag <tag>` | Filter by tag |
301
+ | `-c, --cwd <path>` | Filter by working directory |
302
+ | `--cmd <pattern>` | Filter by command pattern (glob syntax) |
303
+
304
+ **Command Pattern Examples:**
305
+ ```bash
306
+ # Find all Storybook servers
307
+ servherd list --cmd "*storybook*"
308
+
309
+ # Find all Vite servers
310
+ servherd list --cmd "*vite*"
311
+
312
+ # Find servers using npm
313
+ servherd list --cmd "npm *"
314
+
315
+ # Find Vite or Storybook servers (brace expansion)
316
+ servherd list --cmd "*{vite,storybook}*"
317
+
318
+ # Combine with other filters
319
+ servherd list --cmd "*storybook*" --running --tag frontend
320
+ ```
321
+
322
+ ### `servherd info`
323
+
324
+ Show detailed information about a server.
325
+
326
+ ```bash
327
+ servherd info <name>
328
+ ```
329
+
330
+ **Displays:**
331
+ - Server name and status
332
+ - Port and URL
333
+ - Working directory and command
334
+ - Process ID and uptime
335
+ - Memory and CPU usage
336
+ - Tags and description
337
+
338
+ ### `servherd logs`
339
+
340
+ View and manage server logs.
341
+
342
+ ```bash
343
+ servherd logs [name] [options]
344
+ ```
345
+
346
+ **Options:**
347
+ | Option | Description |
348
+ |--------|-------------|
349
+ | `-n, --lines <number>` | Number of lines to show from end (default: 50) |
350
+ | `-e, --error` | Show error logs instead of stdout |
351
+ | `-f, --follow` | Follow logs in real-time (like `tail -f`) |
352
+ | `--since <time>` | Show logs since time (e.g., `1h`, `30m`, `2024-01-15`) |
353
+ | `--head <number>` | Show first N lines instead of last |
354
+ | `--flush` | Clear logs instead of displaying |
355
+ | `-a, --all` | Apply to all servers (with `--flush`) |
356
+
357
+ **Examples:**
358
+ ```bash
359
+ # View last 50 lines (default)
360
+ servherd logs my-app
361
+
362
+ # View last 100 lines
363
+ servherd logs my-app --lines 100
364
+
365
+ # Follow logs in real-time
366
+ servherd logs my-app --follow
367
+
368
+ # Show logs from the last hour
369
+ servherd logs my-app --since 1h
370
+
371
+ # Show logs since a specific date
372
+ servherd logs my-app --since 2024-01-15
373
+
374
+ # Show first 20 lines
375
+ servherd logs my-app --head 20
376
+
377
+ # View error logs
378
+ servherd logs my-app --error
379
+
380
+ # Clear logs for a server
381
+ servherd logs my-app --flush
382
+
383
+ # Clear logs for all servers
384
+ servherd logs --flush --all
385
+ ```
386
+
387
+ ### `servherd restart`
388
+
389
+ Restart a running server.
390
+
391
+ ```bash
392
+ servherd restart [name] [options]
393
+ ```
394
+
395
+ **Options:**
396
+ | Option | Description |
397
+ |--------|-------------|
398
+ | `-a, --all` | Restart all servers |
399
+ | `-t, --tag <tag>` | Restart servers with this tag |
400
+
401
+ ### `servherd remove`
402
+
403
+ Remove servers from the registry and stop them.
404
+
405
+ ```bash
406
+ servherd remove [name] [options]
407
+ ```
408
+
409
+ **Options:**
410
+ | Option | Description |
411
+ |--------|-------------|
412
+ | `-a, --all` | Remove all servers |
413
+ | `-t, --tag <tag>` | Remove servers with this tag |
414
+ | `-f, --force` | Skip confirmation prompt |
415
+
416
+ ### `servherd config`
417
+
418
+ View or modify configuration.
419
+
420
+ ```bash
421
+ servherd config [options]
422
+ ```
423
+
424
+ **Options:**
425
+ | Option | Description |
426
+ |--------|-------------|
427
+ | `-s, --show` | Display all configuration values |
428
+ | `-g, --get <key>` | Get a specific configuration value |
429
+ | `--set <key>` | Set a configuration value (requires `--value`) |
430
+ | `--value <value>` | Value to set |
431
+ | `-r, --reset` | Reset configuration to defaults |
432
+
433
+ **Examples:**
434
+ ```bash
435
+ # Show all configuration
436
+ servherd config --show
437
+
438
+ # Get specific value
439
+ servherd config --get hostname
440
+
441
+ # Set hostname
442
+ servherd config --set hostname --value myhost.local
443
+
444
+ # Set port range
445
+ servherd config --set portRange.min --value 4000
446
+ servherd config --set portRange.max --value 5000
447
+
448
+ # Configure HTTPS
449
+ servherd config --set protocol --value https
450
+ servherd config --set httpsCert --value /path/to/cert.pem
451
+ servherd config --set httpsKey --value /path/to/key.pem
452
+
453
+ # Reset to defaults
454
+ servherd config --reset
455
+ ```
456
+
457
+ ### `servherd mcp`
458
+
459
+ Start the MCP (Model Context Protocol) server.
460
+
461
+ ```bash
462
+ servherd mcp
463
+ ```
464
+
465
+ This starts an MCP server over stdio for integration with AI tools.
466
+
467
+ ## MCP Server Integration
468
+
469
+ ### Setup with Claude Code
470
+
471
+ The easiest way to add servherd to Claude Code is using the `claude mcp add` command:
472
+
473
+ ```bash
474
+ claude mcp add servherd -- npx servherd mcp
475
+ ```
476
+
477
+ This registers servherd as an MCP server that Claude Code can use to manage your development servers.
478
+
479
+ **With a specific scope:**
480
+ ```bash
481
+ # Add for current project only
482
+ claude mcp add --scope project servherd -- npx servherd mcp
483
+
484
+ # Add for current user (all projects)
485
+ claude mcp add --scope user servherd -- npx servherd mcp
486
+ ```
487
+
488
+ **Alternative: Manual configuration**
489
+
490
+ Add to your MCP settings file (`~/.claude/claude_desktop_config.json`):
491
+
492
+ ```json
493
+ {
494
+ "mcpServers": {
495
+ "servherd": {
496
+ "command": "npx",
497
+ "args": ["servherd", "mcp"]
498
+ }
499
+ }
500
+ }
501
+ ```
502
+
503
+ ### Available MCP Tools
504
+
505
+ | Tool | Description |
506
+ |------|-------------|
507
+ | `servherd_start` | Start a development server |
508
+ | `servherd_stop` | Stop a server |
509
+ | `servherd_restart` | Restart a server |
510
+ | `servherd_list` | List all servers (supports filtering by tag, cwd, cmd pattern) |
511
+ | `servherd_info` | Get server details |
512
+ | `servherd_logs` | View server logs |
513
+ | `servherd_remove` | Remove a server |
514
+ | `servherd_config` | View/modify configuration |
515
+ | `servherd_refresh` | Refresh servers with config drift |
516
+
517
+ **`servherd_list` Parameters:**
518
+ - `running` (boolean) - Only show running servers
519
+ - `tag` (string) - Filter by tag
520
+ - `cwd` (string) - Filter by working directory
521
+ - `cmd` (string) - Filter by command pattern (glob syntax, e.g., `*storybook*`)
522
+
523
+ ### MCP Resources
524
+
525
+ | Resource | Description |
526
+ |----------|-------------|
527
+ | `servherd://servers/{name}` | Server details as JSON |
528
+ | `servherd://servers/{name}/logs` | Server output logs |
529
+
530
+ ## Configuration
531
+
532
+ ### Global Configuration File
533
+
534
+ Location: `~/.servherd/config.json`
535
+
536
+ ```json
537
+ {
538
+ "version": "1",
539
+ "hostname": "localhost",
540
+ "protocol": "http",
541
+ "portRange": {
542
+ "min": 3000,
543
+ "max": 9999
544
+ },
545
+ "httpsCert": "/path/to/cert.pem",
546
+ "httpsKey": "/path/to/key.pem",
547
+ "tempDir": "~/.servherd/tmp",
548
+ "pm2": {
549
+ "logDir": "~/.servherd/logs",
550
+ "pidDir": "~/.servherd/pids"
551
+ }
552
+ }
553
+ ```
554
+
555
+ ### Environment Variables
556
+
557
+ Override configuration with environment variables:
558
+
559
+ | Variable | Description | Default |
560
+ |----------|-------------|---------|
561
+ | `SERVHERD_HOSTNAME` | Default hostname | `localhost` |
562
+ | `SERVHERD_PROTOCOL` | Protocol (http/https) | `http` |
563
+ | `SERVHERD_PORT_MIN` | Minimum port number | `3000` |
564
+ | `SERVHERD_PORT_MAX` | Maximum port number | `9999` |
565
+ | `SERVHERD_CONFIG_DIR` | Configuration directory | `~/.servherd` |
566
+
567
+ ### CI Mode
568
+
569
+ servherd automatically detects CI environments and adjusts behavior:
570
+
571
+ - Uses sequential port allocation (instead of deterministic hashing)
572
+ - Disables interactive prompts
573
+ - Uses non-TTY output formatting
574
+ - Respects environment variable configuration
575
+
576
+ **Supported CI environments:**
577
+ - GitHub Actions
578
+ - GitLab CI
579
+ - Jenkins
580
+ - CircleCI
581
+ - Travis CI
582
+ - Azure Pipelines
583
+ - Buildkite
584
+ - TeamCity
585
+ - Any environment with `CI=true`
586
+
587
+ **Manual CI mode control:**
588
+ ```bash
589
+ # Force CI mode
590
+ servherd start --ci -- npm run dev -- --port {{port}}
591
+
592
+ # Force non-CI mode (even in CI environment)
593
+ servherd start --no-ci -- npm run dev -- --port {{port}}
594
+ ```
595
+
596
+ ## API (Programmatic Usage)
597
+
598
+ ```typescript
599
+ import { ConfigService, RegistryService, ProcessService, PortService } from "servherd";
600
+
601
+ // Load configuration
602
+ const config = new ConfigService();
603
+ await config.load();
604
+
605
+ // Access registry
606
+ const registry = new RegistryService(config);
607
+ await registry.load();
608
+
609
+ // Manage processes
610
+ const process = new ProcessService(registry);
611
+ await process.connect();
612
+
613
+ // Generate ports
614
+ const port = new PortService(config);
615
+ const assignedPort = port.generatePort("/path/to/project", "npm start");
616
+ ```
617
+
618
+ ## Troubleshooting
619
+
620
+ ### Server won't start
621
+
622
+ 1. Check if PM2 is installed: `pm2 --version`
623
+ 2. Check if the port is available: `lsof -i :PORT`
624
+ 3. View server logs: `servherd logs <name> --error`
625
+
626
+ ### Port conflicts
627
+
628
+ servherd uses deterministic port assignment based on project path and command. If you need a different port:
629
+
630
+ 1. Use `--port` to specify an exact port
631
+ 2. Use a different server name (changes the hash)
632
+ 3. Modify the port range in config
633
+ 4. Stop the existing server first
634
+
635
+ ### PM2 cleanup
636
+
637
+ If servers become orphaned:
638
+
639
+ ```bash
640
+ # List PM2 processes
641
+ pm2 list
642
+
643
+ # Delete servherd processes
644
+ pm2 delete all --filter servherd-
645
+
646
+ # Or remove all and let servherd recreate
647
+ servherd remove --all --force
648
+ ```
649
+
650
+ ### Log management
651
+
652
+ ```bash
653
+ # Clear logs for a specific server
654
+ servherd logs my-app --flush
655
+
656
+ # Clear all logs
657
+ servherd logs --flush --all
658
+
659
+ # Check log file location
660
+ servherd info my-app # Shows log paths
661
+ ```
662
+
663
+ ## Contributing
664
+
665
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
666
+
667
+ ## License
668
+
669
+ MIT - see [LICENSE](LICENSE)