@wakeshift/sdk 0.3.0 → 0.5.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/spec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,yEAAyE;AACzE,6CAA6C;AAE7C,8BAA8B;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAEhD,6GAA6G;AAC7G,MAAM,CAAC,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AAEtC,sFAAsF;AACtF,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AAYtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC;AAErC,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,CAAC;IAC3I,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,CAAC;AAC3H,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,SAAiB;IAC7D,OAAO,UAAU,CAAC,WAAW,EAAE,KAAK,YAAY,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC7H,CAAC;AAED,mIAAmI;AACnI,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAChH,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["// The SEP-3415 (MCP Events) constants the SDK uses, in one place, matching\n// Wakeshift's own (internal/mcpevents/event/spec.go, which a test checks\n// these against): the draft is still moving.\n\n/** The draft these follow. */\nexport const REVISION = \"SEP-3415 (2026-10-16)\";\n\n/** Capability keys: the draft's extension, and the top-level key ChatGPT reads. A server advertises both. */\nexport const EXTENSION_KEY = \"io.modelcontextprotocol/events\";\nexport const LEGACY_KEY = \"events\";\n\n/** On every events/* result. */\nexport const RESULT_TYPE = \"complete\";\n\n/** The _meta key of an occurrence's rendered line (Wakeshift adds it on delivery). */\nexport const TEXT_META = \"ai.wakeshift/text\";\n\n/** The Streamable HTTP header events/subscribe and events/unsubscribe carry: params.name. */\nexport const NAME_HEADER = \"mcp-name\";\n\nexport type Dialect = \"draft\" | \"chatgpt\";\n\nexport interface Codes {\n notFound: number;\n forbidden: number;\n resourceExhausted: number;\n unsupported: number;\n callbackEndpoint: number;\n}\n\nexport const INVALID_PARAMS = -32602;\nexport const HEADER_MISMATCH = -32020;\nexport const INTERNAL_ERROR = -32603;\n\n/** A dialect's error codes: the draft's (provisional) or ChatGPT's. */\nexport function codesFor(dialect: Dialect): Codes {\n if (dialect === \"chatgpt\") {\n return { notFound: -32011, forbidden: -32012, resourceExhausted: INVALID_PARAMS, unsupported: INVALID_PARAMS, callbackEndpoint: -32015 };\n }\n return { notFound: -32023, forbidden: -32024, resourceExhausted: -32025, unsupported: -32026, callbackEndpoint: -32027 };\n}\n\n/** A client's dialect, by its clientInfo name or User-Agent: ChatGPT's MCP client is openai-mcp. */\nexport function dialectOf(clientName: string, userAgent: string): Dialect {\n return clientName.toLowerCase() === \"openai-mcp\" || userAgent.toLowerCase().startsWith(\"openai-mcp\") ? \"chatgpt\" : \"draft\";\n}\n\n/** Decodes an Mcp-Name header: plain ASCII, or SEP-2243's base64 sentinel (=?base64?…?=). null: a sentinel that doesn't decode. */\nexport function headerValue(h: string): string | null {\n if (!h.startsWith(\"=?base64?\") || !h.endsWith(\"?=\")) return h;\n try {\n const b = Buffer.from(h.slice(\"=?base64?\".length, -2), \"base64\");\n if (b.toString(\"base64\").replace(/=+$/, \"\") !== h.slice(\"=?base64?\".length, -2).replace(/=+$/, \"\")) return null;\n return b.toString(\"utf8\");\n } catch {\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,yEAAyE;AACzE,6CAA6C;AAE7C,8BAA8B;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAEhD,6IAA6I;AAC7I,MAAM,CAAC,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAEtC,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AAEtC,sFAAsF;AACtF,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AAYtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC;AAErC,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,CAAC;IAC3I,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,CAAC;AAC3H,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,SAAiB;IAC7D,OAAO,UAAU,CAAC,WAAW,EAAE,KAAK,YAAY,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC7H,CAAC;AAED,mIAAmI;AACnI,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAChH,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["// The SEP-3415 (MCP Events) constants the SDK uses, in one place, matching\n// Wakeshift's own (internal/mcpevents/event/spec.go, which a test checks\n// these against): the draft is still moving.\n\n/** The draft these follow. */\nexport const REVISION = \"SEP-3415 (2026-10-16)\";\n\n/** Capability keys: the draft's extension, and the top-level key ChatGPT reads. A server advertises both; only the extension is exported. */\nexport const EXTENSION_KEY = \"io.modelcontextprotocol/events\";\nexport const TOP_LEVEL_KEY = \"events\";\n\n/** On every events/* result. */\nexport const RESULT_TYPE = \"complete\";\n\n/** The _meta key of an occurrence's rendered line (Wakeshift adds it on delivery). */\nexport const TEXT_META = \"ai.wakeshift/text\";\n\n/** The Streamable HTTP header events/subscribe and events/unsubscribe carry: params.name. */\nexport const NAME_HEADER = \"mcp-name\";\n\nexport type Dialect = \"draft\" | \"chatgpt\";\n\nexport interface Codes {\n notFound: number;\n forbidden: number;\n resourceExhausted: number;\n unsupported: number;\n callbackEndpoint: number;\n}\n\nexport const INVALID_PARAMS = -32602;\nexport const HEADER_MISMATCH = -32020;\nexport const INTERNAL_ERROR = -32603;\n\n/** A dialect's error codes: the draft's (provisional) or ChatGPT's. */\nexport function codesFor(dialect: Dialect): Codes {\n if (dialect === \"chatgpt\") {\n return { notFound: -32011, forbidden: -32012, resourceExhausted: INVALID_PARAMS, unsupported: INVALID_PARAMS, callbackEndpoint: -32015 };\n }\n return { notFound: -32023, forbidden: -32024, resourceExhausted: -32025, unsupported: -32026, callbackEndpoint: -32027 };\n}\n\n/** A client's dialect, by its clientInfo name or User-Agent: ChatGPT's MCP client is openai-mcp. */\nexport function dialectOf(clientName: string, userAgent: string): Dialect {\n return clientName.toLowerCase() === \"openai-mcp\" || userAgent.toLowerCase().startsWith(\"openai-mcp\") ? \"chatgpt\" : \"draft\";\n}\n\n/** Decodes an Mcp-Name header: plain ASCII, or SEP-2243's base64 sentinel (=?base64?…?=). null: a sentinel that doesn't decode. */\nexport function headerValue(h: string): string | null {\n if (!h.startsWith(\"=?base64?\") || !h.endsWith(\"?=\")) return h;\n try {\n const b = Buffer.from(h.slice(\"=?base64?\".length, -2), \"base64\");\n if (b.toString(\"base64\").replace(/=+$/, \"\") !== h.slice(\"=?base64?\".length, -2).replace(/=+$/, \"\")) return null;\n return b.toString(\"utf8\");\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,154 @@
1
+ import { z } from "zod";
2
+ import type { CallToolResult, ServerNotification, ServerRequest } from "@modelcontextprotocol/sdk/types.js";
3
+ import type { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
5
+ import { type AnySchema, type SchemaInput, type ShapeOutput, type ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
6
+ import type { WakeEvent } from "./events.js";
7
+ import { type Duration, type Recognized } from "./wakeshift.js";
8
+ declare const SESSION_ARG = "session_key";
9
+ declare const HARNESS_ARG = "harness";
10
+ declare const CONVERSATION_ARG = "conversation_id";
11
+ /** MCP's own extra for a tool call: the request's signal, auth, _meta, HTTP request. */
12
+ export type ToolCallExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;
13
+ declare const wakeInputs: {
14
+ session_key: z.ZodOptional<z.ZodString>;
15
+ harness: z.ZodOptional<z.ZodString>;
16
+ conversation_id: z.ZodOptional<z.ZodString>;
17
+ };
18
+ declare const wakeOutput: {
19
+ wakeshift: z.ZodOptional<z.ZodString>;
20
+ };
21
+ /** Wakeshift's three arguments, as attached.inputs adds them. */
22
+ export type WakeInputs = typeof wakeInputs;
23
+ /** The optional wakeshift string attached.output adds. */
24
+ export type WakeOutputShape = typeof wakeOutput;
25
+ /** The names of Wakeshift's three arguments. */
26
+ export type WakeKey = typeof SESSION_ARG | typeof HARNESS_ARG | typeof CONVERSATION_ARG;
27
+ /** An input shape with Wakeshift's three arguments in it (attached.inputs'). */
28
+ export type WakeShape = ZodRawShapeCompat & {
29
+ [K in WakeKey]: AnySchema;
30
+ };
31
+ /** What a wrapped handler gets: the tool's own arguments, without Wakeshift's three. */
32
+ export type AppArgs<S extends ZodRawShapeCompat> = Omit<ShapeOutput<S>, WakeKey>;
33
+ /** What a wrapped handler returns: a string (one text block) or a CallToolResult. */
34
+ export type WrappedResult = string | CallToolResult;
35
+ /**
36
+ * The calling conversation's subscription, made or renewed by
37
+ * call.subscribe. id and user address it later: emit's
38
+ * `to: [{ user, subscription: id }]`, or `event.end(user, id)`.
39
+ */
40
+ export interface Subscription {
41
+ id: string;
42
+ user: string;
43
+ /** False for a renewal. */
44
+ created: boolean;
45
+ /** The conversation's session. A secret: don't show, store or log it. */
46
+ session: string;
47
+ /** What Wakeshift recognized the agent's program as. */
48
+ recognized: Recognized;
49
+ /** The caller subscribes itself (call.native): nothing was made, id is "", and the block tells it what to subscribe to. */
50
+ native: boolean;
51
+ }
52
+ /** How call.subscribe subscribes. */
53
+ export interface ToolSubscribeOptions {
54
+ /** End after this long without a delivery or a fresh subscribe (default 30 days). */
55
+ ttl?: Duration;
56
+ /** Why the app subscribes the conversation, shown in the console (at most 200 characters). */
57
+ reason?: string;
58
+ /** Names a new session (agent@label), for an app acting for its agents. */
59
+ label?: string;
60
+ }
61
+ /**
62
+ * One call of a wrapped tool (attached.events): who's calling, and the
63
+ * calls that subscribe the calling conversation. Only the wrapper makes
64
+ * one, and it works until the handler returns (then CallEnded).
65
+ */
66
+ export interface ToolCall {
67
+ /** Who attach's identify says is calling (undefined for none). */
68
+ readonly user: string | undefined;
69
+ /** The tool being called. */
70
+ readonly tool: string;
71
+ /**
72
+ * The client subscribes to the app's events itself (MCP Events: ChatGPT,
73
+ * the house agents). call.subscribe then makes no conversation
74
+ * subscription, and the block tells it what to subscribe to.
75
+ */
76
+ readonly native: boolean;
77
+ /** A native client's conversation, when it names one (ChatGPT's _meta["openai/session"]). */
78
+ readonly nativeConversation: string | null;
79
+ /** The session_key passed; after a subscribe or resolveSession, the conversation's session. */
80
+ readonly session: string | null;
81
+ /** What Wakeshift recognized the agent's program as: null until a subscribe or resolveSession. */
82
+ readonly recognized: Recognized | null;
83
+ /** MCP's own extra for the call. */
84
+ readonly extra: ToolCallExtra;
85
+ /**
86
+ * Subscribes the calling conversation to event with args, or renews its
87
+ * subscription. The reply then carries what the conversation needs to be
88
+ * woken (one block for the call, however many subscribes it makes), and
89
+ * if the call fails, the subscription is ended. For a native caller
90
+ * nothing is made. Your tool decides who may: authorize isn't consulted.
91
+ * A personal event needs a user (identify's).
92
+ */
93
+ subscribe<A extends AnySchema>(event: WakeEvent<A, any>, args: SchemaInput<A>, opts?: ToolSubscribeOptions): Promise<Subscription>;
94
+ /**
95
+ * Ends the calling conversation's subscription to event with args,
96
+ * resolving to whether one ended. For a native caller it ends the user's
97
+ * own (webhook) subscriptions to the event with those arguments.
98
+ */
99
+ unsubscribe<A extends AnySchema>(event: WakeEvent<A, any>, args: SchemaInput<A>): Promise<boolean>;
100
+ /** Finds or starts the calling conversation's session without subscribing it (it doesn't make it wakeable). */
101
+ resolveSession(): Promise<string>;
102
+ }
103
+ /** A ToolCall used after its handler returned. */
104
+ export declare class CallEnded extends Error {
105
+ constructor();
106
+ }
107
+ /** attach's event options. */
108
+ export interface EventsOptions {
109
+ /**
110
+ * Asked first whether a wrapped tool's call comes from a client that
111
+ * subscribes to the app's events itself (call.native), for callers the
112
+ * SDK can't tell (an app's own house agents). False leaves it to the
113
+ * SDK's own checks.
114
+ */
115
+ native?: (extra: ToolCallExtra) => boolean;
116
+ }
117
+ /** /calls/addition's answer. */
118
+ export interface CallAddition {
119
+ text?: string;
120
+ trailer?: string;
121
+ meta?: Record<string, unknown>;
122
+ }
123
+ /**
124
+ * Wakeshift attached to an MCP server: the handle `wake.attach` returns.
125
+ * Wrap a tool's callback with events, and give its input schema
126
+ * Wakeshift's three arguments with inputs.
127
+ */
128
+ export declare class Attached {
129
+ private readonly at;
130
+ /**
131
+ * shape plus Wakeshift's three optional arguments (session_key, harness
132
+ * and conversation_id), for a wrapped tool's inputSchema:
133
+ * `inputSchema: attached.inputs({ table: z.string() })`.
134
+ */
135
+ inputs<S extends ZodRawShapeCompat>(shape: S): S & WakeInputs;
136
+ /**
137
+ * shape plus an optional wakeshift string, for a wrapped tool's
138
+ * outputSchema: the wrapper sets it to the block's text (without the
139
+ * beacon line), for hosts that show the model only structuredContent.
140
+ * The block stays in the content too.
141
+ */
142
+ output<S extends ZodRawShapeCompat>(shape: S): S & WakeOutputShape;
143
+ /**
144
+ * Wraps a tool's callback, for `server.registerTool(name, …)` with the
145
+ * same name (MCP doesn't tell a callback its tool's name): the handler
146
+ * gets the tool's own arguments and a ToolCall, and returns a string or
147
+ * a CallToolResult; the reply gets Wakeshift's block. The tool's
148
+ * inputSchema must come from attached.inputs (a type error otherwise).
149
+ * Register it on the server passed to attach.
150
+ */
151
+ events<S extends WakeShape>(name: string, handler: (args: AppArgs<S>, call: ToolCall) => WrappedResult | Promise<WrappedResult>): ToolCallback<S>;
152
+ private run;
153
+ }
154
+ export {};