@wakeshift/sdk 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/host.js ADDED
@@ -0,0 +1,380 @@
1
+ // What attach needs of an MCP server, for each MCP TypeScript SDK it takes:
2
+ // @modelcontextprotocol/sdk 1.x and @modelcontextprotocol/server 2.x. The
3
+ // rest of the SDK (events.ts, toolcall.ts, tasks.ts, discover.ts) is
4
+ // written once against Host, and neither MCP SDK is imported here: hostOf
5
+ // tells them apart by the server object it's given.
6
+ //
7
+ // Where the two differ:
8
+ // - a request's context: 1.x's `extra` (_meta, requestInfo.headers,
9
+ // authInfo, signal), 2.x's `ctx` (mcpReq._meta without the reserved
10
+ // io.modelcontextprotocol/* keys, which it lifts into mcpReq.envelope;
11
+ // http.req's Headers; http.authInfo; mcpReq.signal). req() reads either
12
+ // into one shape, putting the envelope's keys back into _meta, so
13
+ // Wakeshift gets the same call from both (test/mcp-tasks-wire.json);
14
+ // - custom methods (events/*): a zod request schema on 1.x, a method name
15
+ // and a params schema on 2.x;
16
+ // - tasks/get and tasks/cancel: 2.x answers them on protocol 2026-07-28
17
+ // only for a handler registered with a params schema (the tasks
18
+ // extension's methods), so setTaskMethod registers them that way;
19
+ // - protocol 2026-07-28: 1.x doesn't speak it, so discover.ts teaches it;
20
+ // 2.x speaks it itself (server/discover, resultType, ttlMs and
21
+ // cacheScope).
22
+ //
23
+ // Both keep their request handlers in a private Map (_requestHandlers),
24
+ // which tools/list, tools/call, server/discover and tasks/* are wrapped
25
+ // through (neither has public middleware for a method it answers itself),
26
+ // and their tools in _registeredTools, which wrapped tools are checked
27
+ // against. Unit tests pin both against each SDK the CI installs.
28
+ import { z } from "zod";
29
+ import * as z4 from "zod/v4";
30
+ import { normalizeObjectSchema, safeParseAsync } from "./zod.js";
31
+ const VERSION_META = "io.modelcontextprotocol/protocolVersion";
32
+ function lowOf(server) {
33
+ return server.server;
34
+ }
35
+ /**
36
+ * @internal The Host for an McpServer from either SDK. 2.x's low-level
37
+ * Server has projectCallToolResult, which 1.x's lacks.
38
+ */
39
+ export function hostOf(server) {
40
+ if (!isMcpServer(server))
41
+ throw new Error(unsupportedServer(server));
42
+ const low = server.server;
43
+ return typeof low.projectCallToolResult === "function" ? new V2Host(server) : new V1Host(server);
44
+ }
45
+ /** Where the docs list the MCP server frameworks Wakeshift works with, and how. */
46
+ export const FRAMEWORKS_DOCS = "https://wakeshift.ai/docs/frameworks";
47
+ // isMcpServer: an McpServer from either MCP SDK (its low-level server, and registerTool).
48
+ function isMcpServer(server) {
49
+ const low = server?.server;
50
+ return !!low && typeof low.setRequestHandler === "function" && typeof server.registerTool === "function";
51
+ }
52
+ const TAKES = "wakeshift: attach takes an McpServer, from @modelcontextprotocol/server 2.x or @modelcontextprotocol/sdk 1.x (@modelcontextprotocol/sdk/server/mcp.js)";
53
+ /**
54
+ * @internal What attach says when it's given something other than an
55
+ * McpServer: what it got, what it takes, and, for a framework it knows,
56
+ * what to do instead.
57
+ */
58
+ export function unsupportedServer(server) {
59
+ const got = describe(server);
60
+ const hint = frameworkHint(server);
61
+ return `${TAKES}, and got ${got}.${hint ? " " + hint : ""} Frameworks Wakeshift works with, and how: ${FRAMEWORKS_DOCS}`;
62
+ }
63
+ function has(o, ...fns) {
64
+ return !!o && (typeof o === "object" || typeof o === "function") && fns.every((f) => typeof o[f] === "function");
65
+ }
66
+ function ctorName(o) {
67
+ const name = o?.constructor?.name;
68
+ return typeof name === "string" && name && name !== "Object" ? name : "";
69
+ }
70
+ // describe names what attach was given: its class, else its type.
71
+ function describe(server) {
72
+ if (server === null)
73
+ return "null";
74
+ if (server === undefined)
75
+ return "undefined";
76
+ if (typeof server !== "object")
77
+ return `a ${typeof server}`;
78
+ const name = ctorName(server);
79
+ return name ? `a ${name}` : "an object";
80
+ }
81
+ // frameworkHint says what to do for a server from a framework attach knows
82
+ // but can't take: "" for any other.
83
+ function frameworkHint(server) {
84
+ if (!server || typeof server !== "object")
85
+ return "";
86
+ // Mastra's MCPServer (@mastra/mcp): builds its MCP server per request, inside.
87
+ if (has(server, "startHTTP", "convertTools") || (has(server, "startHTTP", "startStdio") && "toolActions" in server)) {
88
+ return "This looks like Mastra's MCPServer (@mastra/mcp), which builds its MCP server inside: use attachMastra from @wakeshift/sdk/mastra.";
89
+ }
90
+ // punkpeye's fastmcp: its FastMCP, or a session of it.
91
+ if (has(server, "addTool", "start") && ctorName(server) === "FastMCP") {
92
+ return "This looks like fastmcp's FastMCP (punkpeye), which Wakeshift doesn't support: it refuses MCP protocol 2026-07-28.";
93
+ }
94
+ if (ctorName(server) === "FastMCPSession") {
95
+ return "This looks like a fastmcp session (punkpeye), which Wakeshift doesn't support: fastmcp refuses MCP protocol 2026-07-28.";
96
+ }
97
+ // A low-level Server, not the McpServer around it.
98
+ if (has(server, "setRequestHandler", "connect") && !has(server, "registerTool")) {
99
+ return "This is a low-level MCP Server: pass the McpServer instead (new McpServer(…), whose .server it is).";
100
+ }
101
+ // Cloudflare's McpAgent: its server is the McpServer.
102
+ if ("server" in server && has(server, "init") && isMcpServer(server.server)) {
103
+ return "This looks like a Cloudflare McpAgent: pass its McpServer (this.server).";
104
+ }
105
+ return "";
106
+ }
107
+ /**
108
+ * @internal attach's error when the server refused Wakeshift's
109
+ * capabilities: an McpServer already connected to a transport, or
110
+ * whatever else its MCP SDK said.
111
+ */
112
+ export function capabilitiesError(host, err) {
113
+ const low = host.server.server;
114
+ if (low?.transport)
115
+ return new Error("wakeshift: call attach before connecting the server to a transport", { cause: err });
116
+ return new Error(`wakeshift: attach couldn't add Wakeshift's capabilities to this server: ${String(err?.message ?? err)}`, { cause: err });
117
+ }
118
+ // headerOf reads a header from a plain record (1.x's requestInfo.headers).
119
+ function headerOf(headers, name) {
120
+ if (!headers)
121
+ return "";
122
+ const v = headers[name] ?? headers[name.toLowerCase()];
123
+ return (Array.isArray(v) ? v[0] : v) ?? "";
124
+ }
125
+ /** @internal A context already read (req's output). */
126
+ function isReq(raw) {
127
+ return !!raw && typeof raw.header === "function" && "meta" in raw;
128
+ }
129
+ /**
130
+ * @internal A request's context read the 1.x way: extra's _meta,
131
+ * requestInfo.headers, authInfo and signal. Also what a plain
132
+ * `{ _meta, requestInfo }` (ToolExtra) reads as.
133
+ */
134
+ export function v1Req(raw) {
135
+ if (isReq(raw))
136
+ return raw;
137
+ const e = (raw ?? {});
138
+ return { meta: e._meta, header: (name) => headerOf(e.requestInfo?.headers, name), authInfo: e.authInfo, signal: e.signal };
139
+ }
140
+ /** @internal A request's context read the 2.x way (ctx), putting the envelope's keys back into _meta. */
141
+ export function v2Req(raw) {
142
+ if (isReq(raw))
143
+ return raw;
144
+ const c = (raw ?? {});
145
+ if (!c.mcpReq)
146
+ return v1Req(raw);
147
+ const own = c.mcpReq._meta;
148
+ const env = c.mcpReq.envelope;
149
+ const meta = env && Object.keys(env).length > 0 ? { ...env, ...own } : own;
150
+ const headers = c.http?.req?.headers;
151
+ return {
152
+ meta,
153
+ header: (name) => (headers && typeof headers.get === "function" ? (headers.get(name) ?? "") : ""),
154
+ authInfo: c.http?.authInfo,
155
+ signal: c.mcpReq.signal,
156
+ };
157
+ }
158
+ class BaseHost {
159
+ server;
160
+ servesEvents = true;
161
+ constructor(server) {
162
+ this.server = server;
163
+ }
164
+ get low() {
165
+ return lowOf(this.server);
166
+ }
167
+ registerCapabilities(capabilities) {
168
+ this.low.registerCapabilities(capabilities);
169
+ }
170
+ handlers() {
171
+ const h = this.low._requestHandlers;
172
+ return h instanceof Map ? h : null;
173
+ }
174
+ clientName() {
175
+ return this.low.getClientVersion?.()?.name || undefined;
176
+ }
177
+ clientCapabilities() {
178
+ return this.low.getClientCapabilities?.();
179
+ }
180
+ onInitialized(fn) {
181
+ const low = this.low;
182
+ const prev = low.oninitialized;
183
+ low.oninitialized = () => {
184
+ fn();
185
+ prev?.();
186
+ };
187
+ }
188
+ registeredTool(name) {
189
+ const tools = this.server._registeredTools;
190
+ if (!tools || typeof tools !== "object")
191
+ return null;
192
+ return Object.prototype.hasOwnProperty.call(tools, name) ? tools[name] : undefined;
193
+ }
194
+ }
195
+ class V1Host extends BaseHost {
196
+ version = 1;
197
+ zod = z;
198
+ req(raw) {
199
+ return v1Req(raw);
200
+ }
201
+ registerTool(name, config, cb) {
202
+ return this.server.registerTool(name, config, cb);
203
+ }
204
+ setMethod(method, handler) {
205
+ const schema = z.object({ method: z.literal(method), params: z.any().optional() });
206
+ this.low.setRequestHandler(schema, (request, extra) => handler(request.params ?? {}, extra));
207
+ }
208
+ setTaskMethod(_method) {
209
+ // Nothing to register: 1.x routes whatever is in its handler map. (Its
210
+ // setRequestHandler would ask for its own tasks capability, an older
211
+ // revision's, never advertised.)
212
+ }
213
+ async validOutput(outputSchema, result) {
214
+ // McpServer 1.x's validateToolOutput: an object schema, and structured content that parses.
215
+ if (!outputSchema)
216
+ return true;
217
+ if (typeof result === "string" || !result.structuredContent)
218
+ return false;
219
+ const obj = normalizeObjectSchema(outputSchema);
220
+ if (!obj)
221
+ return true;
222
+ return (await safeParseAsync(obj, result.structuredContent)).success;
223
+ }
224
+ }
225
+ class V2Host extends BaseHost {
226
+ version = 2;
227
+ zod = z4;
228
+ req(raw) {
229
+ return v2Req(raw);
230
+ }
231
+ registerTool(name, config, cb) {
232
+ // 2.x takes an object schema (a bare shape is deprecated there).
233
+ return this.server.registerTool(name, { ...config, inputSchema: objectFromV4Shape(config.inputSchema) }, cb);
234
+ }
235
+ setMethod(method, handler) {
236
+ this.low.setRequestHandler(method, { params: z4.looseObject({}) }, (params, ctx) => handler(params ?? {}, ctx));
237
+ }
238
+ setTaskMethod(method) {
239
+ // Registered with a params schema, so 2.x serves it on protocol
240
+ // 2026-07-28 too, as the tasks extension's method (SEP-2663). The
241
+ // caller replaces the handler that leaves in the map.
242
+ this.low.setRequestHandler(method, { params: z4.looseObject({}) }, async () => {
243
+ throw Object.assign(new Error("Method not found"), { code: -32601 });
244
+ });
245
+ }
246
+ async validOutput(outputSchema, result) {
247
+ // McpServer 2.x's validateToolOutput: structured content (any JSON
248
+ // value) that the output schema (a Standard Schema) accepts.
249
+ if (!outputSchema)
250
+ return true;
251
+ if (typeof result === "string" || result.structuredContent === undefined)
252
+ return false;
253
+ const std = outputSchema["~standard"];
254
+ if (!std || typeof std.validate !== "function")
255
+ return true;
256
+ const out = (await std.validate(result.structuredContent));
257
+ return !out.issues;
258
+ }
259
+ }
260
+ // objectFromV4Shape is a zod 4 object of attach's own tool shapes (written
261
+ // with zod/v4: host.zod).
262
+ function objectFromV4Shape(shape) {
263
+ const values = Object.values(shape);
264
+ if (values.length === 0)
265
+ return z4.object({});
266
+ return z4.object(shape);
267
+ }
268
+ // ── Framework adapters (mastra.ts, xmcp.ts) ─────────────────────────────
269
+ /**
270
+ * @internal The Host for a low-level Server from @modelcontextprotocol/server
271
+ * 2.x, as a framework builds one for each request and fills in itself
272
+ * (Mastra's MCPServer). It has no McpServer to register attach's own
273
+ * tools on, so they're kept here and served from its handler map, beneath
274
+ * every other wrapper attach adds: tools/list lists them after the
275
+ * framework's own, and tools/call answers them. Everything else is
276
+ * V2Host's, on the same map.
277
+ */
278
+ export function lowServerHost(low, framework) {
279
+ if (!low || typeof low.setRequestHandler !== "function" || !(low._requestHandlers instanceof Map)) {
280
+ throw new Error(`wakeshift: ${framework} built an MCP server Wakeshift can't serve (no request handlers it can wrap): check for a newer @wakeshift/sdk`);
281
+ }
282
+ return new LowV2Host(new ToolRegistry(low), framework);
283
+ }
284
+ // ToolRegistry stands in for an McpServer around a low-level Server: what
285
+ // attach registers on it is listed and called through the server's handlers.
286
+ class ToolRegistry {
287
+ server;
288
+ tools = new Map();
289
+ constructor(server) {
290
+ this.server = server;
291
+ const handlers = server._requestHandlers;
292
+ const list = handlers.get("tools/list");
293
+ const call = handlers.get("tools/call");
294
+ if (list) {
295
+ Map.prototype.set.call(handlers, "tools/list", async (request, raw) => {
296
+ const out = await list(request, raw);
297
+ const own = [...this.tools].filter(([, t]) => t.enabled);
298
+ if (own.length === 0 || !out || !Array.isArray(out.tools))
299
+ return out;
300
+ const listed = new Set(out.tools.map((t) => t?.name));
301
+ return { ...out, tools: [...out.tools, ...own.filter(([name]) => !listed.has(name)).map(([name, t]) => listedTool(name, t))] };
302
+ });
303
+ }
304
+ if (call) {
305
+ Map.prototype.set.call(handlers, "tools/call", async (request, raw) => {
306
+ const t = this.tools.get(request?.params?.name);
307
+ if (!t || !t.enabled)
308
+ return call(request, raw);
309
+ const parsed = await t.schema.safeParseAsync(request?.params?.arguments ?? {});
310
+ if (!parsed.success) {
311
+ return { isError: true, content: [{ type: "text", text: `Invalid arguments for tool ${request.params.name}: ${parsed.error.message}` }] };
312
+ }
313
+ return t.cb(parsed.data, raw);
314
+ });
315
+ }
316
+ }
317
+ registerTool(name, config, cb) {
318
+ const t = { description: config.description, annotations: config.annotations, schema: config.inputSchema, cb, enabled: true };
319
+ this.tools.set(name, t);
320
+ return {
321
+ enable: () => void (t.enabled = true),
322
+ disable: () => void (t.enabled = false),
323
+ };
324
+ }
325
+ }
326
+ function listedTool(name, t) {
327
+ const out = { name, description: t.description, inputSchema: z4.toJSONSchema(t.schema, { io: "input" }) };
328
+ if (t.annotations)
329
+ out.annotations = t.annotations;
330
+ return out;
331
+ }
332
+ class LowV2Host extends V2Host {
333
+ framework;
334
+ constructor(registry, framework) {
335
+ super(registry);
336
+ this.framework = framework;
337
+ }
338
+ registeredTool() {
339
+ return null; // the framework's own tools are its own
340
+ }
341
+ }
342
+ /**
343
+ * @internal The Host for a framework that keeps its MCP server to itself
344
+ * (xmcp): attach's own tools go to the adapter, the request is read its
345
+ * way, and there are no handlers to wrap, so no MCP Events, no wait tool
346
+ * and no tools/list changes. Its tools are on @modelcontextprotocol/server
347
+ * 2.x, so they're written in zod 4.
348
+ */
349
+ export function toolsOnlyHost(opts) {
350
+ const noop = () => { };
351
+ return {
352
+ version: 2,
353
+ framework: opts.framework,
354
+ servesEvents: false,
355
+ server: { server: {}, registerTool: noop },
356
+ zod: z4,
357
+ req: opts.req,
358
+ registerCapabilities: noop,
359
+ registerTool(name, config, cb) {
360
+ opts.registerTool(name, config, cb);
361
+ return { enable: noop, disable: noop };
362
+ },
363
+ setMethod: noop,
364
+ setTaskMethod: noop,
365
+ handlers: () => null,
366
+ clientName: () => undefined,
367
+ clientCapabilities: () => undefined,
368
+ onInitialized: noop,
369
+ registeredTool: () => null,
370
+ validOutput: async () => true,
371
+ };
372
+ }
373
+ /** The protocol revision that has server/discover, MCP Events and the tasks extension. */
374
+ export const STATELESS_VERSION = "2026-07-28";
375
+ /** @internal Whether a request is protocol 2026-07-28: its _meta names it, or its MCP-Protocol-Version header does. */
376
+ export function is2026(req) {
377
+ if (req.meta?.[VERSION_META] === STATELESS_VERSION)
378
+ return true;
379
+ return req.header("mcp-protocol-version") === STATELESS_VERSION;
380
+ }
package/dist/index.d.ts CHANGED
@@ -3,5 +3,6 @@ export { harnessAgent } from "./harness.js";
3
3
  export { WakeshiftError, isCode } from "./errors.js";
