codex-plugin-doctor 1.69.1 → 1.71.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 +675 -661
- package/dist/core/mcp-discovery.d.ts +19 -0
- package/dist/core/mcp-discovery.js +24 -5
- package/dist/core/mcp-stdio-tool-catalog.d.ts +31 -0
- package/dist/core/mcp-stdio-tool-catalog.js +595 -0
- package/dist/core/mcp-tool-catalog.d.ts +36 -4
- package/dist/core/mcp-tool-catalog.js +90 -69
- package/dist/core/output-contract.js +20 -0
- package/dist/core/runtime-probe.d.ts +3 -1
- package/dist/core/runtime-probe.js +2 -2
- package/dist/reporting/render-mcp-tool-catalog-report.js +7 -0
- package/dist/run-cli.d.ts +2 -0
- package/dist/run-cli.js +109 -28
- package/package.json +71 -71
|
@@ -26,4 +26,23 @@ export interface McpDiscoveryReport {
|
|
|
26
26
|
export declare function findMcpSseResponse(body: Buffer, requestId?: string): McpJsonObject | null;
|
|
27
27
|
export declare function parseMcpResponse(response: BoundedHttpResponse, requestId?: string): McpJsonObject | null;
|
|
28
28
|
export declare function discoverMcpCapabilities(response: BoundedHttpResponse, requestId?: string): McpJsonObject | null;
|
|
29
|
+
export declare function serializeMcpDiscoverRequest(requestId?: string): string;
|
|
30
|
+
export type McpDiscoverOutcome = {
|
|
31
|
+
kind: "discovered";
|
|
32
|
+
supportedVersions: string[];
|
|
33
|
+
capabilities: McpJsonObject;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "version-not-listed";
|
|
36
|
+
supportedVersions: string[];
|
|
37
|
+
} | {
|
|
38
|
+
kind: "version-unsupported";
|
|
39
|
+
supportedVersions: string[];
|
|
40
|
+
} | {
|
|
41
|
+
kind: "result-invalid";
|
|
42
|
+
} | {
|
|
43
|
+
kind: "envelope-invalid";
|
|
44
|
+
} | {
|
|
45
|
+
kind: "other-error";
|
|
46
|
+
};
|
|
47
|
+
export declare function classifyMcpDiscoverMessage(message: McpJsonObject, requestId?: string): McpDiscoverOutcome;
|
|
29
48
|
export declare function discoverMcpServer(rawUrl: string, options?: McpDiscoveryOptions): Promise<McpDiscoveryReport>;
|
|
@@ -102,6 +102,29 @@ export function discoverMcpCapabilities(response, requestId = REQUEST_ID) {
|
|
|
102
102
|
return null;
|
|
103
103
|
return result.supportedVersions.includes(REQUESTED_VERSION) ? capabilities : null;
|
|
104
104
|
}
|
|
105
|
+
export function serializeMcpDiscoverRequest(requestId = REQUEST_ID) {
|
|
106
|
+
return JSON.stringify({ jsonrpc: "2.0", id: requestId, method: "server/discover", params: { _meta: {
|
|
107
|
+
"io.modelcontextprotocol/protocolVersion": REQUESTED_VERSION,
|
|
108
|
+
"io.modelcontextprotocol/clientInfo": { name: "Codex Plugin Doctor", version: packageVersion },
|
|
109
|
+
"io.modelcontextprotocol/clientCapabilities": {}
|
|
110
|
+
} } });
|
|
111
|
+
}
|
|
112
|
+
// Classifies a transport-neutral server/discover reply. Only a valid result or a valid
|
|
113
|
+
// UnsupportedProtocolVersionError identifies a modern server; other errors do not.
|
|
114
|
+
export function classifyMcpDiscoverMessage(message, requestId = REQUEST_ID) {
|
|
115
|
+
if (!hasMatchingResponseEnvelope(message, requestId))
|
|
116
|
+
return { kind: "envelope-invalid" };
|
|
117
|
+
if (Object.hasOwn(message, "error")) {
|
|
118
|
+
const versions = unsupportedVersions(message.error);
|
|
119
|
+
return versions === null ? { kind: "other-error" } : { kind: "version-unsupported", supportedVersions: versions };
|
|
120
|
+
}
|
|
121
|
+
const result = message.result;
|
|
122
|
+
if (!validDiscoverResult(result))
|
|
123
|
+
return { kind: "result-invalid" };
|
|
124
|
+
return result.supportedVersions.includes(REQUESTED_VERSION)
|
|
125
|
+
? { kind: "discovered", supportedVersions: result.supportedVersions, capabilities: result.capabilities }
|
|
126
|
+
: { kind: "version-not-listed", supportedVersions: result.supportedVersions };
|
|
127
|
+
}
|
|
105
128
|
function failureReport(id, message) {
|
|
106
129
|
return report("failed", "fail", [finding(id, "fail", message, "The discovery response cannot safely establish modern MCP discovery support.", "Verify the endpoint returns a valid server/discover response for the requested protocol version.")]);
|
|
107
130
|
}
|
|
@@ -116,11 +139,7 @@ export async function discoverMcpServer(rawUrl, options = {}) {
|
|
|
116
139
|
return report("blocked", "skipped", [finding("plugin.discovery.url.invalid", "warn", "The MCP discovery endpoint is unsafe or unsupported.", "Unsafe endpoint URLs can bypass network controls or expose credentials.", "Use an absolute HTTP or HTTPS endpoint without credentials, query parameters, fragments, or IP literals.")]);
|
|
117
140
|
}
|
|
118
141
|
const request = options.request ?? requestBoundedHttp;
|
|
119
|
-
const body =
|
|
120
|
-
"io.modelcontextprotocol/protocolVersion": REQUESTED_VERSION,
|
|
121
|
-
"io.modelcontextprotocol/clientInfo": { name: "Codex Plugin Doctor", version: packageVersion },
|
|
122
|
-
"io.modelcontextprotocol/clientCapabilities": {}
|
|
123
|
-
} } });
|
|
142
|
+
const body = serializeMcpDiscoverRequest();
|
|
124
143
|
let response;
|
|
125
144
|
try {
|
|
126
145
|
response = await request(rawUrl, {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import type { RuntimeSandboxMode } from "../domain/types.js";
|
|
3
|
+
import { type McpToolCatalogSnapshot } from "./mcp-tool-catalog.js";
|
|
4
|
+
export interface McpStdioServer {
|
|
5
|
+
packageRoot: string;
|
|
6
|
+
command: string;
|
|
7
|
+
args: string[];
|
|
8
|
+
cwd: string;
|
|
9
|
+
source: "manifest" | "mcp-json";
|
|
10
|
+
}
|
|
11
|
+
export type McpStdioServerResolution = {
|
|
12
|
+
ok: true;
|
|
13
|
+
server: McpStdioServer;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
message: string;
|
|
17
|
+
};
|
|
18
|
+
export interface McpStdioToolCatalogOptions {
|
|
19
|
+
sandbox?: RuntimeSandboxMode;
|
|
20
|
+
now?: () => number;
|
|
21
|
+
spawnImpl?: typeof spawn;
|
|
22
|
+
removeContainerImpl?: (containerName: string) => Promise<boolean>;
|
|
23
|
+
timeouts?: {
|
|
24
|
+
startupMs?: number;
|
|
25
|
+
requestMs?: number;
|
|
26
|
+
totalMs?: number;
|
|
27
|
+
shutdownMs?: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveMcpStdioServer(targetPath: string, serverName: string): Promise<McpStdioServerResolution>;
|
|
31
|
+
export declare function captureStdioMcpToolCatalog(server: McpStdioServer, options?: McpStdioToolCatalogOptions): Promise<McpToolCatalogSnapshot>;
|