Skip to content

Commit ff24774

Browse files
Merge branch 'main' into fweinberger/abort-handlers-on-close
2 parents 6dd5629 + 5516c1b commit ff24774

8 files changed

Lines changed: 84 additions & 12 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@modelcontextprotocol/core': patch
3+
---
4+
5+
Add missing `size` field to `ResourceSchema` to match the MCP specification
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modelcontextprotocol/core': patch
3+
'@modelcontextprotocol/client': patch
4+
'@modelcontextprotocol/server': patch
5+
---
6+
7+
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`.

docs/server.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,26 @@ server.registerTool(
330330
>
331331
> For protocol details, see [Logging](https://modelcontextprotocol.io/specification/latest/server/utilities/logging) in the MCP specification.
332332
333+
## Instructions
334+
335+
Pass an `instructions` string in the server options to describe how to use the server and its features. This can be used by clients to improve the LLM's understanding of available tools, resources, and prompts. It can be thought of like a "hint" to the model — for example, a client MAY add it to the system prompt. See [Instructions](https://modelcontextprotocol.io/specification/latest/basic/lifecycle#instructions) in the MCP specification.
336+
337+
```ts source="../examples/server/src/serverGuide.examples.ts#instructions_basic"
338+
const server = new McpServer(
339+
{
340+
name: 'multi-tool-server',
341+
version: '1.0.0'
342+
},
343+
{
344+
instructions: `This server provides data-pipeline tools. Always call "validate-schema"
345+
before calling "transform-data" to avoid runtime errors.`
346+
}
347+
);
348+
```
349+
350+
> [!TIP]
351+
> Use instructions for cross-tool relationships, workflow ordering, and constraints that individual tool descriptions cannot express on their own.
352+
333353
## Server‑initiated requests
334354

335355
MCP is bidirectional — servers can also send requests *to* the client during tool execution, as long as the client declares matching capabilities.

examples/server/src/serverGuide.examples.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@ import type { CallToolResult, ResourceLink } from '@modelcontextprotocol/server'
1515
import { completable, McpServer, ResourceTemplate, StdioServerTransport } from '@modelcontextprotocol/server';
1616
import * as z from 'zod/v4';
1717

18+
// ---------------------------------------------------------------------------
19+
// Instructions
20+
// ---------------------------------------------------------------------------
21+
22+
/** Example: Providing server instructions to guide LLM usage. */
23+
function instructions_basic() {
24+
//#region instructions_basic
25+
const server = new McpServer(
26+
{
27+
name: 'multi-tool-server',
28+
version: '1.0.0'
29+
},
30+
{
31+
instructions: `This server provides data-pipeline tools. Always call "validate-schema"
32+
before calling "transform-data" to avoid runtime errors.`
33+
}
34+
);
35+
//#endregion instructions_basic
36+
return server;
37+
}
38+
1839
// ---------------------------------------------------------------------------
1940
// Tools, resources, and prompts
2041
// ---------------------------------------------------------------------------
@@ -373,6 +394,7 @@ function dnsRebinding_allowedHosts() {
373394
}
374395

375396
// Suppress unused-function warnings (functions exist solely for type-checking)
397+
void instructions_basic;
376398
void registerTool_basic;
377399
void registerTool_resourceLink;
378400
void registerTool_logging;

packages/client/src/client/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ export class Client extends Protocol<ClientContext> {
456456

457457
protected assertCapability(capability: keyof ServerCapabilities, method: string): void {
458458
if (!this._serverCapabilities?.[capability]) {
459-
throw new Error(`Server does not support ${capability} (required for ${method})`);
459+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support ${capability} (required for ${method})`);
460460
}
461461
}
462462

packages/core/src/experimental/tasks/helpers.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* @experimental
66
*/
77

