diff --git a/docs/server-json/README.md b/docs/server-json/README.md new file mode 100644 index 00000000..6b8f6f13 --- /dev/null +++ b/docs/server-json/README.md @@ -0,0 +1,16 @@ +# server.json file + +There are a variety of use cases where a _static representation of an MCP server_ is necessary: +- Discoverability on a centralized registry (i.e. our official Registry work) +- Discoverability on a decentralized `.well-known` endpoint +- As a response to an initialization call, so the client knows information about the MCP server to which it is connecting +- As an input into crafting a [DXT file](https://www.anthropic.com/engineering/desktop-extensions) +- Packaged in with the source code of an MCP server, so as to have a structured way to identify a server given just its source code + +All of these scenarios (and more) would benefit from an agreed-upon, standardized format that makes it easy to port around and maintain a consistent experience for consumers and developers working with the data. At the end of the day, it's all the same data (or a subset of it). MCP server maintainers should have to manage one copy of this file, and all these use cases can serve that file (or a programmatic derivative/subset of it). + +Please note: this is different from the file commonly referred to as `mcp.json`, which is _an MCP client's configuration file for **running** a specific set of MCP servers_. See [this issue](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/292). + +References: +- [schema.json](./schema.json) - The official JSON schema specification for this representation +- [examples.md](./examples.md) - Example manifestations of the JSON schema \ No newline at end of file diff --git a/docs/server-json/examples.md b/docs/server-json/examples.md new file mode 100644 index 00000000..ff2da127 --- /dev/null +++ b/docs/server-json/examples.md @@ -0,0 +1,326 @@ +# Server JSON Examples + +## Basic Server with NPM Package + +```json +{ + "name": "io.modelcontextprotocol/brave-search", + "description": "MCP server for Brave Search API integration", + "repository": { + "url": "https://github.com/modelcontextprotocol/servers", + "source": "github", + "id": "abc123de-f456-7890-ghij-klmnopqrstuv" + }, + "version_detail": { + "version": "1.0.2", + "release_date": "2023-06-15T10:30:00Z" + }, + "packages": [ + { + "registry_name": "npm", + "name": "@modelcontextprotocol/server-brave-search", + "version": "1.0.2", + "environment_variables": [ + { + "name": "BRAVE_API_KEY", + "description": "Brave Search API Key", + "is_required": true, + "is_secret": true + } + ] + } + ] +} +``` + +## Filesystem Server with Multiple Packages + +```json +{ + "name": "io.modelcontextprotocol/filesystem", + "description": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations.", + "repository": { + "url": "https://github.com/modelcontextprotocol/servers", + "source": "github", + "id": "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9" + }, + "version_detail": { + "version": "1.0.2", + "release_date": "2023-06-15T10:30:00Z" + }, + "packages": [ + { + "registry_name": "npm", + "name": "@modelcontextprotocol/server-filesystem", + "version": "1.0.2", + "package_arguments": [ + { + "type": "positional", + "value_hint": "target_dir", + "description": "Path to access", + "default": "/Users/username/Desktop", + "is_required": true, + "is_repeated": true + } + ], + "environment_variables": [ + { + "name": "LOG_LEVEL", + "description": "Logging level (debug, info, warn, error)", + "default": "info" + } + ] + }, + { + "registry_name": "docker", + "name": "mcp/filesystem", + "version": "1.0.2", + "runtime_arguments": [ + { + "type": "named", + "description": "Mount a volume into the container", + "name": "--mount", + "value": "type=bind,src={source_path},dst={target_path}", + "is_required": true, + "is_repeated": true, + "variables": { + "source_path": { + "description": "Source path on host", + "format": "filepath", + "is_required": true + }, + "target_path": { + "description": "Path to mount in the container. It should be rooted in `/project` directory.", + "is_required": true, + "default": "/project" + } + } + } + ], + "package_arguments": [ + { + "type": "positional", + "value_hint": "target_dir", + "value": "/project" + } + ], + "environment_variables": [ + { + "name": "LOG_LEVEL", + "description": "Logging level (debug, info, warn, error)", + "default": "info" + } + ] + } + ] +} +``` + +## Remote Server Example + +```json +{ + "name": "Remote Filesystem Server", + "description": "Cloud-hosted MCP filesystem server", + "repository": { + "url": "https://github.com/example/remote-fs", + "source": "github", + "id": "xyz789ab-cdef-0123-4567-890ghijklmno" + }, + "version_detail": { + "version": "2.0.0", + "release_date": "2024-01-20T14:30:00Z" + }, + "remotes": [ + { + "transport_type": "sse", + "url": "https://mcp-fs.example.com/sse" + } + ] +} +``` + +## Python Package Example + +```json +{ + "name": "weather-mcp-server", + "description": "Python MCP server for weather data access", + "repository": { + "url": "https://github.com/example/weather-mcp", + "source": "github", + "id": "def456gh-ijkl-7890-mnop-qrstuvwxyz12" + }, + "version_detail": { + "version": "0.5.0", + "release_date": "2024-02-10T09:15:00Z" + }, + "packages": [ + { + "registry_name": "pypi", + "name": "weather-mcp-server", + "version": "0.5.0", + "runtime_hint": "uvx", + "environment_variables": [ + { + "name": "WEATHER_API_KEY", + "description": "API key for weather service", + "is_required": true, + "is_secret": true + }, + { + "name": "WEATHER_UNITS", + "description": "Temperature units (celsius, fahrenheit)", + "default": "celsius" + } + ] + } + ] +} +``` + +## Complex Docker Server with Multiple Arguments + +```json +{ + "name": "mcp-database-manager", + "description": "MCP server for database operations with support for multiple database types", + "repository": { + "url": "https://github.com/example/mcp-database", + "source": "gitlab", + "id": "ghi789jk-lmno-1234-pqrs-tuvwxyz56789" + }, + "version_detail": { + "version": "3.1.0", + "release_date": "2024-03-05T16:45:00Z" + }, + "packages": [ + { + "registry_name": "docker", + "name": "mcp/database-manager", + "version": "3.1.0", + "runtime_arguments": [ + { + "type": "named", + "name": "--network", + "value": "host", + "description": "Use host network mode" + }, + { + "type": "named", + "name": "-e", + "value": "DB_TYPE={db_type}", + "description": "Database type to connect to", + "is_repeated": true, + "variables": { + "db_type": { + "description": "Type of database", + "choices": ["postgres", "mysql", "mongodb", "redis"], + "is_required": true + } + } + } + ], + "package_arguments": [ + { + "type": "named", + "name": "--host", + "description": "Database host", + "default": "localhost", + "is_required": true + }, + { + "type": "named", + "name": "--port", + "description": "Database port", + "format": "number" + }, + { + "type": "positional", + "value_hint": "database_name", + "description": "Name of the database to connect to", + "is_required": true + } + ], + "environment_variables": [ + { + "name": "DB_USERNAME", + "description": "Database username", + "is_required": true + }, + { + "name": "DB_PASSWORD", + "description": "Database password", + "is_required": true, + "is_secret": true + }, + { + "name": "SSL_MODE", + "description": "SSL connection mode", + "default": "prefer", + "choices": ["disable", "prefer", "require"] + } + ] + } + ] +} +``` + +## Server with Remote and Package Options + +```json +{ + "name": "hybrid-mcp-server", + "description": "MCP server available as both local package and remote service", + "repository": { + "url": "https://github.com/example/hybrid-mcp", + "source": "github", + "id": "klm012no-pqrs-3456-tuvw-xyz789abcdef" + }, + "version_detail": { + "version": "1.5.0", + "release_date": "2024-04-01T12:00:00Z" + }, + "packages": [ + { + "registry_name": "npm", + "name": "@example/hybrid-mcp-server", + "version": "1.5.0", + "runtime_hint": "npx", + "package_arguments": [ + { + "type": "named", + "name": "--mode", + "description": "Operation mode", + "default": "local", + "choices": ["local", "cached", "proxy"] + } + ] + } + ], + "remotes": [ + { + "transport_type": "sse", + "url": "https://hybrid-mcp.example.com/sse", + "headers": [ + { + "name": "X-API-Key", + "description": "API key for authentication", + "is_required": true, + "is_secret": true + }, + { + "name": "X-Region", + "description": "Service region", + "default": "us-east-1", + "choices": ["us-east-1", "eu-west-1", "ap-southeast-1"] + } + ] + }, + { + "transport_type": "streamable", + "url": "https://hybrid-mcp.example.com/stream" + } + ] +} +``` \ No newline at end of file diff --git a/docs/server-json/schema.json b/docs/server-json/schema.json new file mode 100644 index 00000000..596c762a --- /dev/null +++ b/docs/server-json/schema.json @@ -0,0 +1,306 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "MCP Server Detail", + "description": "Schema for a static representation of an MCP server. Used in various contexts related to discovery, installation, and configuration.", + "type": "object", + "required": [ + "name", + "description", + "version_detail" + ], + "properties": { + "name": { + "type": "string", + "description": "Server name/identifier", + "example": "io.modelcontextprotocol/filesystem" + }, + "description": { + "type": "string", + "description": "Human-readable description of the server's functionality", + "example": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations." + }, + "repository": { + "type": "object", + "description": "Canonical source repository information", + "required": [ + "url", + "source", + "id" + ], + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Repository URL", + "example": "https://github.com/modelcontextprotocol/servers" + }, + "source": { + "type": "string", + "enum": [ + "github", + "gitlab" + ], + "description": "Repository hosting service", + "example": "github" + }, + "id": { + "type": "string", + "description": "Repository identifier unique and immutable in the corresponding source", + "example": "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9" + } + } + }, + "version_detail": { + "type": "object", + "description": "Version information for this server", + "required": [ + "version", + "release_date" + ], + "properties": { + "version": { + "type": "string", + "description": "Server version (equivalent to Implementation.version in MCP spec)", + "example": "1.0.2" + }, + "release_date": { + "type": "string", + "format": "date-time", + "description": "When this version was published to the registry", + "example": "2023-06-15T10:30:00Z" + } + } + }, + "packages": { + "type": "array", + "description": "Available package distributions", + "items": { + "type": "object", + "required": [ + "registry_name", + "name", + "version" + ], + "properties": { + "registry_name": { + "type": "string", + "enum": [ + "npm", + "docker", + "pypi", + "homebrew" + ], + "description": "Package registry type", + "example": "npm" + }, + "name": { + "type": "string", + "description": "Package name in the registry", + "example": "@modelcontextprotocol/server-filesystem" + }, + "version": { + "type": "string", + "description": "Package version", + "example": "1.0.2" + }, + "runtime_hint": { + "type": "string", + "description": "Hint for appropriate runtime (e.g., npx, uvx)", + "examples": [ + "npx", + "uvx" + ] + }, + "runtime_arguments": { + "type": "array", + "description": "Arguments for the runtime command (docker, npx, etc.)", + "items": { + "$ref": "#/$defs/argument" + } + }, + "package_arguments": { + "type": "array", + "description": "Arguments for the package binary", + "items": { + "$ref": "#/$defs/argument" + } + }, + "environment_variables": { + "type": "array", + "description": "Environment variables to set", + "items": { + "$ref": "#/$defs/key_value_input" + } + } + } + } + }, + "remotes": { + "type": "array", + "description": "Remote server endpoints", + "items": { + "type": "object", + "required": [ + "transport_type", + "url" + ], + "properties": { + "transport_type": { + "type": "string", + "enum": [ + "streamable", + "sse" + ], + "description": "Transport protocol type", + "example": "sse" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Remote server URL", + "example": "https://mcp-fs.example.com/sse" + }, + "headers": { + "type": "array", + "description": "HTTP headers to include", + "items": { + "$ref": "#/$defs/key_value_input" + } + } + } + } + } + }, + "$defs": { + "variable_map": { + "type": "object", + "description": "A map of variable names to their values. Keys in the input `value` that are wrapped in `{curly_braces}` will be replaced with the corresponding variable values.", + "additionalProperties": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "format": { + "type": "string", + "description": "Specifies the input format. Supported values include `filepath`, which should be interpreted as a file on the user's filesystem.\n\nWhen the input is converted to a string, booleans should be represented by the strings \"true\" and \"false\", and numbers should be represented as decimal values.", + "enum": [ + "string", + "number", + "boolean", + "filepath" + ], + "default": "string" + }, + "is_required": { + "type": "boolean" + }, + "default": { + "type": "string" + } + } + } + }, + "key_value_input": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Variable name" + }, + "description": { + "type": "string" + }, + "default": { + "type": "string" + }, + "is_required": { + "type": "boolean", + "default": false + }, + "is_secret": { + "type": "boolean", + "default": false + } + } + }, + "argument": { + "oneOf": [ + { + "type": "object", + "required": [ + "type", + "value_hint" + ], + "properties": { + "type": { + "const": "positional" + }, + "value_hint": { + "type": "string", + "description": "An identifier-like hint for the value. This is not part of the command line, but can be used by client configuration and to provide hints to users." + }, + "description": { + "type": "string" + }, + "value": { + "type": "string", + "description": "The default value for the input. If this is not set, the user may be prompted to provide a value.\n\nIdentifiers wrapped in `{curly_braces}` will be replaced with the corresponding properties from the input `variables` map. If an identifier in braces is not found in `variables`, or if `variables` is not provided, the `{curly_braces}` substring should remain unchanged." + }, + "default": { + "type": "string" + }, + "is_required": { + "type": "boolean", + "default": false + }, + "is_repeated": { + "type": "boolean", + "default": false + }, + "variables": { + "$ref": "#/$defs/variable_map" + } + } + }, + { + "type": "object", + "required": [ + "type", + "name" + ], + "properties": { + "type": { + "const": "named" + }, + "name": { + "type": "string", + "description": "Flag name including dashes" + }, + "description": { + "type": "string" + }, + "value": { + "type": "string", + "description": "The default value for the input. If this is not set, the user may be prompted to provide a value.\n\nIdentifiers wrapped in `{curly_braces}` will be replaced with the corresponding properties from the input `variables` map. If an identifier in braces is not found in `variables`, or if `variables` is not provided, the `{curly_braces}` substring should remain unchanged." + }, + "is_required": { + "type": "boolean", + "default": false + }, + "is_repeated": { + "type": "boolean", + "default": false + }, + "variables": { + "$ref": "#/$defs/variable_map" + } + } + } + ] + } + } +} \ No newline at end of file