mcp-server-diff 2.1.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/.github/dependabot.yml +21 -0
- package/.github/workflows/ci.yml +51 -0
- package/.github/workflows/publish.yml +36 -0
- package/.github/workflows/release.yml +51 -0
- package/.prettierignore +3 -0
- package/.prettierrc +8 -0
- package/CONTRIBUTING.md +81 -0
- package/LICENSE +21 -0
- package/README.md +526 -0
- package/action.yml +250 -0
- package/dist/__tests__/fixtures/http-server.d.ts +7 -0
- package/dist/__tests__/fixtures/stdio-server.d.ts +7 -0
- package/dist/cli/__tests__/fixtures/http-server.d.ts +7 -0
- package/dist/cli/__tests__/fixtures/stdio-server.d.ts +7 -0
- package/dist/cli/cli.d.ts +7 -0
- package/dist/cli/diff.d.ts +44 -0
- package/dist/cli/git.d.ts +37 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +57182 -0
- package/dist/cli/licenses.txt +466 -0
- package/dist/cli/logger.d.ts +46 -0
- package/dist/cli/package.json +3 -0
- package/dist/cli/probe.d.ts +35 -0
- package/dist/cli/reporter.d.ts +20 -0
- package/dist/cli/runner.d.ts +30 -0
- package/dist/cli/types.d.ts +134 -0
- package/dist/cli.d.ts +7 -0
- package/dist/diff.d.ts +44 -0
- package/dist/git.d.ts +37 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +58032 -0
- package/dist/licenses.txt +466 -0
- package/dist/logger.d.ts +46 -0
- package/dist/package.json +3 -0
- package/dist/probe.d.ts +35 -0
- package/dist/reporter.d.ts +20 -0
- package/dist/runner.d.ts +30 -0
- package/dist/types.d.ts +134 -0
- package/eslint.config.mjs +47 -0
- package/jest.config.mjs +26 -0
- package/package.json +64 -0
- package/src/__tests__/fixtures/http-server.ts +103 -0
- package/src/__tests__/fixtures/stdio-server.ts +158 -0
- package/src/__tests__/integration.test.ts +306 -0
- package/src/__tests__/runner.test.ts +430 -0
- package/src/cli.ts +421 -0
- package/src/diff.ts +252 -0
- package/src/git.ts +262 -0
- package/src/index.ts +284 -0
- package/src/logger.ts +93 -0
- package/src/probe.ts +327 -0
- package/src/reporter.ts +214 -0
- package/src/runner.ts +902 -0
- package/src/types.ts +155 -0
- package/tsconfig.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
# MCP Server Diff
|
|
2
|
+
|
|
3
|
+
[](https://github.com/marketplace/actions/mcp-server-diff)
|
|
4
|
+
[](https://github.com/SamMorrowDrums/mcp-server-diff/releases)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
A GitHub Action for diffing [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server **public interfaces** between versions. This action compares the current branch against a baseline to surface any changes to your server's exposed tools, resources, prompts, and capabilities—helping you document API evolution and catch unintended modifications.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
MCP servers expose a **public interface** to AI assistants: tools (with their input schemas), resources, prompts, and server capabilities. As your server evolves, changes to this interface are worth tracking. This action automates public interface comparison by:
|
|
12
|
+
|
|
13
|
+
1. Building your MCP server from both the current branch and a baseline (merge-base, tag, or specified ref)
|
|
14
|
+
2. Querying both versions for their complete public interface (tools, resources, prompts, capabilities)
|
|
15
|
+
3. Generating a diff report showing exactly what changed
|
|
16
|
+
4. Surfacing results directly in GitHub's Job Summary
|
|
17
|
+
|
|
18
|
+
This is **not** about testing internal logic or correctness—it's about visibility into what your server _advertises_ to clients.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
Create `.github/workflows/mcp-diff.yml` in your repository:
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
name: MCP Server Diff
|
|
26
|
+
|
|
27
|
+
on:
|
|
28
|
+
pull_request:
|
|
29
|
+
branches: [main]
|
|
30
|
+
push:
|
|
31
|
+
branches: [main]
|
|
32
|
+
tags: ['v*']
|
|
33
|
+
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
|
|
37
|
+
jobs:
|
|
38
|
+
mcp-diff:
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
with:
|
|
43
|
+
fetch-depth: 0
|
|
44
|
+
|
|
45
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
46
|
+
with:
|
|
47
|
+
setup_node: true
|
|
48
|
+
install_command: npm ci
|
|
49
|
+
build_command: npm run build
|
|
50
|
+
start_command: node dist/stdio.js
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Language Examples
|
|
54
|
+
|
|
55
|
+
### Node.js / TypeScript
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
59
|
+
with:
|
|
60
|
+
setup_node: true
|
|
61
|
+
node_version: '22'
|
|
62
|
+
install_command: npm ci
|
|
63
|
+
build_command: npm run build
|
|
64
|
+
start_command: node dist/stdio.js
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Python
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
71
|
+
with:
|
|
72
|
+
setup_python: true
|
|
73
|
+
python_version: '3.12'
|
|
74
|
+
install_command: pip install -e .
|
|
75
|
+
start_command: python -m my_mcp_server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Go
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
82
|
+
with:
|
|
83
|
+
setup_go: true
|
|
84
|
+
install_command: go mod download
|
|
85
|
+
build_command: go build -o bin/server ./cmd/stdio
|
|
86
|
+
start_command: ./bin/server
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Rust
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
93
|
+
with:
|
|
94
|
+
setup_rust: true
|
|
95
|
+
install_command: cargo fetch
|
|
96
|
+
build_command: cargo build --release
|
|
97
|
+
start_command: ./target/release/my-mcp-server
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### C# / .NET
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
104
|
+
with:
|
|
105
|
+
setup_dotnet: true
|
|
106
|
+
dotnet_version: '9.0.x'
|
|
107
|
+
install_command: dotnet restore
|
|
108
|
+
build_command: dotnet build -c Release
|
|
109
|
+
start_command: dotnet run --no-build -c Release
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Custom Setup
|
|
113
|
+
|
|
114
|
+
If you need more control over environment setup (caching, specific registries, etc.), do your own setup before calling the action:
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
steps:
|
|
118
|
+
- uses: actions/checkout@v4
|
|
119
|
+
with:
|
|
120
|
+
fetch-depth: 0
|
|
121
|
+
|
|
122
|
+
- uses: actions/setup-node@v4
|
|
123
|
+
with:
|
|
124
|
+
node-version: '22'
|
|
125
|
+
cache: 'npm'
|
|
126
|
+
registry-url: 'https://npm.pkg.github.com'
|
|
127
|
+
|
|
128
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
129
|
+
with:
|
|
130
|
+
install_command: npm ci
|
|
131
|
+
build_command: npm run build
|
|
132
|
+
start_command: node dist/stdio.js
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Testing Multiple Transports
|
|
136
|
+
|
|
137
|
+
Test both stdio and HTTP transports in a single run using the `configurations` input:
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
141
|
+
with:
|
|
142
|
+
setup_node: true
|
|
143
|
+
install_command: npm ci
|
|
144
|
+
build_command: npm run build
|
|
145
|
+
configurations: |
|
|
146
|
+
[
|
|
147
|
+
{
|
|
148
|
+
"name": "stdio",
|
|
149
|
+
"transport": "stdio",
|
|
150
|
+
"start_command": "node dist/stdio.js"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "streamable-http",
|
|
154
|
+
"transport": "streamable-http",
|
|
155
|
+
"start_command": "node dist/http.js",
|
|
156
|
+
"server_url": "http://localhost:3000/mcp"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Inputs Reference
|
|
162
|
+
|
|
163
|
+
### Language Setup (Optional)
|
|
164
|
+
|
|
165
|
+
| Input | Description | Default |
|
|
166
|
+
|-------|-------------|---------|
|
|
167
|
+
| `setup_node` | Set up Node.js environment | `false` |
|
|
168
|
+
| `node_version` | Node.js version | `20` |
|
|
169
|
+
| `setup_python` | Set up Python environment | `false` |
|
|
170
|
+
| `python_version` | Python version | `3.11` |
|
|
171
|
+
| `setup_go` | Set up Go environment | `false` |
|
|
172
|
+
| `go_version` | Go version (reads from go.mod if empty) | `""` |
|
|
173
|
+
| `setup_rust` | Set up Rust environment | `false` |
|
|
174
|
+
| `rust_toolchain` | Rust toolchain | `stable` |
|
|
175
|
+
| `setup_dotnet` | Set up .NET environment | `false` |
|
|
176
|
+
| `dotnet_version` | .NET version | `8.0.x` |
|
|
177
|
+
|
|
178
|
+
### Required Inputs
|
|
179
|
+
|
|
180
|
+
| Input | Description |
|
|
181
|
+
|-------|-------------|
|
|
182
|
+
| `install_command` | Command to install dependencies (e.g., `npm ci`, `pip install -e .`, `go mod download`) |
|
|
183
|
+
|
|
184
|
+
### Server Configuration
|
|
185
|
+
|
|
186
|
+
| Input | Description | Default |
|
|
187
|
+
|-------|-------------|---------|
|
|
188
|
+
| `build_command` | Command to build the server. Optional for interpreted languages. | `""` |
|
|
189
|
+
| `start_command` | Command to start the server for stdio transport | `""` |
|
|
190
|
+
| `transport` | Transport type: `stdio` or `streamable-http` | `stdio` |
|
|
191
|
+
| `server_url` | Server URL for HTTP transport (e.g., `http://localhost:3000/mcp`) | `""` |
|
|
192
|
+
| `configurations` | JSON array of test configurations for testing multiple transports | `""` |
|
|
193
|
+
| `server_timeout` | Timeout in seconds to wait for server response | `10` |
|
|
194
|
+
| `env_vars` | Environment variables as newline-separated `KEY=VALUE` pairs | `""` |
|
|
195
|
+
|
|
196
|
+
Either `start_command` (for stdio) or `server_url` (for HTTP) must be provided, unless using `configurations`.
|
|
197
|
+
|
|
198
|
+
### Comparison Configuration
|
|
199
|
+
|
|
200
|
+
| Input | Description | Default |
|
|
201
|
+
|-------|-------------|---------|
|
|
202
|
+
| `compare_ref` | Git ref to compare against. Auto-detects merge-base on PRs or previous tag on tag pushes if not specified. | `""` |
|
|
203
|
+
| `fail_on_diff` | Fail the action if API changes are detected. Useful for release validation workflows. | `false` |
|
|
204
|
+
| `fail_on_error` | Fail the action if probe errors occur (connection failures, etc.) | `true` |
|
|
205
|
+
|
|
206
|
+
### Configuration Object Schema
|
|
207
|
+
|
|
208
|
+
When using `configurations`, each object supports:
|
|
209
|
+
|
|
210
|
+
| Field | Description | Required |
|
|
211
|
+
|-------|-------------|----------|
|
|
212
|
+
| `name` | Identifier for this configuration (appears in report) | Yes |
|
|
213
|
+
| `transport` | `stdio` or `streamable-http` | No (default: `stdio`) |
|
|
214
|
+
| `start_command` | Server start command (stdio: spawns process, HTTP: starts server in background) | Yes for stdio, optional for HTTP |
|
|
215
|
+
| `server_url` | URL for HTTP transport | Required for `streamable-http` |
|
|
216
|
+
| `startup_wait_ms` | Milliseconds to wait for HTTP server to start (when using `start_command`) | No (default: 2000) |
|
|
217
|
+
| `pre_test_command` | Command to run before probing (alternative to `start_command` for HTTP) | No |
|
|
218
|
+
| `pre_test_wait_ms` | Milliseconds to wait after `pre_test_command` | No |
|
|
219
|
+
| `post_test_command` | Command to run after probing (cleanup, used with `pre_test_command`) | No |
|
|
220
|
+
| `headers` | HTTP headers for this configuration | No |
|
|
221
|
+
| `env_vars` | Additional environment variables | No |
|
|
222
|
+
| `custom_messages` | Config-specific custom messages | No |
|
|
223
|
+
|
|
224
|
+
## How It Works
|
|
225
|
+
|
|
226
|
+
### Execution Flow
|
|
227
|
+
|
|
228
|
+
1. **Baseline Detection**: Determines the comparison ref:
|
|
229
|
+
- For pull requests: merge-base with target branch
|
|
230
|
+
- For tag pushes: previous tag (e.g., `v1.1.0` compares against `v1.0.0`)
|
|
231
|
+
- Explicit: uses `compare_ref` if provided
|
|
232
|
+
2. **Build Baseline**: Creates a git worktree at the baseline ref and builds the server
|
|
233
|
+
3. **Build Current**: Builds the server from the current branch
|
|
234
|
+
4. **Conformance Testing**: Sends MCP protocol requests to both servers:
|
|
235
|
+
- `initialize` - Server capabilities and metadata
|
|
236
|
+
- `tools/list` - Available tools and their schemas
|
|
237
|
+
- `resources/list` - Available resources
|
|
238
|
+
- `prompts/list` - Available prompts
|
|
239
|
+
5. **Report Generation**: Produces a Markdown report with diffs, uploaded as an artifact and displayed in Job Summary
|
|
240
|
+
|
|
241
|
+
### What Gets Compared
|
|
242
|
+
|
|
243
|
+
The action queries the **public interface** of both server versions and compares the responses:
|
|
244
|
+
|
|
245
|
+
| Method | What It Reveals |
|
|
246
|
+
|--------|----------------|
|
|
247
|
+
| `initialize` | Server name, version, capabilities |
|
|
248
|
+
| `tools/list` | Available tools and their JSON schemas |
|
|
249
|
+
| `resources/list` | Exposed resources |
|
|
250
|
+
| `prompts/list` | Available prompts |
|
|
251
|
+
|
|
252
|
+
Differences appear as unified diffs in the report. Common changes include:
|
|
253
|
+
|
|
254
|
+
- New tools, resources, or prompts added
|
|
255
|
+
- Schema changes (new parameters, updated descriptions)
|
|
256
|
+
- Capability changes (new features enabled)
|
|
257
|
+
- Version string updates
|
|
258
|
+
|
|
259
|
+
## Transport Support
|
|
260
|
+
|
|
261
|
+
### stdio Transport
|
|
262
|
+
|
|
263
|
+
The default transport communicates with your server via stdin/stdout using JSON-RPC. For stdio, each configuration spawns a fresh server process:
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
267
|
+
with:
|
|
268
|
+
setup_node: true
|
|
269
|
+
install_command: npm ci
|
|
270
|
+
build_command: npm run build
|
|
271
|
+
start_command: node dist/stdio.js
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Streamable HTTP Transport
|
|
275
|
+
|
|
276
|
+
For HTTP servers, you typically want to **start the server once** and test multiple configurations against it. Use `start_command` at the configuration level—the action spawns the server, waits for startup, probes it, then terminates it after that configuration completes:
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
configurations: |
|
|
280
|
+
[{
|
|
281
|
+
"name": "http-server",
|
|
282
|
+
"transport": "streamable-http",
|
|
283
|
+
"start_command": "node dist/http.js",
|
|
284
|
+
"server_url": "http://localhost:3000/mcp",
|
|
285
|
+
"startup_wait_ms": 2000
|
|
286
|
+
}]
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Per-configuration server lifecycle**: If your use case requires a fresh server instance per configuration (e.g., testing different flags or environment variables), include `start_command` in each configuration—each will get its own server process started and stopped.
|
|
290
|
+
|
|
291
|
+
**Shared server for multiple configurations**: If you want one HTTP server to handle multiple test configurations, use `pre_test_command`/`post_test_command` on the first/last configuration, or start the server in a prior workflow step:
|
|
292
|
+
|
|
293
|
+
```yaml
|
|
294
|
+
configurations: |
|
|
295
|
+
[
|
|
296
|
+
{
|
|
297
|
+
"name": "config-a",
|
|
298
|
+
"transport": "streamable-http",
|
|
299
|
+
"server_url": "http://localhost:3000/mcp",
|
|
300
|
+
"pre_test_command": "node dist/http.js &",
|
|
301
|
+
"pre_test_wait_ms": 2000
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"name": "config-b",
|
|
305
|
+
"transport": "streamable-http",
|
|
306
|
+
"server_url": "http://localhost:3000/mcp"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"name": "config-c",
|
|
310
|
+
"transport": "streamable-http",
|
|
311
|
+
"server_url": "http://localhost:3000/mcp",
|
|
312
|
+
"post_test_command": "pkill -f 'node dist/http.js' || true"
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Pre-deployed servers**: For already-running servers (staging, production), omit lifecycle commands entirely:
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
321
|
+
with:
|
|
322
|
+
install_command: 'true'
|
|
323
|
+
transport: streamable-http
|
|
324
|
+
server_url: https://mcp.example.com/api
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Version Comparison Strategies
|
|
328
|
+
|
|
329
|
+
### Pull Requests
|
|
330
|
+
|
|
331
|
+
On pull requests, the action automatically compares against the merge-base with the target branch. This shows exactly what changes the PR introduces.
|
|
332
|
+
|
|
333
|
+
### Tag Releases
|
|
334
|
+
|
|
335
|
+
When triggered by a tag push matching `v*`, the action finds the previous tag and compares against it:
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
on:
|
|
339
|
+
push:
|
|
340
|
+
tags: ['v*']
|
|
341
|
+
|
|
342
|
+
# v1.2.0 will automatically compare against v1.1.0
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Explicit Baseline
|
|
346
|
+
|
|
347
|
+
Specify any git ref to compare against:
|
|
348
|
+
|
|
349
|
+
```yaml
|
|
350
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
351
|
+
with:
|
|
352
|
+
setup_node: true
|
|
353
|
+
install_command: npm ci
|
|
354
|
+
build_command: npm run build
|
|
355
|
+
start_command: node dist/stdio.js
|
|
356
|
+
compare_ref: v1.0.0
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Failing on Changes (Release Validation)
|
|
360
|
+
|
|
361
|
+
For release workflows where you want to ensure no API changes, use `fail_on_diff`:
|
|
362
|
+
|
|
363
|
+
```yaml
|
|
364
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
365
|
+
with:
|
|
366
|
+
setup_node: true
|
|
367
|
+
install_command: npm ci
|
|
368
|
+
build_command: npm run build
|
|
369
|
+
start_command: node dist/stdio.js
|
|
370
|
+
compare_ref: v1.0.0
|
|
371
|
+
fail_on_diff: true # Action fails if any API changes are detected
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Artifacts and Reports
|
|
375
|
+
|
|
376
|
+
The action produces:
|
|
377
|
+
|
|
378
|
+
1. **Job Summary**: Inline Markdown report in the GitHub Actions UI showing test results and diffs
|
|
379
|
+
2. **Artifact**: `mcp-diff-report` artifact containing `MCP_DIFF_REPORT.md` for download or further processing
|
|
380
|
+
|
|
381
|
+
## Example Output
|
|
382
|
+
|
|
383
|
+
### No Changes Detected
|
|
384
|
+
|
|
385
|
+
When the MCP server's public interface hasn't changed between branches:
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
📊 Comparison:
|
|
389
|
+
Current: HEAD
|
|
390
|
+
Compare: abc1234 (v1.0.0)
|
|
391
|
+
|
|
392
|
+
🧪 Running diff...
|
|
393
|
+
|
|
394
|
+
📊 Phase 3: Comparing results...
|
|
395
|
+
📋 Configuration stdio: ✅ No changes
|
|
396
|
+
|
|
397
|
+
✅ No API Changes - All configurations match the baseline.
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Changes Detected
|
|
401
|
+
|
|
402
|
+
When changes are detected, the action shows a semantic diff with clear paths to each change:
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
📋 Configuration stdio: 3 change(s) found
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
The generated report shows exactly what changed using path notation:
|
|
409
|
+
|
|
410
|
+
```diff
|
|
411
|
+
--- base/tools.json
|
|
412
|
+
+++ branch/tools.json
|
|
413
|
+
|
|
414
|
+
+ tools[new_tool]: {"name": "new_tool", "description": "A newly added tool", ...}
|
|
415
|
+
- tools[old_tool].inputSchema.properties.name.description: "Old description"
|
|
416
|
+
+ tools[old_tool].inputSchema.properties.name.description: "Updated description"
|
|
417
|
+
- tools[calculator].inputSchema.properties.precision.type: "string"
|
|
418
|
+
+ tools[calculator].inputSchema.properties.precision.type: "number"
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
```diff
|
|
422
|
+
--- base/resources.json
|
|
423
|
+
+++ branch/resources.json
|
|
424
|
+
|
|
425
|
+
+ resources[config://settings]: {"uri": "config://settings", "name": "Settings", ...}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Each line shows:
|
|
429
|
+
- `+` for additions (new tools, resources, or changed values)
|
|
430
|
+
- `-` for removals (deleted items or previous values)
|
|
431
|
+
- Full path to the change: `tools[tool_name].inputSchema.properties.param.type`
|
|
432
|
+
|
|
433
|
+
This makes it easy to see exactly what changed without wading through entire JSON dumps
|
|
434
|
+
|
|
435
|
+
## Recommended Workflow
|
|
436
|
+
|
|
437
|
+
```yaml
|
|
438
|
+
name: MCP Server Diff
|
|
439
|
+
|
|
440
|
+
on:
|
|
441
|
+
workflow_dispatch:
|
|
442
|
+
pull_request:
|
|
443
|
+
branches: [main]
|
|
444
|
+
push:
|
|
445
|
+
branches: [main]
|
|
446
|
+
tags: ['v*']
|
|
447
|
+
|
|
448
|
+
permissions:
|
|
449
|
+
contents: read
|
|
450
|
+
|
|
451
|
+
jobs:
|
|
452
|
+
mcp-diff:
|
|
453
|
+
runs-on: ubuntu-latest
|
|
454
|
+
steps:
|
|
455
|
+
- uses: actions/checkout@v4
|
|
456
|
+
with:
|
|
457
|
+
fetch-depth: 0
|
|
458
|
+
|
|
459
|
+
- uses: SamMorrowDrums/mcp-server-diff@v2
|
|
460
|
+
with:
|
|
461
|
+
setup_node: true
|
|
462
|
+
install_command: npm ci
|
|
463
|
+
build_command: npm run build
|
|
464
|
+
configurations: |
|
|
465
|
+
[
|
|
466
|
+
{
|
|
467
|
+
"name": "stdio",
|
|
468
|
+
"transport": "stdio",
|
|
469
|
+
"start_command": "node dist/stdio.js"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"name": "streamable-http",
|
|
473
|
+
"transport": "streamable-http",
|
|
474
|
+
"start_command": "node dist/http.js",
|
|
475
|
+
"server_url": "http://localhost:3000/mcp"
|
|
476
|
+
}
|
|
477
|
+
]
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
## Troubleshooting
|
|
481
|
+
|
|
482
|
+
### Server fails to start
|
|
483
|
+
|
|
484
|
+
- Check that `start_command` works locally
|
|
485
|
+
- Increase `server_timeout` for slow-starting servers
|
|
486
|
+
- Verify all dependencies are installed by `install_command`
|
|
487
|
+
|
|
488
|
+
### Missing baseline
|
|
489
|
+
|
|
490
|
+
- Ensure `fetch-depth: 0` in your checkout step
|
|
491
|
+
- For new repositories, the first run may fail (no baseline exists)
|
|
492
|
+
|
|
493
|
+
### HTTP transport connection refused
|
|
494
|
+
|
|
495
|
+
- Verify `server_url` matches your server's listen address
|
|
496
|
+
- Ensure the server binds to `0.0.0.0` or `127.0.0.1`, not just `localhost` on some systems
|
|
497
|
+
- Check firewall or container networking if running in Docker
|
|
498
|
+
|
|
499
|
+
## License
|
|
500
|
+
|
|
501
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
502
|
+
|
|
503
|
+
## Contributing
|
|
504
|
+
|
|
505
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
506
|
+
|
|
507
|
+
## Related Resources
|
|
508
|
+
|
|
509
|
+
- [Model Context Protocol Specification](https://modelcontextprotocol.io/)
|
|
510
|
+
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
511
|
+
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
|
|
512
|
+
- [MCP Go SDK](https://github.com/modelcontextprotocol/go-sdk)
|
|
513
|
+
|
|
514
|
+
### Example Configurations
|
|
515
|
+
|
|
516
|
+
Working examples of this action in various languages:
|
|
517
|
+
|
|
518
|
+
| Language | Repository | Workflow |
|
|
519
|
+
|----------|------------|----------|
|
|
520
|
+
| TypeScript | [mcp-typescript-starter](https://github.com/SamMorrowDrums/mcp-typescript-starter) | [mcp-diff.yml](https://github.com/SamMorrowDrums/mcp-typescript-starter/blob/main/.github/workflows/mcp-diff.yml) |
|
|
521
|
+
| Python | [mcp-python-starter](https://github.com/SamMorrowDrums/mcp-python-starter) | [mcp-diff.yml](https://github.com/SamMorrowDrums/mcp-python-starter/blob/main/.github/workflows/mcp-diff.yml) |
|
|
522
|
+
| Go | [mcp-go-starter](https://github.com/SamMorrowDrums/mcp-go-starter) | [mcp-diff.yml](https://github.com/SamMorrowDrums/mcp-go-starter/blob/main/.github/workflows/mcp-diff.yml) |
|
|
523
|
+
| Rust | [mcp-rust-starter](https://github.com/SamMorrowDrums/mcp-rust-starter) | [mcp-diff.yml](https://github.com/SamMorrowDrums/mcp-rust-starter/blob/main/.github/workflows/mcp-diff.yml) |
|
|
524
|
+
| C# | [mcp-csharp-starter](https://github.com/SamMorrowDrums/mcp-csharp-starter) | [mcp-diff.yml](https://github.com/SamMorrowDrums/mcp-csharp-starter/blob/main/.github/workflows/mcp-diff.yml) |
|
|
525
|
+
|
|
526
|
+
For a production example, see [github-mcp-server](https://github.com/github/github-mcp-server).
|