@jalpp/mcp-adapter 0.3.0 → 0.3.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 +145 -48
- package/dist/index.d.ts +170 -1
- package/dist/index.js +45 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jalpp/mcp-adapter
|
|
2
2
|
|
|
3
|
-
Lightweight adapter utilities for registering tools on an [MCP](https://modelcontextprotocol.io) server with full TypeScript type safety. Supports manual tool registration
|
|
3
|
+
Lightweight adapter utilities for registering tools and resources on an [MCP](https://modelcontextprotocol.io) server with full TypeScript type safety. Supports manual tool registration, automatic HTTP endpoint-to-tool bridging with built-in auth, path variables, method-specific adapters, and MCP resource registration.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -14,37 +14,48 @@ npm install @jalpp/mcp-adapter
|
|
|
14
14
|
npm install @modelcontextprotocol/sdk zod axios
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
---
|
|
18
|
+
|
|
17
19
|
## Adapters
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
21
|
+
### Tool adapters
|
|
22
|
+
|
|
23
|
+
| Adapter | Description |
|
|
24
|
+
|---------|-------------|
|
|
25
|
+
| `toolAdapter` | Registers a tool with a typed callback |
|
|
26
|
+
| `toolContentAdapter` | Normalizes a result into a `CallToolResult` |
|
|
27
|
+
| `httpToolAdapter` | Registers any HTTP endpoint as a tool |
|
|
28
|
+
| `getToolAdapter` | Registers a GET endpoint as a tool — args → query params |
|
|
29
|
+
| `postToolAdapter` | Registers a POST endpoint as a tool — args → request body |
|
|
30
|
+
| `putToolAdapter` | Registers a PUT endpoint as a tool — args → request body |
|
|
31
|
+
| `patchToolAdapter` | Registers a PATCH endpoint as a tool — args → request body |
|
|
32
|
+
| `deleteToolAdapter` | Registers a DELETE endpoint as a tool — args → query params |
|
|
33
|
+
|
|
34
|
+
### Resource adapters
|
|
35
|
+
|
|
36
|
+
| Adapter | Description |
|
|
37
|
+
|---------|-------------|
|
|
38
|
+
| `staticResourceAdapter` | Registers a static MCP resource with a fixed URI |
|
|
39
|
+
| `dynamicResourceAdapter` | Registers a dynamic MCP resource with a URI template |
|
|
29
40
|
|
|
30
41
|
---
|
|
31
42
|
|
|
32
43
|
## Path Variables
|
|
33
44
|
|
|
34
|
-
All HTTP adapters support `:paramName` path variable syntax. Any input arg whose name matches a path variable is interpolated into the URL and removed from query params / request body.
|
|
45
|
+
All HTTP tool adapters support `:paramName` path variable syntax. Any input arg whose name matches a path variable is interpolated into the URL and removed from query params / request body.
|
|
35
46
|
|
|
36
47
|
```ts
|
|
37
48
|
getToolAdapter(server, {
|
|
38
|
-
name: "get-
|
|
39
|
-
description: "Fetch a
|
|
40
|
-
endpoint: "https://api.example.com/
|
|
49
|
+
name: "get-user",
|
|
50
|
+
description: "Fetch a user by ID",
|
|
51
|
+
endpoint: "https://api.example.com/users/:userId",
|
|
41
52
|
inputSchema: {
|
|
42
|
-
|
|
53
|
+
userId: z.string().describe("User ID"),
|
|
43
54
|
expand: z.string().optional().describe("Optional fields to expand"),
|
|
44
55
|
},
|
|
45
56
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
46
57
|
});
|
|
47
|
-
// GET https://api.example.com/
|
|
58
|
+
// Registers get-user tool which calls GET https://api.example.com/users/abc123?expand=profile
|
|
48
59
|
```
|
|
49
60
|
|
|
50
61
|
---
|
|
@@ -67,7 +78,7 @@ getToolAdapter(server, {
|
|
|
67
78
|
},
|
|
68
79
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
69
80
|
});
|
|
70
|
-
//
|
|
81
|
+
// Registers get-user tool which calls GET https://api.example.com/users/abc123?expand=profile
|
|
71
82
|
```
|
|
72
83
|
|
|
73
84
|
---
|
|
@@ -90,7 +101,7 @@ postToolAdapter(server, {
|
|
|
90
101
|
},
|
|
91
102
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
92
103
|
});
|
|
93
|
-
//
|
|
104
|
+
// Registers create-post tool which calls POST https://api.example.com/users/abc123/posts { title, body }
|
|
94
105
|
```
|
|
95
106
|
|
|
96
107
|
---
|
|
@@ -100,6 +111,8 @@ postToolAdapter(server, {
|
|
|
100
111
|
Registers a PUT endpoint as an MCP tool. Remaining args are sent as the **JSON request body**.
|
|
101
112
|
|
|
102
113
|
```ts
|
|
114
|
+
import { putToolAdapter } from "@jalpp/mcp-adapter";
|
|
115
|
+
|
|
103
116
|
putToolAdapter(server, {
|
|
104
117
|
name: "update-user",
|
|
105
118
|
description: "Replace a user record",
|
|
@@ -111,7 +124,7 @@ putToolAdapter(server, {
|
|
|
111
124
|
},
|
|
112
125
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
113
126
|
});
|
|
114
|
-
//
|
|
127
|
+
// Registers update-user tool which calls PUT https://api.example.com/users/abc123 { name, email }
|
|
115
128
|
```
|
|
116
129
|
|
|
117
130
|
---
|
|
@@ -121,6 +134,8 @@ putToolAdapter(server, {
|
|
|
121
134
|
Registers a PATCH endpoint as an MCP tool. Remaining args are sent as the **JSON request body**.
|
|
122
135
|
|
|
123
136
|
```ts
|
|
137
|
+
import { patchToolAdapter } from "@jalpp/mcp-adapter";
|
|
138
|
+
|
|
124
139
|
patchToolAdapter(server, {
|
|
125
140
|
name: "update-post-title",
|
|
126
141
|
description: "Partially update a post",
|
|
@@ -131,7 +146,7 @@ patchToolAdapter(server, {
|
|
|
131
146
|
},
|
|
132
147
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
133
148
|
});
|
|
134
|
-
//
|
|
149
|
+
// Registers update-post-title tool which calls PATCH https://api.example.com/posts/xyz789 { title }
|
|
135
150
|
```
|
|
136
151
|
|
|
137
152
|
---
|
|
@@ -141,6 +156,8 @@ patchToolAdapter(server, {
|
|
|
141
156
|
Registers a DELETE endpoint as an MCP tool. Remaining args (after path variable interpolation) are sent as **query parameters**.
|
|
142
157
|
|
|
143
158
|
```ts
|
|
159
|
+
import { deleteToolAdapter } from "@jalpp/mcp-adapter";
|
|
160
|
+
|
|
144
161
|
deleteToolAdapter(server, {
|
|
145
162
|
name: "delete-post",
|
|
146
163
|
description: "Delete a post by ID",
|
|
@@ -148,26 +165,27 @@ deleteToolAdapter(server, {
|
|
|
148
165
|
inputSchema: { postId: z.string() },
|
|
149
166
|
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
150
167
|
});
|
|
151
|
-
//
|
|
168
|
+
// Registers delete-post tool which calls DELETE https://api.example.com/posts/xyz789
|
|
152
169
|
```
|
|
153
170
|
|
|
154
171
|
---
|
|
155
172
|
|
|
156
173
|
## `httpToolAdapter`
|
|
157
174
|
|
|
158
|
-
Lower-level adapter that accepts an explicit `method` field. Use this when
|
|
175
|
+
Lower-level adapter that accepts an explicit `method` field. Use this when you prefer a single unified call style or need to pass the method dynamically.
|
|
159
176
|
|
|
160
177
|
```ts
|
|
161
178
|
import { httpToolAdapter } from "@jalpp/mcp-adapter";
|
|
162
179
|
|
|
163
180
|
httpToolAdapter(server, {
|
|
164
|
-
name: "
|
|
165
|
-
description: "
|
|
166
|
-
endpoint: "https://api.example.com/
|
|
181
|
+
name: "search-products",
|
|
182
|
+
description: "Search the product catalogue",
|
|
183
|
+
endpoint: "https://api.example.com/products/search",
|
|
167
184
|
method: "POST",
|
|
168
|
-
inputSchema: {
|
|
169
|
-
auth: { type: "
|
|
185
|
+
inputSchema: { query: z.string(), limit: z.number().optional() },
|
|
186
|
+
auth: { type: "apikey", header: "X-API-Key", key: process.env.API_KEY! },
|
|
170
187
|
});
|
|
188
|
+
// Registers search-products tool which calls POST https://api.example.com/products/search { query, limit }
|
|
171
189
|
```
|
|
172
190
|
|
|
173
191
|
---
|
|
@@ -180,19 +198,19 @@ Registers a tool with a fully custom typed callback. Use when you need data tran
|
|
|
180
198
|
|
|
181
199
|
```ts
|
|
182
200
|
import { toolAdapter, toolContentAdapter } from "@jalpp/mcp-adapter";
|
|
201
|
+
import z from "zod";
|
|
183
202
|
|
|
184
203
|
toolAdapter(server, {
|
|
185
|
-
name: "
|
|
204
|
+
name: "summarize-report",
|
|
186
205
|
config: {
|
|
187
|
-
description: "
|
|
206
|
+
description: "Fetch and summarize a sales report",
|
|
188
207
|
inputSchema: {
|
|
189
|
-
|
|
190
|
-
|
|
208
|
+
reportId: z.string().describe("Report ID"),
|
|
209
|
+
format: z.enum(["short", "detailed"]).default("short"),
|
|
191
210
|
},
|
|
192
|
-
annotations: { openWorldHint: true },
|
|
193
211
|
},
|
|
194
|
-
cb: async ({
|
|
195
|
-
const { data, error } = await
|
|
212
|
+
cb: async ({ reportId, format }) => {
|
|
213
|
+
const { data, error } = await reportService.get(reportId, format);
|
|
196
214
|
return toolContentAdapter(data ?? {}, error);
|
|
197
215
|
},
|
|
198
216
|
});
|
|
@@ -202,10 +220,10 @@ toolAdapter(server, {
|
|
|
202
220
|
|
|
203
221
|
```ts
|
|
204
222
|
toolAdapter(server, {
|
|
205
|
-
name: "get-status",
|
|
223
|
+
name: "get-server-status",
|
|
206
224
|
config: { description: "Returns current server status" },
|
|
207
225
|
cb: async () => {
|
|
208
|
-
const { data, error } = await
|
|
226
|
+
const { data, error } = await statusService.get();
|
|
209
227
|
return toolContentAdapter(data ?? {}, error);
|
|
210
228
|
},
|
|
211
229
|
});
|
|
@@ -215,7 +233,7 @@ toolAdapter(server, {
|
|
|
215
233
|
|
|
216
234
|
## `toolContentAdapter`
|
|
217
235
|
|
|
218
|
-
Normalizes a result into a `CallToolResult` text block. If `error` is defined it takes priority; otherwise `data` is serialized as pretty-printed JSON.
|
|
236
|
+
Normalizes a service result into a `CallToolResult` text block. If `error` is defined it takes priority; otherwise `data` is serialized as pretty-printed JSON.
|
|
219
237
|
|
|
220
238
|
```ts
|
|
221
239
|
return toolContentAdapter(data ?? {}, error);
|
|
@@ -228,9 +246,79 @@ return toolContentAdapter(data ?? {}, error);
|
|
|
228
246
|
|
|
229
247
|
---
|
|
230
248
|
|
|
249
|
+
## `staticResourceAdapter`
|
|
250
|
+
|
|
251
|
+
Registers a static MCP resource with a fixed URI. The `load` callback is called on every client request and may return fresh content each time. Use this for resources whose identity is fixed but content may change (e.g. a config file, a status page, a knowledge base).
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import { staticResourceAdapter } from "@jalpp/mcp-adapter";
|
|
255
|
+
|
|
256
|
+
// Expose a live system health report
|
|
257
|
+
staticResourceAdapter(server, {
|
|
258
|
+
name: "system-health",
|
|
259
|
+
uri: "status://health",
|
|
260
|
+
title: "System Health",
|
|
261
|
+
description: "Live health status of all services",
|
|
262
|
+
mimeType: "application/json",
|
|
263
|
+
load: async () => JSON.stringify(await healthService.getReport()),
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Expose a markdown documentation page
|
|
267
|
+
staticResourceAdapter(server, {
|
|
268
|
+
name: "api-docs",
|
|
269
|
+
uri: "docs://api",
|
|
270
|
+
title: "API Documentation",
|
|
271
|
+
description: "REST API reference documentation",
|
|
272
|
+
mimeType: "text/markdown",
|
|
273
|
+
load: () => fs.readFileSync("./docs/api.md", "utf-8"),
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## `dynamicResourceAdapter`
|
|
280
|
+
|
|
281
|
+
Registers a dynamic MCP resource with a URI template. Use `{paramName}` placeholders — matched values are extracted and passed to the `load` callback. Use this for resources identified by an ID or other variable.
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { dynamicResourceAdapter } from "@jalpp/mcp-adapter";
|
|
285
|
+
|
|
286
|
+
// Expose a user profile by ID
|
|
287
|
+
dynamicResourceAdapter(server, {
|
|
288
|
+
name: "user-profile",
|
|
289
|
+
uriTemplate: "users://{userId}/profile",
|
|
290
|
+
title: "User Profile",
|
|
291
|
+
description: "Profile data for a specific user",
|
|
292
|
+
mimeType: "application/json",
|
|
293
|
+
load: async (uri, { userId }) => JSON.stringify(await userService.getProfile(userId)),
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Expose an order invoice by order ID
|
|
297
|
+
dynamicResourceAdapter(server, {
|
|
298
|
+
name: "order-invoice",
|
|
299
|
+
uriTemplate: "orders://{orderId}/invoice",
|
|
300
|
+
title: "Order Invoice",
|
|
301
|
+
description: "Invoice details for a specific order",
|
|
302
|
+
mimeType: "application/json",
|
|
303
|
+
load: async (uri, { orderId }) => JSON.stringify(await orderService.getInvoice(orderId)),
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Expose a blog post by slug
|
|
307
|
+
dynamicResourceAdapter(server, {
|
|
308
|
+
name: "blog-post",
|
|
309
|
+
uriTemplate: "blog://{slug}",
|
|
310
|
+
title: "Blog Post",
|
|
311
|
+
description: "Markdown content for a blog post",
|
|
312
|
+
mimeType: "text/markdown",
|
|
313
|
+
load: async (uri, { slug }) => await blogService.getPostMarkdown(slug),
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
231
319
|
## Authentication
|
|
232
320
|
|
|
233
|
-
All HTTP adapters accept an optional `auth` field. Three strategies are supported:
|
|
321
|
+
All HTTP tool adapters accept an optional `auth` field. Three strategies are supported:
|
|
234
322
|
|
|
235
323
|
**Bearer token** — `Authorization: Bearer <token>`:
|
|
236
324
|
```ts
|
|
@@ -266,17 +354,26 @@ getToolAdapter(server, {
|
|
|
266
354
|
|
|
267
355
|
## API Reference
|
|
268
356
|
|
|
269
|
-
###
|
|
357
|
+
### Tool adapters
|
|
358
|
+
|
|
359
|
+
| Function | Registers | Args mapping |
|
|
360
|
+
|----------|-----------|--------------|
|
|
361
|
+
| `getToolAdapter` | GET tool | remaining args → query params |
|
|
362
|
+
| `postToolAdapter` | POST tool | remaining args → request body |
|
|
363
|
+
| `putToolAdapter` | PUT tool | remaining args → request body |
|
|
364
|
+
| `patchToolAdapter` | PATCH tool | remaining args → request body |
|
|
365
|
+
| `deleteToolAdapter` | DELETE tool | remaining args → query params |
|
|
366
|
+
| `httpToolAdapter` | any method tool | depends on method |
|
|
367
|
+
| `toolAdapter` | custom callback tool | fully custom |
|
|
368
|
+
|
|
369
|
+
All HTTP adapters support optional `inputSchema` and `:paramName` path variables.
|
|
270
370
|
|
|
271
|
-
|
|
272
|
-
|----------|--------|--------------|
|
|
273
|
-
| `getToolAdapter` | GET | remaining args → query params |
|
|
274
|
-
| `postToolAdapter` | POST | remaining args → request body |
|
|
275
|
-
| `putToolAdapter` | PUT | remaining args → request body |
|
|
276
|
-
| `patchToolAdapter` | PATCH | remaining args → request body |
|
|
277
|
-
| `deleteToolAdapter` | DELETE | remaining args → query params |
|
|
371
|
+
### Resource adapters
|
|
278
372
|
|
|
279
|
-
|
|
373
|
+
| Function | Registers | URI style |
|
|
374
|
+
|----------|-----------|-----------|
|
|
375
|
+
| `staticResourceAdapter` | fixed-URI resource | `"scheme://path"` |
|
|
376
|
+
| `dynamicResourceAdapter` | templated resource | `"scheme://{param}/path"` |
|
|
280
377
|
|
|
281
378
|
### Auth types
|
|
282
379
|
|
package/dist/index.d.ts
CHANGED
|
@@ -332,4 +332,173 @@ declare function patchToolAdapter<T extends ZodRawShapeCompat>(server: McpServer
|
|
|
332
332
|
*/
|
|
333
333
|
declare function deleteToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: DeleteToolAdapterConfig<T>): void;
|
|
334
334
|
|
|
335
|
-
|
|
335
|
+
/**
|
|
336
|
+
* Supported MIME types for resource content.
|
|
337
|
+
* Extend with additional types as needed.
|
|
338
|
+
*/
|
|
339
|
+
type ResourceMimeType = "text/plain" | "text/html" | "text/markdown" | "application/json" | "application/xml" | (string & {});
|
|
340
|
+
/**
|
|
341
|
+
* Configuration for registering a static MCP resource.
|
|
342
|
+
*
|
|
343
|
+
* A static resource has a fixed URI with no variable parameters.
|
|
344
|
+
* Use this for resources whose content may change but whose identity does not
|
|
345
|
+
* (e.g. a config file, a status page, a knowledge base).
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* staticResourceAdapter(server, {
|
|
349
|
+
* name: "server-config",
|
|
350
|
+
* uri: "config://server",
|
|
351
|
+
* title: "Server Configuration",
|
|
352
|
+
* description: "Current server configuration and environment settings",
|
|
353
|
+
* mimeType: "application/json",
|
|
354
|
+
* load: async () => JSON.stringify(await configService.get()),
|
|
355
|
+
* });
|
|
356
|
+
*/
|
|
357
|
+
interface StaticResourceConfig {
|
|
358
|
+
/** Unique resource name used to identify the resource in the MCP registry. */
|
|
359
|
+
name: string;
|
|
360
|
+
/**
|
|
361
|
+
* The fixed URI that clients use to request this resource.
|
|
362
|
+
* @example "config://server"
|
|
363
|
+
* @example "docs://readme"
|
|
364
|
+
*/
|
|
365
|
+
uri: string;
|
|
366
|
+
/** Human-readable display title shown in client UIs. */
|
|
367
|
+
title: string;
|
|
368
|
+
/** Description of what the resource contains, shown to the model. */
|
|
369
|
+
description: string;
|
|
370
|
+
/** MIME type of the resource content. Defaults to `"text/plain"`. */
|
|
371
|
+
mimeType?: ResourceMimeType;
|
|
372
|
+
/**
|
|
373
|
+
* Async function that returns the resource content as a string.
|
|
374
|
+
* Called each time a client requests the resource.
|
|
375
|
+
*
|
|
376
|
+
* @returns The resource content string.
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* load: async () => JSON.stringify(await configService.get())
|
|
380
|
+
*/
|
|
381
|
+
load: () => Promise<string> | string;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Configuration for registering a dynamic MCP resource with URI template parameters.
|
|
385
|
+
*
|
|
386
|
+
* A dynamic resource uses a URI template with `{paramName}` placeholders.
|
|
387
|
+
* The matched parameter values are passed to the `load` callback.
|
|
388
|
+
* Use this for resources identified by an ID or other variable (e.g. a user profile, an order record).
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* dynamicResourceAdapter(server, {
|
|
392
|
+
* name: "user-profile",
|
|
393
|
+
* uriTemplate: "users://{userId}/profile",
|
|
394
|
+
* title: "User Profile",
|
|
395
|
+
* description: "Profile data for a given user",
|
|
396
|
+
* mimeType: "application/json",
|
|
397
|
+
* load: async (uri, { userId }) => JSON.stringify(await userService.getProfile(userId)),
|
|
398
|
+
* });
|
|
399
|
+
*/
|
|
400
|
+
interface DynamicResourceConfig {
|
|
401
|
+
/** Unique resource name used to identify the resource in the MCP registry. */
|
|
402
|
+
name: string;
|
|
403
|
+
/**
|
|
404
|
+
* URI template string with `{paramName}` placeholders.
|
|
405
|
+
* @example "users://{userId}/profile"
|
|
406
|
+
* @example "orders://{orderId}/invoice"
|
|
407
|
+
*/
|
|
408
|
+
uriTemplate: string;
|
|
409
|
+
/** human-readable display title shown in client UIs. */
|
|
410
|
+
title: string;
|
|
411
|
+
/** Description of what the resource contains, shown to the model. */
|
|
412
|
+
description: string;
|
|
413
|
+
/** MIME type of the resource content. Defaults to `"text/plain"`. */
|
|
414
|
+
mimeType?: ResourceMimeType;
|
|
415
|
+
/**
|
|
416
|
+
* Async function that returns the resource content as a string.
|
|
417
|
+
* Called each time a client requests the resource with a matching URI.
|
|
418
|
+
*
|
|
419
|
+
* @param uri - The full resolved URI of the request (as a `URL` object).
|
|
420
|
+
* @param params - Key-value map of extracted URI template parameters.
|
|
421
|
+
* @returns The resource content string.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* load: async (uri, { orderId }) => JSON.stringify(await orderService.getInvoice(orderId))
|
|
425
|
+
*/
|
|
426
|
+
load: (uri: URL, params: Record<string, string>) => Promise<string> | string;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Registers a static MCP resource on an `McpServer`.
|
|
430
|
+
*
|
|
431
|
+
* Static resources have a fixed URI. The `load` callback is invoked on every
|
|
432
|
+
* client request and may return fresh data each time.
|
|
433
|
+
*
|
|
434
|
+
* @param server - The `McpServer` instance to register the resource on.
|
|
435
|
+
* @param config - Static resource configuration.
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* // Expose a live system health report
|
|
439
|
+
* staticResourceAdapter(server, {
|
|
440
|
+
* name: "system-health",
|
|
441
|
+
* uri: "status://health",
|
|
442
|
+
* title: "System Health",
|
|
443
|
+
* description: "Live health status of all services",
|
|
444
|
+
* mimeType: "application/json",
|
|
445
|
+
* load: async () => JSON.stringify(await healthService.getReport()),
|
|
446
|
+
* });
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* // Expose a static markdown documentation page
|
|
450
|
+
* staticResourceAdapter(server, {
|
|
451
|
+
* name: "api-docs",
|
|
452
|
+
* uri: "docs://api",
|
|
453
|
+
* title: "API Documentation",
|
|
454
|
+
* description: "REST API reference documentation",
|
|
455
|
+
* mimeType: "text/markdown",
|
|
456
|
+
* load: () => fs.readFileSync("./docs/api.md", "utf-8"),
|
|
457
|
+
* });
|
|
458
|
+
*/
|
|
459
|
+
declare function staticResourceAdapter(server: McpServer, config: StaticResourceConfig): void;
|
|
460
|
+
/**
|
|
461
|
+
* Registers a dynamic MCP resource with a URI template on an `McpServer`.
|
|
462
|
+
*
|
|
463
|
+
* Dynamic resources use `{paramName}` placeholders in the URI template.
|
|
464
|
+
* Matched parameter values are extracted and passed to the `load` callback.
|
|
465
|
+
*
|
|
466
|
+
* @param server - The `McpServer` instance to register the resource on.
|
|
467
|
+
* @param config - Dynamic resource configuration.
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* // Expose a user profile by ID
|
|
471
|
+
* dynamicResourceAdapter(server, {
|
|
472
|
+
* name: "user-profile",
|
|
473
|
+
* uriTemplate: "users://{userId}/profile",
|
|
474
|
+
* title: "User Profile",
|
|
475
|
+
* description: "Profile data for a specific user",
|
|
476
|
+
* mimeType: "application/json",
|
|
477
|
+
* load: async (uri, { userId }) => JSON.stringify(await userService.getProfile(userId)),
|
|
478
|
+
* });
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* // Expose an order invoice by order ID
|
|
482
|
+
* dynamicResourceAdapter(server, {
|
|
483
|
+
* name: "order-invoice",
|
|
484
|
+
* uriTemplate: "orders://{orderId}/invoice",
|
|
485
|
+
* title: "Order Invoice",
|
|
486
|
+
* description: "Invoice details for a specific order",
|
|
487
|
+
* mimeType: "application/json",
|
|
488
|
+
* load: async (uri, { orderId }) => JSON.stringify(await orderService.getInvoice(orderId)),
|
|
489
|
+
* });
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* // Expose a blog post by slug
|
|
493
|
+
* dynamicResourceAdapter(server, {
|
|
494
|
+
* name: "blog-post",
|
|
495
|
+
* uriTemplate: "blog://{slug}",
|
|
496
|
+
* title: "Blog Post",
|
|
497
|
+
* description: "Markdown content for a blog post",
|
|
498
|
+
* mimeType: "text/markdown",
|
|
499
|
+
* load: async (uri, { slug }) => await blogService.getPostMarkdown(slug),
|
|
500
|
+
* });
|
|
501
|
+
*/
|
|
502
|
+
declare function dynamicResourceAdapter(server: McpServer, config: DynamicResourceConfig): void;
|
|
503
|
+
|
|
504
|
+
export { type ApiKeyAuth, type BasicAuth, type BearerAuth, type DeleteToolAdapterConfig, type DynamicResourceConfig, type GetToolAdapterConfig, type GetToolAdapterConfigNoSchema, type HttpAuth, type HttpMethod, type HttpToolAdapterWithSchema, type HttpToolAdapterWithoutSchema, type PatchToolAdapterConfig, type PostToolAdapterConfig, type PostToolAdapterConfigNoSchema, type PutToolAdapterConfig, type ResourceMimeType, type StaticResourceConfig, deleteToolAdapter, dynamicResourceAdapter, getToolAdapter, httpToolAdapter, patchToolAdapter, postToolAdapter, putToolAdapter, staticResourceAdapter, toolAdapter, toolContentAdapter };
|
package/dist/index.js
CHANGED
|
@@ -121,13 +121,58 @@ function patchToolAdapter(server, config) {
|
|
|
121
121
|
function deleteToolAdapter(server, config) {
|
|
122
122
|
httpToolAdapter(server, { ...config, method: "DELETE" });
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
// src/resourceAdapter.ts
|
|
126
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
127
|
+
function staticResourceAdapter(server, config) {
|
|
128
|
+
server.registerResource(
|
|
129
|
+
config.name,
|
|
130
|
+
config.uri,
|
|
131
|
+
{
|
|
132
|
+
title: config.title,
|
|
133
|
+
description: config.description,
|
|
134
|
+
mimeType: config.mimeType ?? "text/plain"
|
|
135
|
+
},
|
|
136
|
+
async (uri) => ({
|
|
137
|
+
contents: [
|
|
138
|
+
{
|
|
139
|
+
uri: uri.href,
|
|
140
|
+
text: await config.load(),
|
|
141
|
+
mimeType: config.mimeType ?? "text/plain"
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
function dynamicResourceAdapter(server, config) {
|
|
148
|
+
server.registerResource(
|
|
149
|
+
config.name,
|
|
150
|
+
new ResourceTemplate(config.uriTemplate, { list: void 0 }),
|
|
151
|
+
{
|
|
152
|
+
title: config.title,
|
|
153
|
+
description: config.description,
|
|
154
|
+
mimeType: config.mimeType ?? "text/plain"
|
|
155
|
+
},
|
|
156
|
+
async (uri, params) => ({
|
|
157
|
+
contents: [
|
|
158
|
+
{
|
|
159
|
+
uri: uri.href,
|
|
160
|
+
text: await config.load(uri, params),
|
|
161
|
+
mimeType: config.mimeType ?? "text/plain"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
}
|
|
124
167
|
export {
|
|
125
168
|
deleteToolAdapter,
|
|
169
|
+
dynamicResourceAdapter,
|
|
126
170
|
getToolAdapter,
|
|
127
171
|
httpToolAdapter,
|
|
128
172
|
patchToolAdapter,
|
|
129
173
|
postToolAdapter,
|
|
130
174
|
putToolAdapter,
|
|
175
|
+
staticResourceAdapter,
|
|
131
176
|
toolAdapter,
|
|
132
177
|
toolContentAdapter
|
|
133
178
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jalpp/mcp-adapter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Adapter utilities for registering MCP tools with full TypeScript type safety — supports typed callbacks and automatic HTTP endpoint bridging with auth",
|
|
5
5
|
"author": "jalpp",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@modelcontextprotocol/sdk": ">=1.0.0",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
47
|
+
"axios": ">=1.0.0",
|
|
48
|
+
"zod": ">=3.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": ">=1.0.0",
|
|
52
|
-
"@types/node": "^
|
|
52
|
+
"@types/node": "^25.4.0",
|
|
53
53
|
"tsup": "^8.0.0",
|
|
54
54
|
"typescript": "^5.0.0",
|
|
55
55
|
"zod": ">=3.0.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"axios": "
|
|
58
|
+
"axios": ">=1.0.0"
|
|
59
59
|
}
|
|
60
60
|
}
|