mcp-server-diff 2.1.0 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # MCP Server Diff
2
2
 
3
3
  [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-MCP%20Server%20Diff-blue?logo=github)](https://github.com/marketplace/actions/mcp-server-diff)
4
+ [![npm version](https://img.shields.io/npm/v/mcp-server-diff)](https://www.npmjs.com/package/mcp-server-diff)
4
5
  [![GitHub release](https://img.shields.io/github/v/release/SamMorrowDrums/mcp-server-diff)](https://github.com/SamMorrowDrums/mcp-server-diff/releases)
5
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
7
 
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
+ A GitHub Action for diffing [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server **public interfaces** between versions. Compares the current branch against a baseline to surface any changes to your server's exposed tools, resources, prompts, and capabilities.
9
+
10
+ > **Also available as a standalone CLI** — see [CLI Documentation](#cli-tool) or install with `npx mcp-server-diff`
8
11
 
9
12
  ## Overview
10
13
 
@@ -496,6 +499,118 @@ jobs:
496
499
  - Ensure the server binds to `0.0.0.0` or `127.0.0.1`, not just `localhost` on some systems
497
500
  - Check firewall or container networking if running in Docker
498
501
 
502
+ ---
503
+
504
+ ## CLI Tool
505
+
506
+ The CLI lets you diff any two MCP servers directly from your terminal—useful for local development, CI pipelines, or comparing servers across different implementations.
507
+
508
+ ### Installation
509
+
510
+ ```bash
511
+ # Run directly with npx (no install required)
512
+ npx mcp-server-diff --help
513
+
514
+ # Or install globally
515
+ npm install -g mcp-server-diff
516
+ ```
517
+
518
+ ### Basic Usage
519
+
520
+ ```bash
521
+ # Compare two local stdio servers
522
+ npx mcp-server-diff -b "python -m mcp_server" -t "node dist/stdio.js"
523
+
524
+ # Compare local server vs remote HTTP endpoint
525
+ npx mcp-server-diff -b "go run ./cmd/server stdio" -t "https://mcp.example.com/api"
526
+
527
+ # Output formats
528
+ npx mcp-server-diff -b "..." -t "..." -o diff # Raw diff hunks only
529
+ npx mcp-server-diff -b "..." -t "..." -o json # Full JSON with details
530
+ npx mcp-server-diff -b "..." -t "..." -o markdown # Formatted report
531
+ npx mcp-server-diff -b "..." -t "..." -o summary # One-line summary (default)
532
+ ```
533
+
534
+ ### HTTP Headers & Authentication
535
+
536
+ For authenticated HTTP endpoints, pass headers with `-H` (target) or `--base-header`:
537
+
538
+ ```bash
539
+ # Direct header value for target
540
+ npx mcp-server-diff -b "./server" -t "https://api.example.com/mcp" \
541
+ -H "Authorization: Bearer your-token-here"
542
+
543
+ # Read from environment variable (keeps secrets out of shell history)
544
+ export MCP_TOKEN="your-secret-token"
545
+ npx mcp-server-diff -b "./server" -t "https://api.example.com/mcp" \
546
+ -H "Authorization: Bearer env:MCP_TOKEN"
547
+
548
+ # Prompt for secret interactively (hidden input, named "token")
549
+ npx mcp-server-diff -b "./server" -t "https://api.example.com/mcp" \
550
+ -H "Authorization: Bearer secret:token"
551
+
552
+ # Headers for both sides (e.g., comparing two authenticated servers)
553
+ npx mcp-server-diff \
554
+ -b "https://api.example.com/v1/mcp" --base-header "Authorization: Bearer secret:v1token" \
555
+ -t "https://api.example.com/v2/mcp" -H "Authorization: Bearer secret:v2token"
556
+ ```
557
+
558
+ ### Config File
559
+
560
+ For complex comparisons or multiple targets, use a config file:
561
+
562
+ ```bash
563
+ npx mcp-server-diff -c servers.json -o diff
564
+ ```
565
+
566
+ ```json
567
+ {
568
+ "base": {
569
+ "name": "python-server",
570
+ "transport": "stdio",
571
+ "start_command": "python -m mcp_server"
572
+ },
573
+ "targets": [
574
+ {
575
+ "name": "typescript-server",
576
+ "transport": "stdio",
577
+ "start_command": "node dist/stdio.js"
578
+ },
579
+ {
580
+ "name": "remote-server",
581
+ "transport": "streamable-http",
582
+ "server_url": "https://mcp.example.com/api",
583
+ "headers": {
584
+ "Authorization": "Bearer token"
585
+ }
586
+ }
587
+ ]
588
+ }
589
+ ```
590
+
591
+ ### CLI Options Reference
592
+
593
+ | Option | Description |
594
+ |--------|-------------|
595
+ | `-b, --base <cmd\|url>` | Base server command (stdio) or URL (http) |
596
+ | `-t, --target <cmd\|url>` | Target server command (stdio) or URL (http) |
597
+ | `-H, --header <header>` | HTTP header for target (repeatable) |
598
+ | `--base-header <header>` | HTTP header for base server (repeatable) |
599
+ | `--target-header <header>` | HTTP header for target (same as `-H`) |
600
+ | `-c, --config <file>` | Config file with base and targets |
601
+ | `-o, --output <format>` | Output: `diff`, `json`, `markdown`, `summary` (default) |
602
+ | `-v, --verbose` | Verbose output |
603
+ | `-q, --quiet` | Quiet mode (only output result) |
604
+ | `-h, --help` | Show help |
605
+ | `--version` | Show version |
606
+
607
+ **Header value patterns:**
608
+ - `Bearer your-token` — literal value
609
+ - `Bearer env:VAR_NAME` — read from environment variable
610
+ - `Bearer secret:name` — prompt once for "name", reuse if used multiple times
611
+
612
+ ---
613
+
499
614
  ## License
500
615
 
501
616
  MIT License. See [LICENSE](LICENSE) for details.
package/dist/cli/index.js CHANGED
@@ -38918,6 +38918,8 @@ var __webpack_exports__ = {};
38918
38918
  var external_node_util_ = __nccwpck_require__(7975);
38919
38919
  // EXTERNAL MODULE: external "fs"
38920
38920
  var external_fs_ = __nccwpck_require__(9896);
38921
+ ;// CONCATENATED MODULE: external "readline"
38922
+ const external_readline_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("readline");
38921
38923
  ;// CONCATENATED MODULE: ./node_modules/zod/v4/core/core.js
38922
38924
  /** A special constant with type `never` */
38923
38925
  const NEVER = Object.freeze({
@@ -56353,6 +56355,13 @@ const log = {
56353
56355
 
56354
56356
 
56355
56357
 
56358
+ /**
56359
+ * Check if an error is "Method not found" (-32601)
56360
+ */
56361
+ function isMethodNotFound(error) {
56362
+ const errorStr = String(error);
56363
+ return errorStr.includes("-32601") || errorStr.includes("Method not found");
56364
+ }
56356
56365
  /**
56357
56366
  * Probes an MCP server and returns capability snapshots
56358
56367
  */
@@ -56425,7 +56434,12 @@ async function probeServer(options) {
56425
56434
  log.info(` Listed ${result.tools.tools.length} tools`);
56426
56435
  }
56427
56436
  catch (error) {
56428
- log.warning(` Failed to list tools: ${error}`);
56437
+ if (isMethodNotFound(error)) {
56438
+ log.info(" Server does not implement tools/list");
56439
+ }
56440
+ else {
56441
+ log.warning(` Failed to list tools: ${error}`);
56442
+ }
56429
56443
  }
56430
56444
  }
56431
56445
  else {
@@ -56439,7 +56453,12 @@ async function probeServer(options) {
56439
56453
  log.info(` Listed ${result.prompts.prompts.length} prompts`);
56440
56454
  }
56441
56455
  catch (error) {
56442
- log.warning(` Failed to list prompts: ${error}`);
56456
+ if (isMethodNotFound(error)) {
56457
+ log.info(" Server does not implement prompts/list");
56458
+ }
56459
+ else {
56460
+ log.warning(` Failed to list prompts: ${error}`);
56461
+ }
56443
56462
  }
56444
56463
  }
56445
56464
  else {
@@ -56453,16 +56472,26 @@ async function probeServer(options) {
56453
56472
  log.info(` Listed ${result.resources.resources.length} resources`);
56454
56473
  }
56455
56474
  catch (error) {
56456
- log.warning(` Failed to list resources: ${error}`);
56475
+ if (isMethodNotFound(error)) {
56476
+ log.info(" Server does not implement resources/list");
56477
+ }
56478
+ else {
56479
+ log.warning(` Failed to list resources: ${error}`);
56480
+ }
56457
56481
  }
56458
- // Also get resource templates
56482
+ // Also try resource templates - some servers support resources but not templates
56459
56483
  try {
56460
56484
  const templatesResult = await client.listResourceTemplates();
56461
56485
  result.resourceTemplates = templatesResult;
56462
56486
  log.info(` Listed ${result.resourceTemplates.resourceTemplates.length} resource templates`);
56463
56487
  }
56464
56488
  catch (error) {
56465
- log.warning(` Failed to list resource templates: ${error}`);
56489
+ if (isMethodNotFound(error)) {
56490
+ log.info(" Server does not implement resources/templates/list");
56491
+ }
56492
+ else {
56493
+ log.warning(` Failed to list resource templates: ${error}`);
56494
+ }
56466
56495
  }
56467
56496
  }
56468
56497
  else {
@@ -56831,6 +56860,7 @@ function diffsToMap(diffs) {
56831
56860
 
56832
56861
 
56833
56862
 
56863
+
56834
56864
  /**
56835
56865
  * Parse command line arguments
56836
56866
  */
@@ -56839,6 +56869,9 @@ function parseCliArgs() {
56839
56869
  options: {
56840
56870
  base: { type: "string", short: "b" },
56841
56871
  target: { type: "string", short: "t" },
56872
+ header: { type: "string", short: "H", multiple: true },
56873
+ "base-header": { type: "string", multiple: true },
56874
+ "target-header": { type: "string", multiple: true },
56842
56875
  config: { type: "string", short: "c" },
56843
56876
  output: { type: "string", short: "o", default: "summary" },
56844
56877
  verbose: { type: "boolean", short: "v", default: false },
@@ -56864,14 +56897,18 @@ USAGE:
56864
56897
  mcp-server-diff --config servers.json
56865
56898
 
56866
56899
  OPTIONS:
56867
- -b, --base <command> Base server command (stdio) or URL (http)
56868
- -t, --target <command> Target server command (stdio) or URL (http)
56869
- -c, --config <file> Config file with base and targets
56870
- -o, --output <format> Output format: json, markdown, summary (default: summary)
56871
- -v, --verbose Verbose output
56872
- -q, --quiet Quiet mode (only output diffs)
56873
- -h, --help Show this help
56874
- --version Show version
56900
+ -b, --base <command> Base server command (stdio) or URL (http)
56901
+ -t, --target <command> Target server command (stdio) or URL (http)
56902
+ -H, --header <header> HTTP header for target (repeatable)
56903
+ --base-header <header> HTTP header for base server (repeatable)
56904
+ --target-header <hdr> HTTP header for target server (repeatable, same as -H)
56905
+ Values support: env:VAR_NAME, secret:name, "Bearer secret:token"
56906
+ -c, --config <file> Config file with base and targets
56907
+ -o, --output <format> Output format: diff, json, markdown, summary (default: summary)
56908
+ -v, --verbose Verbose output
56909
+ -q, --quiet Quiet mode (only output diffs)
56910
+ -h, --help Show this help
56911
+ --version Show version
56875
56912
 
56876
56913
  CONFIG FILE FORMAT:
56877
56914
  {
@@ -56890,6 +56927,7 @@ CONFIG FILE FORMAT:
56890
56927
  }
56891
56928
 
56892
56929
  OUTPUT FORMATS:
56930
+ diff - Raw diff output only
56893
56931
  summary - One line per comparison (default)
56894
56932
  json - Raw JSON with full diff details
56895
56933
  markdown - Formatted markdown report
@@ -56906,6 +56944,18 @@ EXAMPLES:
56906
56944
 
56907
56945
  # Output raw JSON for CI
56908
56946
  mcp-server-diff -c servers.json -o json -q
56947
+
56948
+ # Compare with HTTP headers (for authenticated endpoints)
56949
+ mcp-server-diff -b "go run ./cmd/server stdio" -t "https://api.example.com/mcp" \\
56950
+ -H "Authorization: Bearer token" -o diff
56951
+
56952
+ # Use environment variable for secret (keeps token out of shell history)
56953
+ mcp-server-diff -b "./server" -t "https://api.example.com/mcp" \\
56954
+ -H "Authorization: env:MY_API_TOKEN"
56955
+
56956
+ # Prompt for secret interactively (hidden input)
56957
+ mcp-server-diff -b "./server" -t "https://api.example.com/mcp" \\
56958
+ -H "Authorization: secret:"
56909
56959
  `);
56910
56960
  }
56911
56961
  /**
@@ -56925,12 +56975,13 @@ function loadConfig(configPath) {
56925
56975
  /**
56926
56976
  * Create a server config from a command string
56927
56977
  */
56928
- function commandToConfig(command, name) {
56978
+ function commandToConfig(command, name, headers) {
56929
56979
  if (command.startsWith("http://") || command.startsWith("https://")) {
56930
56980
  return {
56931
56981
  name,
56932
56982
  transport: "streamable-http",
56933
56983
  server_url: command,
56984
+ headers,
56934
56985
  };
56935
56986
  }
56936
56987
  return {
@@ -56939,6 +56990,132 @@ function commandToConfig(command, name) {
56939
56990
  start_command: command,
56940
56991
  };
56941
56992
  }
56993
+ /**
56994
+ * Parse header strings into a record
56995
+ * Accepts formats: "Header: value" or "Header=value"
56996
+ * Special value patterns:
56997
+ * env:VAR_NAME - reads from environment variable
56998
+ * secret:name - prompts for secret (name is the prompt label)
56999
+ * "Bearer secret:token" - prefix + secret (prompts for "token", prepends "Bearer ")
57000
+ */
57001
+ function parseHeaders(headerStrings, secretValues) {
57002
+ const headers = {};
57003
+ if (!headerStrings)
57004
+ return headers;
57005
+ for (const h of headerStrings) {
57006
+ const colonIdx = h.indexOf(":");
57007
+ const eqIdx = h.indexOf("=");
57008
+ const sepIdx = colonIdx > 0 ? colonIdx : eqIdx;
57009
+ if (sepIdx > 0) {
57010
+ const key = h.substring(0, sepIdx).trim();
57011
+ let value = h.substring(sepIdx + 1).trim();
57012
+ // Check for env: prefix to read from environment variable
57013
+ if (value.startsWith("env:")) {
57014
+ const envVar = value.substring(4);
57015
+ const envValue = process.env[envVar];
57016
+ if (!envValue) {
57017
+ throw new Error(`Environment variable ${envVar} not set (referenced in header ${key})`);
57018
+ }
57019
+ value = envValue;
57020
+ }
57021
+ else if (value.includes("secret:")) {
57022
+ // Replace secret:name with the prompted value
57023
+ const secretMatch = value.match(/secret:(\w+)/);
57024
+ if (secretMatch) {
57025
+ const secretName = secretMatch[1];
57026
+ if (secretValues?.has(secretName)) {
57027
+ value = value.replace(`secret:${secretName}`, secretValues.get(secretName));
57028
+ }
57029
+ else {
57030
+ throw new Error(`Secret value for "${secretName}" not collected`);
57031
+ }
57032
+ }
57033
+ }
57034
+ headers[key] = value;
57035
+ }
57036
+ }
57037
+ return headers;
57038
+ }
57039
+ /**
57040
+ * Find secrets that need prompts, returns array of {name, label} objects
57041
+ */
57042
+ function findSecrets(headerStrings) {
57043
+ const secrets = [];
57044
+ if (!headerStrings)
57045
+ return secrets;
57046
+ for (const h of headerStrings) {
57047
+ const secretMatch = h.match(/secret:(\w+)/);
57048
+ if (secretMatch) {
57049
+ const name = secretMatch[1];
57050
+ // Don't add duplicates
57051
+ if (!secrets.find((s) => s.name === name)) {
57052
+ secrets.push({ name, label: name });
57053
+ }
57054
+ }
57055
+ }
57056
+ return secrets;
57057
+ }
57058
+ /**
57059
+ * Prompt for a secret value with hidden input
57060
+ */
57061
+ async function promptSecret(prompt) {
57062
+ return new Promise((resolve) => {
57063
+ const rl = external_readline_namespaceObject.createInterface({
57064
+ input: process.stdin,
57065
+ output: process.stdout,
57066
+ });
57067
+ // Hide input by using raw mode if available
57068
+ if (process.stdin.isTTY) {
57069
+ process.stdout.write(`${prompt}: `);
57070
+ process.stdin.setRawMode(true);
57071
+ process.stdin.resume();
57072
+ let value = "";
57073
+ const onData = (char) => {
57074
+ const c = char.toString();
57075
+ if (c === "\n" || c === "\r") {
57076
+ process.stdin.setRawMode(false);
57077
+ process.stdin.removeListener("data", onData);
57078
+ rl.close();
57079
+ process.stdout.write("\n");
57080
+ resolve(value);
57081
+ }
57082
+ else if (c === "\u0003") {
57083
+ // Ctrl+C
57084
+ process.exit(1);
57085
+ }
57086
+ else if (c === "\u007F" || c === "\b") {
57087
+ // Backspace
57088
+ if (value.length > 0) {
57089
+ value = value.slice(0, -1);
57090
+ }
57091
+ }
57092
+ else {
57093
+ value += c;
57094
+ }
57095
+ };
57096
+ process.stdin.on("data", onData);
57097
+ }
57098
+ else {
57099
+ // Non-TTY: just read the line (won't be hidden)
57100
+ rl.question(`${prompt}: `, (answer) => {
57101
+ rl.close();
57102
+ resolve(answer);
57103
+ });
57104
+ }
57105
+ });
57106
+ }
57107
+ /**
57108
+ * Prompt for secret values with hidden input
57109
+ */
57110
+ async function promptSecrets(secrets) {
57111
+ const values = new Map();
57112
+ if (secrets.length === 0)
57113
+ return values;
57114
+ for (const { name, label } of secrets) {
57115
+ values.set(name, await promptSecret(`Enter ${label}`));
57116
+ }
57117
+ return values;
57118
+ }
56942
57119
  /**
56943
57120
  * Probe a server and return results
56944
57121
  */
@@ -57027,6 +57204,23 @@ async function runComparisons(config) {
57027
57204
  }
57028
57205
  return results;
57029
57206
  }
57207
+ /**
57208
+ * Output raw diff only
57209
+ */
57210
+ function outputDiff(results) {
57211
+ for (const result of results) {
57212
+ if (result.diffs.length > 0) {
57213
+ if (results.length > 1) {
57214
+ console.log(`# ${result.target}`);
57215
+ }
57216
+ for (const { endpoint, diff } of result.diffs) {
57217
+ console.log(`## ${endpoint}`);
57218
+ console.log(diff);
57219
+ console.log("");
57220
+ }
57221
+ }
57222
+ }
57223
+ }
57030
57224
  /**
57031
57225
  * Output results in summary format
57032
57226
  */
@@ -57133,7 +57327,7 @@ async function main() {
57133
57327
  process.exit(0);
57134
57328
  }
57135
57329
  if (values.version) {
57136
- console.log("mcp-server-diff v2.1.0");
57330
+ console.log("mcp-server-diff v2.1.1");
57137
57331
  process.exit(0);
57138
57332
  }
57139
57333
  // Set up logger - CLI uses console logger by default
@@ -57148,9 +57342,21 @@ async function main() {
57148
57342
  config = loadConfig(values.config);
57149
57343
  }
57150
57344
  else if (values.base && values.target) {
57345
+ // Combine -H and --target-header for target, use --base-header for base
57346
+ const baseHeaderStrings = values["base-header"];
57347
+ const targetHeaderStrings = [
57348
+ ...(values.header || []),
57349
+ ...(values["target-header"] || []),
57350
+ ];
57351
+ // Find all secrets needed from both header sets
57352
+ const allHeaderStrings = [...(baseHeaderStrings || []), ...targetHeaderStrings];
57353
+ const secrets = findSecrets(allHeaderStrings);
57354
+ const secretValues = await promptSecrets(secrets);
57355
+ const baseHeaders = parseHeaders(baseHeaderStrings, secretValues);
57356
+ const targetHeaders = parseHeaders(targetHeaderStrings.length > 0 ? targetHeaderStrings : undefined, secretValues);
57151
57357
  config = {
57152
- base: commandToConfig(values.base, "base"),
57153
- targets: [commandToConfig(values.target, "target")],
57358
+ base: commandToConfig(values.base, "base", baseHeaders),
57359
+ targets: [commandToConfig(values.target, "target", targetHeaders)],
57154
57360
  };
57155
57361
  }
57156
57362
  else {
@@ -57161,6 +57367,9 @@ async function main() {
57161
57367
  const results = await runComparisons(config);
57162
57368
  const outputFormat = values.output || "summary";
57163
57369
  switch (outputFormat) {
57370
+ case "diff":
57371
+ outputDiff(results);
57372
+ break;
57164
57373
  case "json":
57165
57374
  outputJson(results);
57166
57375
  break;
package/dist/index.js CHANGED
@@ -56605,6 +56605,13 @@ const log = {
56605
56605
 
56606
56606
 
56607
56607
 
56608
+ /**
56609
+ * Check if an error is "Method not found" (-32601)
56610
+ */
56611
+ function isMethodNotFound(error) {
56612
+ const errorStr = String(error);
56613
+ return errorStr.includes("-32601") || errorStr.includes("Method not found");
56614
+ }
56608
56615
  /**
56609
56616
  * Probes an MCP server and returns capability snapshots
56610
56617
  */
@@ -56677,7 +56684,12 @@ async function probeServer(options) {
56677
56684
  log.info(` Listed ${result.tools.tools.length} tools`);
56678
56685
  }
56679
56686
  catch (error) {
56680
- log.warning(` Failed to list tools: ${error}`);
56687
+ if (isMethodNotFound(error)) {
56688
+ log.info(" Server does not implement tools/list");
56689
+ }
56690
+ else {
56691
+ log.warning(` Failed to list tools: ${error}`);
56692
+ }
56681
56693
  }
56682
56694
  }
56683
56695
  else {
@@ -56691,7 +56703,12 @@ async function probeServer(options) {
56691
56703
  log.info(` Listed ${result.prompts.prompts.length} prompts`);
56692
56704
  }
56693
56705
  catch (error) {
56694
- log.warning(` Failed to list prompts: ${error}`);
56706
+ if (isMethodNotFound(error)) {
56707
+ log.info(" Server does not implement prompts/list");
56708
+ }
56709
+ else {
56710
+ log.warning(` Failed to list prompts: ${error}`);
56711
+ }
56695
56712
  }
56696
56713
  }
56697
56714
  else {
@@ -56705,16 +56722,26 @@ async function probeServer(options) {
56705
56722
  log.info(` Listed ${result.resources.resources.length} resources`);
56706
56723
  }
56707
56724
  catch (error) {
56708
- log.warning(` Failed to list resources: ${error}`);
56725
+ if (isMethodNotFound(error)) {
56726
+ log.info(" Server does not implement resources/list");
56727
+ }
56728
+ else {
56729
+ log.warning(` Failed to list resources: ${error}`);
56730
+ }
56709
56731
  }
56710
- // Also get resource templates
56732
+ // Also try resource templates - some servers support resources but not templates
56711
56733
  try {
56712
56734
  const templatesResult = await client.listResourceTemplates();
56713
56735
  result.resourceTemplates = templatesResult;
56714
56736
  log.info(` Listed ${result.resourceTemplates.resourceTemplates.length} resource templates`);
56715
56737
  }
56716
56738
  catch (error) {
56717
- log.warning(` Failed to list resource templates: ${error}`);
56739
+ if (isMethodNotFound(error)) {
56740
+ log.info(" Server does not implement resources/templates/list");
56741
+ }
56742
+ else {
56743
+ log.warning(` Failed to list resource templates: ${error}`);
56744
+ }
56718
56745
  }
56719
56746
  }
56720
56747
  else {
package/package.json CHANGED
@@ -1,11 +1,16 @@
1
1
  {
2
2
  "name": "mcp-server-diff",
3
- "version": "2.1.0",
3
+ "version": "2.1.6",
4
4
  "description": "Diff MCP server public interfaces - CLI tool and GitHub Action",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "mcp-server-diff": "dist/cli/index.js"
8
8
  },
9
+ "files": [
10
+ "dist/",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
9
14
  "type": "module",
10
15
  "scripts": {
11
16
  "build": "npm run build:action && npm run build:cli",
@@ -1,21 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "github-actions"
4
- directory: "/"
5
- schedule:
6
- interval: "weekly"
7
- commit-message:
8
- prefix: "ci"
9
- labels:
10
- - "dependencies"
11
- - "github-actions"
12
-
13
- - package-ecosystem: "npm"
14
- directory: "/probe"
15
- schedule:
16
- interval: "weekly"
17
- commit-message:
18
- prefix: "deps"
19
- labels:
20
- - "dependencies"
21
- - "javascript"
@@ -1,51 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- permissions:
10
- contents: read
11
-
12
- jobs:
13
- test:
14
- runs-on: ubuntu-latest
15
- strategy:
16
- matrix:
17
- node-version: [20, 22]
18
-
19
- steps:
20
- - name: Checkout
21
- uses: actions/checkout@v4
22
-
23
- - name: Setup Node.js ${{ matrix.node-version }}
24
- uses: actions/setup-node@v6
25
- with:
26
- node-version: ${{ matrix.node-version }}
27
- cache: 'npm'
28
-
29
- - name: Install dependencies
30
- run: npm ci
31
-
32
- - name: Type Check
33
- run: npm run typecheck
34
-
35
- - name: Lint
36
- run: npm run lint
37
-
38
- - name: Check Formatting
39
- run: npm run format:check
40
-
41
- - name: Run Tests
42
- run: npm test
43
-
44
- - name: Build
45
- run: npm run build
46
-
47
- - name: Verify dist is up to date
48
- if: matrix.node-version == 20
49
- run: |
50
- # Check if dist files are up to date
51
- git diff --exit-code dist/ || (echo "::error::dist/ is out of date. Run 'npm run build' and commit the changes." && exit 1)