Snapshot, parse, validate, and document Model Context Protocol servers.
snapshot requests protocol revision 2025-11-25 by default. Pass protocolVersion (or --protocol-version) to request another:
- A handshake revision (
2025-11-25and earlier) is offered ininitialize. Later requests declare the revision the server negotiates in theMCP-Protocol-Versionheader, and the snapshot records it asmcpVersion. - A stateless revision (
2026-07-28and later) is declared on every request in_metaand in headers, includingMcp-MethodandMcp-Name. The snapshot readsserver/discoverinstead ofinitializeand records the server's supported revisions asmcpVersions.
Snapshotting a server at each revision it claims to serve is a conformance check: a server that refuses a revision reports the ones it supports in the error.
Parsing, validation, and generation are revision-independent: they read an mcp.json document, whatever revision produced it.
Transports:
| Transport | Support |
|---|---|
| stdio | Full |
| Streamable HTTP | Full, including server-minted sessions (Mcp-Session-Id) |
| HTTP+SSE | Full. Deprecated by the specification; prefer Streamable HTTP |
Paginated tools/list, resources/list, resources/templates/list, and prompts/list results are followed to the last page. A snapshot stopped early by the page bound records x-mcp-parser-incomplete rather than presenting a partial list as complete.
Not implemented: tools/call, resources/read, prompts/get, completions, and the client features the specification deprecated in 2026-07-28 (roots, sampling, logging). This package describes a server's surface; it does not exercise it.
npm install mcp-parser
import { snapshot, validate, generateMarkdown } from "mcp-parser"; import { writeFile } from "node:fs/promises"; const spec = await snapshot({ transport: { type: "stdio", command: "node", args: ["server.js"] }, }); const result = validate(spec); if (!result.valid) { for (const d of result.diagnostics) { console.error(`${d.severity}: ${d.path} - ${d.message}`); } } await writeFile("mcp.json", JSON.stringify(spec, null, 2)); await writeFile("mcp.md", generateMarkdown(spec));
Two different documents commonly use the name mcp.json:
| Document | Identifying fields | Purpose |
|---|---|---|
| Sourcey server snapshot | mcpSpec, server, tools/resources/prompts |
Capture and document one server's advertised surface |
| Agent Plugins MCP configuration | $schema, mcpServers |
Locate and connect to the servers in a plugin |
The package supports the published Agent Plugins 1.0.0 configuration contract.
Use mcp.json for that configuration at the plugin root, and a separate filename
such as api.snapshot.json for a captured surface. A connection configuration
does not contain tools or their schemas; snapshot its server to obtain them.
mcp-parser validate-config ./plugin/mcp.json mcp-parser parse-config ./plugin/mcp.json mcp-parser snapshot --config ./plugin/mcp.json --server api -o api.snapshot.json # For stdio, also supply a dedicated persistent directory: mcp-parser snapshot --config ./plugin/mcp.json --server local \ --plugin-data ./plugin-state/local -o local.snapshot.json # Emit the standard plugin configuration from explicit snapshot transport hints: mcp-parser generate api.snapshot.json --format agent-plugin --server api -o mcp.json
Config snapshots select exactly one server and default to mcp.snapshot.json;
they refuse to overwrite the input configuration. --config cannot be combined
with another transport or --header. --plugin-root defaults to the config's
directory. stdio uses that root as its default working directory, resolves
bundled executables and explicit working directories within their real roots,
and supplies PLUGIN_ROOT and PLUGIN_DATA. Only args, env values and cwd
expand those two variables, once. Other placeholders remain literal.
Remote URLs require HTTPS except on loopback, and cannot contain user information or fragments. Configured headers remain literal; generated HTTP/MCP headers take precedence. Redirects and cross-origin SSE message endpoints are refused. Snapshots omit environment values and HTTP headers. Add any required public configuration values when authoring a plugin; never embed credentials in it. Generation requires valid explicit transport hints and does not infer missing commands, URLs, or authentication settings.
These are MCP configuration utilities, not a plugin installer or a complete
Agent Plugins client. The caller owns manifest validation, matching its schema
version, skill discovery, authorization, and the per-plugin data directory's
lifecycle. validateConfig(value, { pluginSchema }) can check the manifest's
schema identifier against the MCP configuration. Validation is offline, selects
only the recognized canonical schema, and rejects unsupported releases.
parseConfig(path) and parseConfigString(content) require a fully valid config.
validateConfig(value, options?) returns valid, topLevelValid, diagnostics,
and a servers map containing independently valid entries. An invalid envelope
empties that map; an invalid server leaves valid siblings available.
resolveConfigServer(config, name, { pluginRoot, pluginData? }) resolves one
entry for the existing snapshot API. snapshotConfig combines those steps.
import { createConfig, snapshotConfig } from "mcp-parser"; const config = createConfig({ api: { type: "streamable-http", url: "https://example.com/mcp" }, }); const surface = await snapshotConfig(config, "api", { pluginRoot: "/path/to/plugin" });
A static snapshot of an MCP server's capabilities: its tools, resources, and prompts. Think of it as openapi.json for MCP servers.
MCP servers describe themselves at runtime via tools/list, resources/list, and prompts/list. An mcp.json captures that live surface in a versionable file for documentation, validation, diffing, and tooling that should not need a running server.
See mcp-schema for the full type definitions and JSON Schema.
Parse an mcp.json file into a typed McpSpec object.
const spec = await parse("./mcp.json"); console.log(spec.server.name); // "my-server" console.log(spec.tools?.length); // 5
Options:
dereference(default:true). Resolves$refpointers using the spec's$defs.
Parse a JSON string directly.
const spec = parseString('{ "mcpSpec": "0.3.1", ... }');
Validate an McpSpec for correctness and best practices.
const result = validate(spec); // result.valid: boolean (true if no errors) // result.diagnostics: array of { severity, path, message }
Checks for:
- Required fields (mcpSpec, server, tool names, inputSchema)
- Duplicate tool/resource/prompt names
- Missing descriptions (warnings)
- Invalid inputSchema types
Connect to a running MCP server and capture a static snapshot over any of the three MCP transports.
import { snapshot } from "mcp-parser"; import { writeFile } from "node:fs/promises"; // stdio const spec = await snapshot({ transport: { type: "stdio", command: "node", args: ["server.js"] }, }); // SSE const spec = await snapshot({ transport: { type: "sse", url: "http://localhost:3000/sse" }, }); // Streamable HTTP const spec = await snapshot({ transport: { type: "streamable-http", url: "http://localhost:3000/mcp" }, }); await writeFile("mcp.json", JSON.stringify(spec, null, 2));
All transports support an optional timeout (default: 30s). SSE and HTTP transports accept a headers object for authentication.
Generate a full markdown reference document.
Generate a compact llms.txt-style index. This is a compatibility export for tools and docs sites that already consume the convention, not a guarantee that model providers will discover or fetch it automatically.
const txt = generateLlmsTxt(spec, "https://docs.example.com");
Generate a complete markdown reference with the server context inline.
const full = generateLlmsFullTxt(spec);
# Parse and pretty-print mcp-parser parse ./mcp.json # Validate mcp-parser validate ./mcp.json # Snapshot via stdio mcp-parser snapshot --stdio "node server.js" -o mcp.json # Snapshot via SSE mcp-parser snapshot --sse http://localhost:3000/sse -o mcp.json # Snapshot via streamable HTTP mcp-parser snapshot --http http://localhost:3000/mcp -o mcp.json # With auth headers mcp-parser snapshot --sse http://localhost:3000/sse --header "Authorization:Bearer tok" -o mcp.json # Generate markdown reference (default) mcp-parser generate ./mcp.json -o mcp.md # Generate compact context index mcp-parser generate ./mcp.json --format llms-txt -o llms.txt # Generate full context reference mcp-parser generate ./mcp.json --format llms-full-txt -o llms-full.txt
- MCP Specification (current revision)
- MCP Specification
2025-11-25(the revision this client requests) - Specification repo (includes JSON Schema for each protocol version)
- TypeScript SDK (
@modelcontextprotocol/sdk) - Python SDK (
mcpon PyPI)
- mcp-schema: TypeScript types and JSON Schema for MCP specs
- sourcey: generate documentation from MCP specs, OpenAPI, and markdown
MIT