@mcp-b/webmcp-ts-sdk 2.1.0 → 2.2.1

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/README.md CHANGED
@@ -14,13 +14,13 @@
14
14
 
15
15
  ## Why Use @mcp-b/webmcp-ts-sdk?
16
16
 
17
- | Feature | Benefit |
18
- |---------|---------|
17
+ | Feature | Benefit |
18
+ | ----------------------------- | --------------------------------------------------------------------- |
19
19
  | **Dynamic Tool Registration** | Register tools after transport connection - required for browser apps |
20
- | **Minimal Overhead** | Only ~50 lines of custom code on top of official SDK |
21
- | **Full SDK Compatibility** | Re-exports all types, classes, and utilities from official SDK |
22
- | **Type-Safe** | No prototype hacks - clean TypeScript extension |
23
- | **Auto-Updates** | Types and protocol follow official SDK automatically |
20
+ | **Minimal Overhead** | Only ~50 lines of custom code on top of official SDK |
21
+ | **Full SDK Compatibility** | Re-exports all types, classes, and utilities from official SDK |
22
+ | **Type-Safe** | No prototype hacks - clean TypeScript extension |
23
+ | **Auto-Updates** | Types and protocol follow official SDK automatically |
24
24
 
25
25
  ## Overview
26
26
 
@@ -41,12 +41,19 @@ public registerCapabilities(capabilities: ServerCapabilities): void {
41
41
 
42
42
  For the Web Model Context API, this restriction is incompatible because:
43
43
 
44
- 1. **Tools arrive dynamically** - Web pages call `window.navigator.modelContext.provideContext({ tools: [...] })` at any time
44
+ 1. **Tools arrive dynamically** - Web pages call `window.navigator.modelContext.registerTool(...)` at any time
45
45
  2. **Transport must be ready immediately** - The MCP server/transport needs to be connected when the page loads
46
46
  3. **Asynchronous registration** - Tools are registered as the page's JavaScript executes, potentially long after initialization
47
47
 
48
48
  This package solves the problem by **pre-registering tool capabilities** before the transport connects, allowing dynamic tool registration to work seamlessly.
49
49
 
50
+ Compatibility note:
51
+
52
+ - `BrowserMcpServer.registerTool(tool, options?)` accepts the WebMCP April 23, 2026 draft signature, including `options.signal` (`AbortSignal`) for unregistration. When the signal aborts, both the server-side registration and the mirrored native registration are removed.
53
+ - The same call still returns a deprecated `{ unregister }` compatibility handle so existing MCP-B integrations do not break, even though spec/native runtimes return `undefined`. The handle will be removed in the next major version — prefer `options.signal`.
54
+ - `unregisterTool(name)` was removed from the WebMCP draft on April 23, 2026 in favor of the `AbortSignal` flow. It is kept on `BrowserMcpServer` with a one-time deprecation warning to interoperate with current Chrome Beta 147 (which still ships the string-name API). It will be removed in the next major version.
55
+ - `provideContext()` and `clearContext()` were removed from the WebMCP draft on March 5, 2026. They are kept here as deprecated compatibility shims and emit a one-time deprecation warning when invoked.
56
+
50
57
  ## Modifications from Official SDK
51
58
 
52
59
  ### BrowserMcpServer Class
@@ -60,8 +67,8 @@ export class BrowserMcpServer extends BaseMcpServer {
60
67
  const enhancedOptions = {
61
68
  ...options,
62
69
  capabilities: mergeCapabilities(options?.capabilities || {}, {
63
- tools: { listChanged: true }
64
- })
70
+ tools: { listChanged: true },
71
+ }),
65
72
  };
66
73
  super(serverInfo, enhancedOptions);
67
74
  }
