docs: Document context servers and model context protocol (#16531)

jvmncs created

Release Notes:

- N/A

Change summary

docs/src/assistant/assistant.md              |   4 
docs/src/assistant/context_servers.md        |  45 ++
docs/src/assistant/model_context_protocol.md | 364 ++++++++++++++++++++++
3 files changed, 413 insertions(+)

Detailed changes

docs/src/assistant/assistant.md 🔗

@@ -15,3 +15,7 @@ This section covers various aspects of the Assistant:
 - [Using Commands](./commands.md): Explore slash commands that enhance the Assistant's capabilities and future extensibility.
 
 - [Prompting & Prompt Library](./prompting.md): Learn how to write and save prompts, how to use the Prompt Library, and how to edit prompt templates.
+
+- [Context Servers](./context_servers.md): Learn how to add custom slash commands implemented in external codebases with the Context Server Protocol.
+
+  - [Model Context Protocol](./model_context_protocol.md): Read the full specification of the Model Context Protocol that Context Servers follow to interface with the Assistant.

docs/src/assistant/context_servers.md 🔗

@@ -0,0 +1,45 @@
+# Context Servers
+
+A Context Server is an experimental interface for defining simple, language-agnostic slash commands in Zed's [Assistant](./assistant.md). Context Servers allow you to extend Zed's Assistant to interface with external capabilities and systems in a language-agnostic way.
+
+If slash commands allow you to extend the Assistant with new capabilities, Context Servers follow a simple protocol for registering and making use of those capabilities.
+
+## Using a Context Server
+
+To configure Zed to use a Context Server, add the command required to start the server to your [settings](./configuring-zed.md):
+
+```json
+{
+  "experimental": {
+    "context_servers": [
+      {
+        "id": "python_context_server",
+        "executable": "python",
+        "args": ["-m", "my_context_server"]
+      }
+    ]
+  }
+}
+```
+
+## Developing a Context Server
+
+A Context Server is a server listening for JSON-RPC requests over stdin/stdout. The server must follow the Model Context Protocol (defined below) in order to declare its capabilities such that Zed can make use of them.
+
+### Should you write a Context Server?
+
+[Extensions](./extensions.md) are also capable of adding slash commands to the Assistant.
+
+If your slash commands are already implemented in a language other than Rust, wrapping them in a Context Server implementation will likely be the fastest way to plug them into Zed.
+
+An Extension should be preferred when:
+
+- Your slash commands are implemented in WebAssembly-compatible Rust
+- You want Zed to manage distribution of your slash commands
+- You want to publish your slash commands
+
+### Implementing a Context Server
+
+Context Servers must comply with the [Model Context Protocol (MCP)](./model_context_protocol). See [python-context-server](https://github.com/zed-industries/python-context-server) for a minimal working example.
+
+Currently, Zed's client only implements the subset of the protocol required to support custom prompt insertions and manipulations, although this is likely to be extended in the future.

docs/src/assistant/model_context_protocol.md 🔗

@@ -0,0 +1,364 @@
+# Model Context Protocol
+
+## Overview
+
+The Model Context Protocol (MCP) is a JSON-RPC based protocol for communication between a client (e.g., Zed) and context servers. It enables context-aware development assistance through various features like prompts, resources, and tools.
+
+Currently, Zed's client only implements a subset of the protocol required to support custom prompt insertions and manipulations. This is likely to be expanded in the future.
+
+## Protocol Basics
+
+- Communication: JSON-RPC 2.0 over stdio
+- Versioning: Protocol version negotiated during initialization
+
+## Message Types
+
+1. Requests: Client-to-server method calls
+2. Responses: Server-to-client replies to requests
+3. Notifications: Unidirectional messages (no response expected)
+
+## Lifecycle
+
+1. Client sends `initialize` request
+2. Server responds with capabilities
+3. Client sends `initialized` notification
+4. Normal operation begins
+
+### Initialize Request
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 1,
+  "method": "initialize",
+  "params": {
+    "protocolVersion": 1,
+    "capabilities": {
+      "experimental": {},
+      "sampling": {}
+    },
+    "clientInfo": {
+      "name": "Zed",
+      "version": "1.0.0"
+    }
+  }
+}
+```
+
+### Initialize Response
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 1,
+  "result": {
+    "protocolVersion": 1,
+    "capabilities": {
+      "experimental": {},
+      "logging": {},
+      "prompts": {},
+      "resources": {
+        "subscribe": true
+      },
+      "tools": {}
+    },
+    "serverInfo": {
+      "name": "ExampleServer",
+      "version": "1.0.0"
+    }
+  }
+}
+```
+
+### Initialized Notification
+
+```json
+{
+  "jsonrpc": "2.0",
+  "method": "notifications/initialized",
+  "params": {}
+}
+```
+
+## Features
+
+### Prompts
+
+#### List Prompts
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 2,
+  "method": "prompts/list",
+  "params": {}
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 2,
+  "result": {
+    "prompts": [
+      {
+        "name": "examplePrompt",
+        "arguments": [
+          {
+            "name": "arg1",
+            "description": "Description of arg1",
+            "required": true
+          }
+        ]
+      }
+    ]
+  }
+}
+```
+
+#### Execute Prompt
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 3,
+  "method": "prompts/get",
+  "params": {
+    "name": "examplePrompt",
+    "arguments": {
+      "arg1": "value1"
+    }
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 3,
+  "result": {
+    "prompt": "Generated prompt text"
+  }
+}
+```
+
+### Resources
+
+#### List Resources
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 4,
+  "method": "resources/list",
+  "params": {}
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 4,
+  "result": {
+    "resourceTemplates": [
+      {
+        "uriTemplate": "template://example/{param}",
+        "name": "Example Template",
+        "description": "Description of the template"
+      }
+    ],
+    "resources": [
+      {
+        "uri": "https://example.com/resource",
+        "mimeType": "text/plain"
+      }
+    ]
+  }
+}
+```
+
+#### Read Resource
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 5,
+  "method": "resources/read",
+  "params": {
+    "uri": "https://example.com/resource"
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 5,
+  "result": {
+    "contents": [
+      {
+        "uri": "https://example.com/resource",
+        "mimeType": "text/plain",
+        "contentType": "text",
+        "text": "Resource content"
+      }
+    ]
+  }
+}
+```
+
+#### Subscribe to Resource
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 6,
+  "method": "resources/subscribe",
+  "params": {
+    "uri": "https://example.com/resource"
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 6,
+  "result": null
+}
+```
+
+#### Unsubscribe from Resource
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 7,
+  "method": "resources/unsubscribe",
+  "params": {
+    "uri": "https://example.com/resource"
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 7,
+  "result": null
+}
+```
+
+### Tools
+
+#### Call Tool
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 8,
+  "method": "tools/call",
+  "params": {
+    "name": "exampleTool",
+    "arguments": {
+      "key": "value"
+    }
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 8,
+  "result": {
+    "output": "Tool execution result"
+  }
+}
+```
+
+### Logging
+
+#### Set Logging Level
+
+Request:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 9,
+  "method": "logging/setLevel",
+  "params": {
+    "level": "info"
+  }
+}
+```
+
+Response:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": 9,
+  "result": null
+}
+```
+
+### Notifications
+
+#### Progress
+
+```json
+{
+  "jsonrpc": "2.0",
+  "method": "notifications/progress",
+  "params": {
+    "progressToken": "operation1",
+    "progress": 50.0,
+    "total": 100.0
+  }
+}
+```
+
+## Error Handling
+
+Errors should be returned as standard JSON-RPC 2.0 error objects:
+
+```json
+{
+  "jsonrpc": "2.0",
+  "id": null,
+  "error": {
+    "code": -32000,
+    "message": "Error message"
+  }
+}
+```