@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 +60 -42
- package/dist/index.d.ts +9042 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +244 -59
- package/dist/index.js.map +1 -1
- package/package.json +39 -39
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
## Why Use @mcp-b/webmcp-ts-sdk?
|
|
16
16
|
|
|
17
|
-
| Feature
|
|
18
|
-
|
|
17
|
+
| Feature | Benefit |
|
|
18
|
+
| ----------------------------- | --------------------------------------------------------------------- |
|
|
19
19
|
| **Dynamic Tool Registration** | Register tools after transport connection - required for browser apps |
|
|
20
|
-
| **Minimal Overhead**
|
|
21
|
-
| **Full SDK Compatibility**
|
|
22
|
-
| **Type-Safe**
|
|
23
|
-
| **Auto-Updates**
|
|
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.
|
|
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(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
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
|