@@ -81,16 +88,19 @@ export class BrowserMcpServer extends BaseMcpServer {
81
88
  This package re-exports almost everything from the official SDK:
82
89
 
83
90
  ### Types
91
+
84
92
  - All MCP protocol types (`Tool`, `Resource`, `Prompt`, etc.)
85
93
  - Request/response schemas
86
94
  - Client and server capabilities
87
95
  - Error codes and constants
88
96
 
89
97
  ### Classes
98
+
90
99
  - `Server` - Base server class (unchanged)
91
100
  - `McpServer` - Aliased to `BrowserMcpServer` with our modifications
92
101
 
93
102
  ### Utilities
103
+
94
104
  - `Transport` interface
95
105
  - `mergeCapabilities` helper
96
106
  - Protocol version constants
@@ -113,7 +123,7 @@ import { TabServerTransport } from '@mcp-b/transports';
113
123
 
114
124
  const server = new McpServer({
115
125
  name: 'my-web-app',
116
- version: '1.0.0'
126
+ version: '1.0.0',
117
127
  });
118
128
 
119
129
  // Connect transport first
@@ -121,42 +131,50 @@ const transport = new TabServerTransport({ allowedOrigins: ['*'] });
121
131
  await server.connect(transport);
122
132
 
123
133
  // Now you can register tools dynamically (this would fail with official SDK)
124
- server.registerTool('my-tool', {
125
- description: 'A dynamically registered tool',
126
- inputSchema: { message: z.string() },
127
- // Output schemas enable structured, type-safe AI responses
128
- outputSchema: { result: z.string() }
129
- }, async ({ message }) => {
130
- return {
131
- content: [{ type: 'text', text: `Echo: ${message}` }],
132
- // structuredContent must match the outputSchema
133
- structuredContent: { result: `Echo: ${message}` }
134
- };
135
- });
134
+ server.registerTool(
135
+ 'my-tool',
136
+ {
137
+ description: 'A dynamically registered tool',
138
+ inputSchema: { message: z.string() },
139
+ // Output schemas enable structured, type-safe AI responses
140
+ outputSchema: { result: z.string() },
141
+ },
142
+ async ({ message }) => {
143
+ return {
144
+ content: [{ type: 'text', text: `Echo: ${message}` }],
145
+ // structuredContent must match the outputSchema
146
+ structuredContent: { result: `Echo: ${message}` },
147
+ };
148
+ }
149
+ );
136
150
 
137
151
  // Example with complex output schema
138
- server.registerTool('analyze-data', {
139
- description: 'Analyze data and return structured results',
140
- inputSchema: {
141
- data: z.array(z.number()),
142
- operation: z.enum(['sum', 'average', 'stats'])
152
+ server.registerTool(
153
+ 'analyze-data',
154
+ {
155
+ description: 'Analyze data and return structured results',
156
+ inputSchema: {
157
+ data: z.array(z.number()),
158
+ operation: z.enum(['sum', 'average', 'stats']),
159
+ },
160
+ outputSchema: {
161
+ result: z.number(),
162
+ operation: z.string(),
163
+ metadata: z.object({
164
+ count: z.number(),
165
+ min: z.number().optional(),
166
+ max: z.number().optional(),
167
+ }),
168
+ },
143
169
  },
144
- outputSchema: {
145
- result: z.number(),
146
- operation: z.string(),
147
- metadata: z.object({
148
- count: z.number(),
149
- min: z.number().optional(),
150
- max: z.number().optional()
151
- })
170
+ async ({ data, operation }) => {
171
+ const stats = calculateStats(data, operation);
172
+ return {
173
+ content: [{ type: 'text', text: `Result: ${stats.result}` }],
174
+ structuredContent: stats,
175
+ };
152
176
  }
153
- }, async ({ data, operation }) => {
154
- const stats = calculateStats(data, operation);
155
- return {
156
- content: [{ type: 'text', text: `Result: ${stats.result}` }],
157
- structuredContent: stats
158
- };
159
- });
177
+ );
160
178
  ```
161
179
 
162
180
  ## Architecture