@0xmonaco/mcp-server 0.1.1 → 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/CHANGELOG.md +7 -11
- package/bin/cli.js +38 -35
- package/package.json +2 -2
- package/src/connect.js +37 -37
- package/src/index.js +41 -41
- package/src/initialize.js +6 -6
- package/src/search.d.ts +1 -3
- package/src/search.js +104 -104
- package/src/tools/helpers.d.ts +5 -16
- package/src/tools/helpers.js +241 -241
- package/src/tools/index.d.ts +1 -4
- package/src/tools/index.js +175 -175
- package/src/tools/zod.d.ts +2 -9
- package/src/tools/zod.js +176 -176
- package/src/tools.json +6 -6
- package/src/utils.d.ts +3 -12
- package/src/utils.js +52 -52
package/src/tools/helpers.js
CHANGED
|
@@ -8,271 +8,271 @@ import { z } from "zod";
|
|
|
8
8
|
import { initializeObject } from "../utils.js";
|
|
9
9
|
import { dataSchemaArrayToZod, dataSchemaToZod } from "./zod.js";
|
|
10
10
|
export function convertStrToTitle(str) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
const spacedString = str.replace(/[-_]/g, " ");
|
|
12
|
+
const words = spacedString.split(/(?=[A-Z])|\s+/);
|
|
13
|
+
const titleCasedWords = words.map((word) => {
|
|
14
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
15
|
+
});
|
|
16
|
+
return titleCasedWords.join(" ");
|
|
17
17
|
}
|
|
18
18
|
export function findNextIteration(set, str) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
let count = 1;
|
|
20
|
+
set.forEach((val) => {
|
|
21
|
+
if (val.startsWith(`${str}---`)) {
|
|
22
|
+
count = Number(val.replace(`${str}---`, ""));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return count + 1;
|
|
26
26
|
}
|
|
27
27
|
export function getMcpEnabledEndpointsFromOpenApiSpec(spec) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
var _a;
|
|
29
|
+
const mcpEnabledEndpoints = [];
|
|
30
|
+
const isMcpEnabledGloballyInSpec =
|
|
31
|
+
((_a = spec["x-mcp"]) === null || _a === void 0 ? void 0 : _a.enabled) ===
|
|
32
|
+
true;
|
|
33
|
+
const endpoints = getEndpointsFromOpenApi(spec);
|
|
34
|
+
if (isMcpEnabledGloballyInSpec) {
|
|
35
|
+
const notDisabledEndpoints = endpoints.filter((endpoint) => {
|
|
36
|
+
var _a;
|
|
37
|
+
return (
|
|
38
|
+
((_a = endpoint.xMcp) === null || _a === void 0
|
|
39
|
+
? void 0
|
|
40
|
+
: _a.enabled) !== false
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
mcpEnabledEndpoints.push(...notDisabledEndpoints);
|
|
44
|
+
} else {
|
|
45
|
+
const enabledEndpoints = endpoints.filter((endpoint) => {
|
|
46
|
+
var _a;
|
|
47
|
+
return (
|
|
48
|
+
((_a = endpoint.xMcp) === null || _a === void 0
|
|
49
|
+
? void 0
|
|
50
|
+
: _a.enabled) === true
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
mcpEnabledEndpoints.push(...enabledEndpoints);
|
|
54
|
+
}
|
|
55
|
+
return mcpEnabledEndpoints;
|
|
56
56
|
}
|
|
57
57
|
export function convertEndpointToTool(endpoint) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
58
|
+
var _a, _b;
|
|
59
|
+
let name;
|
|
60
|
+
if ((_a = endpoint.xMcp) === null || _a === void 0 ? void 0 : _a.name) {
|
|
61
|
+
name = endpoint.xMcp.name;
|
|
62
|
+
} else if (endpoint.title) {
|
|
63
|
+
name = dashify(endpoint.title);
|
|
64
|
+
} else {
|
|
65
|
+
name = convertStrToTitle(endpoint.path);
|
|
66
|
+
}
|
|
67
|
+
let description;
|
|
68
|
+
if (
|
|
69
|
+
(_b = endpoint.xMcp) === null || _b === void 0 ? void 0 : _b.description
|
|
70
|
+
) {
|
|
71
|
+
description = endpoint.xMcp.description;
|
|
72
|
+
} else if (endpoint.description) {
|
|
73
|
+
description = endpoint.description;
|
|
74
|
+
} else {
|
|
75
|
+
description = `${endpoint.method} ${endpoint.path}`;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
name,
|
|
79
|
+
description,
|
|
80
|
+
};
|
|
81
81
|
}
|
|
82
82
|
export function getMcpToolsAndEndpointsFromOpenApiSpec(spec) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
const endpoints = getMcpEnabledEndpointsFromOpenApiSpec(spec);
|
|
84
|
+
const toolsWithEndpoints = [];
|
|
85
|
+
endpoints.forEach((endpoint) => {
|
|
86
|
+
const tool = convertEndpointToTool(endpoint);
|
|
87
|
+
toolsWithEndpoints.push({
|
|
88
|
+
tool,
|
|
89
|
+
endpoint,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
return toolsWithEndpoints;
|
|
93
93
|
}
|
|
94
94
|
export function getEndpointsFromOpenApi(specification) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
95
|
+
const endpoints = [];
|
|
96
|
+
const paths = specification.paths;
|
|
97
|
+
for (const path in paths) {
|
|
98
|
+
const pathObj = paths[path];
|
|
99
|
+
const httpMethods = Object.values(OpenAPIV3.HttpMethods);
|
|
100
|
+
for (const method of httpMethods) {
|
|
101
|
+
if (!pathObj || !(method in pathObj)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const endpoint = OpenApiToEndpointConverter.convert(
|
|
105
|
+
specification,
|
|
106
|
+
path,
|
|
107
|
+
method,
|
|
108
|
+
true,
|
|
109
|
+
);
|
|
110
|
+
endpoints.push(endpoint);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return endpoints;
|
|
114
114
|
}
|
|
115
115
|
export function loadEnv(key) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
116
|
+
var _a;
|
|
117
|
+
let envVars = {};
|
|
118
|
+
try {
|
|
119
|
+
const envPath = path.join(
|
|
120
|
+
fileURLToPath(import.meta.url),
|
|
121
|
+
"../../../",
|
|
122
|
+
".env.json",
|
|
123
|
+
);
|
|
124
|
+
if (fs.existsSync(envPath)) {
|
|
125
|
+
envVars = JSON.parse(fs.readFileSync(envPath).toString());
|
|
126
|
+
return (_a = envVars[key]) !== null && _a !== void 0 ? _a : {};
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
// if there's no env, the user will be prompted
|
|
130
|
+
// for their auth info at runtime if necessary
|
|
131
|
+
// (shouldn't happen either way)
|
|
132
|
+
}
|
|
133
|
+
return envVars;
|
|
134
134
|
}
|
|
135
135
|
function convertParameterSection(parameters, paramSection) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
Object.entries(parameters).forEach(([key, value]) => {
|
|
137
|
+
const schema = value.schema;
|
|
138
|
+
paramSection[key] = dataSchemaArrayToZod(schema);
|
|
139
|
+
});
|
|
140
140
|
}
|
|
141
141
|
function convertParametersAndAddToRelevantParamGroups(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
parameters,
|
|
143
|
+
paths,
|
|
144
|
+
queries,
|
|
145
|
+
headers,
|
|
146
|
+
cookies,
|
|
147
147
|
) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
convertParameterSection(parameters.path, paths);
|
|
149
|
+
convertParameterSection(parameters.query, queries);
|
|
150
|
+
convertParameterSection(parameters.header, headers);
|
|
151
|
+
convertParameterSection(parameters.cookie, cookies);
|
|
152
152
|
}
|
|
153
153
|
// this function returns all the securityParameters and seeds them with the envVariables if we have them
|
|
154
154
|
export function convertSecurityParameterSection(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
securityParameters,
|
|
156
|
+
envVariables,
|
|
157
|
+
location,
|
|
158
158
|
) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
159
|
+
const res = [];
|
|
160
|
+
Object.entries(securityParameters).forEach(([key, value]) => {
|
|
161
|
+
let envKeyList = [];
|
|
162
|
+
let targetKey = "";
|
|
163
|
+
switch (value.type) {
|
|
164
|
+
case "apiKey":
|
|
165
|
+
envKeyList = [location, key];
|
|
166
|
+
targetKey = "API_KEY";
|
|
167
|
+
break;
|
|
168
|
+
case "http":
|
|
169
|
+
envKeyList = [location, key, "HTTP"];
|
|
170
|
+
targetKey = value.scheme;
|
|
171
|
+
break;
|
|
172
|
+
case "oauth2":
|
|
173
|
+
default:
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
const target = initializeObject(
|
|
177
|
+
Object.assign({}, envVariables),
|
|
178
|
+
envKeyList,
|
|
179
|
+
);
|
|
180
|
+
if (envKeyList.length && !target[targetKey]) {
|
|
181
|
+
res.push({
|
|
182
|
+
key,
|
|
183
|
+
value: undefined,
|
|
184
|
+
});
|
|
185
|
+
} else {
|
|
186
|
+
res.push({
|
|
187
|
+
key,
|
|
188
|
+
value: target[targetKey],
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return res;
|
|
193
193
|
}
|
|
194
194
|
function convertSecurityParametersAndAddToRelevantParamGroups(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
195
|
+
securityParameters,
|
|
196
|
+
queries,
|
|
197
|
+
headers,
|
|
198
|
+
cookies,
|
|
199
|
+
envVariables,
|
|
200
200
|
) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
201
|
+
const queryRes = convertSecurityParameterSection(
|
|
202
|
+
securityParameters.query,
|
|
203
|
+
envVariables,
|
|
204
|
+
"query",
|
|
205
|
+
);
|
|
206
|
+
const headerRes = convertSecurityParameterSection(
|
|
207
|
+
securityParameters.header,
|
|
208
|
+
envVariables,
|
|
209
|
+
"header",
|
|
210
|
+
);
|
|
211
|
+
const cookieRes = convertSecurityParameterSection(
|
|
212
|
+
securityParameters.cookie,
|
|
213
|
+
envVariables,
|
|
214
|
+
"cookie",
|
|
215
|
+
);
|
|
216
|
+
// non intuitive that we seed the query with a zod type if it *doesn't* exist
|
|
217
|
+
// but that's because if we don't have it in our env Variables, that means the user should provide it in their query.
|
|
218
|
+
queryRes.forEach(({ key, value }) => {
|
|
219
|
+
if (!value) {
|
|
220
|
+
queries[key] = z.string();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
headerRes.forEach(({ key, value }) => {
|
|
224
|
+
if (!value) {
|
|
225
|
+
headers[key] = z.string();
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
cookieRes.forEach(({ key, value }) => {
|
|
229
|
+
if (!value) {
|
|
230
|
+
cookies[key] = z.string();
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
233
|
}
|
|
234
234
|
export function convertEndpointToCategorizedZod(envKey, endpoint) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
235
|
+
var _a, _b, _c;
|
|
236
|
+
const envVariables = loadEnv(envKey);
|
|
237
|
+
const url = `${((_b = (_a = endpoint.servers) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.url) || ""}${endpoint.path}`;
|
|
238
|
+
const method = endpoint.method;
|
|
239
|
+
const paths = {};
|
|
240
|
+
const queries = {};
|
|
241
|
+
const headers = {};
|
|
242
|
+
const cookies = {};
|
|
243
|
+
let body = undefined;
|
|
244
|
+
convertParametersAndAddToRelevantParamGroups(
|
|
245
|
+
endpoint.request.parameters,
|
|
246
|
+
paths,
|
|
247
|
+
queries,
|
|
248
|
+
headers,
|
|
249
|
+
cookies,
|
|
250
|
+
);
|
|
251
|
+
if (
|
|
252
|
+
(_c = endpoint.request.security[0]) === null || _c === void 0
|
|
253
|
+
? void 0
|
|
254
|
+
: _c.parameters
|
|
255
|
+
) {
|
|
256
|
+
convertSecurityParametersAndAddToRelevantParamGroups(
|
|
257
|
+
endpoint.request.security[0].parameters,
|
|
258
|
+
queries,
|
|
259
|
+
headers,
|
|
260
|
+
cookies,
|
|
261
|
+
envVariables,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
const jsonBodySchema = endpoint.request.body["application/json"];
|
|
265
|
+
const bodySchemaArray =
|
|
266
|
+
jsonBodySchema === null || jsonBodySchema === void 0
|
|
267
|
+
? void 0
|
|
268
|
+
: jsonBodySchema.schemaArray;
|
|
269
|
+
const bodySchema =
|
|
270
|
+
bodySchemaArray === null || bodySchemaArray === void 0
|
|
271
|
+
? void 0
|
|
272
|
+
: bodySchemaArray[0];
|
|
273
|
+
if (bodySchema) {
|
|
274
|
+
const zodBodySchema = dataSchemaToZod(bodySchema);
|
|
275
|
+
body = { body: zodBodySchema };
|
|
276
|
+
}
|
|
277
|
+
return { url, method, paths, queries, body, headers, cookies };
|
|
278
278
|
}
|
package/src/tools/index.d.ts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
export declare function createTools(
|
|
3
|
-
server: McpServer,
|
|
4
|
-
existingTools: Set<string>,
|
|
5
|
-
): Promise<void>;
|
|
2
|
+
export declare function createTools(server: McpServer, existingTools: Set<string>): Promise<void>;
|