## Summary
This PR adds support for the MCP (Model Context Protocol)
`notifications/tools/list_changed` notification, enabling dynamic tool
discovery when MCP servers add, remove, or modify their available tools
at runtime.
## Release Notes:
- Improved: MCP tools are now automatically reloaded when a context
server sends a `tools/list_changed` notification, eliminating the need
to restart the server to discover new tools.
## Changes
- Register a notification handler for `notifications/tools/list_changed`
in `ContextServerRegistry`
- Automatically reload tools when the notification is received
- Handler is registered both on initial server startup and when a server
transitions to `Running` status
## Motivation
The MCP specification includes a `notifications/tools/list_changed`
notification to inform clients when the list of available tools has
changed. Previously, Zed's agent would only load tools once when a
context server started. This meant that:
1. If an MCP server dynamically registered new tools after
initialization, they would not be available to the agent
2. The only way to refresh tools was to restart the entire context
server
3. Tools that were removed or modified would remain in the old state
until restart
## Implementation Details
The implementation follows these steps:
1. When a context server transitions to `Running` status, register a
notification handler for `notifications/tools/list_changed`
2. The handler captures a weak reference to the `ContextServerRegistry`
entity
3. When the notification is received, spawn a task that calls
`reload_tools_for_server` with the server ID
4. The existing `reload_tools_for_server` method handles fetching the
updated tool list and notifying observers
This approach is minimal and reuses existing tool-loading
infrastructure.
## Testing
- [x] Code compiles with `./script/clippy -p agent`
- The notification handler infrastructure already exists and is tested
in the codebase
- The `reload_tools_for_server` method is already tested and working
## Benefits
- Improves developer experience by enabling hot-reloading of MCP tools
- Aligns with the MCP specification's capability negotiation system
- No breaking changes to existing functionality
- Enables more flexible and dynamic MCP server implementations
## Related Issues
This implements part of the MCP specification that was already defined
in the type system but not wired up to actually handle the
notifications.
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
serde 1.0.221 introduced serde_core into the build graph, which should
render explicitly depending on serde_derive for faster build times an
obsolote method.
Besides, I'm not even sure if that worked for us. My hunch is that at
least one of our deps would have `serde` with derive feature enabled..
and then, most of the crates using `serde_derive` explicitly were also
depending on gpui, which depended on `serde`.. thus, we wouldn't have
gained anything from explicit dep on `serde_derive`
Release Notes:
- N/A
Closes: #32668
- Add
[tool_call_timeout_millis](https://github.com/cline/cline/pull/1904)
field to ContextServerCommand, like in Cline
- Update ModelContextServerBinary to include timeout configuration
- Modify Client to store and use configurable request timeout
- Replace hardcoded REQUEST_TIMEOUT with self.request_timeout
- Rename REQUEST_TIMEOUT to DEFAULT_REQUEST_TIMEOUT for clarity
- Maintain backward compatibility with 60-second default
Release Notes:
- context_server: Add support for configurable timeout for MCP tool
calls
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This fixes an issue where we were not setting the context server working
directory at all.
Release Notes:
- Context servers will now be spawned in the currently active project
root.
---------
Co-authored-by: Danilo Leal <danilo@zed.dev>
https://github.com/zed-industries/zed/issues/30972 brought up another
case where our context is not enough to track the actual source of the
issue: we get a general top-level error without inner error.
The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD
SHA"))?; ` on the top level.
The PR finally reworks the way we use anyhow to reduce such issues (or
at least make it simpler to bubble them up later in a fix).
On top of that, uses a few more anyhow methods for better readability.
* `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error
conversion/option reporting cases are replaced with `context` and
`with_context` calls
* in addition to that, various `anyhow!("failed to do ...")` are
stripped with `.context("Doing ...")` messages instead to remove the
parasitic `failed to` text
* `anyhow::ensure!` is used instead of `if ... { return Err(...); }`
calls
* `anyhow::bail!` is used instead of `return Err(anyhow!(...));`
Release Notes:
- N/A
Because we instantiated `ContextServerManager` both in `agent` and
`assistant-context-editor`, and these two entities track the running MCP
servers separately, we were effectively running every MCP server twice.
This PR moves the `ContextServerManager` into the project crate (now
called `ContextServerStore`). The store can be accessed via a project
instance. This ensures that we only instantiate one `ContextServerStore`
per project.
Also, this PR adds a bunch of tests to ensure that the
`ContextServerStore` behaves correctly (Previously there were none).
Closes#28714Closes#29530
Release Notes:
- N/A
This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052
TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code
Release Notes:
- N/A
This PR abstracts the communication layer for context servers, laying
the groundwork for supporting multiple transport mechanisms and taking
one step towards enabling remote servers.
Key changes centre around creating a new `Transport` trait with methods
for sending and receiving messages. I've implemented this trait for the
existing stdio-based communication, which is now encapsulated in a
`StdioTransport` struct. The `Client` struct has been refactored to use
this new `Transport` trait instead of directly managing stdin and
stdout.
The next steps will involve implementing an SSE + HTTP transport and
defining alternative context server settings for remote servers.
Release Notes:
- N/A
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Done automatically with
> ast-grep -p '$A.background_executor().spawn($B)' -r
'$A.background_spawn($B)' --update-all --globs "\!crates/gpui"
Followed by:
* `cargo fmt`
* Unexpected need to remove some trailing whitespace.
* Manually adding imports of `gpui::{AppContext as _}` which provides
`background_spawn`
* Added `AppContext as _` to existing use of `AppContext`
Release Notes:
- N/A
Fix a bug where a GPUI macro still used `ModelContext`
Rename `AsyncAppContext` -> `AsyncApp`
Rename update_model, read_model, insert_model, and reserve_model to
update_entity, read_entity, insert_entity, and reserve_entity
Release Notes:
- N/A
There's still a bit more work to do on this, but this PR is compiling
(with warnings) after eliminating the key types. When the tasks below
are complete, this will be the new narrative for GPUI:
- `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit
of state, and if `T` implements `Render`, then `Entity<T>` implements
`Element`.
- `&mut App` This replaces `AppContext` and represents the app.
- `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It
is provided by the framework when updating an entity.
- `&mut Window` Broken out of `&mut WindowContext` which no longer
exists. Every method that once took `&mut WindowContext` now takes `&mut
Window, &mut App` and every method that took `&mut ViewContext<T>` now
takes `&mut Window, &mut Context<T>`
Not pictured here are the two other failed attempts. It's been quite a
month!
Tasks:
- [x] Remove `View`, `ViewContext`, `WindowContext` and thread through
`Window`
- [x] [@cole-miller @mikayla-maki] Redraw window when entities change
- [x] [@cole-miller @mikayla-maki] Get examples and Zed running
- [x] [@cole-miller @mikayla-maki] Fix Zed rendering
- [x] [@mikayla-maki] Fix todo! macros and comments
- [x] Fix a bug where the editor would not be redrawn because of view
caching
- [x] remove publicness window.notify() and replace with
`AppContext::notify`
- [x] remove `observe_new_window_models`, replace with
`observe_new_models` with an optional window
- [x] Fix a bug where the project panel would not be redrawn because of
the wrong refresh() call being used
- [x] Fix the tests
- [x] Fix warnings by eliminating `Window` params or using `_`
- [x] Fix conflicts
- [x] Simplify generic code where possible
- [x] Rename types
- [ ] Update docs
### issues post merge
- [x] Issues switching between normal and insert mode
- [x] Assistant re-rendering failure
- [x] Vim test failures
- [x] Mac build issue
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Joseph <joseph@zed.dev>
Co-authored-by: max <max@zed.dev>
Co-authored-by: Michael Sloan <michael@zed.dev>
Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local>
Co-authored-by: Mikayla <mikayla.c.maki@gmail.com>
Co-authored-by: joão <joao@zed.dev>
This PR factors the tool definitions out of the `assistant` crate so
that they can be shared between `assistant` and `assistant2`.
`ToolWorkingSet` now lives in `assistant_tool`. The tool definitions
themselves live in `assistant_tools`, with the exception of the
`ContextServerTool`, which has been moved to the `context_server` crate.
As part of this refactoring I needed to extract the
`ContextServerSettings` to a separate `context_server_settings` crate so
that the `extension_host`—which is referenced by the `remote_server`—can
name the `ContextServerSettings` type without pulling in some undesired
dependencies.
Release Notes:
- N/A