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

Release Notes:

- N/A
This commit is contained in:
jvmncs 2024-08-20 13:42:46 -04:00 committed by GitHub
parent 5c0d800b21
commit a89844bcc9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 413 additions and 0 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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"
}
}
```