@k08200/mcp-probe 1.6.0 → 1.10.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 (57) hide show
  1. package/README.md +120 -507
  2. package/dist/assertions.d.ts.map +1 -1
  3. package/dist/assertions.js +93 -0
  4. package/dist/assertions.js.map +1 -1
  5. package/dist/checker.d.ts.map +1 -1
  6. package/dist/checker.js +54 -56
  7. package/dist/checker.js.map +1 -1
  8. package/dist/cli.js +52 -10
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +30 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/doctor.d.ts +5 -0
  14. package/dist/doctor.d.ts.map +1 -1
  15. package/dist/doctor.js +258 -31
  16. package/dist/doctor.js.map +1 -1
  17. package/dist/exit-code.d.ts +3 -0
  18. package/dist/exit-code.d.ts.map +1 -0
  19. package/dist/exit-code.js +8 -0
  20. package/dist/exit-code.js.map +1 -0
  21. package/dist/init.d.ts.map +1 -1
  22. package/dist/init.js +1 -118
  23. package/dist/init.js.map +1 -1
  24. package/dist/issues.d.ts.map +1 -1
  25. package/dist/issues.js +33 -14
  26. package/dist/issues.js.map +1 -1
  27. package/dist/protocols/mcp-client.d.ts.map +1 -1
  28. package/dist/protocols/mcp-client.js +36 -17
  29. package/dist/protocols/mcp-client.js.map +1 -1
  30. package/dist/reporters/receipt.d.ts +16 -0
  31. package/dist/reporters/receipt.d.ts.map +1 -0
  32. package/dist/reporters/receipt.js +21 -0
  33. package/dist/reporters/receipt.js.map +1 -0
  34. package/dist/scaffold.d.ts +17 -0
  35. package/dist/scaffold.d.ts.map +1 -0
  36. package/dist/scaffold.js +152 -0
  37. package/dist/scaffold.js.map +1 -0
  38. package/dist/sidecar.d.ts +6 -0
  39. package/dist/sidecar.d.ts.map +1 -0
  40. package/dist/sidecar.js +79 -0
  41. package/dist/sidecar.js.map +1 -0
  42. package/dist/types.d.ts +8 -1
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/version.d.ts +2 -0
  45. package/dist/version.d.ts.map +1 -0
  46. package/dist/version.js +5 -0
  47. package/dist/version.js.map +1 -0
  48. package/examples/fixtures/stdio-mcp-server.js +68 -0
  49. package/examples/github-actions/fleet.yml +9 -1
  50. package/examples/github-actions/remote-server.yml +9 -1
  51. package/examples/github-actions/single-server.yml +9 -1
  52. package/examples/self-check.config.json +3 -1
  53. package/examples/self-check.strict.config.json +16 -0
  54. package/examples/self-check.strict.tools.json +49 -0
  55. package/package.json +1 -1
  56. package/schemas/mcp-probe.config.schema.json +15 -0
  57. package/schemas/mcp-probe.sidecar.schema.json +5 -1
