fix: convert remaining capability throws to SdkError (#1761)

Co-authored-by: Matteo Gobbo <info@matteogobbo.it>
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
This commit is contained in:
Felix Weinberger 2026-03-26 21:47:07 +00:00 • committed by GitHub
commit 01954e621a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 12 deletions

View file

@ -0,0 +1,7 @@
---
'@modelcontextprotocol/core': patch
'@modelcontextprotocol/client': patch
'@modelcontextprotocol/server': patch
---
Convert remaining capability-assertion throws to `SdkError(SdkErrorCode.CapabilityNotSupported, ...)`. Follow-up to #1454 which missed `Client.assertCapability()`, the task capability helpers in `experimental/tasks/helpers.ts`, and the sampling/elicitation capability checks in `experimental/tasks/server.ts`.

View file

@ -456,7 +456,7 @@ export class Client extends Protocol<ClientContext> {
protected assertCapability(capability: keyof ServerCapabilities, method: string): void {
if (!this._serverCapabilities?.[capability]) {
throw new Error(`Server does not support ${capability} (required for ${method})`);
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support ${capability} (required for ${method})`);
}
}

View file

@ -5,6 +5,8 @@
* @experimental
*/
import { SdkError, SdkErrorCode } from '../../errors/sdkErrors.js';
/**
* Type representing the task requests capability structure.
* This is derived from `ClientTasksCapability.requests` and `ServerTasksCapability.requests`.
@ -22,7 +24,7 @@ interface TaskRequestsCapability {
* @param requests - The task requests capability object
* @param method - The method being checked
* @param entityName - `'Server'` or `'Client'` for error messages
* @throws Error if the capability is not supported
* @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
*
* @experimental
*/
@ -32,13 +34,16 @@ export function assertToolsCallTaskCapability(
entityName: 'Server' | 'Client'
): void {
if (!requests) {
throw new Error(`${entityName} does not support task creation (required for ${method})`);
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
}
switch (method) {
case 'tools/call': {
if (!requests.tools?.call) {
throw new Error(`${entityName} does not support task creation for tools/call (required for ${method})`);
throw new SdkError(
SdkErrorCode.CapabilityNotSupported,
`${entityName} does not support task creation for tools/call (required for ${method})`
);
}
break;
}
@ -57,7 +62,7 @@ export function assertToolsCallTaskCapability(
* @param requests - The task requests capability object
* @param method - The method being checked
* @param entityName - `'Server'` or `'Client'` for error messages
* @throws Error if the capability is not supported
* @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
*
* @experimental
*/
@ -67,20 +72,26 @@ export function assertClientRequestTaskCapability(
entityName: 'Server' | 'Client'
): void {
if (!requests) {
throw new Error(`${entityName} does not support task creation (required for ${method})`);
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
}
switch (method) {
case 'sampling/createMessage': {
if (!requests.sampling?.createMessage) {
throw new Error(`${entityName} does not support task creation for sampling/createMessage (required for ${method})`);
throw new SdkError(
SdkErrorCode.CapabilityNotSupported,
`${entityName} does not support task creation for sampling/createMessage (required for ${method})`
);
}
break;
}
case 'elicitation/create': {
if (!requests.elicitation?.create) {
throw new Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);
throw new SdkError(
SdkErrorCode.CapabilityNotSupported,
`${entityName} does not support task creation for elicitation/create (required for ${method})`
);
}
break;
}

View file

@ -22,7 +22,7 @@ import type {
ResponseMessage,
ResultTypeMap
} from '@modelcontextprotocol/core';
import { getResultSchema, GetTaskPayloadResultSchema } from '@modelcontextprotocol/core';
import { getResultSchema, GetTaskPayloadResultSchema, SdkError, SdkErrorCode } from '@modelcontextprotocol/core';
import type { Server } from '../../server/server.js';
@ -122,7 +122,7 @@ export class ExperimentalServerTasks {
// Capability check - only required when tools/toolChoice are provided
if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
throw new Error('Client does not support sampling tools capability.');
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support sampling tools capability.');
}
// Message structure validation - always validate tool_use/tool_result pairs.
@ -221,13 +221,13 @@ export class ExperimentalServerTasks {
switch (mode) {
case 'url': {
if (!clientCapabilities?.elicitation?.url) {
throw new Error('Client does not support url elicitation.');
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support url elicitation.');
}
break;
}
case 'form': {
if (!clientCapabilities?.elicitation?.form) {
throw new Error('Client does not support form elicitation.');
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support form elicitation.');
}
break;
}