4
4
  export { parseKey, signAssertion, type AppKey } from "./key.js";
5
5
  export { WakeEvent, ArgsError, EVENT_TOOL_TEXT, SUBSCRIBE_TOOL_DESCRIPTION, UNSUBSCRIBE_TOOL_DESCRIPTION, LIST_TOOL_DESCRIPTION, BUILTIN_TOOLS, type BuiltinTool, type EventOptions, type EmitOptions, type EventStatus, type EventSubscriptionStatus, MAX_STATUS_SUBSCRIPTIONS, type EventTypeManifest, type AttachOptions, type Identity, type Subscriber, } from "./events.js";
6
- export { CallEnded, type Attached, type AppArgs, type EventsOptions, type Subscription, type ToolCall, type ToolCallExtra, type ToolSubscribeOptions, type WakeInputs, type WakeKey, type WakeOutputShape, type WakeShape, type WrappedResult, } from "./toolcall.js";
6
+ export { CallEnded, type Attached, type AppArgs, type EventsOptions, type Subscription, type ToolCall, type ToolCallExtra, type ToolSubscribeOptions, type WakeArgs, type WakeInputs, type WakeInputsV3, type WakeInputsV4, type WakeKey, type WakeOutputShape, type WakeOutputV3, type WakeOutputV4, type WakeShape, type WrappedCallback, type WrappedResult, } from "./toolcall.js";
7
+ export type { AuthInfo, CallToolResult, ContentBlock, HostContext, McpServerLike } from "./mcp.js";
7
8
  export { EXTENSION_KEY, TEXT_META, REVISION as EVENTS_REVISION } from "./spec.js";
