@jalpp/mcp-adapter 0.1.3 → 0.3.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/README.md +233 -26
- package/dist/index.d.ts +241 -1
- package/dist/index.js +103 -0
- package/package.json +27 -7
package/README.md
CHANGED
|
@@ -1,29 +1,185 @@
|
|
|
1
|
-
# mcp-adapter
|
|
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.
|
|
3
|
+
Lightweight adapter utilities for registering tools on an [MCP](https://modelcontextprotocol.io) server with full TypeScript type safety. Supports manual tool registration and automatic HTTP endpoint-to-tool bridging with built-in auth, path variables, and method-specific adapters.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install mcp-adapter
|
|
8
|
+
npm install @jalpp/mcp-adapter
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Peer dependencies** — install these in your project if not already present:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npm install @modelcontextprotocol/sdk zod axios
|
|
15
|
+
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
## Adapters
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
| Adapter | Method | Description |
|
|
20
|
+
|---------|--------|-------------|
|
|
21
|
+
| `toolAdapter` | any | Register a tool with a typed callback |
|
|
22
|
+
| `toolContentAdapter` | — | Normalize a result into a `CallToolResult` |
|
|
23
|
+
| `httpToolAdapter` | any | Register any HTTP endpoint as a tool |
|
|
24
|
+
| `getToolAdapter` | GET | Register a GET endpoint — args → query params |
|
|
25
|
+
| `postToolAdapter` | POST | Register a POST endpoint — args → request body |
|
|
26
|
+
| `putToolAdapter` | PUT | Register a PUT endpoint — args → request body |
|
|
27
|
+
| `patchToolAdapter` | PATCH | Register a PATCH endpoint — args → request body |
|
|
28
|
+
| `deleteToolAdapter` | DELETE | Register a DELETE endpoint — args → query params |
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Path Variables
|
|
33
|
+
|
|
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.
|
|
20
35
|
|
|
21
36
|
```ts
|
|
22
|
-
|
|
23
|
-
|
|
37
|
+
getToolAdapter(server, {
|
|
38
|
+
name: "get-game-details",
|
|
39
|
+
description: "Fetch a game by ID",
|
|
40
|
+
endpoint: "https://api.example.com/games/:gameId",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
gameId: z.string().describe("Game ID"),
|
|
43
|
+
expand: z.string().optional().describe("Optional fields to expand"),
|
|
44
|
+
},
|
|
45
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
46
|
+
});
|
|
47
|
+
// GET https://api.example.com/games/abc123?expand=moves
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## `getToolAdapter`
|
|
53
|
+
|
|
54
|
+
Registers a GET endpoint as an MCP tool. Remaining args (after path variable interpolation) are sent as **query parameters**.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { getToolAdapter } from "@jalpp/mcp-adapter";
|
|
24
58
|
import z from "zod";
|
|
25
59
|
|
|
26
|
-
|
|
60
|
+
getToolAdapter(server, {
|
|
61
|
+
name: "get-user",
|
|
62
|
+
description: "Fetch a user by ID",
|
|
63
|
+
endpoint: "https://api.example.com/users/:userId",
|
|
64
|
+
inputSchema: {
|
|
65
|
+
userId: z.string().describe("User ID"),
|
|
66
|
+
expand: z.string().optional().describe("Comma-separated fields to expand"),
|
|
67
|
+
},
|
|
68
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
69
|
+
});
|
|
70
|
+
// → GET https://api.example.com/users/abc123?expand=profile
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## `postToolAdapter`
|
|
76
|
+
|
|
77
|
+
Registers a POST endpoint as an MCP tool. Remaining args (after path variable interpolation) are sent as the **JSON request body**.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { postToolAdapter } from "@jalpp/mcp-adapter";
|
|
81
|
+
|
|
82
|
+
postToolAdapter(server, {
|
|
83
|
+
name: "create-post",
|
|
84
|
+
description: "Create a new post for a user",
|
|
85
|
+
endpoint: "https://api.example.com/users/:userId/posts",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
userId: z.string().describe("User ID"),
|
|
88
|
+
title: z.string().describe("Post title"),
|
|
89
|
+
body: z.string().describe("Post body"),
|
|
90
|
+
},
|
|
91
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
92
|
+
});
|
|
93
|
+
// → POST https://api.example.com/users/abc123/posts { title, body }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## `putToolAdapter`
|
|
99
|
+
|
|
100
|
+
Registers a PUT endpoint as an MCP tool. Remaining args are sent as the **JSON request body**.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
putToolAdapter(server, {
|
|
104
|
+
name: "update-user",
|
|
105
|
+
description: "Replace a user record",
|
|
106
|
+
endpoint: "https://api.example.com/users/:userId",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
userId: z.string(),
|
|
109
|
+
name: z.string(),
|
|
110
|
+
email: z.string(),
|
|
111
|
+
},
|
|
112
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
113
|
+
});
|
|
114
|
+
// → PUT https://api.example.com/users/abc123 { name, email }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## `patchToolAdapter`
|
|
120
|
+
|
|
121
|
+
Registers a PATCH endpoint as an MCP tool. Remaining args are sent as the **JSON request body**.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
patchToolAdapter(server, {
|
|
125
|
+
name: "update-post-title",
|
|
126
|
+
description: "Partially update a post",
|
|
127
|
+
endpoint: "https://api.example.com/posts/:postId",
|
|
128
|
+
inputSchema: {
|
|
129
|
+
postId: z.string(),
|
|
130
|
+
title: z.string(),
|
|
131
|
+
},
|
|
132
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
133
|
+
});
|
|
134
|
+
// → PATCH https://api.example.com/posts/xyz789 { title }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## `deleteToolAdapter`
|
|
140
|
+
|
|
141
|
+
Registers a DELETE endpoint as an MCP tool. Remaining args (after path variable interpolation) are sent as **query parameters**.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
deleteToolAdapter(server, {
|
|
145
|
+
name: "delete-post",
|
|
146
|
+
description: "Delete a post by ID",
|
|
147
|
+
endpoint: "https://api.example.com/posts/:postId",
|
|
148
|
+
inputSchema: { postId: z.string() },
|
|
149
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
150
|
+
});
|
|
151
|
+
// → DELETE https://api.example.com/posts/xyz789
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## `httpToolAdapter`
|
|
157
|
+
|
|
158
|
+
Lower-level adapter that accepts an explicit `method` field. Use this when the method needs to be dynamic or you prefer a single unified call style.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { httpToolAdapter } from "@jalpp/mcp-adapter";
|
|
162
|
+
|
|
163
|
+
httpToolAdapter(server, {
|
|
164
|
+
name: "get-analysis",
|
|
165
|
+
description: "Fetch position analysis",
|
|
166
|
+
endpoint: "https://api.example.com/analyze",
|
|
167
|
+
method: "POST",
|
|
168
|
+
inputSchema: { fen: z.string(), depth: z.number() },
|
|
169
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## `toolAdapter`
|
|
176
|
+
|
|
177
|
+
Registers a tool with a fully custom typed callback. Use when you need data transformation, custom error handling, or logic that goes beyond a single HTTP call.
|
|
178
|
+
|
|
179
|
+
**With input schema:**
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { toolAdapter, toolContentAdapter } from "@jalpp/mcp-adapter";
|
|
27
183
|
|
|
28
184
|
toolAdapter(server, {
|
|
29
185
|
name: "get-analysis",
|
|
@@ -47,9 +203,7 @@ toolAdapter(server, {
|
|
|
47
203
|
```ts
|
|
48
204
|
toolAdapter(server, {
|
|
49
205
|
name: "get-status",
|
|
50
|
-
config: {
|
|
51
|
-
description: "Returns current server status",
|
|
52
|
-
},
|
|
206
|
+
config: { description: "Returns current server status" },
|
|
53
207
|
cb: async () => {
|
|
54
208
|
const { data, error } = await myService.getStatus();
|
|
55
209
|
return toolContentAdapter(data ?? {}, error);
|
|
@@ -57,13 +211,13 @@ toolAdapter(server, {
|
|
|
57
211
|
});
|
|
58
212
|
```
|
|
59
213
|
|
|
60
|
-
|
|
214
|
+
---
|
|
61
215
|
|
|
62
|
-
|
|
216
|
+
## `toolContentAdapter`
|
|
63
217
|
|
|
64
|
-
|
|
65
|
-
import { toolContentAdapter } from "mcp-adapter";
|
|
218
|
+
Normalizes a result into a `CallToolResult` text block. If `error` is defined it takes priority; otherwise `data` is serialized as pretty-printed JSON.
|
|
66
219
|
|
|
220
|
+
```ts
|
|
67
221
|
return toolContentAdapter(data ?? {}, error);
|
|
68
222
|
```
|
|
69
223
|
|
|
@@ -72,18 +226,71 @@ return toolContentAdapter(data ?? {}, error);
|
|
|
72
226
|
| `data` | `object` | Successful result payload |
|
|
73
227
|
| `error` | `string \| undefined` | Error message — takes priority over `data` |
|
|
74
228
|
|
|
75
|
-
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Authentication
|
|
232
|
+
|
|
233
|
+
All HTTP adapters accept an optional `auth` field. Three strategies are supported:
|
|
234
|
+
|
|
235
|
+
**Bearer token** — `Authorization: Bearer <token>`:
|
|
236
|
+
```ts
|
|
237
|
+
auth: { type: "bearer", token: process.env.API_TOKEN! }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**API key** — custom header:
|
|
241
|
+
```ts
|
|
242
|
+
auth: { type: "apikey", header: "X-API-Key", key: process.env.API_KEY! }
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Basic auth** — `Authorization: Basic <base64>`:
|
|
246
|
+
```ts
|
|
247
|
+
auth: { type: "basic", username: "user", password: process.env.PASSWORD! }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Extra axios config
|
|
253
|
+
|
|
254
|
+
Pass any [axios request config](https://axios-http.com/docs/req_config) via `axiosConfig`:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
getToolAdapter(server, {
|
|
258
|
+
name: "get-data",
|
|
259
|
+
description: "Fetch with custom timeout",
|
|
260
|
+
endpoint: "https://api.example.com/data",
|
|
261
|
+
axiosConfig: { timeout: 5000 },
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## API Reference
|
|
268
|
+
|
|
269
|
+
### Method-specific adapters
|
|
270
|
+
|
|
271
|
+
| Function | Method | Args mapping |
|
|
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 |
|
|
278
|
+
|
|
279
|
+
All support optional `inputSchema` and `:paramName` path variables.
|
|
280
|
+
|
|
281
|
+
### Auth types
|
|
76
282
|
|
|
77
|
-
|
|
283
|
+
| Type | Interface | Fields |
|
|
284
|
+
|------|-----------|--------|
|
|
285
|
+
| Bearer | `BearerAuth` | `token` |
|
|
286
|
+
| API Key | `ApiKeyAuth` | `header`, `key` |
|
|
287
|
+
| Basic | `BasicAuth` | `username`, `password` |
|
|
78
288
|
|
|
79
|
-
|
|
80
|
-
|----------|-------------|
|
|
81
|
-
| `toolAdapter<T>(server, ToolInputAdapterWithSchema<T>)` | Tool with typed input schema |
|
|
82
|
-
| `toolAdapter(server, ToolInputAdapterWithoutSchema)` | Tool with no input arguments |
|
|
289
|
+
---
|
|
83
290
|
|
|
84
|
-
|
|
291
|
+
## Repository
|
|
85
292
|
|
|
86
|
-
|
|
293
|
+
[github.com/jalpp/mcp-adapter](https://github.com/jalpp/mcp-adapter)
|
|
87
294
|
|
|
88
295
|
## License
|
|
89
296
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { McpServer, ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js';
|
|
3
3
|
import { ToolAnnotations, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { AxiosRequestConfig } from 'axios';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Adapter input for registering a tool that declares an input schema.
|
|
@@ -92,4 +93,243 @@ declare function toolAdapter<T extends ZodRawShapeCompat>(server: McpServer, too
|
|
|
92
93
|
*/
|
|
93
94
|
declare function toolAdapter(server: McpServer, toolInputAdapter: ToolInputAdapterWithoutSchema): void;
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Supported HTTP methods for the HTTP tool adapter.
|
|
98
|
+
*/
|
|
99
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
100
|
+
/**
|
|
101
|
+
* API key authentication — sent as a request header.
|
|
102
|
+
* @example { type: "apikey", header: "X-API-Key", key: process.env.API_KEY! }
|
|
103
|
+
*/
|
|
104
|
+
interface ApiKeyAuth {
|
|
105
|
+
type: "apikey";
|
|
106
|
+
/** Header name to send the key in (e.g. `"X-API-Key"`) */
|
|
107
|
+
header: string;
|
|
108
|
+
key: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Bearer token authentication — sends `Authorization: Bearer <token>`.
|
|
112
|
+
* @example { type: "bearer", token: process.env.API_TOKEN! }
|
|
113
|
+
*/
|
|
114
|
+
interface BearerAuth {
|
|
115
|
+
type: "bearer";
|
|
116
|
+
token: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* HTTP Basic authentication — sends `Authorization: Basic <base64>`.
|
|
120
|
+
* @example { type: "basic", username: "user", password: process.env.PASSWORD! }
|
|
121
|
+
*/
|
|
122
|
+
interface BasicAuth {
|
|
123
|
+
type: "basic";
|
|
124
|
+
username: string;
|
|
125
|
+
password: string;
|
|
126
|
+
}
|
|
127
|
+
/** Union of all supported authentication strategies. */
|
|
128
|
+
type HttpAuth = ApiKeyAuth | BearerAuth | BasicAuth;
|
|
129
|
+
/**
|
|
130
|
+
* Configuration for registering an HTTP endpoint as an MCP tool with an input schema.
|
|
131
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
132
|
+
*/
|
|
133
|
+
interface HttpToolAdapterWithSchema<T extends ZodRawShapeCompat> {
|
|
134
|
+
/** Unique tool name in the MCP registry. */
|
|
135
|
+
name: string;
|
|
136
|
+
/** Description of the tool shown to the model. */
|
|
137
|
+
description: string;
|
|
138
|
+
/**
|
|
139
|
+
* Full URL of the API endpoint. Supports path variable templates using `:paramName` syntax.
|
|
140
|
+
* @example "https://api.example.com/users/:userId/posts"
|
|
141
|
+
*/
|
|
142
|
+
endpoint: string;
|
|
143
|
+
/** HTTP method to use. */
|
|
144
|
+
method: HttpMethod;
|
|
145
|
+
/** Zod shape defining the tool's input arguments. */
|
|
146
|
+
inputSchema: T;
|
|
147
|
+
/** Optional authentication strategy. */
|
|
148
|
+
auth?: HttpAuth;
|
|
149
|
+
/** Optional extra axios config (e.g. headers, timeout). */
|
|
150
|
+
axiosConfig?: AxiosRequestConfig;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Configuration for registering an HTTP endpoint as an MCP tool with no input arguments.
|
|
154
|
+
*/
|
|
155
|
+
interface HttpToolAdapterWithoutSchema {
|
|
156
|
+
/** Unique tool name in the MCP registry. */
|
|
157
|
+
name: string;
|
|
158
|
+
/** Description of the tool shown to the model. */
|
|
159
|
+
description: string;
|
|
160
|
+
/**
|
|
161
|
+
* Full URL of the API endpoint. Supports path variable templates using `:paramName` syntax.
|
|
162
|
+
* @example "https://api.example.com/status"
|
|
163
|
+
*/
|
|
164
|
+
endpoint: string;
|
|
165
|
+
/** HTTP method to use. */
|
|
166
|
+
method: HttpMethod;
|
|
167
|
+
inputSchema?: undefined;
|
|
168
|
+
/** Optional authentication strategy. */
|
|
169
|
+
auth?: HttpAuth;
|
|
170
|
+
/** Optional extra axios config (e.g. headers, timeout). */
|
|
171
|
+
axiosConfig?: AxiosRequestConfig;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Configuration specific to GET tool adapters.
|
|
175
|
+
* Input args are mapped to query parameters unless consumed by path variables.
|
|
176
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
177
|
+
*/
|
|
178
|
+
type GetToolAdapterConfig<T extends ZodRawShapeCompat> = Omit<HttpToolAdapterWithSchema<T>, "method">;
|
|
179
|
+
/**
|
|
180
|
+
* Configuration specific to GET tool adapters without input schema.
|
|
181
|
+
*/
|
|
182
|
+
type GetToolAdapterConfigNoSchema = Omit<HttpToolAdapterWithoutSchema, "method">;
|
|
183
|
+
/**
|
|
184
|
+
* Configuration specific to POST tool adapters.
|
|
185
|
+
* Input args are sent as the JSON request body unless consumed by path variables.
|
|
186
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
187
|
+
*/
|
|
188
|
+
type PostToolAdapterConfig<T extends ZodRawShapeCompat> = Omit<HttpToolAdapterWithSchema<T>, "method">;
|
|
189
|
+
/**
|
|
190
|
+
* Configuration specific to POST tool adapters without input schema.
|
|
191
|
+
*/
|
|
192
|
+
type PostToolAdapterConfigNoSchema = Omit<HttpToolAdapterWithoutSchema, "method">;
|
|
193
|
+
/**
|
|
194
|
+
* Configuration specific to PUT tool adapters.
|
|
195
|
+
* Input args are sent as the JSON request body unless consumed by path variables.
|
|
196
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
197
|
+
*/
|
|
198
|
+
type PutToolAdapterConfig<T extends ZodRawShapeCompat> = Omit<HttpToolAdapterWithSchema<T>, "method">;
|
|
199
|
+
/**
|
|
200
|
+
* Configuration specific to PATCH tool adapters.
|
|
201
|
+
* Input args are sent as the JSON request body unless consumed by path variables.
|
|
202
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
203
|
+
*/
|
|
204
|
+
type PatchToolAdapterConfig<T extends ZodRawShapeCompat> = Omit<HttpToolAdapterWithSchema<T>, "method">;
|
|
205
|
+
/**
|
|
206
|
+
* Configuration specific to DELETE tool adapters.
|
|
207
|
+
* Input args are sent as query parameters unless consumed by path variables.
|
|
208
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
209
|
+
*/
|
|
210
|
+
type DeleteToolAdapterConfig<T extends ZodRawShapeCompat> = Omit<HttpToolAdapterWithSchema<T>, "method">;
|
|
211
|
+
/**
|
|
212
|
+
* Core HTTP tool adapter. Registers any HTTP endpoint as an MCP tool.
|
|
213
|
+
*
|
|
214
|
+
* Prefer the method-specific adapters (`getToolAdapter`, `postToolAdapter`, etc.)
|
|
215
|
+
* for cleaner, self-documenting code.
|
|
216
|
+
*
|
|
217
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
218
|
+
* - GET/DELETE: remaining args → query parameters.
|
|
219
|
+
* - POST/PUT/PATCH: remaining args → JSON request body.
|
|
220
|
+
*
|
|
221
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
222
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
223
|
+
* @param adapter - HTTP tool configuration.
|
|
224
|
+
*/
|
|
225
|
+
declare function httpToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, adapter: HttpToolAdapterWithSchema<T>): void;
|
|
226
|
+
declare function httpToolAdapter(server: McpServer, adapter: HttpToolAdapterWithoutSchema): void;
|
|
227
|
+
/**
|
|
228
|
+
* Registers a GET endpoint as an MCP tool.
|
|
229
|
+
*
|
|
230
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
231
|
+
* - Remaining args are sent as **query parameters**.
|
|
232
|
+
*
|
|
233
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
234
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
235
|
+
* @param config - Tool configuration without `method`.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* getToolAdapter(server, {
|
|
239
|
+
* name: "get-user",
|
|
240
|
+
* description: "Fetch a user by ID",
|
|
241
|
+
* endpoint: "https://api.example.com/users/:userId",
|
|
242
|
+
* inputSchema: { userId: z.string(), expand: z.string().optional() },
|
|
243
|
+
* auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
244
|
+
* });
|
|
245
|
+
* // GET https://api.example.com/users/abc123?expand=profile
|
|
246
|
+
*/
|
|
247
|
+
declare function getToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: GetToolAdapterConfig<T>): void;
|
|
248
|
+
declare function getToolAdapter(server: McpServer, config: GetToolAdapterConfigNoSchema): void;
|
|
249
|
+
/**
|
|
250
|
+
* Registers a POST endpoint as an MCP tool.
|
|
251
|
+
*
|
|
252
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
253
|
+
* - Remaining args are sent as the **JSON request body**.
|
|
254
|
+
*
|
|
255
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
256
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
257
|
+
* @param config - Tool configuration without `method`.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* postToolAdapter(server, {
|
|
261
|
+
* name: "create-post",
|
|
262
|
+
* description: "Create a new post for a user",
|
|
263
|
+
* endpoint: "https://api.example.com/users/:userId/posts",
|
|
264
|
+
* inputSchema: { userId: z.string(), title: z.string(), body: z.string() },
|
|
265
|
+
* auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
266
|
+
* });
|
|
267
|
+
* // POST https://api.example.com/users/abc123/posts { title, body }
|
|
268
|
+
*/
|
|
269
|
+
declare function postToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: PostToolAdapterConfig<T>): void;
|
|
270
|
+
declare function postToolAdapter(server: McpServer, config: PostToolAdapterConfigNoSchema): void;
|
|
271
|
+
/**
|
|
272
|
+
* Registers a PUT endpoint as an MCP tool.
|
|
273
|
+
*
|
|
274
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
275
|
+
* - Remaining args are sent as the **JSON request body**.
|
|
276
|
+
*
|
|
277
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
278
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
279
|
+
* @param config - Tool configuration without `method`.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* putToolAdapter(server, {
|
|
283
|
+
* name: "update-user",
|
|
284
|
+
* description: "Replace a user record",
|
|
285
|
+
* endpoint: "https://api.example.com/users/:userId",
|
|
286
|
+
* inputSchema: { userId: z.string(), name: z.string(), email: z.string() },
|
|
287
|
+
* auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
288
|
+
* });
|
|
289
|
+
* // PUT https://api.example.com/users/abc123 { name, email }
|
|
290
|
+
*/
|
|
291
|
+
declare function putToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: PutToolAdapterConfig<T>): void;
|
|
292
|
+
/**
|
|
293
|
+
* Registers a PATCH endpoint as an MCP tool.
|
|
294
|
+
*
|
|
295
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
296
|
+
* - Remaining args are sent as the **JSON request body**.
|
|
297
|
+
*
|
|
298
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
299
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
300
|
+
* @param config - Tool configuration without `method`.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* patchToolAdapter(server, {
|
|
304
|
+
* name: "update-post-title",
|
|
305
|
+
* description: "Partially update a post",
|
|
306
|
+
* endpoint: "https://api.example.com/posts/:postId",
|
|
307
|
+
* inputSchema: { postId: z.string(), title: z.string() },
|
|
308
|
+
* auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
309
|
+
* });
|
|
310
|
+
* // PATCH https://api.example.com/posts/xyz789 { title }
|
|
311
|
+
*/
|
|
312
|
+
declare function patchToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: PatchToolAdapterConfig<T>): void;
|
|
313
|
+
/**
|
|
314
|
+
* Registers a DELETE endpoint as an MCP tool.
|
|
315
|
+
*
|
|
316
|
+
* - Path variables (`:paramName`) are interpolated from input args.
|
|
317
|
+
* - Remaining args are sent as **query parameters**.
|
|
318
|
+
*
|
|
319
|
+
* @template T - Zod raw shape inferred from `inputSchema`.
|
|
320
|
+
* @param server - The `McpServer` instance to register the tool on.
|
|
321
|
+
* @param config - Tool configuration without `method`.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* deleteToolAdapter(server, {
|
|
325
|
+
* name: "delete-post",
|
|
326
|
+
* description: "Delete a post by ID",
|
|
327
|
+
* endpoint: "https://api.example.com/posts/:postId",
|
|
328
|
+
* inputSchema: { postId: z.string() },
|
|
329
|
+
* auth: { type: "bearer", token: process.env.API_TOKEN! },
|
|
330
|
+
* });
|
|
331
|
+
* // DELETE https://api.example.com/posts/xyz789
|
|
332
|
+
*/
|
|
333
|
+
declare function deleteToolAdapter<T extends ZodRawShapeCompat>(server: McpServer, config: DeleteToolAdapterConfig<T>): void;
|
|
334
|
+
|
|
335
|
+
export { type ApiKeyAuth, type BasicAuth, type BearerAuth, type DeleteToolAdapterConfig, type GetToolAdapterConfig, type GetToolAdapterConfigNoSchema, type HttpAuth, type HttpMethod, type HttpToolAdapterWithSchema, type HttpToolAdapterWithoutSchema, type PatchToolAdapterConfig, type PostToolAdapterConfig, type PostToolAdapterConfigNoSchema, type PutToolAdapterConfig, deleteToolAdapter, getToolAdapter, httpToolAdapter, patchToolAdapter, postToolAdapter, putToolAdapter, toolAdapter, toolContentAdapter };
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,110 @@ function toolAdapter(server, toolInputAdapter) {
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
// src/axiosAdapter.ts
|
|
29
|
+
import axios from "axios";
|
|
30
|
+
function buildAuthHeaders(auth) {
|
|
31
|
+
switch (auth.type) {
|
|
32
|
+
case "apikey":
|
|
33
|
+
return { [auth.header]: auth.key };
|
|
34
|
+
case "bearer":
|
|
35
|
+
return { Authorization: `Bearer ${auth.token}` };
|
|
36
|
+
case "basic": {
|
|
37
|
+
const encoded = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
|
|
38
|
+
return { Authorization: `Basic ${encoded}` };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function resolvePathParams(endpoint, args) {
|
|
43
|
+
const remainingArgs = { ...args };
|
|
44
|
+
const url = endpoint.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, key) => {
|
|
45
|
+
if (key in remainingArgs) {
|
|
46
|
+
const value = remainingArgs[key];
|
|
47
|
+
delete remainingArgs[key];
|
|
48
|
+
return encodeURIComponent(String(value));
|
|
49
|
+
}
|
|
50
|
+
return `:${key}`;
|
|
51
|
+
});
|
|
52
|
+
return { url, remainingArgs };
|
|
53
|
+
}
|
|
54
|
+
async function executeRequest(endpoint, method, args, auth, extraConfig) {
|
|
55
|
+
try {
|
|
56
|
+
const authHeaders = auth ? buildAuthHeaders(auth) : {};
|
|
57
|
+
const { url, remainingArgs } = resolvePathParams(endpoint, args);
|
|
58
|
+
const isQueryMethod = method === "GET" || method === "DELETE";
|
|
59
|
+
const config = {
|
|
60
|
+
url,
|
|
61
|
+
method,
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
...authHeaders,
|
|
65
|
+
...extraConfig?.headers
|
|
66
|
+
},
|
|
67
|
+
...isQueryMethod ? { params: remainingArgs } : { data: remainingArgs },
|
|
68
|
+
...extraConfig
|
|
69
|
+
};
|
|
70
|
+
const response = await axios(config);
|
|
71
|
+
return { data: response.data };
|
|
72
|
+
} catch (err) {
|
|
73
|
+
if (axios.isAxiosError(err)) {
|
|
74
|
+
const status = err.response?.status ?? "unknown";
|
|
75
|
+
const message = err.response?.data?.message ?? err.message;
|
|
76
|
+
return { error: `HTTP ${status}: ${message}` };
|
|
77
|
+
}
|
|
78
|
+
return { error: `Unexpected error: ${String(err)}` };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function httpToolAdapter(server, adapter) {
|
|
82
|
+
if (adapter.inputSchema) {
|
|
83
|
+
const { endpoint, method, auth, axiosConfig, inputSchema } = adapter;
|
|
84
|
+
toolAdapter(server, {
|
|
85
|
+
name: adapter.name,
|
|
86
|
+
config: { description: adapter.description, inputSchema },
|
|
87
|
+
cb: (async (args) => {
|
|
88
|
+
const { data, error } = await executeRequest(endpoint, method, args, auth, axiosConfig);
|
|
89
|
+
return toolContentAdapter(data ?? {}, error);
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
toolAdapter(server, {
|
|
94
|
+
name: adapter.name,
|
|
95
|
+
config: { description: adapter.description },
|
|
96
|
+
cb: async () => {
|
|
97
|
+
const { data, error } = await executeRequest(
|
|
98
|
+
adapter.endpoint,
|
|
99
|
+
adapter.method,
|
|
100
|
+
{},
|
|
101
|
+
adapter.auth,
|
|
102
|
+
adapter.axiosConfig
|
|
103
|
+
);
|
|
104
|
+
return toolContentAdapter(data ?? {}, error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function getToolAdapter(server, config) {
|
|
110
|
+
httpToolAdapter(server, { ...config, method: "GET" });
|
|
111
|
+
}
|
|
112
|
+
function postToolAdapter(server, config) {
|
|
113
|
+
httpToolAdapter(server, { ...config, method: "POST" });
|
|
114
|
+
}
|
|
115
|
+
function putToolAdapter(server, config) {
|
|
116
|
+
httpToolAdapter(server, { ...config, method: "PUT" });
|
|
117
|
+
}
|
|
118
|
+
function patchToolAdapter(server, config) {
|
|
119
|
+
httpToolAdapter(server, { ...config, method: "PATCH" });
|
|
120
|
+
}
|
|
121
|
+
function deleteToolAdapter(server, config) {
|
|
122
|
+
httpToolAdapter(server, { ...config, method: "DELETE" });
|
|
123
|
+
}
|
|
27
124
|
export {
|
|
125
|
+
deleteToolAdapter,
|
|
126
|
+
getToolAdapter,
|
|
127
|
+
httpToolAdapter,
|
|
128
|
+
patchToolAdapter,
|
|
129
|
+
postToolAdapter,
|
|
130
|
+
putToolAdapter,
|
|
28
131
|
toolAdapter,
|
|
29
132
|
toolContentAdapter
|
|
30
133
|
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jalpp/mcp-adapter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Adapter utilities for registering MCP tools",
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mcp",
|
|
9
|
+
"model-context-protocol",
|
|
10
|
+
"adapter",
|
|
11
|
+
"llm",
|
|
12
|
+
"typescript",
|
|
13
|
+
"axios",
|
|
14
|
+
"http",
|
|
15
|
+
"tool"
|
|
16
|
+
],
|
|
7
17
|
"repository": {
|
|
8
18
|
"type": "git",
|
|
9
19
|
"url": "git+https://github.com/jalpp/mcp-adapter.git"
|
|
10
20
|
},
|
|
21
|
+
"homepage": "https://github.com/jalpp/mcp-adapter#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/jalpp/mcp-adapter/issues"
|
|
24
|
+
},
|
|
11
25
|
"type": "module",
|
|
12
26
|
"main": "./dist/index.js",
|
|
13
27
|
"module": "./dist/index.js",
|
|
@@ -19,7 +33,9 @@
|
|
|
19
33
|
}
|
|
20
34
|
},
|
|
21
35
|
"files": [
|
|
22
|
-
"dist"
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
23
39
|
],
|
|
24
40
|
"scripts": {
|
|
25
41
|
"build": "tsup",
|
|
@@ -28,13 +44,17 @@
|
|
|
28
44
|
},
|
|
29
45
|
"peerDependencies": {
|
|
30
46
|
"@modelcontextprotocol/sdk": ">=1.0.0",
|
|
31
|
-
"zod": ">=3.0.0"
|
|
47
|
+
"zod": ">=3.0.0",
|
|
48
|
+
"axios": ">=1.0.0"
|
|
32
49
|
},
|
|
33
50
|
"devDependencies": {
|
|
34
51
|
"@modelcontextprotocol/sdk": ">=1.0.0",
|
|
35
|
-
"
|
|
36
|
-
"typescript": "^5.0.0",
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
37
53
|
"tsup": "^8.0.0",
|
|
38
|
-
"
|
|
54
|
+
"typescript": "^5.0.0",
|
|
55
|
+
"zod": ">=3.0.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"axios": "^1.13.6"
|
|
39
59
|
}
|
|
40
60
|
}
|