@@ -0,0 +1,152 @@
1
+ export const CONFIG_SCHEMA_URL = 'https://raw.githubusercontent.com/k08200/mcp-probe/main/schemas/mcp-probe.config.schema.json';
2
+ export const SIDECAR_SCHEMA_URL = 'https://raw.githubusercontent.com/k08200/mcp-probe/main/schemas/mcp-probe.sidecar.schema.json';
3
+ export function json(value) {
4
+ return JSON.stringify(value, null, 2) + '\n';
5
+ }
6
+ export function serverNameFromTarget(target) {
7
+ const withoutProtocol = target.replace(/^https?:\/\//i, '');
8
+ const last = withoutProtocol.split('/').filter(Boolean).pop() ?? 'mcp-server';
9
+ return last
10
+ .replace(/^@/, '')
11
+ .replace(/[^a-zA-Z0-9_-]+/g, '-')
12
+ .replace(/^-+|-+$/g, '')
13
+ || 'mcp-server';
14
+ }
15
+ export function buildConfig(options) {
16
+ const server = {
17
+ name: options.name ?? serverNameFromTarget(options.target),
18
+ target: options.target,
19
+ probeTools: true,
20
+ toolsFile: options.toolsFile,
21
+ };
22
+ if (options.transport) {
23
+ server.transport = options.transport;
24
+ }
25
+ if (options.headerEnv) {
26
+ server.headers = {
27
+ Authorization: `Bearer \${${options.headerEnv}}`,
28
+ };
29
+ }
30
+ return {
31
+ $schema: CONFIG_SCHEMA_URL,
32
+ timeoutMs: 10000,
33
+ servers: [server],
34
+ };
35
+ }
36
+ function minimalInputFromSchema(schema) {
37
+ if (!schema || typeof schema !== 'object')
38
+ return {};
39
+ const typed = schema;
40
+ const properties = typed.properties;
41
+ if (!properties)
42
+ return {};
43
+ const required = typed.required ?? Object.keys(properties);
44
+ const input = {};
45
+ for (const key of required) {
46
+ const property = properties[key];
47
+ const type = Array.isArray(property?.type) ? property?.type[0] : property?.type;
48
+ switch (type) {
49
+ case 'string':
50
+ input[key] = '';
51
+ break;
52
+ case 'number':
53
+ case 'integer':
54
+ input[key] = 0;
55
+ break;
56
+ case 'boolean':
57
+ input[key] = false;
58
+ break;
59
+ case 'array':
60
+ input[key] = [];
61
+ break;
62
+ case 'object':
63
+ input[key] = {};
64
+ break;
65
+ default:
66
+ input[key] = null;
67
+ }
68
+ }
69
+ return input;
70
+ }
71
+ function sidecarEntryForTool(tool) {
72
+ return {
73
+ input: minimalInputFromSchema(tool.inputSchema),
74
+ expect: {
75
+ not_error_code: [401, 403],
76
+ },
77
+ };
78
+ }
79
+ export function buildToolsFile(discoveredTools) {
80
+ const tools = discoveredTools && discoveredTools.length > 0
81
+ ? Object.fromEntries(discoveredTools.map((tool) => [tool.name, sidecarEntryForTool(tool)]))
82
+ : {
83
+ replace_with_tool_name: {
84
+ input: {},
85
+ expect: {
86
+ not_error_code: [401, 403],
87
+ },
88
+ },
89
+ };
90
+ return {
91
+ $schema: SIDECAR_SCHEMA_URL,
92
+ tools,
93
+ };
94
+ }
95
+ export function buildToolsFileFromNames(toolNames) {
96
+ const unique = [...new Set(toolNames)].filter(Boolean);
97
+ const tools = unique.length > 0
98
+ ? Object.fromEntries(unique.map((name) => [
99
+ name,
100
+ {
101
+ input: {},
102
+ expect: {
103
+ not_error_code: [401, 403],
104
+ },
105
+ },
106
+ ]))
107
+ : {
108
+ replace_with_tool_name: {
109
+ input: {},
110
+ expect: {
111
+ not_error_code: [401, 403],
112
+ },
113
+ },
114
+ };
115
+ return {
116
+ $schema: SIDECAR_SCHEMA_URL,
117
+ tools,
118
+ };
119
+ }
120
+ export function buildWorkflow(configFile) {
121
+ return `name: MCP Probe
122
+
123
+ on:
124
+ pull_request:
125
+ push:
126
+ branches: [main]
127
+
128
+ jobs:
129
+ mcp-probe:
130
+ runs-on: ubuntu-latest
131
+ timeout-minutes: 5
132
+
133
+ steps:
134
+ - uses: actions/checkout@v6
135
+
136
+ - name: Validate MCP readiness
137
+ run: |
138
+ npx @k08200/mcp-probe@latest \\
139
+ --config ${configFile} \\
140
+ --github-summary \\
141
+ --fail-on-warn \\
142
+ --badge-file mcp-probe-badge.json \\
143
+ --receipt-file mcp-probe.receipt.json
144
+
145
+ - name: Upload MCP readiness receipt
146
+ uses: actions/upload-artifact@v4
147
+ with:
148
+ name: mcp-probe-receipt
149
+ path: mcp-probe.receipt.json
150
+ `;
151
+ }
152
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ToolSidecar } from './types.js';
2
+ export declare const DEFAULT_SIDECAR_FILENAME = ".mcp-probe.json";
3
+ export declare function parseToolSidecar(parsed: unknown, label: string): ToolSidecar;
4
+ export declare function readToolSidecar(path: string): ToolSidecar;
5
+ export declare function loadOptionalSidecar(toolsFile?: string): ToolSidecar | undefined;
6
+ //# sourceMappingURL=sidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAc1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAmD5E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAQzD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAO/E"}
@@ -0,0 +1,79 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ export const DEFAULT_SIDECAR_FILENAME = '.mcp-probe.json';
3
+ function isObject(value) {
4
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
5
+ }
6
+ function rejectUnknownKeys(value, allowed, label) {
7
+ const allowedSet = new Set(allowed);
8
+ const unknown = Object.keys(value).filter((key) => !allowedSet.has(key));
9
+ if (unknown.length > 0) {
10
+ throw new Error(`Invalid tools file: ${label} contains unknown field${unknown.length === 1 ? '' : 's'} ${unknown.join(', ')}`);
11
+ }
12
+ }
13
+ export function parseToolSidecar(parsed, label) {
14
+ if (!isObject(parsed)) {
15
+ throw new Error(`Invalid tools file: ${label} must be an object`);
16
+ }
17
+ rejectUnknownKeys(parsed, ['$schema', 'tools'], label);
18
+ if (!isObject(parsed.tools)) {
19
+ throw new Error(`Invalid tools file: ${label} must contain a tools object`);
20
+ }
21
+ for (const [toolName, entry] of Object.entries(parsed.tools)) {
22
+ if (!isObject(entry)) {
23
+ throw new Error(`Invalid tools file: ${toolName} entry must be an object`);
24
+ }
25
+ rejectUnknownKeys(entry, ['input', 'expect'], toolName);
26
+ if (!isObject(entry.input)) {
27
+ throw new Error(`Invalid tools file: ${toolName}.input must be an object`);
28
+ }
29
+ if (entry.expect !== undefined) {
30
+ if (!isObject(entry.expect)) {
31
+ throw new Error(`Invalid tools file: ${toolName}.expect must be an object`);
32
+ }
33
+ const expect = entry.expect;
34
+ rejectUnknownKeys(expect, ['status', 'not_error_code', 'requiredFields', 'maxRows', 'errorCode', 'contains', 'notContains', 'jsonSchema'], `${toolName}.expect`);
35
+ if (expect.status !== undefined && expect.status !== 'pass' && expect.status !== 'fail' && expect.status !== 'warn') {
36
+ throw new Error(`Invalid tools file: ${toolName}.expect.status must be pass, fail, or warn`);
37
+ }
38
+ if (expect.not_error_code !== undefined && (!Array.isArray(expect.not_error_code) || !expect.not_error_code.every((code) => Number.isInteger(code)))) {
39
+ throw new Error(`Invalid tools file: ${toolName}.expect.not_error_code must be an integer array`);
40
+ }
41
+ for (const key of ['requiredFields', 'contains', 'notContains']) {
42
+ const value = expect[key];
43
+ if (value !== undefined && (!Array.isArray(value) || !value.every((item) => typeof item === 'string'))) {
44
+ throw new Error(`Invalid tools file: ${toolName}.expect.${key} must be a string array`);
45
+ }
46
+ }
47
+ if (expect.maxRows !== undefined && (typeof expect.maxRows !== 'number' || expect.maxRows < 0)) {
48
+ throw new Error(`Invalid tools file: ${toolName}.expect.maxRows must be a non-negative number`);
49
+ }
50
+ if (expect.errorCode !== undefined && typeof expect.errorCode !== 'string') {
51
+ throw new Error(`Invalid tools file: ${toolName}.expect.errorCode must be a string`);
52
+ }
53
+ if (expect.jsonSchema !== undefined && !isObject(expect.jsonSchema)) {
54
+ throw new Error(`Invalid tools file: ${toolName}.expect.jsonSchema must be an object`);
55
+ }
56
+ }
57
+ }
58
+ return parsed;
59
+ }
60
+ export function readToolSidecar(path) {
61
+ let parsed;
62
+ try {
63
+ parsed = JSON.parse(readFileSync(path, 'utf8'));
64
+ }
65
+ catch {
66
+ throw new Error(`Invalid tools file JSON: ${path}`);
67
+ }
68
+ return parseToolSidecar(parsed, path);
69
+ }
70
+ export function loadOptionalSidecar(toolsFile) {
71
+ const path = toolsFile ?? DEFAULT_SIDECAR_FILENAME;
72
+ if (!existsSync(path)) {
73
+ if (!toolsFile)
74
+ return undefined;
75
+ throw new Error(`Cannot read tools file: ${path}`);
76
+ }
77
+ return readToolSidecar(path);
78
+ }
79
+ //# sourceMappingURL=sidecar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type CheckStatus = 'pass' | 'fail' | 'warn';
2
- export type IssueCode = 'NO_TOOLS' | 'TOOL_SCHEMA_INVALID' | 'TOOL_CALL_AUTH' | 'TOOL_CALL_FAILED' | 'TOOL_CALL_TIMEOUT' | 'CONTRACT_ASSERTION_FAILED' | 'AUTO_DRY_RUN_INPUT' | 'SIDECAR_MISSING' | 'SIDECAR_INVALID' | 'HANDSHAKE_TIMEOUT' | 'HANDSHAKE_AUTH' | 'HANDSHAKE_FAILED' | 'TARGET_NOT_FOUND';
2
+ export type IssueCode = 'NO_TOOLS' | 'TOOL_SCHEMA_INVALID' | 'TOOL_CATALOG_MISMATCH' | 'TOOL_DRY_RUN_COVERAGE_MISSING' | 'TOOL_CALL_AUTH' | 'TOOL_CALL_FAILED' | 'TOOL_CALL_TIMEOUT' | 'CONTRACT_ASSERTION_FAILED' | 'AUTO_DRY_RUN_INPUT' | 'SIDECAR_MISSING' | 'SIDECAR_INVALID' | 'HANDSHAKE_TIMEOUT' | 'HANDSHAKE_AUTH' | 'HANDSHAKE_FAILED' | 'TARGET_NOT_FOUND';
3
3
  export type Issue = {
4
4
  code: IssueCode;
5
5
  hint: string;
@@ -40,6 +40,7 @@ export type ToolExpectations = {
40
40
  errorCode?: string;
41
41
  contains?: string[];
42
42
  notContains?: string[];
43
+ jsonSchema?: Record<string, unknown>;
43
44
  };
44
45
  export type ToolSidecarEntry = {
45
46
  input: Record<string, unknown>;
@@ -83,6 +84,9 @@ export type CheckOptions = {
83
84
  transport?: TransportMode;
84
85
  headers?: Record<string, string>;
85
86
  stderr?: StderrRules;
87
+ expectedTools?: string[];
88
+ allowedTools?: string[];
89
+ forbiddenTools?: string[];
86
90
  probeTools?: boolean;
87
91
  toolsFile?: string;
88
92
  };
@@ -94,6 +98,9 @@ export type ConfigServer = {
94
98
  transport?: TransportMode;
95
99
  headers?: Record<string, string>;
96
100
  stderr?: StderrRules;
101
+ expectedTools?: string[];
102
+ allowedTools?: string[];
103
+ forbiddenTools?: string[];
97
104
  probeTools?: boolean;
98
105
  toolsFile?: string;
99
106
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,QAA0E,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { createRequire } from 'module';
2
+ const require = createRequire(import.meta.url);
3
+ const packageJson = require('../package.json');
4
+ export const VERSION = typeof packageJson.version === 'string' ? packageJson.version : '0.0.0';
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAA0B,CAAC;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { z } from 'zod';
4
+
5
+ const server = new McpServer({ name: 'fixture-server', version: '1.0.0' });
6
+
7
+ server.registerTool(
8
+ 'echo',
9
+ {
10
+ description: 'Echoes a message',
11
+ inputSchema: { message: z.string() },
12
+ },
13
+ async ({ message }) => ({
14
+ content: [{ type: 'text', text: message }],
15
+ })
16
+ );
17
+
18
+ server.registerTool(
19
+ 'auth_check',
20
+ {
21
+ description: 'Simulates a browser auth failure',
22
+ inputSchema: { query: z.string() },
23
+ },
24
+ async () => ({
25
+ isError: true,
26
+ content: [{ type: 'text', text: '401 Unauthorized: browser auth required' }],
27
+ })
28
+ );
29
+
30
+ server.registerTool(
31
+ 'db_query',
32
+ {
33
+ description: 'Simulates a read-only database query result',
34
+ inputSchema: { sql: z.string() },
35
+ },
36
+ async () => ({
37
+ content: [{
38
+ type: 'text',
39
+ text: JSON.stringify({
40
+ rowCount: 1,
41
+ limit: 100,
42
+ source: 'fixture-db',
43
+ freshness: '2026-05-24T00:00:00.000Z',
44
+ rows: [{ ok: 1 }],
45
+ }),
46
+ }],
47
+ })
48
+ );
49
+
50
+ server.registerTool(
51
+ 'db_write',
52
+ {
53
+ description: 'Simulates a denied database write',
54
+ inputSchema: { sql: z.string() },
55
+ },
56
+ async () => ({
57
+ isError: true,
58
+ content: [{
59
+ type: 'text',
60
+ text: JSON.stringify({
61
+ code: 'WRITE_NOT_ALLOWED',
62
+ message: 'Write operations are blocked for this role',
63
+ }),
64
+ }],
65
+ })
66
+ );
67
+
68
+ await server.connect(new StdioServerTransport());
@@ -22,4 +22,12 @@ jobs:
22
22
  npx @k08200/mcp-probe \
23
23
  --config mcp-probe.config.json \
24
24
  --github-summary \
25
- --badge-file mcp-probe-badge.json
25
+ --fail-on-warn \
26
+ --badge-file mcp-probe-badge.json \
27
+ --receipt-file mcp-probe.receipt.json
28
+
29
+ - name: Upload MCP readiness receipt
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: mcp-probe-receipt
33
+ path: mcp-probe.receipt.json
@@ -21,4 +21,12 @@ jobs:
21
21
  --header "Authorization: Bearer $MCP_TOKEN" \
22
22
  --tools-file .mcp-probe.json \
23
23
  --github-summary \
24
- --badge-file mcp-probe-badge.json
24
+ --fail-on-warn \
25
+ --badge-file mcp-probe-badge.json \
26
+ --receipt-file mcp-probe.receipt.json
27
+
28
+ - name: Upload MCP readiness receipt
29
+ uses: actions/upload-artifact@v4
30
+ with:
31
+ name: mcp-probe-receipt
32
+ path: mcp-probe.receipt.json
@@ -18,4 +18,12 @@ jobs:
18
18
  npx @k08200/mcp-probe @modelcontextprotocol/server-memory \
19
19
  --probe-tools \
20
20
  --github-summary \
21
- --badge-file mcp-probe-badge.json
21
+ --fail-on-warn \
22
+ --badge-file mcp-probe-badge.json \
23
+ --receipt-file mcp-probe.receipt.json
24
+
25
+ - name: Upload MCP readiness receipt
26
+ uses: actions/upload-artifact@v4
27
+ with:
28
+ name: mcp-probe-receipt
29
+ path: mcp-probe.receipt.json
@@ -3,7 +3,9 @@
3
3
  "servers": [
4
4
  {
5
5
  "name": "fixture-stdio",
6
- "target": "./tests/fixtures/stdio-mcp-server.js",
6
+ "target": "./fixtures/stdio-mcp-server.js",
7
+ "expectedTools": ["echo", "auth_check", "db_query", "db_write"],
8
+ "forbiddenTools": ["drop_database"],
7
9
  "toolsFile": "./self-check.tools.json",
8
10
  "stderr": {
9
11
  "allow": ["^Warning:", "missing optional config"],
@@ -0,0 +1,16 @@
1
+ {
2
+ "timeoutMs": 10000,
3
+ "servers": [
4
+ {
5
+ "name": "fixture-stdio-strict",
6
+ "target": "./fixtures/stdio-mcp-server.js",
7
+ "expectedTools": ["echo", "db_query", "db_write"],
8
+ "forbiddenTools": ["drop_database"],
9
+ "toolsFile": "./self-check.strict.tools.json",
10
+ "stderr": {
11
+ "allow": ["^Warning:", "missing optional config"],
12
+ "fatal": ["panic", "FATAL"]
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "tools": {
3
+ "echo": {
4
+ "input": {
5
+ "message": "mcp-probe strict self-check"
6
+ }
7
+ },
8
+ "db_query": {
9
+ "input": {
10
+ "sql": "select 1 as ok"
11
+ },
12
+ "expect": {
13
+ "status": "pass",
14
+ "requiredFields": ["rowCount", "limit", "source", "freshness"],
15
+ "maxRows": 100,
16
+ "jsonSchema": {
17
+ "type": "object",
18
+ "required": ["rowCount", "limit", "source", "freshness", "rows"],
19
+ "properties": {
20
+ "rowCount": { "type": "integer" },
21
+ "limit": { "type": "integer" },
22
+ "source": { "type": "string" },
23
+ "freshness": { "type": "string" },
24
+ "rows": {
25
+ "type": "array",
26
+ "items": {
27
+ "type": "object",
28
+ "required": ["ok"],
29
+ "properties": {
30
+ "ok": { "type": "integer" }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ },
38
+ "db_write": {
39
+ "input": {
40
+ "sql": "delete from users where id = 1"
41
+ },
42
+ "expect": {
43
+ "status": "fail",
44
+ "errorCode": "WRITE_NOT_ALLOWED",
45
+ "notContains": ["DATABASE_URL", "password", "stack"]
46
+ }
47
+ }
48
+ }
49
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k08200/mcp-probe",
3
- "version": "1.6.0",
3
+ "version": "1.10.0",
4
4
  "description": "Quality checker for MCP servers — validates protocol handshake, discovery, tool-call dry-runs, and latency",
5
5
  "type": "module",
6
6
  "bin": {
@@ -61,6 +61,21 @@
61
61
  }
62
62
  }
63
63
  },
64
+ "expectedTools": {
65
+ "type": "array",
66
+ "items": { "type": "string" },
67
+ "description": "Tool names that must be present in tools/list."
68
+ },
69
+ "allowedTools": {
70
+ "type": "array",
71
+ "items": { "type": "string" },
72
+ "description": "When set, every discovered tool must be listed here."
73
+ },
74
+ "forbiddenTools": {
75
+ "type": "array",
76
+ "items": { "type": "string" },
77
+ "description": "Tool names that must not be present in tools/list."
78
+ },
64
79
  "probeTools": {
65
80
  "type": "boolean"
66
81
  },
@@ -27,7 +27,7 @@
27
27
  "properties": {
28
28
  "not_error_code": {
29
29
  "type": "array",
30
- "items": { "type": "number" },
30
+ "items": { "type": "integer" },
31
31
  "description": "HTTP/status codes that should be treated as warnings instead of failures."
32
32
  },
33
33
  "status": {
@@ -58,6 +58,10 @@
58
58
  "type": "array",
59
59
  "items": { "type": "string" },
60
60
  "description": "Text snippets that must not appear in the result or error payload. Use this to catch leaked internals."
61
+ },
62
+ "jsonSchema": {
63
+ "type": "object",
64
+ "description": "JSON Schema subset applied to the observed tool result payload."
61
65
  }
62
66
  }
63
67
  }