The four list-fetching state managers fired their list RPC against every server on connect regardless of advertised capabilities, so a server that doesn't implement a given primitive replied -32601 "Method not found", surfacing in the console on every connect. Mirrors the `tasks`-capability gate added for ManagedRequestorTasksState in #1349. - managedToolsState → gate on capabilities.tools - managedPromptsState → gate on capabilities.prompts - managedResourcesState → gate on capabilities.resources - managedResourceTemplatesState → gate on capabilities.resources (the spec defines no separate resourceTemplates capability; resources/templates/list is part of the resources surface) When the capability is absent each manager sets an empty list, dispatches its change event, and returns — the right semantics for "this server doesn't support X." Tests: existing flow tests now construct their FakeInspectorClient with the relevant capability so the live list path is still exercised; added a "refresh skips listX when capability absent" and a "connect against an X-less server doesn't fire listX" test per manager. Updated the useManagedX peers and resourceSubscriptionsState (which drives a ManagedResourcesState refresh) to advertise the capability too. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
905b80a88c
commit
9e494544e7
4 changed files with 206 additions and 9 deletions
|
|
@ -70,6 +70,16 @@ export class ManagedPromptsState extends TypedEventTarget<ManagedPromptsStateEve
|
|||
if (!client || client.getStatus() !== "connected") {
|
||||
return this.getPrompts();
|
||||
}
|
||||
// Gate on the server's `prompts` capability — calling prompts/list against
|
||||
// a server that doesn't advertise it returns -32601 "Method not found",
|
||||
// which then surfaces in the console for every connect against a
|
||||
// prompts-less server. Empty list is the right semantics for "this server
|
||||
// doesn't support prompts."
|
||||
if (!client.getCapabilities()?.prompts) {
|
||||
this.prompts = [];
|
||||
this.dispatchTypedEvent("promptsChange", this.prompts);
|
||||
return this.getPrompts();
|
||||
}
|
||||
const effectiveMetadata = metadata ?? this._metadata;
|
||||
this.prompts = [];
|
||||
let cursor: string | undefined;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,21 @@ export class ManagedResourceTemplatesState extends TypedEventTarget<ManagedResou
|
|||
if (!client || client.getStatus() !== "connected") {
|
||||
return this.getResourceTemplates();
|
||||
}
|
||||
// Gate on the server's `resources` capability — the MCP spec doesn't define
|
||||
// a separate `resourceTemplates` capability; resources/templates/list is
|
||||
// part of the resources surface. Calling it against a server that doesn't
|
||||
// advertise resources returns -32601 "Method not found", which then
|
||||
// surfaces in the console for every connect against a resources-less
|
||||
// server. Empty list is the right semantics for "this server doesn't
|
||||
// support resources."
|
||||
if (!client.getCapabilities()?.resources) {
|
||||
this.resourceTemplates = [];
|
||||
this.dispatchTypedEvent(
|
||||
"resourceTemplatesChange",
|
||||
this.resourceTemplates,
|
||||
);
|
||||
return this.getResourceTemplates();
|
||||
}
|
||||
const effectiveMetadata = metadata ?? this._metadata;
|
||||
this.resourceTemplates = [];
|
||||
let cursor: string | undefined;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,16 @@ export class ManagedResourcesState extends TypedEventTarget<ManagedResourcesStat
|
|||
if (!client || client.getStatus() !== "connected") {
|
||||
return this.getResources();
|
||||
}
|
||||
// Gate on the server's `resources` capability — calling resources/list
|
||||
// against a server that doesn't advertise it returns -32601 "Method not
|
||||
// found", which then surfaces in the console for every connect against a
|
||||
// resources-less server. Empty list is the right semantics for "this
|
||||
// server doesn't support resources."
|
||||
if (!client.getCapabilities()?.resources) {
|
||||
this.resources = [];
|
||||
this.dispatchTypedEvent("resourcesChange", this.resources);
|
||||
return this.getResources();
|
||||
}
|
||||
const effectiveMetadata = metadata ?? this._metadata;
|
||||
this.resources = [];
|
||||
let cursor: string | undefined;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,16 @@ export class ManagedToolsState extends TypedEventTarget<ManagedToolsStateEventMa
|
|||
if (!client || client.getStatus() !== "connected") {
|
||||
return this.getTools();
|
||||
}
|
||||
// Gate on the server's `tools` capability — calling tools/list against a
|
||||
// server that doesn't advertise it returns -32601 "Method not found",
|
||||
// which then surfaces in the console for every connect against a
|
||||
// tools-less server. Empty list is the right semantics for "this server
|
||||
// doesn't support tools."
|
||||
if (!client.getCapabilities()?.tools) {
|
||||
this.tools = [];
|
||||
this.dispatchTypedEvent("toolsChange", this.tools);
|
||||
return this.getTools();
|
||||
}
|
||||
const effectiveMetadata = metadata ?? this._metadata;
|
||||
this.tools = [];
|
||||
let cursor: string | undefined;
|
||||
|
|
|
|||
Loading…
Reference in a new issue