@minasoft/mcp-inspector-core 0.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/README.md +203 -0
- package/dist/core.d.ts +16 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +429 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# @minasoft/mcp-inspector-core
|
|
2
|
+
|
|
3
|
+
Framework-light client inspection core used by Mina Inspector and the `mmcp`
|
|
4
|
+
CLI. It builds MCP JSON-RPC requests, sends them to Streamable HTTP or legacy
|
|
5
|
+
SSE endpoints, and returns normalized evidence that a UI or CLI can render.
|
|
6
|
+
|
|
7
|
+
Use this package when you are building your own MCP debugger, health-check page,
|
|
8
|
+
developer tool, or CI verifier and do not want to copy protocol request code.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @minasoft/mcp-inspector-core
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires Node.js `>=20.11`.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { buildMcpRequest, inspectMcpTarget } from "@minasoft/mcp-inspector-core";
|
|
22
|
+
|
|
23
|
+
const payload = buildMcpRequest({
|
|
24
|
+
family: "resources",
|
|
25
|
+
action: "read",
|
|
26
|
+
uri: "mock://resources/server-status",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const result = await inspectMcpTarget({
|
|
30
|
+
url: "http://127.0.0.1:3100/mcp/none",
|
|
31
|
+
method: payload.method,
|
|
32
|
+
params: payload.params,
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The package has no Next.js, React, Prisma, or Mock Server dependency. Host apps
|
|
37
|
+
remain responsible for OAuth, token storage, permissions, routing, and any UI.
|
|
38
|
+
|
|
39
|
+
## Build MCP Requests
|
|
40
|
+
|
|
41
|
+
Tools:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
buildMcpRequest({ family: "tools", action: "list" });
|
|
45
|
+
|
|
46
|
+
buildMcpRequest({
|
|
47
|
+
family: "tools",
|
|
48
|
+
action: "call",
|
|
49
|
+
name: "echo",
|
|
50
|
+
args: { message: "hello" },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Resources:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
buildMcpRequest({ family: "resources", action: "list" });
|
|
58
|
+
|
|
59
|
+
buildMcpRequest({
|
|
60
|
+
family: "resources",
|
|
61
|
+
action: "read",
|
|
62
|
+
uri: "mock://resources/server-status",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
buildMcpRequest({ family: "resources", action: "templates" });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prompts:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
buildMcpRequest({ family: "prompts", action: "list" });
|
|
72
|
+
|
|
73
|
+
buildMcpRequest({
|
|
74
|
+
family: "prompts",
|
|
75
|
+
action: "get",
|
|
76
|
+
name: "support_reply",
|
|
77
|
+
args: { tone: "friendly" },
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Completion:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
buildMcpRequest({
|
|
85
|
+
family: "completion",
|
|
86
|
+
action: "prompt",
|
|
87
|
+
name: "support_reply",
|
|
88
|
+
argument: { name: "tone", value: "fr" },
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
buildMcpRequest({
|
|
92
|
+
family: "completion",
|
|
93
|
+
action: "resource",
|
|
94
|
+
uri: "mock://resources/customers/{customerId}",
|
|
95
|
+
argument: { name: "customerId", value: "cus" },
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Raw JSON-RPC method:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
buildMcpRequest({
|
|
103
|
+
family: "raw",
|
|
104
|
+
action: "raw",
|
|
105
|
+
method: "resources/list",
|
|
106
|
+
params: {},
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Inspect A Target
|
|
111
|
+
|
|
112
|
+
Streamable HTTP-style POST is the default:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const result = await inspectMcpTarget({
|
|
116
|
+
url: "https://mcp.example.com/mcp",
|
|
117
|
+
method: "tools/list",
|
|
118
|
+
protocolVersion: "2025-06-18",
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (!result.ok) {
|
|
122
|
+
console.error(result.summary);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Legacy SSE:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
await inspectMcpTarget({
|
|
130
|
+
url: "https://mcp.example.com/sse",
|
|
131
|
+
transport: "sse",
|
|
132
|
+
method: "resources/list",
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Bearer auth:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
await inspectMcpTarget({
|
|
140
|
+
url: "https://mcp.example.com/mcp",
|
|
141
|
+
method: "prompts/list",
|
|
142
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Basic auth helper:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { createAuthorizationHeaders } from "@minasoft/mcp-inspector-core";
|
|
150
|
+
|
|
151
|
+
await inspectMcpTarget({
|
|
152
|
+
url: "http://127.0.0.1:3100/mcp/basic",
|
|
153
|
+
method: "tools/list",
|
|
154
|
+
headers: createAuthorizationHeaders({ basic: "default:default" }),
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Evidence Shape
|
|
159
|
+
|
|
160
|
+
`inspectMcpTarget()` returns:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
{
|
|
164
|
+
ok: boolean,
|
|
165
|
+
targetUrl: string,
|
|
166
|
+
transport: "http" | "sse",
|
|
167
|
+
steps: [
|
|
168
|
+
{
|
|
169
|
+
name: "MCP initialize",
|
|
170
|
+
status: "pass",
|
|
171
|
+
request: { url, headers, body },
|
|
172
|
+
response: { status, ok, elapsedMs, headers, body }
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
diagnostics: [["method", "tools/list"]],
|
|
176
|
+
summary: { pass: 2, warn: 0, skip: 0, fail: 0 }
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Sensitive request headers such as `Authorization`, `Cookie`, `token`, `secret`,
|
|
181
|
+
and `api-key` are redacted in evidence.
|
|
182
|
+
|
|
183
|
+
## Scope
|
|
184
|
+
|
|
185
|
+
Included:
|
|
186
|
+
|
|
187
|
+
- JSON-RPC payload builders for tools, resources, prompts, completion, and raw calls
|
|
188
|
+
- Streamable HTTP-style POST inspection
|
|
189
|
+
- legacy SSE endpoint/message inspection
|
|
190
|
+
- Basic/Bearer/raw header helpers
|
|
191
|
+
- response/evidence normalization
|
|
192
|
+
- protocol-version header support
|
|
193
|
+
|
|
194
|
+
Not included:
|
|
195
|
+
|
|
196
|
+
- OAuth popup UI
|
|
197
|
+
- token storage
|
|
198
|
+
- rate limiting
|
|
199
|
+
- app permission checks
|
|
200
|
+
- Mock Server admin APIs
|
|
201
|
+
- Prisma, Next.js, React, or browser UI
|
|
202
|
+
|
|
203
|
+
For a ready-to-use CLI built on this core, use `@minasoft/mmcp-cli`.
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AuthorizationOptions, BuildMcpRequestOptions, InspectMcpTargetOptions, InspectionResult, JsonObject } from "./types.js";
|
|
2
|
+
type JsonRpcPayload = {
|
|
3
|
+
jsonrpc: "2.0";
|
|
4
|
+
id?: string | number | null;
|
|
5
|
+
method: string;
|
|
6
|
+
params?: JsonObject;
|
|
7
|
+
};
|
|
8
|
+
export declare function parseJsonObject(value: string | undefined, label?: string): JsonObject;
|
|
9
|
+
export declare function parseKeyValueArgs(values?: string[]): JsonObject;
|
|
10
|
+
export declare function parseHeaderLines(values?: string[]): Record<string, string>;
|
|
11
|
+
export declare function createAuthorizationHeaders(options?: AuthorizationOptions): Record<string, string>;
|
|
12
|
+
export declare function redactHeaders(headers?: Record<string, string>): Record<string, string>;
|
|
13
|
+
export declare function buildMcpRequest(options: BuildMcpRequestOptions): JsonRpcPayload;
|
|
14
|
+
export declare function inspectMcpTarget(options: InspectMcpTargetOptions): Promise<InspectionResult>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAEtB,uBAAuB,EACvB,gBAAgB,EAEhB,UAAU,EAEX,MAAM,YAAY,CAAC;AAKpB,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,SAAe,GAAG,UAAU,CAO3F;AAED,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAM,EAAO,GAAG,UAAU,CAanE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,MAAM,EAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU9E;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAerG;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO1F;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAqE/E;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4FlG"}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { request as httpRequest } from "node:http";
|
|
2
|
+
import { request as httpsRequest } from "node:https";
|
|
3
|
+
import { performance } from "node:perf_hooks";
|
|
4
|
+
import { Buffer } from "node:buffer";
|
|
5
|
+
const DEFAULT_PROTOCOL_VERSION = "2025-06-18";
|
|
6
|
+
export function parseJsonObject(value, label = "JSON value") {
|
|
7
|
+
if (!value || !value.trim())
|
|
8
|
+
return {};
|
|
9
|
+
const parsed = JSON.parse(value);
|
|
10
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
11
|
+
throw new Error(`${label} must be a JSON object.`);
|
|
12
|
+
}
|
|
13
|
+
return parsed;
|
|
14
|
+
}
|
|
15
|
+
export function parseKeyValueArgs(values = []) {
|
|
16
|
+
const parsed = {};
|
|
17
|
+
for (const value of values) {
|
|
18
|
+
const separator = value.indexOf("=");
|
|
19
|
+
if (separator <= 0) {
|
|
20
|
+
throw new Error(`Argument must use key=value syntax: ${value}`);
|
|
21
|
+
}
|
|
22
|
+
const key = value.slice(0, separator).trim();
|
|
23
|
+
const rawValue = value.slice(separator + 1);
|
|
24
|
+
if (!key)
|
|
25
|
+
throw new Error(`Argument key is empty: ${value}`);
|
|
26
|
+
parsed[key] = parseScalar(rawValue);
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
export function parseHeaderLines(values = []) {
|
|
31
|
+
const parsed = {};
|
|
32
|
+
for (const value of values) {
|
|
33
|
+
const separator = value.indexOf(":");
|
|
34
|
+
if (separator <= 0) {
|
|
35
|
+
throw new Error(`Header must use "Name: Value" syntax: ${value}`);
|
|
36
|
+
}
|
|
37
|
+
parsed[value.slice(0, separator).trim()] = value.slice(separator + 1).trim();
|
|
38
|
+
}
|
|
39
|
+
return parsed;
|
|
40
|
+
}
|
|
41
|
+
export function createAuthorizationHeaders(options = {}) {
|
|
42
|
+
const headers = normalizeHeaderInput(options.headers);
|
|
43
|
+
if (options.basic && options.bearer) {
|
|
44
|
+
throw new Error("Use either Basic auth or Bearer auth, not both.");
|
|
45
|
+
}
|
|
46
|
+
if (options.basic) {
|
|
47
|
+
const credentials = typeof options.basic === "string"
|
|
48
|
+
? options.basic
|
|
49
|
+
: `${options.basic.username}:${options.basic.password}`;
|
|
50
|
+
headers.Authorization = `Basic ${Buffer.from(credentials, "utf8").toString("base64")}`;
|
|
51
|
+
}
|
|
52
|
+
if (options.bearer) {
|
|
53
|
+
headers.Authorization = `Bearer ${options.bearer}`;
|
|
54
|
+
}
|
|
55
|
+
return headers;
|
|
56
|
+
}
|
|
57
|
+
export function redactHeaders(headers = {}) {
|
|
58
|
+
return Object.fromEntries(Object.entries(headers).map(([key, value]) => [
|
|
59
|
+
key,
|
|
60
|
+
/authorization|cookie|token|secret|api[-_]?key/i.test(key) ? "<redacted>" : value,
|
|
61
|
+
]));
|
|
62
|
+
}
|
|
63
|
+
export function buildMcpRequest(options) {
|
|
64
|
+
const id = options.id ?? `mmcp-${options.family}-${options.action}`;
|
|
65
|
+
if (options.family === "raw") {
|
|
66
|
+
if (!options.method)
|
|
67
|
+
throw new Error("raw commands require method.");
|
|
68
|
+
return {
|
|
69
|
+
jsonrpc: "2.0",
|
|
70
|
+
id,
|
|
71
|
+
method: options.method,
|
|
72
|
+
...(options.params && Object.keys(options.params).length ? { params: options.params } : {}),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (options.family === "tools" && options.action === "list") {
|
|
76
|
+
return { jsonrpc: "2.0", id, method: "tools/list" };
|
|
77
|
+
}
|
|
78
|
+
if (options.family === "tools" && options.action === "call") {
|
|
79
|
+
if (!options.name)
|
|
80
|
+
throw new Error("tools call requires --name.");
|
|
81
|
+
return {
|
|
82
|
+
jsonrpc: "2.0",
|
|
83
|
+
id,
|
|
84
|
+
method: "tools/call",
|
|
85
|
+
params: { name: options.name, arguments: options.args ?? {} },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (options.family === "resources" && options.action === "list") {
|
|
89
|
+
return { jsonrpc: "2.0", id, method: "resources/list" };
|
|
90
|
+
}
|
|
91
|
+
if (options.family === "resources" && options.action === "read") {
|
|
92
|
+
if (!options.uri)
|
|
93
|
+
throw new Error("resources read requires --uri.");
|
|
94
|
+
return { jsonrpc: "2.0", id, method: "resources/read", params: { uri: options.uri } };
|
|
95
|
+
}
|
|
96
|
+
if (options.family === "resources" && options.action === "templates") {
|
|
97
|
+
return { jsonrpc: "2.0", id, method: "resources/templates/list" };
|
|
98
|
+
}
|
|
99
|
+
if (options.family === "prompts" && options.action === "list") {
|
|
100
|
+
return { jsonrpc: "2.0", id, method: "prompts/list" };
|
|
101
|
+
}
|
|
102
|
+
if (options.family === "prompts" && options.action === "get") {
|
|
103
|
+
if (!options.name)
|
|
104
|
+
throw new Error("prompts get requires --name.");
|
|
105
|
+
return {
|
|
106
|
+
jsonrpc: "2.0",
|
|
107
|
+
id,
|
|
108
|
+
method: "prompts/get",
|
|
109
|
+
params: { name: options.name, arguments: options.args ?? {} },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (options.family === "completion" && (options.action === "prompt" || options.action === "resource")) {
|
|
113
|
+
if (!options.argument?.name)
|
|
114
|
+
throw new Error("completion requires --argument name=value.");
|
|
115
|
+
if (options.action === "prompt" && !options.name) {
|
|
116
|
+
throw new Error("completion prompt requires --name.");
|
|
117
|
+
}
|
|
118
|
+
if (options.action === "resource" && !options.uri) {
|
|
119
|
+
throw new Error("completion resource requires --uri.");
|
|
120
|
+
}
|
|
121
|
+
const ref = options.action === "prompt"
|
|
122
|
+
? { type: "ref/prompt", name: options.name }
|
|
123
|
+
: { type: "ref/resource", uri: options.uri };
|
|
124
|
+
return {
|
|
125
|
+
jsonrpc: "2.0",
|
|
126
|
+
id,
|
|
127
|
+
method: "completion/complete",
|
|
128
|
+
params: { ref, argument: options.argument },
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
throw new Error(`Unsupported MCP command: ${options.family} ${options.action}`);
|
|
132
|
+
}
|
|
133
|
+
export async function inspectMcpTarget(options) {
|
|
134
|
+
const targetUrl = normalizeTargetUrl(options.url);
|
|
135
|
+
const transport = options.transport ?? "http";
|
|
136
|
+
const protocolVersion = options.protocolVersion ?? DEFAULT_PROTOCOL_VERSION;
|
|
137
|
+
const headers = {
|
|
138
|
+
"content-type": "application/json",
|
|
139
|
+
accept: "application/json, text/event-stream",
|
|
140
|
+
...normalizeHeaderInput(options.headers),
|
|
141
|
+
};
|
|
142
|
+
const protocolHeaders = { ...headers, "MCP-Protocol-Version": protocolVersion };
|
|
143
|
+
const steps = [];
|
|
144
|
+
const diagnostics = [
|
|
145
|
+
["transport", transport],
|
|
146
|
+
["tls verification", options.insecureTls ? "self-signed allowed" : "default"],
|
|
147
|
+
];
|
|
148
|
+
const sender = transport === "sse"
|
|
149
|
+
? await createSseSender(targetUrl, headers, Boolean(options.insecureTls))
|
|
150
|
+
: null;
|
|
151
|
+
const send = async (payload, requestHeaders) => {
|
|
152
|
+
if (sender)
|
|
153
|
+
return sender.send(payload, requestHeaders);
|
|
154
|
+
return postJson(targetUrl, payload, requestHeaders, Boolean(options.insecureTls));
|
|
155
|
+
};
|
|
156
|
+
if (options.initialize !== false) {
|
|
157
|
+
const initializePayload = {
|
|
158
|
+
jsonrpc: "2.0",
|
|
159
|
+
id: "inspector-initialize",
|
|
160
|
+
method: "initialize",
|
|
161
|
+
params: {
|
|
162
|
+
protocolVersion,
|
|
163
|
+
capabilities: {},
|
|
164
|
+
clientInfo: options.clientInfo ?? { name: "mina-mcp-inspector-core", version: "0.1.0" },
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
const initialize = await send(initializePayload, headers);
|
|
168
|
+
steps.push(makeStep("MCP initialize", initialize.ok ? "pass" : "fail", {
|
|
169
|
+
request: { url: targetUrl, headers: redactHeaders(headers), body: initializePayload },
|
|
170
|
+
response: initialize,
|
|
171
|
+
}));
|
|
172
|
+
diagnostics.push(["initialize status", initialize.status]);
|
|
173
|
+
diagnostics.push([
|
|
174
|
+
"negotiated protocol",
|
|
175
|
+
String(readPath(initialize.body, ["result", "protocolVersion"])
|
|
176
|
+
?? initialize.headers["mcp-protocol-version"]
|
|
177
|
+
?? "not reported"),
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
180
|
+
const payload = {
|
|
181
|
+
jsonrpc: "2.0",
|
|
182
|
+
id: `inspector-${options.method.replaceAll("/", "-")}`,
|
|
183
|
+
method: options.method,
|
|
184
|
+
...(options.params && Object.keys(options.params).length ? { params: options.params } : {}),
|
|
185
|
+
};
|
|
186
|
+
const methodResult = await send(payload, protocolHeaders);
|
|
187
|
+
const hasResultOrJsonRpcError = Boolean(readPath(methodResult.body, ["result"]) !== undefined || readPath(methodResult.body, ["error"]) !== undefined);
|
|
188
|
+
steps.push(makeStep(`MCP ${options.method}`, methodResult.ok && hasResultOrJsonRpcError ? "pass" : "fail", {
|
|
189
|
+
request: { url: targetUrl, headers: redactHeaders(protocolHeaders), body: payload },
|
|
190
|
+
response: methodResult,
|
|
191
|
+
}));
|
|
192
|
+
diagnostics.push(["method", options.method]);
|
|
193
|
+
diagnostics.push(["response protocol header", methodResult.headers["mcp-protocol-version"] ?? "not reported"]);
|
|
194
|
+
if (options.includeProtocolProbe) {
|
|
195
|
+
const badVersionPayload = buildMcpRequest({ family: "tools", action: "list", id: "inspector-bad-version" });
|
|
196
|
+
const badVersionHeaders = { ...headers, "MCP-Protocol-Version": "1900-01-01" };
|
|
197
|
+
const badVersion = await send(badVersionPayload, badVersionHeaders);
|
|
198
|
+
const status = badVersion.status >= 400 ? "pass" : "warn";
|
|
199
|
+
steps.push(makeStep("Unsupported protocol-version probe", status, {
|
|
200
|
+
request: { url: targetUrl, headers: redactHeaders(badVersionHeaders), body: badVersionPayload },
|
|
201
|
+
response: badVersion,
|
|
202
|
+
evidence: status === "pass"
|
|
203
|
+
? "Target rejects an intentionally unsupported protocol version."
|
|
204
|
+
: "Target accepted the unsupported probe; this may be allowed by that server.",
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
sender?.close();
|
|
208
|
+
return summarize({
|
|
209
|
+
ok: steps.every((step) => step.status !== "fail"),
|
|
210
|
+
targetUrl,
|
|
211
|
+
transport,
|
|
212
|
+
steps,
|
|
213
|
+
diagnostics,
|
|
214
|
+
result: methodResult.body,
|
|
215
|
+
raw: methodResult,
|
|
216
|
+
summary: { pass: 0, warn: 0, skip: 0, fail: 0 },
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function normalizeHeaderInput(input) {
|
|
220
|
+
if (!input)
|
|
221
|
+
return {};
|
|
222
|
+
if (Array.isArray(input))
|
|
223
|
+
return parseHeaderLines(input);
|
|
224
|
+
return Object.fromEntries(Object.entries(input).map(([key, value]) => [key, String(value)]));
|
|
225
|
+
}
|
|
226
|
+
function parseScalar(value) {
|
|
227
|
+
if (value === "true")
|
|
228
|
+
return true;
|
|
229
|
+
if (value === "false")
|
|
230
|
+
return false;
|
|
231
|
+
if (value === "null")
|
|
232
|
+
return null;
|
|
233
|
+
if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(value))
|
|
234
|
+
return Number(value);
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
function normalizeTargetUrl(value) {
|
|
238
|
+
const targetUrl = String(value ?? "").trim();
|
|
239
|
+
if (!targetUrl)
|
|
240
|
+
throw new Error("MCP endpoint URL is required.");
|
|
241
|
+
const url = new URL(targetUrl);
|
|
242
|
+
if (!["http:", "https:"].includes(url.protocol)) {
|
|
243
|
+
throw new Error("MCP endpoint URL must be http or https.");
|
|
244
|
+
}
|
|
245
|
+
return url.toString();
|
|
246
|
+
}
|
|
247
|
+
function makeStep(name, status, data) {
|
|
248
|
+
return { name, status, ...data };
|
|
249
|
+
}
|
|
250
|
+
function summarize(result) {
|
|
251
|
+
const summary = {
|
|
252
|
+
pass: result.steps.filter((step) => step.status === "pass").length,
|
|
253
|
+
warn: result.steps.filter((step) => step.status === "warn").length,
|
|
254
|
+
skip: result.steps.filter((step) => step.status === "skip").length,
|
|
255
|
+
fail: result.steps.filter((step) => step.status === "fail").length,
|
|
256
|
+
};
|
|
257
|
+
return { ...result, ok: summary.fail === 0, summary };
|
|
258
|
+
}
|
|
259
|
+
function readPath(value, path) {
|
|
260
|
+
let current = value;
|
|
261
|
+
for (const key of path) {
|
|
262
|
+
if (!current || typeof current !== "object" || !(key in current))
|
|
263
|
+
return undefined;
|
|
264
|
+
current = current[key];
|
|
265
|
+
}
|
|
266
|
+
return current;
|
|
267
|
+
}
|
|
268
|
+
async function postJson(url, payload, headers, insecureTls) {
|
|
269
|
+
const startedAt = performance.now();
|
|
270
|
+
const response = insecureTls && url.startsWith("https:")
|
|
271
|
+
? await nodeRequest("POST", url, headers, JSON.stringify(payload), true)
|
|
272
|
+
: await fetch(url, { method: "POST", headers, body: JSON.stringify(payload) });
|
|
273
|
+
const elapsedMs = Math.round(performance.now() - startedAt);
|
|
274
|
+
const responseHeaders = Object.fromEntries(response.headers.entries());
|
|
275
|
+
const text = await response.text();
|
|
276
|
+
return {
|
|
277
|
+
status: response.status,
|
|
278
|
+
ok: response.ok,
|
|
279
|
+
elapsedMs,
|
|
280
|
+
headers: responseHeaders,
|
|
281
|
+
body: parseResponseBody(text, responseHeaders["content-type"] ?? ""),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function parseResponseBody(text, contentType) {
|
|
285
|
+
if (!text)
|
|
286
|
+
return "";
|
|
287
|
+
if (contentType.includes("application/json"))
|
|
288
|
+
return JSON.parse(text);
|
|
289
|
+
try {
|
|
290
|
+
return JSON.parse(text);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return text;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async function nodeRequest(method, url, headers, body, insecureTls) {
|
|
297
|
+
return new Promise((resolve, reject) => {
|
|
298
|
+
const parsed = new URL(url);
|
|
299
|
+
const transport = parsed.protocol === "https:" ? httpsRequest : httpRequest;
|
|
300
|
+
const request = transport({
|
|
301
|
+
method,
|
|
302
|
+
protocol: parsed.protocol,
|
|
303
|
+
hostname: parsed.hostname,
|
|
304
|
+
port: parsed.port,
|
|
305
|
+
path: `${parsed.pathname}${parsed.search}`,
|
|
306
|
+
headers,
|
|
307
|
+
rejectUnauthorized: insecureTls ? false : undefined,
|
|
308
|
+
}, (response) => {
|
|
309
|
+
const chunks = [];
|
|
310
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
311
|
+
response.on("end", () => {
|
|
312
|
+
const responseHeaders = new Headers();
|
|
313
|
+
for (const [key, value] of Object.entries(response.headers)) {
|
|
314
|
+
if (Array.isArray(value))
|
|
315
|
+
responseHeaders.set(key, value.join(", "));
|
|
316
|
+
else if (value !== undefined)
|
|
317
|
+
responseHeaders.set(key, value);
|
|
318
|
+
}
|
|
319
|
+
resolve(new Response(Buffer.concat(chunks), {
|
|
320
|
+
status: response.statusCode ?? 0,
|
|
321
|
+
headers: responseHeaders,
|
|
322
|
+
}));
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
request.on("error", reject);
|
|
326
|
+
if (body)
|
|
327
|
+
request.write(body);
|
|
328
|
+
request.end();
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
async function createSseSender(url, headers, insecureTls) {
|
|
332
|
+
if (insecureTls && url.startsWith("https:")) {
|
|
333
|
+
throw new Error("Legacy SSE with --insecure-tls is not supported by the inspector core yet.");
|
|
334
|
+
}
|
|
335
|
+
const response = await fetch(url, { method: "GET", headers: { ...headers, accept: "text/event-stream" } });
|
|
336
|
+
if (!response.ok || !response.body) {
|
|
337
|
+
throw new Error(`SSE connection failed with HTTP ${response.status}.`);
|
|
338
|
+
}
|
|
339
|
+
const reader = response.body.getReader();
|
|
340
|
+
const decoder = new TextDecoder();
|
|
341
|
+
let buffer = "";
|
|
342
|
+
let closed = false;
|
|
343
|
+
const readEvent = async (expectedEvent) => {
|
|
344
|
+
const deadline = Date.now() + 7000;
|
|
345
|
+
while (Date.now() < deadline) {
|
|
346
|
+
const event = takeEventFromBuffer();
|
|
347
|
+
if (event && (!expectedEvent || event.event === expectedEvent))
|
|
348
|
+
return event;
|
|
349
|
+
const remainingMs = Math.max(1, deadline - Date.now());
|
|
350
|
+
const chunk = await readWithTimeout(reader, remainingMs);
|
|
351
|
+
if (chunk.done)
|
|
352
|
+
break;
|
|
353
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
354
|
+
}
|
|
355
|
+
throw new Error(`Timed out waiting for SSE ${expectedEvent ?? "event"}.`);
|
|
356
|
+
};
|
|
357
|
+
const takeEventFromBuffer = () => {
|
|
358
|
+
const normalized = buffer.replaceAll("\r\n", "\n");
|
|
359
|
+
const boundary = normalized.indexOf("\n\n");
|
|
360
|
+
if (boundary < 0)
|
|
361
|
+
return null;
|
|
362
|
+
const rawEvent = normalized.slice(0, boundary);
|
|
363
|
+
buffer = normalized.slice(boundary + 2);
|
|
364
|
+
const lines = rawEvent.split("\n");
|
|
365
|
+
let event = "message";
|
|
366
|
+
const data = [];
|
|
367
|
+
for (const line of lines) {
|
|
368
|
+
if (line.startsWith("event:"))
|
|
369
|
+
event = line.slice(6).trim();
|
|
370
|
+
if (line.startsWith("data:"))
|
|
371
|
+
data.push(line.slice(5).trimStart());
|
|
372
|
+
}
|
|
373
|
+
return { event, data: data.join("\n") };
|
|
374
|
+
};
|
|
375
|
+
const endpoint = await readEvent("endpoint");
|
|
376
|
+
const messageUrl = new URL(endpoint.data, url).toString();
|
|
377
|
+
return {
|
|
378
|
+
async send(payload, requestHeaders) {
|
|
379
|
+
const startedAt = performance.now();
|
|
380
|
+
const post = await fetch(messageUrl, {
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: requestHeaders,
|
|
383
|
+
body: JSON.stringify(payload),
|
|
384
|
+
});
|
|
385
|
+
if (!post.ok) {
|
|
386
|
+
const elapsedMs = Math.round(performance.now() - startedAt);
|
|
387
|
+
const text = await post.text();
|
|
388
|
+
return {
|
|
389
|
+
status: post.status,
|
|
390
|
+
ok: false,
|
|
391
|
+
elapsedMs,
|
|
392
|
+
headers: Object.fromEntries(post.headers.entries()),
|
|
393
|
+
body: parseResponseBody(text, post.headers.get("content-type") ?? ""),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
const message = await readEvent("message");
|
|
397
|
+
const elapsedMs = Math.round(performance.now() - startedAt);
|
|
398
|
+
return {
|
|
399
|
+
status: post.status,
|
|
400
|
+
ok: post.ok,
|
|
401
|
+
elapsedMs,
|
|
402
|
+
headers: Object.fromEntries(post.headers.entries()),
|
|
403
|
+
body: parseResponseBody(message.data, "application/json"),
|
|
404
|
+
};
|
|
405
|
+
},
|
|
406
|
+
close() {
|
|
407
|
+
if (!closed) {
|
|
408
|
+
closed = true;
|
|
409
|
+
void reader.cancel();
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
async function readWithTimeout(reader, timeoutMs) {
|
|
415
|
+
let timeout;
|
|
416
|
+
try {
|
|
417
|
+
return await Promise.race([
|
|
418
|
+
reader.read(),
|
|
419
|
+
new Promise((_, reject) => {
|
|
420
|
+
timeout = setTimeout(() => reject(new Error("SSE read timeout.")), timeoutMs);
|
|
421
|
+
}),
|
|
422
|
+
]);
|
|
423
|
+
}
|
|
424
|
+
finally {
|
|
425
|
+
if (timeout)
|
|
426
|
+
clearTimeout(timeout);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { AuthorizationOptions, BuildMcpRequestOptions, HeaderInput, InspectMcpTargetOptions, InspectionResult, InspectionStep, JsonObject, JsonValue, McpTransport, } from "./types.js";
|
|
2
|
+
export { buildMcpRequest, createAuthorizationHeaders, inspectMcpTarget, parseHeaderLines, parseJsonObject, parseKeyValueArgs, redactHeaders, } from "./core.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,WAAW,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
2
|
+
[key: string]: JsonValue;
|
|
3
|
+
};
|
|
4
|
+
export type JsonObject = {
|
|
5
|
+
[key: string]: JsonValue;
|
|
6
|
+
};
|
|
7
|
+
export type McpTransport = "http" | "sse";
|
|
8
|
+
export type HeaderInput = Record<string, string> | string[];
|
|
9
|
+
export type AuthorizationOptions = {
|
|
10
|
+
headers?: HeaderInput;
|
|
11
|
+
basic?: string | {
|
|
12
|
+
username: string;
|
|
13
|
+
password: string;
|
|
14
|
+
};
|
|
15
|
+
bearer?: string;
|
|
16
|
+
};
|
|
17
|
+
export type BuildMcpRequestOptions = {
|
|
18
|
+
family: "tools" | "resources" | "prompts" | "completion" | "raw";
|
|
19
|
+
action: string;
|
|
20
|
+
id?: string | number | null;
|
|
21
|
+
name?: string;
|
|
22
|
+
uri?: string;
|
|
23
|
+
method?: string;
|
|
24
|
+
args?: JsonObject;
|
|
25
|
+
params?: JsonObject;
|
|
26
|
+
argument?: {
|
|
27
|
+
name: string;
|
|
28
|
+
value?: string;
|
|
29
|
+
};
|
|
30
|
+
refType?: "prompt" | "resource";
|
|
31
|
+
};
|
|
32
|
+
export type InspectionStep = {
|
|
33
|
+
name: string;
|
|
34
|
+
status: "pass" | "warn" | "fail" | "skip";
|
|
35
|
+
request?: {
|
|
36
|
+
url: string;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
body?: unknown;
|
|
39
|
+
};
|
|
40
|
+
response?: {
|
|
41
|
+
status: number;
|
|
42
|
+
ok: boolean;
|
|
43
|
+
elapsedMs: number;
|
|
44
|
+
headers: Record<string, string>;
|
|
45
|
+
body: unknown;
|
|
46
|
+
};
|
|
47
|
+
evidence?: string;
|
|
48
|
+
};
|
|
49
|
+
export type InspectionResult = {
|
|
50
|
+
ok: boolean;
|
|
51
|
+
targetUrl: string;
|
|
52
|
+
transport: McpTransport;
|
|
53
|
+
steps: InspectionStep[];
|
|
54
|
+
diagnostics: Array<[string, string | number | boolean]>;
|
|
55
|
+
result?: unknown;
|
|
56
|
+
raw?: unknown;
|
|
57
|
+
summary: {
|
|
58
|
+
pass: number;
|
|
59
|
+
warn: number;
|
|
60
|
+
skip: number;
|
|
61
|
+
fail: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export type InspectMcpTargetOptions = {
|
|
65
|
+
url: string;
|
|
66
|
+
transport?: McpTransport;
|
|
67
|
+
method: string;
|
|
68
|
+
params?: JsonObject;
|
|
69
|
+
headers?: HeaderInput;
|
|
70
|
+
protocolVersion?: string;
|
|
71
|
+
insecureTls?: boolean;
|
|
72
|
+
initialize?: boolean;
|
|
73
|
+
includeProtocolProbe?: boolean;
|
|
74
|
+
clientInfo?: {
|
|
75
|
+
name: string;
|
|
76
|
+
version: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@minasoft/mcp-inspector-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-light MCP inspector client core for Streamable HTTP and legacy SSE targets.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"homepage": "https://github.com/stevennana/mina-mock-mcpserver#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/stevennana/mina-mock-mcpserver.git",
|
|
11
|
+
"directory": "packages/mcp-inspector-core"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/stevennana/mina-mock-mcpserver/issues"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20.11"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"module": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"default": "./dist/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.json",
|
|
37
|
+
"test": "npm run build && node --import tsx --test --test-concurrency=1 \"test/**/*.test.ts\""
|
|
38
|
+
},
|
|
39
|
+
"sideEffects": false
|
|
40
|
+
}
|