package/dist/index.js CHANGED
@@ -5,4 +5,3 @@ export { parseKey, signAssertion } from "./key.js";
5
5
  export { WakeEvent, ArgsError, EVENT_TOOL_TEXT, SUBSCRIBE_TOOL_DESCRIPTION, UNSUBSCRIBE_TOOL_DESCRIPTION, LIST_TOOL_DESCRIPTION, BUILTIN_TOOLS, MAX_STATUS_SUBSCRIPTIONS, } from "./events.js";
6
6
  export { CallEnded, } from "./toolcall.js";
7
7
  export { EXTENSION_KEY, TEXT_META, REVISION as EVENTS_REVISION } from "./spec.js";
8
- //# sourceMappingURL=index.js.map
package/dist/key.js CHANGED
@@ -108,4 +108,3 @@ export function signAssertion(k, core, now = Date.now(), appId) {
108
108
  const input = b64({ alg: "EdDSA", typ: "app+jwt", kid: k.kid }) + "." + b64(claims);
109
109
  return input + "." + sign(null, Buffer.from(input), k.privateKey).toString("base64url");
110
110
  }
111
- //# sourceMappingURL=key.js.map
@@ -0,0 +1,79 @@
1
+ import type * as z3 from "zod/v3";
2
+ import type * as z4 from "zod/v4";
3
+ import type { ToolCallExtra } from "./mcp.js";
4
+ import type { ZodRawShapeCompat } from "./zod.js";
5
+ import { type AttachOptions, type BuiltinTool, type Identity } from "./events.js";
6
+ import { CallEnded, type ToolCall, type WakeArgs, type WakeInputs, type WakeInputsV3, type WakeInputsV4, type WakeOutputShape, type WakeOutputV3, type WakeOutputV4 } from "./toolcall.js";
7
+ import type { Wakeshift } from "./wakeshift.js";
8
+ /** The @mastra/mcp releases serve() is built for: 2.x, from 2.7. */
9
+ export declare const MASTRA_MCP_RANGE = ">=2.7.0 <3.0.0";
10
+ /**
11
+ * The request context Wakeshift reads in Mastra: the MCP SDK 2.x's
12
+ * ServerContext (`ctx`) of the request, the verified token in
13
+ * `ctx.http?.authInfo`. A Mastra tool sees the same as `context.mcp.extra`.
14
+ */
15
+ export type MastraContext = ToolCallExtra;
16
+ /** attachMastra's options: attach's, with identify and events.native getting the request's ctx. */
17
+ export type MastraAttachOptions = AttachOptions<MastraContext>;
18
+ /** The second argument Mastra passes a tool's execute: what Wakeshift reads of it. */
19
+ export interface MastraToolContext {
20
+ mcp?: {
21
+ extra?: {
22
+ mcpReq?: object;
23
+ [k: string]: any;
24
+ };
25
+ [k: string]: any;
26
+ };
27
+ [k: string]: any;
28
+ }
29
+ /** Wakeshift in a Mastra MCPServer: make it with attachMastra, then serve your MCPServer with it. */
30
+ export declare class MastraAttached {
31
+ private readonly wake;
32
+ private readonly opts;
33
+ private readonly wrapped;
34
+ private readonly scopes;
35
+ private readonly shapes;
36
+ private readonly served;
37
+ /**
38
+ * A tool's input schema plus Wakeshift's three optional arguments
39
+ * (session_key, harness and conversation_id), for a wrapped tool's
40
+ * inputSchema: `inputSchema: attached.inputs(z.object({ … }))`.
41
+ */
42
+ inputs<O extends z4.ZodObject>(schema: O): z4.ZodObject<O["shape"] & WakeInputsV4, O["_zod"]["config"]>;
43
+ inputs<O extends z3.AnyZodObject>(schema: O): z3.ZodObject<O["shape"] & WakeInputsV3, O["_def"]["unknownKeys"], O["_def"]["catchall"]>;
44
+ inputs<S extends ZodRawShapeCompat>(shape: S): S & WakeInputs;
45
+ /** A tool's output schema plus an optional wakeshift string, for a wrapped tool's outputSchema. Optional: see attach's. */
46
+ output<O extends z4.ZodObject>(schema: O): z4.ZodObject<O["shape"] & WakeOutputV4, O["_zod"]["config"]>;
47
+ output<O extends z3.AnyZodObject>(schema: O): z3.ZodObject<O["shape"] & WakeOutputV3, O["_def"]["unknownKeys"], O["_def"]["catchall"]>;
48
+ output<S extends ZodRawShapeCompat>(shape: S): S & WakeOutputShape;
49
+ /**
50
+ * Wraps a Mastra tool's execute, for the tool your MCPServer serves under
51
+ * the same name (its key in `tools`): `execute: attached.events("watch_ci",
52
+ * async (args, call) => …)`. handler gets your own arguments, a ToolCall
53
+ * and Mastra's tool context, and returns what a Mastra tool returns (a
54
+ * string, or your output). The reply an MCP client gets carries what
55
+ * Wakeshift adds for the conversation; a call that fails ends the
56
+ * subscriptions it made. Its inputSchema must come from attached.inputs.
57
+ * Run outside an MCP request (by an agent, a workflow or Studio), the
58
+ * handler gets a call whose subscribe throws.
59
+ */
60
+ events<P extends Record<string, any> = Record<string, any>, R = unknown>(name: string, handler: (args: P, call: ToolCall<MastraContext>, context: MastraToolContext) => R | Promise<R>): (input: P & WakeArgs, context?: any) => Promise<R>;
61
+ /**
62
+ * Serves Wakeshift from your MCPServer (@mastra/mcp 2.7 or later, 2.x),
63
+ * after your last defineEvent: attach's own tools, MCP Events for clients
64
+ * that speak it, the wait tool, and your wrapped tools' blocks. Returns
65
+ * the server. Call it once, before the server takes requests.
66
+ */
67
+ serve<S extends object>(server: S): S;
68
+ private attachTo;
69
+ private wrapCalls;
70
+ }
71
+ /**
72
+ * Wakeshift for a Mastra MCPServer (@mastra/mcp 2.7 or later). Returns the
73
+ * handle your tools use (attached.inputs, attached.events) and that serves
74
+ * your MCPServer (attached.serve). Options are attach's; identify and
75
+ * events.native get the request's MCP context (ctx: the verified token is
76
+ * ctx.http?.authInfo).
77
+ */
78
+ export declare function attachMastra(wake: Wakeshift, opts?: MastraAttachOptions): MastraAttached;
79
+ export { CallEnded, type BuiltinTool, type Identity, type ToolCall, type WakeArgs };