@sriramadari/mcp-devkit 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/LICENSE +21 -0
- package/README.md +180 -0
- package/dist/chunk-EANYYOGZ.js +437 -0
- package/dist/chunk-EANYYOGZ.js.map +1 -0
- package/dist/cli.cjs +619 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +196 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +623 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +409 -0
- package/dist/index.d.ts +409 -0
- package/dist/index.js +181 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connect.ts","../src/schema.ts","../src/client.ts","../src/conformance.ts","../src/cli.ts"],"names":["Client","InMemoryTransport","StdioClientTransport","c","parseArgs"],"mappings":"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","file":"cli.cjs","sourcesContent":["/**\n * connect.ts — establish a live MCP client connection to a target.\n *\n * Two transports, one entry point:\n * - in-process (`InMemoryTransport.createLinkedPair`) for an `McpServer` you\n * constructed in the same test, and\n * - stdio (`StdioClientTransport`) for a server you launch as a child process.\n */\n\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport type { ConnectOptions, ConnectTarget } from \"./types\";\n\nexport interface Connection {\n client: Client;\n /** Tears down the client, the transport, and any spawned child process. */\n close: () => Promise<void>;\n}\n\nexport async function openConnection(\n target: ConnectTarget,\n options: ConnectOptions = {},\n): Promise<Connection> {\n const client = new Client({\n name: options.clientName ?? \"mcp-devkit\",\n version: options.clientVersion ?? \"0.1.0\",\n });\n\n if (\"server\" in target && target.server) {\n const server = typeof target.server === \"function\" ? await target.server() : target.server;\n const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();\n // Connect the server first so it's listening before the client handshakes.\n await server.connect(serverTransport);\n await client.connect(clientTransport);\n return {\n client,\n close: async () => {\n await client.close().catch(() => {});\n await server.close().catch(() => {});\n },\n };\n }\n\n if (\"command\" in target && target.command) {\n const transport = new StdioClientTransport({\n command: target.command,\n args: target.args ?? [],\n env: target.env,\n cwd: target.cwd,\n });\n await client.connect(transport);\n return {\n client,\n // Closing the client closes the transport, which terminates the child.\n close: async () => {\n await client.close().catch(() => {});\n },\n };\n }\n\n throw new Error(\"openConnection: target must provide either `server` or `command`\");\n}\n","/**\n * schema.ts — a tiny, dependency-free JSON Schema validator.\n *\n * This is NOT a spec-complete validator (use ajv for that). It covers the\n * subset MCP tool `inputSchema`s actually use in practice — types, required\n * properties, enums, nested objects/arrays, basic numeric/string bounds, and\n * the combinators — so a test can catch \"I'm calling this tool with the wrong\n * args\" before the call ever leaves the process.\n */\n\nimport type { JsonSchema, JsonSchemaType } from \"./types\";\n\nexport interface ValidationError {\n /** JSON-pointer-ish path to the offending value, e.g. `/items/0/name`. */\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\nconst TYPEOF: Record<string, JsonSchemaType> = {\n string: \"string\",\n number: \"number\",\n boolean: \"boolean\",\n};\n\nfunction typeOf(value: unknown): JsonSchemaType {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n return TYPEOF[t] ?? \"string\";\n}\n\nfunction matchesType(value: unknown, type: JsonSchemaType): boolean {\n switch (type) {\n case \"integer\":\n return typeof value === \"number\" && Number.isInteger(value);\n case \"number\":\n return typeof value === \"number\";\n case \"null\":\n return value === null;\n default:\n return typeOf(value) === type;\n }\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b || a === null || b === null) return false;\n if (typeof a !== \"object\") return false;\n const ka = Object.keys(a as object);\n const kb = Object.keys(b as object);\n if (ka.length !== kb.length) return false;\n return ka.every((k) =>\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n );\n}\n\n/**\n * Validate `value` against `schema`. Returns every error found, not just the\n * first — handy for surfacing all the problems with a tool call at once.\n */\nexport function validateAgainstSchema(value: unknown, schema: JsonSchema): ValidationResult {\n const errors: ValidationError[] = [];\n walk(value, schema, \"\", errors);\n return { valid: errors.length === 0, errors };\n}\n\nfunction walk(value: unknown, schema: JsonSchema, path: string, errors: ValidationError[]): void {\n if (!schema || typeof schema !== \"object\") return;\n\n // const / enum\n if (\"const\" in schema && !deepEqual(value, schema.const)) {\n errors.push({ path: path || \"/\", message: `must equal ${JSON.stringify(schema.const)}` });\n }\n if (schema.enum && !schema.enum.some((e) => deepEqual(e, value))) {\n errors.push({ path: path || \"/\", message: `must be one of ${JSON.stringify(schema.enum)}` });\n }\n\n // combinators\n if (schema.allOf) {\n for (const sub of schema.allOf) walk(value, sub, path, errors);\n }\n if (schema.anyOf && !schema.anyOf.some((sub) => validateAgainstSchema(value, sub).valid)) {\n errors.push({ path: path || \"/\", message: \"did not match any schema in anyOf\" });\n }\n if (schema.oneOf) {\n const hits = schema.oneOf.filter((sub) => validateAgainstSchema(value, sub).valid).length;\n if (hits !== 1) {\n errors.push({ path: path || \"/\", message: `must match exactly one schema in oneOf (matched ${hits})` });\n }\n }\n\n // type\n const types = schema.type === undefined ? [] : Array.isArray(schema.type) ? schema.type : [schema.type];\n if (types.length > 0 && !types.some((t) => matchesType(value, t))) {\n errors.push({ path: path || \"/\", message: `expected type ${types.join(\" | \")}, got ${typeOf(value)}` });\n return; // further checks would be noise once the type is wrong\n }\n\n const actual = typeOf(value);\n\n if (actual === \"string\" && typeof value === \"string\") {\n if (schema.minLength !== undefined && value.length < schema.minLength) {\n errors.push({ path: path || \"/\", message: `shorter than minLength ${schema.minLength}` });\n }\n if (schema.maxLength !== undefined && value.length > schema.maxLength) {\n errors.push({ path: path || \"/\", message: `longer than maxLength ${schema.maxLength}` });\n }\n }\n\n if (actual === \"number\" && typeof value === \"number\") {\n if (schema.minimum !== undefined && value < schema.minimum) {\n errors.push({ path: path || \"/\", message: `less than minimum ${schema.minimum}` });\n }\n if (schema.maximum !== undefined && value > schema.maximum) {\n errors.push({ path: path || \"/\", message: `greater than maximum ${schema.maximum}` });\n }\n }\n\n if (actual === \"object\" && value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n for (const key of schema.required ?? []) {\n if (!(key in obj)) {\n errors.push({ path: `${path}/${key}`, message: \"is required\" });\n }\n }\n if (schema.properties) {\n for (const [key, sub] of Object.entries(schema.properties)) {\n if (key in obj) walk(obj[key], sub, `${path}/${key}`, errors);\n }\n }\n if (schema.additionalProperties === false && schema.properties) {\n const allowed = new Set(Object.keys(schema.properties));\n for (const key of Object.keys(obj)) {\n if (!allowed.has(key)) {\n errors.push({ path: `${path}/${key}`, message: \"is not an allowed property\" });\n }\n }\n } else if (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n const declared = new Set(Object.keys(schema.properties ?? {}));\n for (const key of Object.keys(obj)) {\n if (!declared.has(key)) {\n walk(obj[key], schema.additionalProperties, `${path}/${key}`, errors);\n }\n }\n }\n }\n\n if (actual === \"array\" && Array.isArray(value)) {\n if (Array.isArray(schema.items)) {\n schema.items.forEach((sub, i) => {\n if (i < value.length) walk(value[i], sub, `${path}/${i}`, errors);\n });\n } else if (schema.items) {\n value.forEach((item, i) => walk(item, schema.items as JsonSchema, `${path}/${i}`, errors));\n }\n }\n}\n","/**\n * client.ts — the TestClient: an ergonomic wrapper over the raw SDK Client.\n *\n * Everything a test reaches for, with the protocol boilerplate removed:\n * - cached `tools()` / `resources()` / `prompts()` listings\n * - `hasTool()`, `tool()` lookups\n * - `call()` that optionally validates args against the tool's declared\n * `inputSchema` *before* sending, so a bad call fails loudly in your test\n * instead of silently in the server\n * - `readResource()` / `getPrompt()` passthroughs\n *\n * Construct one with `createTestClient(target, options)`.\n */\n\nimport type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { openConnection } from \"./connect\";\nimport { validateAgainstSchema } from \"./schema\";\nimport type {\n ConnectOptions,\n ConnectTarget,\n PromptInfo,\n ResourceInfo,\n ToolInfo,\n ToolResult,\n} from \"./types\";\n\nexport interface CallOptions {\n /**\n * Validate `args` against the tool's `inputSchema` before sending.\n * Default `true`. Throws a descriptive error if the args don't match.\n */\n validate?: boolean;\n /** Per-call timeout in ms (overrides the connection default). */\n timeoutMs?: number;\n}\n\nexport class TestClient {\n /** The underlying SDK client — escape hatch for anything not wrapped here. */\n readonly raw: Client;\n private readonly _close: () => Promise<void>;\n private readonly defaultTimeoutMs: number;\n\n private _tools?: ToolInfo[];\n private _resources?: ResourceInfo[];\n private _prompts?: PromptInfo[];\n\n /** @internal — use {@link createTestClient}. */\n constructor(raw: Client, close: () => Promise<void>, defaultTimeoutMs: number) {\n this.raw = raw;\n this._close = close;\n this.defaultTimeoutMs = defaultTimeoutMs;\n }\n\n // ── server identity / capabilities ─────────────────────────────────────────\n\n serverInfo(): { name: string; version: string } | undefined {\n return this.raw.getServerVersion() as { name: string; version: string } | undefined;\n }\n\n capabilities(): Record<string, unknown> | undefined {\n return this.raw.getServerCapabilities() as Record<string, unknown> | undefined;\n }\n\n // ── tools ───────────────────────────────────────────────────────────────────\n\n /** List the server's tools (cached after the first call — see {@link refresh}). */\n async tools(): Promise<ToolInfo[]> {\n if (!this._tools) {\n const res = await this.raw.listTools();\n this._tools = (res.tools ?? []) as ToolInfo[];\n }\n return this._tools;\n }\n\n async toolNames(): Promise<string[]> {\n return (await this.tools()).map((t) => t.name);\n }\n\n async hasTool(name: string): Promise<boolean> {\n return (await this.tools()).some((t) => t.name === name);\n }\n\n async tool(name: string): Promise<ToolInfo | undefined> {\n return (await this.tools()).find((t) => t.name === name);\n }\n\n /**\n * Call a tool. By default the args are validated against the tool's declared\n * `inputSchema` first; set `{ validate: false }` to send them as-is (e.g. to\n * test how the server handles bad input).\n */\n async call(\n name: string,\n args: Record<string, unknown> = {},\n options: CallOptions = {},\n ): Promise<ToolResult> {\n if (options.validate !== false) {\n const info = await this.tool(name);\n if (info?.inputSchema) {\n const { valid, errors } = validateAgainstSchema(args, info.inputSchema);\n if (!valid) {\n const detail = errors.map((e) => ` ${e.path} ${e.message}`).join(\"\\n\");\n throw new Error(`Arguments for tool \"${name}\" do not match its inputSchema:\\n${detail}`);\n }\n }\n }\n const result = await this.raw.callTool(\n { name, arguments: args },\n undefined,\n { timeout: options.timeoutMs ?? this.defaultTimeoutMs },\n );\n return result as ToolResult;\n }\n\n // ── resources ─────────────────────────────────────────────────────────────\n\n async resources(): Promise<ResourceInfo[]> {\n if (!this._resources) {\n try {\n const res = await this.raw.listResources();\n this._resources = (res.resources ?? []) as ResourceInfo[];\n } catch {\n this._resources = []; // server doesn't advertise the resources capability\n }\n }\n return this._resources;\n }\n\n async readResource(uri: string): Promise<{ contents: Array<{ uri: string; text?: string; blob?: string; mimeType?: string }> }> {\n return (await this.raw.readResource({ uri })) as {\n contents: Array<{ uri: string; text?: string; blob?: string; mimeType?: string }>;\n };\n }\n\n // ── prompts ───────────────────────────────────────────────────────────────\n\n async prompts(): Promise<PromptInfo[]> {\n if (!this._prompts) {\n try {\n const res = await this.raw.listPrompts();\n this._prompts = (res.prompts ?? []) as PromptInfo[];\n } catch {\n this._prompts = [];\n }\n }\n return this._prompts;\n }\n\n async getPrompt(name: string, args: Record<string, unknown> = {}): Promise<unknown> {\n return this.raw.getPrompt({ name, arguments: args as Record<string, string> });\n }\n\n // ── lifecycle ───────────────────────────────────────────────────────────────\n\n /** Drop cached listings so the next `tools()`/`resources()`/`prompts()` re-fetches. */\n refresh(): void {\n this._tools = undefined;\n this._resources = undefined;\n this._prompts = undefined;\n }\n\n /** Liveness check — resolves if the server answers a ping. */\n async ping(): Promise<void> {\n await this.raw.ping();\n }\n\n /** Tear down the connection (and any spawned child process). Idempotent. */\n async close(): Promise<void> {\n await this._close();\n }\n}\n\n/**\n * Open a connection to an MCP server and return a ready-to-use {@link TestClient}.\n *\n * @example In-process (your own server):\n * ```ts\n * const client = await createTestClient({ server: buildMyServer() });\n * const res = await client.call(\"search\", { q: \"mcp\" });\n * await client.close();\n * ```\n *\n * @example Over stdio (any server binary):\n * ```ts\n * const client = await createTestClient({ command: \"node\", args: [\"dist/server.js\"] });\n * ```\n */\nexport async function createTestClient(\n target: ConnectTarget,\n options: ConnectOptions = {},\n): Promise<TestClient> {\n const { client, close } = await openConnection(target, options);\n return new TestClient(client, close, options.timeoutMs ?? 10_000);\n}\n\n/**\n * Run `fn` with a connected client and guarantee it's closed afterwards, even\n * if the test throws. Returns whatever `fn` returns.\n *\n * @example\n * ```ts\n * await withTestClient({ server }, async (client) => {\n * expectToolResult(await client.call(\"ping\")).toSucceed();\n * });\n * ```\n */\nexport async function withTestClient<T>(\n target: ConnectTarget,\n fn: (client: TestClient) => Promise<T>,\n options: ConnectOptions = {},\n): Promise<T> {\n const client = await createTestClient(target, options);\n try {\n return await fn(client);\n } finally {\n await client.close();\n }\n}\n","/**\n * conformance.ts — an automated best-practices checker for MCP servers.\n *\n * Point it at a connected {@link TestClient} and it runs a battery of checks\n * that catch the mistakes that make a server hard for an LLM to use well or\n * brittle in production: missing tool descriptions, malformed input schemas,\n * duplicate or illegally-named tools, a server that crashes on an unknown\n * tool, missing server identity, and so on.\n *\n * Each check yields a {@link CheckResult}; the rolled-up {@link ConformanceReport}\n * tells you pass/fail at a glance and is what the CLI's `check` command prints.\n */\n\nimport type { TestClient } from \"./client\";\nimport type { ToolInfo } from \"./types\";\n\nexport type Severity = \"error\" | \"warning\" | \"info\";\nexport type CheckStatus = \"pass\" | \"fail\" | \"skip\";\n\nexport interface CheckResult {\n id: string;\n title: string;\n severity: Severity;\n status: CheckStatus;\n /** Present when status is `fail` or `skip` — why. */\n detail?: string;\n /** Per-item findings (e.g. which tools are missing a description). */\n findings?: string[];\n}\n\nexport interface ConformanceReport {\n ok: boolean;\n checks: CheckResult[];\n summary: { passed: number; failed: number; warnings: number; skipped: number };\n}\n\nexport interface ConformanceOptions {\n /** Check ids to skip entirely. */\n skip?: string[];\n /**\n * Whether to actually *call* a non-existent tool to verify graceful error\n * handling. Default `true`. Disable if your tools have side effects you'd\n * rather not risk (this only ever calls a random non-existent name, but the\n * escape hatch is here regardless).\n */\n probeUnknownTool?: boolean;\n}\n\n// MCP tool names: keep to a conservative, widely-accepted charset.\nconst TOOL_NAME_RE = /^[a-zA-Z0-9_-]{1,128}$/;\n\ntype Check = {\n id: string;\n title: string;\n severity: Severity;\n run: (ctx: { client: TestClient; tools: ToolInfo[]; options: ConformanceOptions }) => Promise<Omit<CheckResult, \"id\" | \"title\" | \"severity\">>;\n};\n\nconst CHECKS: Check[] = [\n {\n id: \"server-identity\",\n title: \"Server reports a name and version\",\n severity: \"warning\",\n run: async ({ client }) => {\n const info = client.serverInfo();\n if (info?.name && info?.version) return { status: \"pass\" };\n return { status: \"fail\", detail: `server info is ${JSON.stringify(info)}` };\n },\n },\n {\n id: \"tools-listable\",\n title: \"tools/list responds\",\n severity: \"error\",\n run: async ({ tools }) => {\n // If we got here, listing already succeeded (tools are pre-fetched).\n return { status: \"pass\", detail: `${tools.length} tool(s)` };\n },\n },\n {\n id: \"unique-tool-names\",\n title: \"Tool names are unique\",\n severity: \"error\",\n run: async ({ tools }) => {\n const seen = new Set<string>();\n const dupes = new Set<string>();\n for (const t of tools) {\n if (seen.has(t.name)) dupes.add(t.name);\n seen.add(t.name);\n }\n return dupes.size === 0\n ? { status: \"pass\" }\n : { status: \"fail\", detail: \"duplicate tool names\", findings: [...dupes] };\n },\n },\n {\n id: \"valid-tool-names\",\n title: \"Tool names use a safe charset and length\",\n severity: \"error\",\n run: async ({ tools }) => {\n const bad = tools.filter((t) => !TOOL_NAME_RE.test(t.name)).map((t) => t.name);\n return bad.length === 0\n ? { status: \"pass\" }\n : { status: \"fail\", detail: \"names must match /^[a-zA-Z0-9_-]{1,128}$/\", findings: bad };\n },\n },\n {\n id: \"tool-descriptions\",\n title: \"Every tool has a description\",\n severity: \"warning\",\n run: async ({ tools }) => {\n const missing = tools.filter((t) => !t.description || !t.description.trim()).map((t) => t.name);\n return missing.length === 0\n ? { status: \"pass\" }\n : { status: \"fail\", detail: \"an LLM picks tools by their description\", findings: missing };\n },\n },\n {\n id: \"description-quality\",\n title: \"Descriptions are substantive (≥ 12 chars)\",\n severity: \"info\",\n run: async ({ tools }) => {\n const thin = tools\n .filter((t) => t.description && t.description.trim().length > 0 && t.description.trim().length < 12)\n .map((t) => `${t.name} (\"${t.description!.trim()}\")`);\n return thin.length === 0\n ? { status: \"pass\" }\n : { status: \"fail\", detail: \"very short descriptions hurt tool selection\", findings: thin };\n },\n },\n {\n id: \"tool-input-schema\",\n title: \"Every tool declares an object inputSchema\",\n severity: \"warning\",\n run: async ({ tools }) => {\n const bad = tools\n .filter((t) => {\n const s = t.inputSchema;\n return !s || typeof s !== \"object\" || s.type !== \"object\";\n })\n .map((t) => t.name);\n return bad.length === 0\n ? { status: \"pass\" }\n : { status: \"fail\", detail: 'inputSchema should be a JSON Schema with type:\"object\"', findings: bad };\n },\n },\n {\n id: \"required-props-exist\",\n title: \"Every `required` entry names a declared property\",\n severity: \"error\",\n run: async ({ tools }) => {\n const findings: string[] = [];\n for (const t of tools) {\n const s = t.inputSchema;\n if (!s?.required || !s.properties) continue;\n const props = new Set(Object.keys(s.properties));\n for (const r of s.required) {\n if (!props.has(r)) findings.push(`${t.name}: required \"${r}\" has no matching property`);\n }\n }\n return findings.length === 0 ? { status: \"pass\" } : { status: \"fail\", findings };\n },\n },\n {\n id: \"unknown-tool-handled\",\n title: \"Calling an unknown tool fails gracefully (no crash/hang)\",\n severity: \"error\",\n run: async ({ client, options }) => {\n if (options.probeUnknownTool === false) {\n return { status: \"skip\", detail: \"probeUnknownTool disabled\" };\n }\n const phantom = \"__mcp_devkit_nonexistent_tool__\";\n try {\n const res = await client.call(phantom, {}, { validate: false, timeoutMs: 5_000 });\n // Either a protocol error (caught below) or an isError result is fine —\n // both are graceful. A *successful* result for a tool that doesn't exist\n // is the bug.\n return res.isError === true\n ? { status: \"pass\", detail: \"returned isError result\" }\n : { status: \"fail\", detail: \"server returned a success result for a non-existent tool\" };\n } catch {\n // A thrown JSON-RPC error is the expected, graceful outcome.\n return { status: \"pass\", detail: \"rejected with a protocol error\" };\n }\n },\n },\n];\n\n/** Run the full conformance battery against a connected client. */\nexport async function conformanceCheck(\n client: TestClient,\n options: ConformanceOptions = {},\n): Promise<ConformanceReport> {\n const skip = new Set(options.skip ?? []);\n const tools = await client.tools();\n const checks: CheckResult[] = [];\n\n for (const check of CHECKS) {\n if (skip.has(check.id)) {\n checks.push({ id: check.id, title: check.title, severity: check.severity, status: \"skip\", detail: \"skipped by caller\" });\n continue;\n }\n try {\n const outcome = await check.run({ client, tools, options });\n checks.push({ id: check.id, title: check.title, severity: check.severity, ...outcome });\n } catch (e) {\n checks.push({\n id: check.id,\n title: check.title,\n severity: check.severity,\n status: \"fail\",\n detail: `check threw: ${(e as Error).message}`,\n });\n }\n }\n\n const summary = {\n passed: checks.filter((c) => c.status === \"pass\").length,\n failed: checks.filter((c) => c.status === \"fail\").length,\n warnings: checks.filter((c) => c.status === \"fail\" && c.severity === \"warning\").length,\n skipped: checks.filter((c) => c.status === \"skip\").length,\n };\n // The server is \"ok\" only if no *error*-severity check failed.\n const ok = !checks.some((c) => c.status === \"fail\" && c.severity === \"error\");\n\n return { ok, checks, summary };\n}\n\n/** The list of checks the kit runs, for documentation/UIs. */\nexport function listChecks(): Array<{ id: string; title: string; severity: Severity }> {\n return CHECKS.map((c) => ({ id: c.id, title: c.title, severity: c.severity }));\n}\n","#!/usr/bin/env node\n/**\n * cli.ts — `mcp-devkit` command-line entry point.\n *\n * Drives a stdio MCP server (launched as a child process) for three jobs you\n * don't want to write a script for:\n *\n * mcp-devkit inspect -- <command...> dump tools / resources / prompts\n * mcp-devkit check -- <command...> run the conformance battery\n * mcp-devkit call --tool NAME [--args JSON] -- <command...> invoke one tool\n *\n * Everything after `--` is the server command, e.g.\n * mcp-devkit inspect -- node dist/server.js\n * mcp-devkit check -- npx -y @some/mcp-server\n */\n\nimport { parseArgs } from \"node:util\";\nimport { createTestClient } from \"./client\";\nimport { conformanceCheck } from \"./conformance\";\nimport type { CheckResult } from \"./conformance\";\n\n// ── tiny ANSI helpers (respect NO_COLOR) ─────────────────────────────────────\nconst useColor = process.stdout.isTTY && !process.env.NO_COLOR;\nconst c = {\n dim: (s: string) => (useColor ? `\\x1b[2m${s}\\x1b[0m` : s),\n bold: (s: string) => (useColor ? `\\x1b[1m${s}\\x1b[0m` : s),\n green: (s: string) => (useColor ? `\\x1b[32m${s}\\x1b[0m` : s),\n yellow: (s: string) => (useColor ? `\\x1b[33m${s}\\x1b[0m` : s),\n red: (s: string) => (useColor ? `\\x1b[31m${s}\\x1b[0m` : s),\n cyan: (s: string) => (useColor ? `\\x1b[36m${s}\\x1b[0m` : s),\n};\n\nconst USAGE = `${c.bold(\"mcp-devkit\")} — testing & inspection toolkit for MCP servers\n\n${c.bold(\"Usage:\")}\n mcp-devkit inspect -- <command...>\n mcp-devkit check -- <command...>\n mcp-devkit call --tool <name> [--args <json>] [--no-validate] -- <command...>\n\n${c.bold(\"Examples:\")}\n mcp-devkit inspect -- node dist/server.js\n mcp-devkit check -- npx -y @modelcontextprotocol/server-everything\n mcp-devkit call --tool search --args '{\"q\":\"mcp\"}' -- node dist/server.js\n\n${c.bold(\"Options:\")}\n --tool <name> tool to call (call command)\n --args <json> JSON arguments object for the tool (default {})\n --no-validate skip client-side inputSchema validation on call\n --json machine-readable JSON output (inspect / check)\n --timeout <ms> per-request timeout (default 15000)\n -h, --help show this help\n\nEverything after ${c.bold(\"--\")} is the MCP server command to launch over stdio.\n`;\n\n/** Split argv into [devkit flags, server command] around the first `--`. */\nfunction splitOnDoubleDash(argv: string[]): { flags: string[]; command: string[] } {\n const i = argv.indexOf(\"--\");\n if (i === -1) return { flags: argv, command: [] };\n return { flags: argv.slice(0, i), command: argv.slice(i + 1) };\n}\n\nasync function main(): Promise<number> {\n const rawArgv = process.argv.slice(2);\n const sub = rawArgv[0];\n\n if (!sub || sub === \"-h\" || sub === \"--help\" || sub === \"help\") {\n process.stdout.write(USAGE);\n return sub ? 0 : 1;\n }\n\n const { flags, command } = splitOnDoubleDash(rawArgv.slice(1));\n\n const { values } = parseArgs({\n args: flags,\n options: {\n tool: { type: \"string\" },\n args: { type: \"string\" },\n \"no-validate\": { type: \"boolean\", default: false },\n json: { type: \"boolean\", default: false },\n timeout: { type: \"string\" },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n allowPositionals: true,\n });\n\n if (values.help) {\n process.stdout.write(USAGE);\n return 0;\n }\n\n if (command.length === 0) {\n process.stderr.write(c.red(\"error: no server command given. Put it after `--`, e.g. `-- node dist/server.js`\\n\"));\n return 2;\n }\n\n const timeoutMs = values.timeout ? Number(values.timeout) : 15_000;\n const [cmd, ...cmdArgs] = command;\n\n const client = await createTestClient(\n { command: cmd!, args: cmdArgs },\n { timeoutMs },\n );\n\n try {\n switch (sub) {\n case \"inspect\":\n return await runInspect(client, !!values.json);\n case \"check\":\n return await runCheck(client, !!values.json);\n case \"call\":\n return await runCall(client, {\n tool: values.tool,\n args: values.args,\n validate: !values[\"no-validate\"],\n });\n default:\n process.stderr.write(c.red(`error: unknown command \"${sub}\"\\n\\n`));\n process.stdout.write(USAGE);\n return 2;\n }\n } finally {\n await client.close().catch(() => {});\n }\n}\n\nasync function runInspect(client: Awaited<ReturnType<typeof createTestClient>>, json: boolean): Promise<number> {\n const [tools, resources, prompts] = await Promise.all([\n client.tools(),\n client.resources(),\n client.prompts(),\n ]);\n const info = client.serverInfo();\n\n if (json) {\n process.stdout.write(JSON.stringify({ server: info, tools, resources, prompts }, null, 2) + \"\\n\");\n return 0;\n }\n\n process.stdout.write(\n `${c.bold(info?.name ?? \"(unnamed server)\")} ${c.dim(\"v\" + (info?.version ?? \"?\"))}\\n\\n`,\n );\n\n process.stdout.write(c.bold(`Tools (${tools.length})\\n`));\n for (const t of tools) {\n process.stdout.write(` ${c.cyan(t.name)}${t.description ? \" \" + c.dim(t.description) : \"\"}\\n`);\n const props = t.inputSchema?.properties;\n if (props && Object.keys(props).length > 0) {\n const req = new Set(t.inputSchema?.required ?? []);\n for (const [name, sub] of Object.entries(props)) {\n const type = Array.isArray(sub.type) ? sub.type.join(\"|\") : (sub.type ?? \"any\");\n process.stdout.write(` ${name}${req.has(name) ? \"*\" : \"\"}: ${c.dim(String(type))}\\n`);\n }\n }\n }\n\n if (resources.length > 0) {\n process.stdout.write(\"\\n\" + c.bold(`Resources (${resources.length})\\n`));\n for (const r of resources) {\n process.stdout.write(` ${c.cyan(r.uri)}${r.name ? \" \" + c.dim(r.name) : \"\"}\\n`);\n }\n }\n if (prompts.length > 0) {\n process.stdout.write(\"\\n\" + c.bold(`Prompts (${prompts.length})\\n`));\n for (const p of prompts) {\n process.stdout.write(` ${c.cyan(p.name)}${p.description ? \" \" + c.dim(p.description) : \"\"}\\n`);\n }\n }\n return 0;\n}\n\nasync function runCheck(client: Awaited<ReturnType<typeof createTestClient>>, json: boolean): Promise<number> {\n const report = await conformanceCheck(client);\n\n if (json) {\n process.stdout.write(JSON.stringify(report, null, 2) + \"\\n\");\n return report.ok ? 0 : 1;\n }\n\n const mark = (r: CheckResult) =>\n r.status === \"pass\" ? c.green(\"✓\") : r.status === \"skip\" ? c.dim(\"–\") : r.severity === \"error\" ? c.red(\"✗\") : c.yellow(\"!\");\n\n for (const r of report.checks) {\n process.stdout.write(`${mark(r)} ${r.title}${r.detail ? c.dim(\" — \" + r.detail) : \"\"}\\n`);\n for (const f of r.findings ?? []) {\n process.stdout.write(` ${c.dim(\"•\")} ${f}\\n`);\n }\n }\n\n const { passed, failed, skipped } = report.summary;\n process.stdout.write(\n `\\n${report.ok ? c.green(\"PASS\") : c.red(\"FAIL\")} ${passed} passed, ${failed} failed, ${skipped} skipped\\n`,\n );\n return report.ok ? 0 : 1;\n}\n\nasync function runCall(\n client: Awaited<ReturnType<typeof createTestClient>>,\n opts: { tool?: string; args?: string; validate: boolean },\n): Promise<number> {\n if (!opts.tool) {\n process.stderr.write(c.red(\"error: --tool <name> is required for `call`\\n\"));\n return 2;\n }\n let args: Record<string, unknown> = {};\n if (opts.args) {\n try {\n args = JSON.parse(opts.args);\n } catch (e) {\n process.stderr.write(c.red(`error: --args is not valid JSON: ${(e as Error).message}\\n`));\n return 2;\n }\n }\n\n const res = await client.call(opts.tool, args, { validate: opts.validate });\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return res.isError ? 1 : 0;\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(`${c.red(\"error:\")} ${err?.message ?? err}\\n`);\n process.exit(1);\n });\n"]}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createTestClient, conformanceCheck } from './chunk-EANYYOGZ.js';
|
|
3
|
+
import { parseArgs } from 'util';
|
|
4
|
+
|
|
5
|
+
var useColor = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
6
|
+
var c = {
|
|
7
|
+
dim: (s) => useColor ? `\x1B[2m${s}\x1B[0m` : s,
|
|
8
|
+
bold: (s) => useColor ? `\x1B[1m${s}\x1B[0m` : s,
|
|
9
|
+
green: (s) => useColor ? `\x1B[32m${s}\x1B[0m` : s,
|
|
10
|
+
yellow: (s) => useColor ? `\x1B[33m${s}\x1B[0m` : s,
|
|
11
|
+
red: (s) => useColor ? `\x1B[31m${s}\x1B[0m` : s,
|
|
12
|
+
cyan: (s) => useColor ? `\x1B[36m${s}\x1B[0m` : s
|
|
13
|
+
};
|
|
14
|
+
var USAGE = `${c.bold("mcp-devkit")} \u2014 testing & inspection toolkit for MCP servers
|
|
15
|
+
|
|
16
|
+
${c.bold("Usage:")}
|
|
17
|
+
mcp-devkit inspect -- <command...>
|
|
18
|
+
mcp-devkit check -- <command...>
|
|
19
|
+
mcp-devkit call --tool <name> [--args <json>] [--no-validate] -- <command...>
|
|
20
|
+
|
|
21
|
+
${c.bold("Examples:")}
|
|
22
|
+
mcp-devkit inspect -- node dist/server.js
|
|
23
|
+
mcp-devkit check -- npx -y @modelcontextprotocol/server-everything
|
|
24
|
+
mcp-devkit call --tool search --args '{"q":"mcp"}' -- node dist/server.js
|
|
25
|
+
|
|
26
|
+
${c.bold("Options:")}
|
|
27
|
+
--tool <name> tool to call (call command)
|
|
28
|
+
--args <json> JSON arguments object for the tool (default {})
|
|
29
|
+
--no-validate skip client-side inputSchema validation on call
|
|
30
|
+
--json machine-readable JSON output (inspect / check)
|
|
31
|
+
--timeout <ms> per-request timeout (default 15000)
|
|
32
|
+
-h, --help show this help
|
|
33
|
+
|
|
34
|
+
Everything after ${c.bold("--")} is the MCP server command to launch over stdio.
|
|
35
|
+
`;
|
|
36
|
+
function splitOnDoubleDash(argv) {
|
|
37
|
+
const i = argv.indexOf("--");
|
|
38
|
+
if (i === -1) return { flags: argv, command: [] };
|
|
39
|
+
return { flags: argv.slice(0, i), command: argv.slice(i + 1) };
|
|
40
|
+
}
|
|
41
|
+
async function main() {
|
|
42
|
+
const rawArgv = process.argv.slice(2);
|
|
43
|
+
const sub = rawArgv[0];
|
|
44
|
+
if (!sub || sub === "-h" || sub === "--help" || sub === "help") {
|
|
45
|
+
process.stdout.write(USAGE);
|
|
46
|
+
return sub ? 0 : 1;
|
|
47
|
+
}
|
|
48
|
+
const { flags, command } = splitOnDoubleDash(rawArgv.slice(1));
|
|
49
|
+
const { values } = parseArgs({
|
|
50
|
+
args: flags,
|
|
51
|
+
options: {
|
|
52
|
+
tool: { type: "string" },
|
|
53
|
+
args: { type: "string" },
|
|
54
|
+
"no-validate": { type: "boolean", default: false },
|
|
55
|
+
json: { type: "boolean", default: false },
|
|
56
|
+
timeout: { type: "string" },
|
|
57
|
+
help: { type: "boolean", short: "h", default: false }
|
|
58
|
+
},
|
|
59
|
+
allowPositionals: true
|
|
60
|
+
});
|
|
61
|
+
if (values.help) {
|
|
62
|
+
process.stdout.write(USAGE);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
if (command.length === 0) {
|
|
66
|
+
process.stderr.write(c.red("error: no server command given. Put it after `--`, e.g. `-- node dist/server.js`\n"));
|
|
67
|
+
return 2;
|
|
68
|
+
}
|
|
69
|
+
const timeoutMs = values.timeout ? Number(values.timeout) : 15e3;
|
|
70
|
+
const [cmd, ...cmdArgs] = command;
|
|
71
|
+
const client = await createTestClient(
|
|
72
|
+
{ command: cmd, args: cmdArgs },
|
|
73
|
+
{ timeoutMs }
|
|
74
|
+
);
|
|
75
|
+
try {
|
|
76
|
+
switch (sub) {
|
|
77
|
+
case "inspect":
|
|
78
|
+
return await runInspect(client, !!values.json);
|
|
79
|
+
case "check":
|
|
80
|
+
return await runCheck(client, !!values.json);
|
|
81
|
+
case "call":
|
|
82
|
+
return await runCall(client, {
|
|
83
|
+
tool: values.tool,
|
|
84
|
+
args: values.args,
|
|
85
|
+
validate: !values["no-validate"]
|
|
86
|
+
});
|
|
87
|
+
default:
|
|
88
|
+
process.stderr.write(c.red(`error: unknown command "${sub}"
|
|
89
|
+
|
|
90
|
+
`));
|
|
91
|
+
process.stdout.write(USAGE);
|
|
92
|
+
return 2;
|
|
93
|
+
}
|
|
94
|
+
} finally {
|
|
95
|
+
await client.close().catch(() => {
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function runInspect(client, json) {
|
|
100
|
+
const [tools, resources, prompts] = await Promise.all([
|
|
101
|
+
client.tools(),
|
|
102
|
+
client.resources(),
|
|
103
|
+
client.prompts()
|
|
104
|
+
]);
|
|
105
|
+
const info = client.serverInfo();
|
|
106
|
+
if (json) {
|
|
107
|
+
process.stdout.write(JSON.stringify({ server: info, tools, resources, prompts }, null, 2) + "\n");
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
process.stdout.write(
|
|
111
|
+
`${c.bold(info?.name ?? "(unnamed server)")} ${c.dim("v" + (info?.version ?? "?"))}
|
|
112
|
+
|
|
113
|
+
`
|
|
114
|
+
);
|
|
115
|
+
process.stdout.write(c.bold(`Tools (${tools.length})
|
|
116
|
+
`));
|
|
117
|
+
for (const t of tools) {
|
|
118
|
+
process.stdout.write(` ${c.cyan(t.name)}${t.description ? " " + c.dim(t.description) : ""}
|
|
119
|
+
`);
|
|
120
|
+
const props = t.inputSchema?.properties;
|
|
121
|
+
if (props && Object.keys(props).length > 0) {
|
|
122
|
+
const req = new Set(t.inputSchema?.required ?? []);
|
|
123
|
+
for (const [name, sub] of Object.entries(props)) {
|
|
124
|
+
const type = Array.isArray(sub.type) ? sub.type.join("|") : sub.type ?? "any";
|
|
125
|
+
process.stdout.write(` ${name}${req.has(name) ? "*" : ""}: ${c.dim(String(type))}
|
|
126
|
+
`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (resources.length > 0) {
|
|
131
|
+
process.stdout.write("\n" + c.bold(`Resources (${resources.length})
|
|
132
|
+
`));
|
|
133
|
+
for (const r of resources) {
|
|
134
|
+
process.stdout.write(` ${c.cyan(r.uri)}${r.name ? " " + c.dim(r.name) : ""}
|
|
135
|
+
`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (prompts.length > 0) {
|
|
139
|
+
process.stdout.write("\n" + c.bold(`Prompts (${prompts.length})
|
|
140
|
+
`));
|
|
141
|
+
for (const p of prompts) {
|
|
142
|
+
process.stdout.write(` ${c.cyan(p.name)}${p.description ? " " + c.dim(p.description) : ""}
|
|
143
|
+
`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
async function runCheck(client, json) {
|
|
149
|
+
const report = await conformanceCheck(client);
|
|
150
|
+
if (json) {
|
|
151
|
+
process.stdout.write(JSON.stringify(report, null, 2) + "\n");
|
|
152
|
+
return report.ok ? 0 : 1;
|
|
153
|
+
}
|
|
154
|
+
const mark = (r) => r.status === "pass" ? c.green("\u2713") : r.status === "skip" ? c.dim("\u2013") : r.severity === "error" ? c.red("\u2717") : c.yellow("!");
|
|
155
|
+
for (const r of report.checks) {
|
|
156
|
+
process.stdout.write(`${mark(r)} ${r.title}${r.detail ? c.dim(" \u2014 " + r.detail) : ""}
|
|
157
|
+
`);
|
|
158
|
+
for (const f of r.findings ?? []) {
|
|
159
|
+
process.stdout.write(` ${c.dim("\u2022")} ${f}
|
|
160
|
+
`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const { passed, failed, skipped } = report.summary;
|
|
164
|
+
process.stdout.write(
|
|
165
|
+
`
|
|
166
|
+
${report.ok ? c.green("PASS") : c.red("FAIL")} ${passed} passed, ${failed} failed, ${skipped} skipped
|
|
167
|
+
`
|
|
168
|
+
);
|
|
169
|
+
return report.ok ? 0 : 1;
|
|
170
|
+
}
|
|
171
|
+
async function runCall(client, opts) {
|
|
172
|
+
if (!opts.tool) {
|
|
173
|
+
process.stderr.write(c.red("error: --tool <name> is required for `call`\n"));
|
|
174
|
+
return 2;
|
|
175
|
+
}
|
|
176
|
+
let args = {};
|
|
177
|
+
if (opts.args) {
|
|
178
|
+
try {
|
|
179
|
+
args = JSON.parse(opts.args);
|
|
180
|
+
} catch (e) {
|
|
181
|
+
process.stderr.write(c.red(`error: --args is not valid JSON: ${e.message}
|
|
182
|
+
`));
|
|
183
|
+
return 2;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const res = await client.call(opts.tool, args, { validate: opts.validate });
|
|
187
|
+
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
188
|
+
return res.isError ? 1 : 0;
|
|
189
|
+
}
|
|
190
|
+
main().then((code) => process.exit(code)).catch((err) => {
|
|
191
|
+
process.stderr.write(`${c.red("error:")} ${err?.message ?? err}
|
|
192
|
+
`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=cli.js.map
|
|
196
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env node\n/**\n * cli.ts — `mcp-devkit` command-line entry point.\n *\n * Drives a stdio MCP server (launched as a child process) for three jobs you\n * don't want to write a script for:\n *\n * mcp-devkit inspect -- <command...> dump tools / resources / prompts\n * mcp-devkit check -- <command...> run the conformance battery\n * mcp-devkit call --tool NAME [--args JSON] -- <command...> invoke one tool\n *\n * Everything after `--` is the server command, e.g.\n * mcp-devkit inspect -- node dist/server.js\n * mcp-devkit check -- npx -y @some/mcp-server\n */\n\nimport { parseArgs } from \"node:util\";\nimport { createTestClient } from \"./client\";\nimport { conformanceCheck } from \"./conformance\";\nimport type { CheckResult } from \"./conformance\";\n\n// ── tiny ANSI helpers (respect NO_COLOR) ─────────────────────────────────────\nconst useColor = process.stdout.isTTY && !process.env.NO_COLOR;\nconst c = {\n dim: (s: string) => (useColor ? `\\x1b[2m${s}\\x1b[0m` : s),\n bold: (s: string) => (useColor ? `\\x1b[1m${s}\\x1b[0m` : s),\n green: (s: string) => (useColor ? `\\x1b[32m${s}\\x1b[0m` : s),\n yellow: (s: string) => (useColor ? `\\x1b[33m${s}\\x1b[0m` : s),\n red: (s: string) => (useColor ? `\\x1b[31m${s}\\x1b[0m` : s),\n cyan: (s: string) => (useColor ? `\\x1b[36m${s}\\x1b[0m` : s),\n};\n\nconst USAGE = `${c.bold(\"mcp-devkit\")} — testing & inspection toolkit for MCP servers\n\n${c.bold(\"Usage:\")}\n mcp-devkit inspect -- <command...>\n mcp-devkit check -- <command...>\n mcp-devkit call --tool <name> [--args <json>] [--no-validate] -- <command...>\n\n${c.bold(\"Examples:\")}\n mcp-devkit inspect -- node dist/server.js\n mcp-devkit check -- npx -y @modelcontextprotocol/server-everything\n mcp-devkit call --tool search --args '{\"q\":\"mcp\"}' -- node dist/server.js\n\n${c.bold(\"Options:\")}\n --tool <name> tool to call (call command)\n --args <json> JSON arguments object for the tool (default {})\n --no-validate skip client-side inputSchema validation on call\n --json machine-readable JSON output (inspect / check)\n --timeout <ms> per-request timeout (default 15000)\n -h, --help show this help\n\nEverything after ${c.bold(\"--\")} is the MCP server command to launch over stdio.\n`;\n\n/** Split argv into [devkit flags, server command] around the first `--`. */\nfunction splitOnDoubleDash(argv: string[]): { flags: string[]; command: string[] } {\n const i = argv.indexOf(\"--\");\n if (i === -1) return { flags: argv, command: [] };\n return { flags: argv.slice(0, i), command: argv.slice(i + 1) };\n}\n\nasync function main(): Promise<number> {\n const rawArgv = process.argv.slice(2);\n const sub = rawArgv[0];\n\n if (!sub || sub === \"-h\" || sub === \"--help\" || sub === \"help\") {\n process.stdout.write(USAGE);\n return sub ? 0 : 1;\n }\n\n const { flags, command } = splitOnDoubleDash(rawArgv.slice(1));\n\n const { values } = parseArgs({\n args: flags,\n options: {\n tool: { type: \"string\" },\n args: { type: \"string\" },\n \"no-validate\": { type: \"boolean\", default: false },\n json: { type: \"boolean\", default: false },\n timeout: { type: \"string\" },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n allowPositionals: true,\n });\n\n if (values.help) {\n process.stdout.write(USAGE);\n return 0;\n }\n\n if (command.length === 0) {\n process.stderr.write(c.red(\"error: no server command given. Put it after `--`, e.g. `-- node dist/server.js`\\n\"));\n return 2;\n }\n\n const timeoutMs = values.timeout ? Number(values.timeout) : 15_000;\n const [cmd, ...cmdArgs] = command;\n\n const client = await createTestClient(\n { command: cmd!, args: cmdArgs },\n { timeoutMs },\n );\n\n try {\n switch (sub) {\n case \"inspect\":\n return await runInspect(client, !!values.json);\n case \"check\":\n return await runCheck(client, !!values.json);\n case \"call\":\n return await runCall(client, {\n tool: values.tool,\n args: values.args,\n validate: !values[\"no-validate\"],\n });\n default:\n process.stderr.write(c.red(`error: unknown command \"${sub}\"\\n\\n`));\n process.stdout.write(USAGE);\n return 2;\n }\n } finally {\n await client.close().catch(() => {});\n }\n}\n\nasync function runInspect(client: Awaited<ReturnType<typeof createTestClient>>, json: boolean): Promise<number> {\n const [tools, resources, prompts] = await Promise.all([\n client.tools(),\n client.resources(),\n client.prompts(),\n ]);\n const info = client.serverInfo();\n\n if (json) {\n process.stdout.write(JSON.stringify({ server: info, tools, resources, prompts }, null, 2) + \"\\n\");\n return 0;\n }\n\n process.stdout.write(\n `${c.bold(info?.name ?? \"(unnamed server)\")} ${c.dim(\"v\" + (info?.version ?? \"?\"))}\\n\\n`,\n );\n\n process.stdout.write(c.bold(`Tools (${tools.length})\\n`));\n for (const t of tools) {\n process.stdout.write(` ${c.cyan(t.name)}${t.description ? \" \" + c.dim(t.description) : \"\"}\\n`);\n const props = t.inputSchema?.properties;\n if (props && Object.keys(props).length > 0) {\n const req = new Set(t.inputSchema?.required ?? []);\n for (const [name, sub] of Object.entries(props)) {\n const type = Array.isArray(sub.type) ? sub.type.join(\"|\") : (sub.type ?? \"any\");\n process.stdout.write(` ${name}${req.has(name) ? \"*\" : \"\"}: ${c.dim(String(type))}\\n`);\n }\n }\n }\n\n if (resources.length > 0) {\n process.stdout.write(\"\\n\" + c.bold(`Resources (${resources.length})\\n`));\n for (const r of resources) {\n process.stdout.write(` ${c.cyan(r.uri)}${r.name ? \" \" + c.dim(r.name) : \"\"}\\n`);\n }\n }\n if (prompts.length > 0) {\n process.stdout.write(\"\\n\" + c.bold(`Prompts (${prompts.length})\\n`));\n for (const p of prompts) {\n process.stdout.write(` ${c.cyan(p.name)}${p.description ? \" \" + c.dim(p.description) : \"\"}\\n`);\n }\n }\n return 0;\n}\n\nasync function runCheck(client: Awaited<ReturnType<typeof createTestClient>>, json: boolean): Promise<number> {\n const report = await conformanceCheck(client);\n\n if (json) {\n process.stdout.write(JSON.stringify(report, null, 2) + \"\\n\");\n return report.ok ? 0 : 1;\n }\n\n const mark = (r: CheckResult) =>\n r.status === \"pass\" ? c.green(\"✓\") : r.status === \"skip\" ? c.dim(\"–\") : r.severity === \"error\" ? c.red(\"✗\") : c.yellow(\"!\");\n\n for (const r of report.checks) {\n process.stdout.write(`${mark(r)} ${r.title}${r.detail ? c.dim(\" — \" + r.detail) : \"\"}\\n`);\n for (const f of r.findings ?? []) {\n process.stdout.write(` ${c.dim(\"•\")} ${f}\\n`);\n }\n }\n\n const { passed, failed, skipped } = report.summary;\n process.stdout.write(\n `\\n${report.ok ? c.green(\"PASS\") : c.red(\"FAIL\")} ${passed} passed, ${failed} failed, ${skipped} skipped\\n`,\n );\n return report.ok ? 0 : 1;\n}\n\nasync function runCall(\n client: Awaited<ReturnType<typeof createTestClient>>,\n opts: { tool?: string; args?: string; validate: boolean },\n): Promise<number> {\n if (!opts.tool) {\n process.stderr.write(c.red(\"error: --tool <name> is required for `call`\\n\"));\n return 2;\n }\n let args: Record<string, unknown> = {};\n if (opts.args) {\n try {\n args = JSON.parse(opts.args);\n } catch (e) {\n process.stderr.write(c.red(`error: --args is not valid JSON: ${(e as Error).message}\\n`));\n return 2;\n }\n }\n\n const res = await client.call(opts.tool, args, { validate: opts.validate });\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return res.isError ? 1 : 0;\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(`${c.red(\"error:\")} ${err?.message ?? err}\\n`);\n process.exit(1);\n });\n"]}
|