@wakeshift/sdk 0.6.0 → 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/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  What changed in each release of `@wakeshift/sdk`. 0.4.0 is the first published release: to start with it, read the [README](README.md). Its notes below, and the earlier releases', are for apps that ran the preview builds.
4
4
 
5
+ ## 0.7.0 (2026-10-31)
6
+
7
+ ### Added
8
+
9
+ - **Mastra.** `@wakeshift/sdk/mastra` serves Wakeshift from a Mastra `MCPServer` (`@mastra/mcp` 2.7 or later): `attachMastra(wake, opts)`, then `attached.inputs` and `attached.events` for the Mastra tools that subscribe, and `attached.serve(new MCPServer({ … }))`. Everything `attach` gives an `McpServer` works there: Wakeshift's block (text and `_meta`) in your wrapped tools' results, the built-in tools, MCP Events, Claude Code's `wakeshift_wait`, and who's calling (`identify` gets the request's `ctx`). Mastra's own MCP Events keep working beside Wakeshift's: `events/list` lists both. See [Mastra](README.md#mastra).
10
+ - **xmcp.** `@wakeshift/sdk/xmcp` brings Wakeshift into an xmcp app through its tool files: `attachXmcp(wake, opts)`, then `attached.inputs` and `attached.events` in the tools that subscribe, and `attached.tool("subscribe_events")` (and the other two) for a tool file each. xmcp offers no way to add MCP methods, so clients that subscribe natively (ChatGPT) and Claude Code's `wakeshift_wait` aren't served there; Claude Code and every other agent are woken their usual ways. See [xmcp](README.md#xmcp).
11
+ - Both are subpath exports, so an app that uses neither loads neither, and `@mastra/mcp` and `xmcp` are optional peer dependencies.
12
+
13
+ ### Changed
14
+
15
+ - **A smaller package.** It no longer ships source maps (`dist/*.js.map`), which carried the SDK's TypeScript source inline: about half the unpacked size. Stack traces point at the compiled JavaScript in `dist/`, which is readable as it is.
16
+ - **A clearer error from `attach`.** Given something other than an `McpServer`, `attach` says what it got and what it takes, and, for a framework it recognizes (Mastra's `MCPServer`, punkpeye's `fastmcp`, a low-level `Server`, a Cloudflare `McpAgent`), what to do instead (for Mastra, `attachMastra`), with a link to [the frameworks Wakeshift works with](https://wakeshift.ai/docs/frameworks). It says to call `attach` before connecting only when the server is already connected.
17
+
5
18
  ## 0.6.0 (2026-10-31)
6
19
 
7
20
  ### Breaking
package/README.md CHANGED
@@ -206,6 +206,83 @@ What's different on 2.x:
206
206
  - Write your schemas, events' included, with zod 4 (4.2 or later), which 2.x requires.
207
207
  - 2.x speaks MCP protocol 2026-07-28 itself, and `createMcpHandler` answers older clients too, so clients on either revision connect with nothing more to set up. Wakeshift lists its tools for each request's client, so `tools/list` is cached by that client only, whatever cache hint you set for it.
208
208
 
209
+ ## Mastra
210
+
211
+ Mastra's `MCPServer` (`@mastra/mcp` 2.7 or later) builds its MCP server itself, so it has its own entry point, `@wakeshift/sdk/mastra` (0.7.0 or later). Wrap the `execute` of each Mastra tool that subscribes, and serve your `MCPServer` with it:
212
+
213
+ ```ts
214
+ import { createTool } from "@mastra/core/tools"
215
+ import { MCPServer } from "@mastra/mcp"
216
+ import { z } from "zod"
217
+ import { Wakeshift } from "@wakeshift/sdk"
218
+ import { attachMastra } from "@wakeshift/sdk/mastra"
219
+
220
+ const wake = new Wakeshift({ key: process.env.WAKESHIFT_KEY! })
221
+ const ciFinished = wake.defineEvent("ci.finished", {
222
+ description: "CI finished on a GitHub repo",
223
+ args: z.object({ owner: z.string(), repo: z.string() }),
224
+ payload: z.object({ branch: z.string(), conclusion: z.string() }),
225
+ text: (run, { owner, repo }) => `CI ${run.conclusion} on ${owner}/${repo} ${run.branch}`,
226
+ })
227
+
228
+ // identify gets the request's MCP context: the verified token is ctx.http?.authInfo.
229
+ const attached = attachMastra(wake, { identify: (ctx) => ({ user: myUser(ctx.http?.authInfo) }) })
230
+
231
+ const watchCi = createTool({
232
+ id: "watch_ci",
233
+ description: "Watch CI on a repo",
234
+ inputSchema: attached.inputs(z.object({ owner: z.string(), repo: z.string() })),
235
+ execute: attached.events("watch_ci", async ({ owner, repo }: { owner: string; repo: string }, call) => {
236
+ await call.subscribe(ciFinished, { owner, repo }, { reason: `Watching ${owner}/${repo}` })
237
+ return `Watching CI on ${owner}/${repo}.`
238
+ }),
239
+ })
240
+
241
+ const server = attached.serve(new MCPServer({ id: "ci-bot", name: "CI bot", version: "1.0.0", tools: { watch_ci: watchCi } }))
242
+ ```
243
+
244
+ Serve it as Mastra's docs do (`server.startHTTP`, `server.startStdio`, or registered on your `Mastra` instance). It gets everything `attach` gives: the built-in tools, MCP Events for clients that speak it, Claude Code's `wakeshift_wait`, and Wakeshift's addition in your wrapped tools' results.
245
+
246
+ - `attached.events(name, handler)` wraps a tool's `execute` for the tool your `MCPServer` serves under `name` (its key in `tools`). `handler(args, call, context)` returns what a Mastra tool returns: a string, or your output. Run outside an MCP client's call (by an agent, a workflow or Studio), `call.subscribe` throws.
247
+ - Wrapped tools answer in one call: a Mastra task or a request for input from one ends what it subscribed.
248
+ - Your own MCP Events (`MCPServer`'s `events`) keep working: `events/list` lists yours and Wakeshift's, and each request goes to whichever serves the event it names.
249
+ - `attached.serve` checks your `@mastra/mcp` version and throws for one outside 2.7–2.x.
250
+
251
+ ## xmcp
252
+
253
+ xmcp builds its MCP server from your tool files, so Wakeshift comes in through them, with `@wakeshift/sdk/xmcp` (0.7.0 or later):
254
+
255
+ ```ts
256
+ import { z } from "zod"
257
+ import { Wakeshift } from "@wakeshift/sdk"
258
+ import { attachXmcp } from "@wakeshift/sdk/xmcp"
259
+
260
+ // src/wake.ts
261
+ const wake = new Wakeshift({ key: process.env.WAKESHIFT_KEY! })
262
+ const ciFinished = wake.defineEvent("ci.finished", {
263
+ description: "CI finished on a GitHub repo",
264
+ args: z.object({ owner: z.string(), repo: z.string() }),
265
+ payload: z.object({ branch: z.string(), conclusion: z.string() }),
266
+ text: (run, { owner, repo }) => `CI ${run.conclusion} on ${owner}/${repo} ${run.branch}`,
267
+ })
268
+ // identify gets xmcp's tool context: the verified token is extra.authInfo.
269
+ const attached = attachXmcp(wake, { identify: (extra) => ({ user: myUser(extra.authInfo) }) })
270
+
271
+ // src/tools/watch_ci.ts: export these three
272
+ const schema = attached.inputs({ owner: z.string(), repo: z.string() })
273
+ const metadata = { name: "watch_ci", description: "Watch CI on a repo" }
274
+ const handler = attached.events("watch_ci", async ({ owner, repo }: { owner: string; repo: string }, call) => {
275
+ await call.subscribe(ciFinished, { owner, repo }, { reason: `Watching ${owner}/${repo}` })
276
+ return `Watching CI on ${owner}/${repo}.`
277
+ })
278
+
279
+ // src/tools/subscribe_events.ts, and the same for unsubscribe_events and list_subscriptions
280
+ const tool = attached.tool("subscribe_events")
281
+ // export const schema = tool.schema; export const metadata = tool.metadata; export default tool.handler
282
+ ```
283
+
284
+ Each wrapped tool's result gets Wakeshift's addition in its content and `_meta` (not in `structuredContent`, which xmcp checks strictly against your output schema). xmcp can't serve MCP methods of an app's own, so on xmcp there are no MCP Events (ChatGPT and other clients that subscribe natively can't subscribe) and no `wakeshift_wait`: Claude Code is woken its other ways, and every other agent as usual.
285
+
209
286
  ## Reference
210
287
 
211
288
  ### `new Wakeshift({ key, core?, fetch?, timeoutMs?, onWarning? })`
package/dist/discover.js CHANGED
@@ -125,4 +125,3 @@ export function serveStateless(host, opts = {}) {
125
125
  return out;
126
126
  });
127
127
  }
128
- //# sourceMappingURL=discover.js.map
package/dist/errors.js CHANGED
@@ -25,4 +25,3 @@ export class WakeshiftError extends Error {
25
25
  export function isCode(err, code) {
26
26
  return err instanceof WakeshiftError && err.code === code;
27
27
  }
28
- //# sourceMappingURL=errors.js.map
package/dist/events.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // https://wakeshift.ai/docs/events has the guide.
9
9
  import { RpcError } from "./mcp.js";
10
10
  import { isSchema, objectFromShape, safeParse, toJsonSchema } from "./zod.js";
11
- import { hostOf } from "./host.js";
11
+ import { capabilitiesError, hostOf } from "./host.js";
12
12
  import { WakeshiftError } from "./errors.js";
13
13
  import { DELIVERY, EXTENSION_KEY, HEADER_MISMATCH, INTERNAL_ERROR, INVALID_PARAMS, TOP_LEVEL_KEY, NAME_HEADER, RESULT_TYPE, codesFor, dialectOf, headerValue, } from "./spec.js";
14
14
  import { toolCallOf, userAgentOf } from "./wakeshift.js";
@@ -395,13 +395,20 @@ export const LIST_TOOL_DESCRIPTION = EVENT_TOOL_TEXT.list_description;
395
395
  const MAX_LISTED_EVENTS = 20;
396
396
  /** @internal The events part of Wakeshift.attach. */
397
397
  export function attachEvents(wake, server, events, opts = {}) {
398
+ checkAttach(events, opts);
399
+ return attachHost(wake, hostOf(server), events, opts);
400
+ }
401
+ /** @internal What attach refuses before it touches a server: no events, or an own tool it doesn't have. */
402
+ export function checkAttach(events, opts, what = "attach") {
398
403
  if (events.length === 0)
399
- throw new Error("wakeshift: attach needs at least one event (wake.defineEvent) defined first");
404
+ throw new Error(`wakeshift: ${what} needs at least one event (wake.defineEvent) defined first`);
400
405
  for (const t of opts.tools ?? []) {
401
406
  if (!BUILTIN_TOOLS.includes(t))
402
- throw new Error(`wakeshift: attach's tools names "${t}": its own tools are ${BUILTIN_TOOLS.join(", ")}`);
407
+ throw new Error(`wakeshift: ${what}'s tools names "${t}": its own tools are ${BUILTIN_TOOLS.join(", ")}`);
403
408
  }
404
- const host = hostOf(server);
409
+ }
410
+ /** @internal attach on a Host: an McpServer's, or a framework adapter's (mastra.ts, xmcp.ts). */
411
+ export function attachHost(wake, host, events, opts = {}) {
405
412
  const tools = new Set(opts.tools ?? BUILTIN_TOOLS);
406
413
  // raw is the MCP SDK's own request context (1.x's extra, 2.x's ctx): what identify gets.
407
414
  const identityOf = (raw) => opts.identify?.(raw) ?? undefined;
@@ -423,9 +430,9 @@ export function attachEvents(wake, server, events, opts = {}) {
423
430
  host.registerCapabilities({ [TOP_LEVEL_KEY]: { listChanged: false }, extensions: { [EXTENSION_KEY]: { listChanged: false } } });
424
431
  }
425
432
  catch (err) {
426
- throw new Error("wakeshift: call attach before connecting the server to a transport", { cause: err });
433
+ throw capabilitiesError(host, err);
427
434
  }
428
- if (!host.handlers()) {
435
+ if (!host.handlers() && !host.framework) {
429
436
  // An MCP SDK release that keeps its request handlers elsewhere: the native
430
437
  // events and the built-in tools still work, but not what wraps the SDK's own methods.
431
438
  wake.warnOnce("handlers", "wakeshift: this MCP SDK keeps its request handlers where Wakeshift can't reach them, so wakeshift_wait, the 2026-07-28 tools/list changes and wrapped tools' output schemas are off: check for a newer @wakeshift/sdk");
@@ -704,4 +711,3 @@ export function rpcErrorOf(err, codes) {
704
711
  }
705
712
  return new RpcError(INTERNAL_ERROR, "Wakeshift refused the subscription: " + err.detail);
706
713
  }
707
- //# sourceMappingURL=events.js.map
package/dist/harness.js CHANGED
@@ -75,4 +75,3 @@ function slug(name) {
75
75
  id = id.slice(0, 40).replace(/^-+|-+$/g, "");
76
76
  return id.length < 2 ? "agent" : id;
77
77
  }
78
- //# sourceMappingURL=harness.js.map
package/dist/host.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+ /** Where the docs list the MCP server frameworks Wakeshift works with, and how. */
2
+ export declare const FRAMEWORKS_DOCS = "https://wakeshift.ai/docs/frameworks";
1
3
  /** The protocol revision that has server/discover, MCP Events and the tasks extension. */
2
4
  export declare const STATELESS_VERSION = "2026-07-28";
package/dist/host.js CHANGED
@@ -37,11 +37,83 @@ function lowOf(server) {
37
37
  * Server has projectCallToolResult, which 1.x's lacks.
38
38
  */
39
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) {
40
49
  const low = server?.server;
41
- if (!low || typeof low.setRequestHandler !== "function" || typeof server.registerTool !== "function") {
42
- throw new Error("wakeshift: attach takes an McpServer, from @modelcontextprotocol/server 2.x or @modelcontextprotocol/sdk 1.x (@modelcontextprotocol/sdk/server/mcp.js)");
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.";
43
89
  }
44
- return typeof low.projectCallToolResult === "function" ? new V2Host(server) : new V1Host(server);
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 });
45
117
  }
46
118
  // headerOf reads a header from a plain record (1.x's requestInfo.headers).
47
119
  function headerOf(headers, name) {
@@ -85,6 +157,7 @@ export function v2Req(raw) {
85
157
  }
86
158
  class BaseHost {
87
159
  server;
160
+ servesEvents = true;
88
161
  constructor(server) {
89
162
  this.server = server;
90
163
  }
@@ -192,6 +265,111 @@ function objectFromV4Shape(shape) {
192
265
  return z4.object({});
193
266
  return z4.object(shape);
194
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
+ }
195
373
  /** The protocol revision that has server/discover, MCP Events and the tasks extension. */
196
374
  export const STATELESS_VERSION = "2026-07-28";
197
375
  /** @internal Whether a request is protocol 2026-07-28: its _meta names it, or its MCP-Protocol-Version header does. */
@@ -200,4 +378,3 @@ export function is2026(req) {
200
378
  return true;
201
379
  return req.header("mcp-protocol-version") === STATELESS_VERSION;
202
380
  }
203
- //# sourceMappingURL=host.js.map
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 };