8+
import { SdkError, SdkErrorCode } from '../../errors/sdkErrors.js';
9+
810
/**
911
* Type representing the task requests capability structure.
1012
* This is derived from `ClientTasksCapability.requests` and `ServerTasksCapability.requests`.
@@ -22,7 +24,7 @@ interface TaskRequestsCapability {
2224
* @param requests - The task requests capability object
2325
* @param method - The method being checked
2426
* @param entityName - `'Server'` or `'Client'` for error messages
25-
* @throws Error if the capability is not supported
27+
* @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
2628
*
2729
* @experimental
2830
*/
@@ -32,13 +34,16 @@ export function assertToolsCallTaskCapability(
3234
entityName: 'Server' | 'Client'
3335
): void {
3436
if (!requests) {
35-
throw new Error(`${entityName} does not support task creation (required for ${method})`);
37+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
3638
}
3739

3840
switch (method) {
3941
case 'tools/call': {
4042
if (!requests.tools?.call) {
41-
throw new Error(`${entityName} does not support task creation for tools/call (required for ${method})`);
43+
throw new SdkError(
44+
SdkErrorCode.CapabilityNotSupported,
45+
`${entityName} does not support task creation for tools/call (required for ${method})`
46+
);
4247
}
4348
break;
4449
}
@@ -57,7 +62,7 @@ export function assertToolsCallTaskCapability(
5762
* @param requests - The task requests capability object
5863
* @param method - The method being checked
5964
* @param entityName - `'Server'` or `'Client'` for error messages
60-
* @throws Error if the capability is not supported
65+
* @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported
6166
*
6267
* @experimental
6368
*/
@@ -67,20 +72,26 @@ export function assertClientRequestTaskCapability(
6772
entityName: 'Server' | 'Client'
6873
): void {
6974
if (!requests) {
70-
throw new Error(`${entityName} does not support task creation (required for ${method})`);
75+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);
7176
}
7277

7378
switch (method) {
7479
case 'sampling/createMessage': {
7580
if (!requests.sampling?.createMessage) {
76-
throw new Error(`${entityName} does not support task creation for sampling/createMessage (required for ${method})`);
81+
throw new SdkError(
82+
SdkErrorCode.CapabilityNotSupported,
83+
`${entityName} does not support task creation for sampling/createMessage (required for ${method})`
84+
);
7785
}
7886
break;
7987
}
8088

8189
case 'elicitation/create': {
8290
if (!requests.elicitation?.create) {
83-
throw new Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);
91+
throw new SdkError(
92+
SdkErrorCode.CapabilityNotSupported,
93+
`${entityName} does not support task creation for elicitation/create (required for ${method})`
94+
);
8495
}
8596
break;
8697
}

packages/core/src/types/schemas.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,13 @@ export const ResourceSchema = z.object({
832832
*/
833833
mimeType: z.optional(z.string()),
834834

835+
/**
836+
* The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
837+
*
838+
* This can be used by Hosts to display file sizes and estimate context window usage.
839+
*/
840+
size: z.optional(z.number()),
841+
835842
/**
836843
* Optional annotations for the client.
837844
*/

packages/server/src/experimental/tasks/server.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import type {
2222
ResponseMessage,
2323
ResultTypeMap
2424
} from '@modelcontextprotocol/core';
25-
import { getResultSchema, GetTaskPayloadResultSchema } from '@modelcontextprotocol/core';
25+
import { getResultSchema, GetTaskPayloadResultSchema, SdkError, SdkErrorCode } from '@modelcontextprotocol/core';
2626

2727
import type { Server } from '../../server/server.js';
2828

@@ -122,7 +122,7 @@ export class ExperimentalServerTasks {
122122

123123
// Capability check - only required when tools/toolChoice are provided
124124
if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
125-
throw new Error('Client does not support sampling tools capability.');
125+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support sampling tools capability.');
126126
}
127127

128128
// Message structure validation - always validate tool_use/tool_result pairs.
@@ -221,13 +221,13 @@ export class ExperimentalServerTasks {
221221
switch (mode) {
222222
case 'url': {
223223
if (!clientCapabilities?.elicitation?.url) {
224-
throw new Error('Client does not support url elicitation.');
224+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support url elicitation.');
225225
}
226226
break;
227227
}
228228
case 'form': {
229229
if (!clientCapabilities?.elicitation?.form) {
230-
throw new Error('Client does not support form elicitation.');
230+
throw new SdkError(SdkErrorCode.CapabilityNotSupported, 'Client does not support form elicitation.');
231231
}
232232
break;
233233
}

0 commit comments

Comments
 (0)