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.
- package/CONTRIBUTING.md +250 -0
- package/LICENSE +21 -0
- package/README.md +653 -29
- package/dist/cli/commands/config.d.ts +35 -0
- package/dist/cli/commands/config.js +336 -0
- package/dist/cli/commands/info.d.ts +37 -0
- package/dist/cli/commands/info.js +98 -0
- package/dist/cli/commands/list.d.ts +26 -0
- package/dist/cli/commands/list.js +86 -0
- package/dist/cli/commands/logs.d.ts +46 -0
- package/dist/cli/commands/logs.js +292 -0
- package/dist/cli/commands/mcp.d.ts +5 -0
- package/dist/cli/commands/mcp.js +17 -0
- package/dist/cli/commands/refresh.d.ts +20 -0
- package/dist/cli/commands/refresh.js +139 -0
- package/dist/cli/commands/remove.d.ts +20 -0
- package/dist/cli/commands/remove.js +144 -0
- package/dist/cli/commands/restart.d.ts +25 -0
- package/dist/cli/commands/restart.js +177 -0
- package/dist/cli/commands/start.d.ts +37 -0
- package/dist/cli/commands/start.js +293 -0
- package/dist/cli/commands/stop.d.ts +20 -0
- package/dist/cli/commands/stop.js +108 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +160 -0
- package/dist/cli/output/formatters.d.ts +117 -0
- package/dist/cli/output/formatters.js +454 -0
- package/dist/cli/output/json-formatter.d.ts +22 -0
- package/dist/cli/output/json-formatter.js +40 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +25 -0
- package/dist/mcp/index.d.ts +14 -0
- package/dist/mcp/index.js +352 -0
- package/dist/mcp/resources/servers.d.ts +14 -0
- package/dist/mcp/resources/servers.js +128 -0
- package/dist/mcp/tools/config.d.ts +33 -0
- package/dist/mcp/tools/config.js +88 -0
- package/dist/mcp/tools/info.d.ts +36 -0
- package/dist/mcp/tools/info.js +65 -0
- package/dist/mcp/tools/list.d.ts +36 -0
- package/dist/mcp/tools/list.js +49 -0
- package/dist/mcp/tools/logs.d.ts +44 -0
- package/dist/mcp/tools/logs.js +55 -0
- package/dist/mcp/tools/refresh.d.ts +33 -0
- package/dist/mcp/tools/refresh.js +54 -0
- package/dist/mcp/tools/remove.d.ts +23 -0
- package/dist/mcp/tools/remove.js +43 -0
- package/dist/mcp/tools/restart.d.ts +23 -0
- package/dist/mcp/tools/restart.js +42 -0
- package/dist/mcp/tools/start.d.ts +38 -0
- package/dist/mcp/tools/start.js +73 -0
- package/dist/mcp/tools/stop.d.ts +23 -0
- package/dist/mcp/tools/stop.js +40 -0
- package/dist/services/config.service.d.ts +80 -0
- package/dist/services/config.service.js +227 -0
- package/dist/services/port.service.d.ts +82 -0
- package/dist/services/port.service.js +151 -0
- package/dist/services/process.service.d.ts +61 -0
- package/dist/services/process.service.js +220 -0
- package/dist/services/registry.service.d.ts +50 -0
- package/dist/services/registry.service.js +157 -0
- package/dist/types/config.d.ts +107 -0
- package/dist/types/config.js +44 -0
- package/dist/types/errors.d.ts +102 -0
- package/dist/types/errors.js +197 -0
- package/dist/types/pm2.d.ts +50 -0
- package/dist/types/pm2.js +4 -0
- package/dist/types/registry.d.ts +230 -0
- package/dist/types/registry.js +33 -0
- package/dist/utils/ci-detector.d.ts +31 -0
- package/dist/utils/ci-detector.js +68 -0
- package/dist/utils/config-drift.d.ts +71 -0
- package/dist/utils/config-drift.js +128 -0
- package/dist/utils/error-handler.d.ts +21 -0
- package/dist/utils/error-handler.js +38 -0
- package/dist/utils/log-follower.d.ts +10 -0
- package/dist/utils/log-follower.js +98 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.js +24 -0
- package/dist/utils/names.d.ts +7 -0
- package/dist/utils/names.js +20 -0
- package/dist/utils/template.d.ts +88 -0
- package/dist/utils/template.js +180 -0
- package/dist/utils/time-parser.d.ts +19 -0
- package/dist/utils/time-parser.js +54 -0
- package/docs/ci-cd.md +408 -0
- package/docs/configuration.md +325 -0
- package/docs/mcp-integration.md +411 -0
- package/examples/basic-usage/README.md +187 -0
- package/examples/ci-github-actions/workflow.yml +195 -0
- package/examples/mcp-claude-code/README.md +213 -0
- package/examples/multi-server/README.md +270 -0
- package/examples/storybook/README.md +187 -0
- package/examples/vite-project/README.md +251 -0
- package/package.json +123 -6
package/README.md
CHANGED
|
@@ -1,45 +1,669 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="servherd logo" width="180">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">servherd</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Herd your development servers</strong>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
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
|
-
##
|
|
18
|
+
## The Problem
|
|
10
19
|
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
+
## The Solution
|
|
19
28
|
|
|
20
|
-
|
|
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
|
-
|
|
31
|
+
## Key Features
|
|
23
32
|
|
|
24
|
-
|
|
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
|
-
|
|
35
|
+
servherd uses [PM2](https://pm2.keymetrics.io) under the hood for robust process management:
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
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
|
-
|
|
43
|
+
### Intelligent Port Management
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
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
|
-
**
|
|
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)
|