Skip to content

Commit 98d7742

Browse files
docs(core): clarify schema-bundle overload validates only; add test
The {params, result} schema bundle in sendCustomRequest/sendCustomNotification is a type guard, not a transformer — the caller-provided value is sent as-is, matching request()/v1 behavior. Transforms/defaults on the params schema are not applied outbound (parsed.data is intentionally unused on the send path). Adds JSDoc and a test asserting params are sent verbatim.
1 parent 07c5491 commit 98d7742

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

packages/core/src/shared/protocol.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,10 @@ export abstract class Protocol<ContextT extends BaseContext> {
11431143
*
11441144
* Pass a `{ params, result }` schema bundle as the third argument to get typed `params` and
11451145
* pre-send validation; pass a bare result schema for loose, unvalidated params.
1146+
*
1147+
* The `params` schema is used only for validation — the value you pass is sent as-is.
1148+
* Transforms (e.g. `.trim()`) and defaults (e.g. `.default(n)`) on the schema are not
1149+
* applied to outbound data, matching the behavior of {@linkcode Protocol.request | request}.
11461150
*/
11471151
sendCustomRequest<P extends AnySchema, R extends AnySchema>(
11481152
method: string,
@@ -1185,7 +1189,8 @@ export abstract class Protocol<ContextT extends BaseContext> {
11851189
* standard MCP notifications.
11861190
*
11871191
* Pass a `{ params }` schema bundle as the third argument to get typed `params` and pre-send
1188-
* validation.
1192+
* validation. The schema validates only — transforms and defaults are not applied to
1193+
* outbound data; the value you pass is sent as-is.
11891194
*/
11901195
sendCustomNotification<P extends AnySchema>(
11911196
method: string,

packages/core/test/shared/customMethods.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ describe('sendCustomRequest', () => {
191191
})
192192
).rejects.toSatisfy((e: unknown) => e instanceof ProtocolError && e.code === ProtocolErrorCode.InvalidParams);
193193
});
194+
195+
test('schema bundle overload: params sent as-is (validate-only, no outbound transforms)', async () => {
196+
const [client, server] = await linkedPair();
197+
const P = z.object({ query: z.string().transform(s => s.trim()), page: z.number() });
198+
let received: unknown;
199+
server.setCustomRequestHandler('acme/q', z.unknown(), p => {
200+
received = p;
201+
return {};
202+
});
203+
await client.sendCustomRequest('acme/q', { query: ' hi ', page: 1 }, { params: P, result: z.object({}) });
204+
expect(received).toEqual({ query: ' hi ', page: 1 });
205+
});
194206
});
195207

196208
describe('sendCustomNotification', () => {

0 commit comments

Comments
 (0)