@mondaydotcomorg/atp-mcp-adapter 0.17.14
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 +407 -0
- package/dist/http-connector.d.ts +18 -0
- package/dist/http-connector.d.ts.map +1 -0
- package/dist/http-connector.js +86 -0
- package/dist/http-connector.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-connector.d.ts +57 -0
- package/dist/mcp-connector.d.ts.map +1 -0
- package/dist/mcp-connector.js +131 -0
- package/dist/mcp-connector.js.map +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
- package/src/http-connector.ts +121 -0
- package/src/index.ts +3 -0
- package/src/mcp-connector.ts +166 -0
- package/src/types.ts +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# @mondaydotcomorg/atp-mcp-adapter
|
|
2
|
+
|
|
3
|
+
Model Context Protocol (MCP) adapter for Agent Tool Protocol - connect MCP servers and use their tools in ATP.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package enables seamless integration between MCP (Model Context Protocol) servers and ATP servers. Connect to any MCP server (stdio or HTTP) and expose their tools as ATP APIs.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @mondaydotcomorg/atp-mcp-adapter
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
graph LR
|
|
19
|
+
ATP[ATP Server] --> Adapter[MCP Adapter]
|
|
20
|
+
Adapter --> Stdio[StdioTransport]
|
|
21
|
+
Adapter --> HTTP[HTTPTransport]
|
|
22
|
+
|
|
23
|
+
Stdio --> MCP1[MCP Server 1<br/>Filesystem]
|
|
24
|
+
HTTP --> MCP2[MCP Server 2<br/>Database]
|
|
25
|
+
HTTP --> MCP3[MCP Server 3<br/>API]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Connect to MCP Server (stdio)
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { createServer } from '@mondaydotcomorg/atp-server';
|
|
34
|
+
import { MCPConnector } from '@mondaydotcomorg/atp-mcp-adapter';
|
|
35
|
+
|
|
36
|
+
const server = createServer();
|
|
37
|
+
const mcpConnector = new MCPConnector();
|
|
38
|
+
|
|
39
|
+
// Connect to filesystem MCP server
|
|
40
|
+
const filesystemAPI = await mcpConnector.connectToMCPServer({
|
|
41
|
+
name: 'filesystem',
|
|
42
|
+
command: 'npx',
|
|
43
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/files'],
|
|
44
|
+
env: {
|
|
45
|
+
LOG_LEVEL: 'info',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
server.addAPIGroup(filesystemAPI);
|
|
50
|
+
|
|
51
|
+
await server.start(3333);
|
|
52
|
+
|
|
53
|
+
// Agents can now use MCP tools:
|
|
54
|
+
// await atp.api.filesystem.read_file({ path: 'README.md' })
|
|
55
|
+
// await atp.api.filesystem.write_file({ path: 'file.txt', content: 'Hello' })
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Connect to HTTP MCP Server
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { MCPHttpConnector } from '@mondaydotcomorg/atp-mcp-adapter';
|
|
62
|
+
|
|
63
|
+
const httpConnector = new MCPHttpConnector();
|
|
64
|
+
|
|
65
|
+
const databaseAPI = await httpConnector.connectToHttpServer({
|
|
66
|
+
name: 'database',
|
|
67
|
+
baseUrl: 'http://localhost:8080/mcp',
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: 'Bearer token',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
server.addAPIGroup(databaseAPI);
|
|
74
|
+
|
|
75
|
+
// Agents can use:
|
|
76
|
+
// await atp.api.database.query({ sql: 'SELECT * FROM users' })
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Multiple MCP Servers
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const mcpConnector = new MCPConnector();
|
|
83
|
+
|
|
84
|
+
const apis = await mcpConnector.connectToMultipleServers([
|
|
85
|
+
{
|
|
86
|
+
name: 'filesystem',
|
|
87
|
+
command: 'npx',
|
|
88
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/data'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'git',
|
|
92
|
+
command: 'npx',
|
|
93
|
+
args: ['-y', '@modelcontextprotocol/server-git', '/repo'],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'database',
|
|
97
|
+
command: 'npx',
|
|
98
|
+
args: ['-y', '@modelcontextprotocol/server-postgres'],
|
|
99
|
+
env: {
|
|
100
|
+
DATABASE_URL: process.env.DATABASE_URL,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
apis.forEach((api) => server.addAPIGroup(api));
|
|
106
|
+
|
|
107
|
+
// Agents can now use:
|
|
108
|
+
// - atp.api.filesystem.*
|
|
109
|
+
// - atp.api.git.*
|
|
110
|
+
// - atp.api.database.*
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## MCP Connectors
|
|
114
|
+
|
|
115
|
+
### MCPConnector (stdio)
|
|
116
|
+
|
|
117
|
+
Connect to MCP servers running as child processes via stdio.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { MCPConnector } from '@mondaydotcomorg/atp-mcp-adapter';
|
|
121
|
+
|
|
122
|
+
const connector = new MCPConnector();
|
|
123
|
+
|
|
124
|
+
const apiGroup = await connector.connectToMCPServer({
|
|
125
|
+
name: string; // API group name
|
|
126
|
+
command: string; // Command to execute
|
|
127
|
+
args: string[]; // Command arguments
|
|
128
|
+
env?: Record<string, string>; // Environment variables
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Examples:**
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Filesystem MCP server
|
|
136
|
+
const filesystem = await connector.connectToMCPServer({
|
|
137
|
+
name: 'files',
|
|
138
|
+
command: 'npx',
|
|
139
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/data'],
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Custom Python MCP server
|
|
143
|
+
const custom = await connector.connectToMCPServer({
|
|
144
|
+
name: 'custom',
|
|
145
|
+
command: 'python',
|
|
146
|
+
args: ['mcp_server.py'],
|
|
147
|
+
env: {
|
|
148
|
+
API_KEY: process.env.API_KEY,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### MCPHttpConnector
|
|
154
|
+
|
|
155
|
+
Connect to MCP servers over HTTP.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { MCPHttpConnector } from '@mondaydotcomorg/atp-mcp-adapter';
|
|
159
|
+
|
|
160
|
+
const connector = new MCPHttpConnector();
|
|
161
|
+
|
|
162
|
+
const apiGroup = await connector.connectToHttpServer({
|
|
163
|
+
name: string; // API group name
|
|
164
|
+
baseUrl: string; // MCP server URL
|
|
165
|
+
headers?: Record<string, string>; // HTTP headers
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Example:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const api = await connector.connectToHttpServer({
|
|
173
|
+
name: 'remote-api',
|
|
174
|
+
baseUrl: 'https://mcp.example.com',
|
|
175
|
+
headers: {
|
|
176
|
+
Authorization: 'Bearer token',
|
|
177
|
+
'X-API-Key': process.env.API_KEY,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Tool Conversion
|
|
183
|
+
|
|
184
|
+
MCP tools are automatically converted to ATP format:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// MCP tool definition
|
|
188
|
+
{
|
|
189
|
+
name: 'read_file',
|
|
190
|
+
description: 'Read file contents',
|
|
191
|
+
inputSchema: {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {
|
|
194
|
+
path: { type: 'string' }
|
|
195
|
+
},
|
|
196
|
+
required: ['path']
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Converted to ATP function
|
|
201
|
+
{
|
|
202
|
+
name: 'read_file',
|
|
203
|
+
description: 'Read file contents',
|
|
204
|
+
inputSchema: { /* same schema */ },
|
|
205
|
+
handler: async (input) => {
|
|
206
|
+
// Calls MCP server
|
|
207
|
+
const result = await mcpClient.callTool({
|
|
208
|
+
name: 'read_file',
|
|
209
|
+
arguments: input
|
|
210
|
+
});
|
|
211
|
+
return result.content;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Agent Usage
|
|
217
|
+
|
|
218
|
+
Once MCP servers are connected, agents can use their tools naturally:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// Agent-generated code
|
|
222
|
+
const files = await atp.api.filesystem.list_directory({
|
|
223
|
+
path: '/data',
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
atp.log.info('Found files', { count: files.length });
|
|
227
|
+
|
|
228
|
+
for (const file of files) {
|
|
229
|
+
const content = await atp.api.filesystem.read_file({
|
|
230
|
+
path: file.path,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Process with LLM
|
|
234
|
+
const summary = await atp.llm.call({
|
|
235
|
+
prompt: `Summarize this file: ${content}`,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Write summary
|
|
239
|
+
await atp.api.filesystem.write_file({
|
|
240
|
+
path: `${file.path}.summary`,
|
|
241
|
+
content: summary,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## MCP Server Examples
|
|
247
|
+
|
|
248
|
+
### Official MCP Servers
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// Filesystem
|
|
252
|
+
await connector.connectToMCPServer({
|
|
253
|
+
name: 'filesystem',
|
|
254
|
+
command: 'npx',
|
|
255
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Git
|
|
259
|
+
await connector.connectToMCPServer({
|
|
260
|
+
name: 'git',
|
|
261
|
+
command: 'npx',
|
|
262
|
+
args: ['-y', '@modelcontextprotocol/server-git', '/repo'],
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// PostgreSQL
|
|
266
|
+
await connector.connectToMCPServer({
|
|
267
|
+
name: 'postgres',
|
|
268
|
+
command: 'npx',
|
|
269
|
+
args: ['-y', '@modelcontextprotocol/server-postgres'],
|
|
270
|
+
env: {
|
|
271
|
+
DATABASE_URL: process.env.DATABASE_URL,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Puppeteer (browser automation)
|
|
276
|
+
await connector.connectToMCPServer({
|
|
277
|
+
name: 'browser',
|
|
278
|
+
command: 'npx',
|
|
279
|
+
args: ['-y', '@modelcontextprotocol/server-puppeteer'],
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Custom MCP Server
|
|
284
|
+
|
|
285
|
+
Create your own MCP server:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
# mcp_server.py
|
|
289
|
+
from mcp.server import Server, Tool
|
|
290
|
+
|
|
291
|
+
server = Server("custom-mcp-server")
|
|
292
|
+
|
|
293
|
+
@server.tool()
|
|
294
|
+
async def process_data(data: str) -> dict:
|
|
295
|
+
"""Process data and return result"""
|
|
296
|
+
result = perform_processing(data)
|
|
297
|
+
return {"result": result}
|
|
298
|
+
|
|
299
|
+
if __name__ == "__main__":
|
|
300
|
+
server.run()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Connect in ATP:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
await connector.connectToMCPServer({
|
|
307
|
+
name: 'custom',
|
|
308
|
+
command: 'python',
|
|
309
|
+
args: ['mcp_server.py'],
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Error Handling
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
try {
|
|
317
|
+
const api = await connector.connectToMCPServer({
|
|
318
|
+
name: 'filesystem',
|
|
319
|
+
command: 'npx',
|
|
320
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],
|
|
321
|
+
});
|
|
322
|
+
server.addAPIGroup(api);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
console.error('Failed to connect to MCP server:', error);
|
|
325
|
+
// Handle connection error
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Lifecycle Management
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const connector = new MCPConnector();
|
|
333
|
+
|
|
334
|
+
// Connect
|
|
335
|
+
const api = await connector.connectToMCPServer(config);
|
|
336
|
+
|
|
337
|
+
// List connected servers
|
|
338
|
+
const servers = connector.listServers();
|
|
339
|
+
// Returns: ['filesystem', 'git', 'database']
|
|
340
|
+
|
|
341
|
+
// Close specific server
|
|
342
|
+
await connector.closeServer('filesystem');
|
|
343
|
+
|
|
344
|
+
// Close all servers
|
|
345
|
+
await connector.closeAll();
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Types
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
interface MCPServerConfig {
|
|
352
|
+
name: string;
|
|
353
|
+
command: string;
|
|
354
|
+
args: string[];
|
|
355
|
+
env?: Record<string, string>;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
interface MCPHttpConfig {
|
|
359
|
+
name: string;
|
|
360
|
+
baseUrl: string;
|
|
361
|
+
headers?: Record<string, string>;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
interface MCPTool {
|
|
365
|
+
name: string;
|
|
366
|
+
description?: string;
|
|
367
|
+
inputSchema: {
|
|
368
|
+
type: string;
|
|
369
|
+
properties?: Record<string, unknown>;
|
|
370
|
+
required?: string[];
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Integration Flow
|
|
376
|
+
|
|
377
|
+
```mermaid
|
|
378
|
+
sequenceDiagram
|
|
379
|
+
participant Agent
|
|
380
|
+
participant ATP Server
|
|
381
|
+
participant MCP Adapter
|
|
382
|
+
participant MCP Server
|
|
383
|
+
|
|
384
|
+
Agent->>ATP Server: execute(code with atp.api.filesystem.read_file())
|
|
385
|
+
ATP Server->>MCP Adapter: Call function
|
|
386
|
+
MCP Adapter->>MCP Server: MCP request
|
|
387
|
+
MCP Server-->>MCP Adapter: MCP response
|
|
388
|
+
MCP Adapter-->>ATP Server: Converted result
|
|
389
|
+
ATP Server-->>Agent: Execution result
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Benefits
|
|
393
|
+
|
|
394
|
+
- ✅ **Zero modifications** to existing MCP servers
|
|
395
|
+
- ✅ **Automatic tool discovery** and conversion
|
|
396
|
+
- ✅ **Type-safe** integration with ATP
|
|
397
|
+
- ✅ **Support for stdio and HTTP** transports
|
|
398
|
+
- ✅ **Multiple server connections** in single ATP server
|
|
399
|
+
- ✅ **Error handling** and lifecycle management
|
|
400
|
+
|
|
401
|
+
## TypeScript Support
|
|
402
|
+
|
|
403
|
+
Full TypeScript definitions included.
|
|
404
|
+
|
|
405
|
+
## License
|
|
406
|
+
|
|
407
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MCPTool, MCPPrompt } from './types.js';
|
|
2
|
+
export declare class MCPHttpConnector {
|
|
3
|
+
private baseUrl;
|
|
4
|
+
private headers;
|
|
5
|
+
constructor(baseUrl: string, headers?: Record<string, string>);
|
|
6
|
+
private makeRequest;
|
|
7
|
+
listTools(): Promise<MCPTool[]>;
|
|
8
|
+
listPrompts(): Promise<MCPPrompt[]>;
|
|
9
|
+
getPrompt(name: string, args?: Record<string, string>): Promise<{
|
|
10
|
+
messages: Array<{
|
|
11
|
+
role: string;
|
|
12
|
+
content: string;
|
|
13
|
+
}>;
|
|
14
|
+
}>;
|
|
15
|
+
callTool(name: string, input: Record<string, unknown>): Promise<unknown>;
|
|
16
|
+
disconnect(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=http-connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-connector.d.ts","sourceRoot":"","sources":["../src/http-connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAarD,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;YAQnD,WAAW;IAmCnB,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAK/B,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IASnC,SAAS,CACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IAc5D,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BxE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CACjC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export class MCPHttpConnector {
|
|
2
|
+
baseUrl;
|
|
3
|
+
headers;
|
|
4
|
+
constructor(baseUrl, headers = {}) {
|
|
5
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
6
|
+
this.headers = {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
...headers,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async makeRequest(method, params) {
|
|
12
|
+
const body = {
|
|
13
|
+
jsonrpc: '2.0',
|
|
14
|
+
id: Date.now(),
|
|
15
|
+
method,
|
|
16
|
+
};
|
|
17
|
+
if (params) {
|
|
18
|
+
body.params = params;
|
|
19
|
+
}
|
|
20
|
+
const response = await fetch(this.baseUrl, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: this.headers,
|
|
23
|
+
body: JSON.stringify(body),
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
27
|
+
}
|
|
28
|
+
const data = (await response.json());
|
|
29
|
+
if (data.error) {
|
|
30
|
+
throw new Error(`MCP Error: ${data.error.message || JSON.stringify(data.error)}`);
|
|
31
|
+
}
|
|
32
|
+
return data.result;
|
|
33
|
+
}
|
|
34
|
+
async listTools() {
|
|
35
|
+
const result = (await this.makeRequest('tools/list'));
|
|
36
|
+
return result.tools || [];
|
|
37
|
+
}
|
|
38
|
+
async listPrompts() {
|
|
39
|
+
try {
|
|
40
|
+
const result = (await this.makeRequest('prompts/list'));
|
|
41
|
+
return result.prompts || [];
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async getPrompt(name, args) {
|
|
48
|
+
const result = (await this.makeRequest('prompts/get', {
|
|
49
|
+
name,
|
|
50
|
+
arguments: args,
|
|
51
|
+
}));
|
|
52
|
+
return {
|
|
53
|
+
messages: result.messages.map((msg) => ({
|
|
54
|
+
role: msg.role,
|
|
55
|
+
content: typeof msg.content === 'string' ? msg.content : msg.content.text,
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async callTool(name, input) {
|
|
60
|
+
const result = (await this.makeRequest('tools/call', {
|
|
61
|
+
name,
|
|
62
|
+
arguments: input,
|
|
63
|
+
}));
|
|
64
|
+
if (!result.content || result.content.length === 0) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const firstBlock = result.content[0];
|
|
68
|
+
if (result.content.length === 1 && firstBlock && firstBlock.type === 'text') {
|
|
69
|
+
const text = firstBlock.text || '';
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(text);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return text;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return result.content.map((block) => {
|
|
78
|
+
if (block.type === 'text') {
|
|
79
|
+
return block.text;
|
|
80
|
+
}
|
|
81
|
+
return block;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async disconnect() { }
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=http-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-connector.js","sourceRoot":"","sources":["../src/http-connector.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import type { APIGroupConfig } from '@mondaydotcomorg/atp-protocol';
|
|
3
|
+
interface MCPServerConfig {
|
|
4
|
+
name: string;
|
|
5
|
+
command: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* MCPConnector connects to MCP servers and converts their tools to Agent Tool Protocol format.
|
|
11
|
+
*/
|
|
12
|
+
export declare class MCPConnector {
|
|
13
|
+
private clients;
|
|
14
|
+
private currentClient;
|
|
15
|
+
private currentServerName;
|
|
16
|
+
/**
|
|
17
|
+
* Connects to an MCP server and retrieves its tools.
|
|
18
|
+
* @param config - MCP server configuration
|
|
19
|
+
* @returns APIGroupConfig with converted tools
|
|
20
|
+
*/
|
|
21
|
+
connectToMCPServer(config: MCPServerConfig): Promise<APIGroupConfig>;
|
|
22
|
+
/**
|
|
23
|
+
* Connects to multiple MCP servers.
|
|
24
|
+
* @param configs - Array of MCP server configurations
|
|
25
|
+
* @returns Array of APIGroupConfig objects
|
|
26
|
+
*/
|
|
27
|
+
connectToMultipleServers(configs: MCPServerConfig[]): Promise<APIGroupConfig[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Disconnects from all MCP servers.
|
|
30
|
+
*/
|
|
31
|
+
disconnectAll(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Gets a connected MCP client by name.
|
|
34
|
+
* @param name - Server name
|
|
35
|
+
* @returns MCP Client or undefined
|
|
36
|
+
*/
|
|
37
|
+
getClient(name: string): Client | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Lists all tools from the currently connected MCP server.
|
|
40
|
+
* @returns Array of tools
|
|
41
|
+
*/
|
|
42
|
+
listTools(): Promise<any[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Lists all prompts from the currently connected MCP server.
|
|
45
|
+
* @returns Array of prompts
|
|
46
|
+
*/
|
|
47
|
+
listPrompts(): Promise<any[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Calls a tool on the currently connected MCP server.
|
|
50
|
+
* @param name - Tool name
|
|
51
|
+
* @param input - Tool input parameters
|
|
52
|
+
* @returns Tool execution result
|
|
53
|
+
*/
|
|
54
|
+
callTool(name: string, input: Record<string, unknown>): Promise<unknown>;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=mcp-connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-connector.d.ts","sourceRoot":"","sources":["../src/mcp-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,+BAA+B,CAAC;AAEvF,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,iBAAiB,CAAuB;IAEhD;;;;OAIG;IACG,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAkE1E;;;;OAIG;IACG,wBAAwB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAIrF;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAUpC;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3C;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAQjC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAYnC;;;;;OAKG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAU9E"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
/**
|
|
4
|
+
* MCPConnector connects to MCP servers and converts their tools to Agent Tool Protocol format.
|
|
5
|
+
*/
|
|
6
|
+
export class MCPConnector {
|
|
7
|
+
clients = new Map();
|
|
8
|
+
currentClient = null;
|
|
9
|
+
currentServerName = null;
|
|
10
|
+
/**
|
|
11
|
+
* Connects to an MCP server and retrieves its tools.
|
|
12
|
+
* @param config - MCP server configuration
|
|
13
|
+
* @returns APIGroupConfig with converted tools
|
|
14
|
+
*/
|
|
15
|
+
async connectToMCPServer(config) {
|
|
16
|
+
const transport = new StdioClientTransport({
|
|
17
|
+
command: config.command,
|
|
18
|
+
args: config.args,
|
|
19
|
+
env: config.env,
|
|
20
|
+
});
|
|
21
|
+
const client = new Client({
|
|
22
|
+
name: 'agent-tool-protocol-connector',
|
|
23
|
+
version: '1.0.0',
|
|
24
|
+
}, {
|
|
25
|
+
capabilities: {},
|
|
26
|
+
});
|
|
27
|
+
await client.connect(transport);
|
|
28
|
+
this.clients.set(config.name, client);
|
|
29
|
+
this.currentClient = client;
|
|
30
|
+
this.currentServerName = config.name;
|
|
31
|
+
const toolsResult = await client.listTools();
|
|
32
|
+
const tools = toolsResult.tools || [];
|
|
33
|
+
const functions = tools.map((tool) => {
|
|
34
|
+
const schema = tool.inputSchema;
|
|
35
|
+
const inputSchema = schema || { type: 'object', properties: {} };
|
|
36
|
+
if (!inputSchema.type) {
|
|
37
|
+
inputSchema.type = 'object';
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
name: tool.name,
|
|
41
|
+
description: tool.description || `MCP tool: ${tool.name}`,
|
|
42
|
+
inputSchema: inputSchema,
|
|
43
|
+
handler: async (input) => {
|
|
44
|
+
const result = await client.callTool({
|
|
45
|
+
name: tool.name,
|
|
46
|
+
arguments: input,
|
|
47
|
+
});
|
|
48
|
+
return result.content;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
name: config.name,
|
|
54
|
+
type: 'mcp',
|
|
55
|
+
functions,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Connects to multiple MCP servers.
|
|
60
|
+
* @param configs - Array of MCP server configurations
|
|
61
|
+
* @returns Array of APIGroupConfig objects
|
|
62
|
+
*/
|
|
63
|
+
async connectToMultipleServers(configs) {
|
|
64
|
+
return Promise.all(configs.map((config) => this.connectToMCPServer(config)));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Disconnects from all MCP servers.
|
|
68
|
+
*/
|
|
69
|
+
async disconnectAll() {
|
|
70
|
+
const disconnectPromises = Array.from(this.clients.values()).map(async (client) => {
|
|
71
|
+
try {
|
|
72
|
+
await client.close();
|
|
73
|
+
}
|
|
74
|
+
catch (error) { }
|
|
75
|
+
});
|
|
76
|
+
await Promise.all(disconnectPromises);
|
|
77
|
+
this.clients.clear();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Gets a connected MCP client by name.
|
|
81
|
+
* @param name - Server name
|
|
82
|
+
* @returns MCP Client or undefined
|
|
83
|
+
*/
|
|
84
|
+
getClient(name) {
|
|
85
|
+
return this.clients.get(name);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Lists all tools from the currently connected MCP server.
|
|
89
|
+
* @returns Array of tools
|
|
90
|
+
*/
|
|
91
|
+
async listTools() {
|
|
92
|
+
if (!this.currentClient) {
|
|
93
|
+
throw new Error('Not connected to any MCP server');
|
|
94
|
+
}
|
|
95
|
+
const toolsResult = await this.currentClient.listTools();
|
|
96
|
+
return toolsResult.tools || [];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Lists all prompts from the currently connected MCP server.
|
|
100
|
+
* @returns Array of prompts
|
|
101
|
+
*/
|
|
102
|
+
async listPrompts() {
|
|
103
|
+
if (!this.currentClient) {
|
|
104
|
+
throw new Error('Not connected to any MCP server');
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const promptsResult = await this.currentClient.listPrompts();
|
|
108
|
+
return promptsResult.prompts || [];
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Calls a tool on the currently connected MCP server.
|
|
116
|
+
* @param name - Tool name
|
|
117
|
+
* @param input - Tool input parameters
|
|
118
|
+
* @returns Tool execution result
|
|
119
|
+
*/
|
|
120
|
+
async callTool(name, input) {
|
|
121
|
+
if (!this.currentClient) {
|
|
122
|
+
throw new Error('Not connected to any MCP server');
|
|
123
|
+
}
|
|
124
|
+
const result = await this.currentClient.callTool({
|
|
125
|
+
name,
|
|
126
|
+
arguments: input,
|
|
127
|
+
});
|
|
128
|
+
return result.content;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=mcp-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-connector.js","sourceRoot":"","sources":["../src/mcp-connector.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for MCP Adapter
|
|
3
|
+
*/
|
|
4
|
+
export interface MCPTool {
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: string;
|
|
9
|
+
properties?: Record<string, unknown>;
|
|
10
|
+
required?: string[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface MCPPrompt {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
arguments?: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
required?: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACF;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;CACH"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mondaydotcomorg/atp-mcp-adapter",
|
|
3
|
+
"version": "0.17.14",
|
|
4
|
+
"description": "MCP compatibility adapter for Agent Tool Protocol",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
21
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"lint": "tsc --noEmit"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"agent",
|
|
27
|
+
"protocol",
|
|
28
|
+
"mcp",
|
|
29
|
+
"adapter",
|
|
30
|
+
"ai",
|
|
31
|
+
"llm"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
36
|
+
"@mondaydotcomorg/atp-protocol": "0.17.14",
|
|
37
|
+
"@mondaydotcomorg/atp-server": "0.17.14",
|
|
38
|
+
"zod": "^4.1.11"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"typescript": "^5.3.3",
|
|
42
|
+
"vitest": "^1.2.1"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { MCPTool, MCPPrompt } from './types.js';
|
|
2
|
+
|
|
3
|
+
interface JsonRpcResponse {
|
|
4
|
+
jsonrpc: string;
|
|
5
|
+
id: number;
|
|
6
|
+
result?: unknown;
|
|
7
|
+
error?: {
|
|
8
|
+
code?: number;
|
|
9
|
+
message?: string;
|
|
10
|
+
data?: unknown;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class MCPHttpConnector {
|
|
15
|
+
private baseUrl: string;
|
|
16
|
+
private headers: Record<string, string>;
|
|
17
|
+
|
|
18
|
+
constructor(baseUrl: string, headers: Record<string, string> = {}) {
|
|
19
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
20
|
+
this.headers = {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...headers,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private async makeRequest(method: string, params?: unknown): Promise<unknown> {
|
|
27
|
+
const body: {
|
|
28
|
+
jsonrpc: string;
|
|
29
|
+
id: number;
|
|
30
|
+
method: string;
|
|
31
|
+
params?: unknown;
|
|
32
|
+
} = {
|
|
33
|
+
jsonrpc: '2.0',
|
|
34
|
+
id: Date.now(),
|
|
35
|
+
method,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (params) {
|
|
39
|
+
body.params = params;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const response = await fetch(this.baseUrl, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: this.headers,
|
|
45
|
+
body: JSON.stringify(body),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const data = (await response.json()) as JsonRpcResponse;
|
|
53
|
+
|
|
54
|
+
if (data.error) {
|
|
55
|
+
throw new Error(`MCP Error: ${data.error.message || JSON.stringify(data.error)}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return data.result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async listTools(): Promise<MCPTool[]> {
|
|
62
|
+
const result = (await this.makeRequest('tools/list')) as { tools: MCPTool[] };
|
|
63
|
+
return result.tools || [];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async listPrompts(): Promise<MCPPrompt[]> {
|
|
67
|
+
try {
|
|
68
|
+
const result = (await this.makeRequest('prompts/list')) as { prompts: MCPPrompt[] };
|
|
69
|
+
return result.prompts || [];
|
|
70
|
+
} catch (error) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async getPrompt(
|
|
76
|
+
name: string,
|
|
77
|
+
args?: Record<string, string>
|
|
78
|
+
): Promise<{ messages: Array<{ role: string; content: string }> }> {
|
|
79
|
+
const result = (await this.makeRequest('prompts/get', {
|
|
80
|
+
name,
|
|
81
|
+
arguments: args,
|
|
82
|
+
})) as { messages: Array<{ role: string; content: { type: string; text: string } | string }> };
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
messages: result.messages.map((msg) => ({
|
|
86
|
+
role: msg.role,
|
|
87
|
+
content: typeof msg.content === 'string' ? msg.content : msg.content.text,
|
|
88
|
+
})),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async callTool(name: string, input: Record<string, unknown>): Promise<unknown> {
|
|
93
|
+
const result = (await this.makeRequest('tools/call', {
|
|
94
|
+
name,
|
|
95
|
+
arguments: input,
|
|
96
|
+
})) as { content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> };
|
|
97
|
+
|
|
98
|
+
if (!result.content || result.content.length === 0) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const firstBlock = result.content[0];
|
|
103
|
+
if (result.content.length === 1 && firstBlock && firstBlock.type === 'text') {
|
|
104
|
+
const text = firstBlock.text || '';
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(text);
|
|
107
|
+
} catch {
|
|
108
|
+
return text;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return result.content.map((block) => {
|
|
113
|
+
if (block.type === 'text') {
|
|
114
|
+
return block.text;
|
|
115
|
+
}
|
|
116
|
+
return block;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async disconnect(): Promise<void> {}
|
|
121
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import type { APIGroupConfig, CustomFunctionDef } from '@mondaydotcomorg/atp-protocol';
|
|
4
|
+
|
|
5
|
+
interface MCPServerConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* MCPConnector connects to MCP servers and converts their tools to Agent Tool Protocol format.
|
|
14
|
+
*/
|
|
15
|
+
export class MCPConnector {
|
|
16
|
+
private clients: Map<string, Client> = new Map();
|
|
17
|
+
private currentClient: Client | null = null;
|
|
18
|
+
private currentServerName: string | null = null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Connects to an MCP server and retrieves its tools.
|
|
22
|
+
* @param config - MCP server configuration
|
|
23
|
+
* @returns APIGroupConfig with converted tools
|
|
24
|
+
*/
|
|
25
|
+
async connectToMCPServer(config: MCPServerConfig): Promise<APIGroupConfig> {
|
|
26
|
+
const transport = new StdioClientTransport({
|
|
27
|
+
command: config.command,
|
|
28
|
+
args: config.args,
|
|
29
|
+
env: config.env,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const client = new Client(
|
|
33
|
+
{
|
|
34
|
+
name: 'agent-tool-protocol-connector',
|
|
35
|
+
version: '1.0.0',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
capabilities: {},
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await client.connect(transport);
|
|
43
|
+
this.clients.set(config.name, client);
|
|
44
|
+
this.currentClient = client;
|
|
45
|
+
this.currentServerName = config.name;
|
|
46
|
+
|
|
47
|
+
const toolsResult = await client.listTools();
|
|
48
|
+
const tools = toolsResult.tools || [];
|
|
49
|
+
|
|
50
|
+
const functions: CustomFunctionDef[] = tools.map(
|
|
51
|
+
(tool: { name: string; description?: string; inputSchema: unknown }) => {
|
|
52
|
+
const schema = tool.inputSchema as
|
|
53
|
+
| {
|
|
54
|
+
type?: string;
|
|
55
|
+
properties?: Record<string, any>;
|
|
56
|
+
required?: string[];
|
|
57
|
+
}
|
|
58
|
+
| undefined;
|
|
59
|
+
|
|
60
|
+
const inputSchema = schema || { type: 'object', properties: {} };
|
|
61
|
+
if (!inputSchema.type) {
|
|
62
|
+
inputSchema.type = 'object';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
name: tool.name,
|
|
67
|
+
description: tool.description || `MCP tool: ${tool.name}`,
|
|
68
|
+
inputSchema: inputSchema as {
|
|
69
|
+
type: string;
|
|
70
|
+
properties?: Record<string, any>;
|
|
71
|
+
required?: string[];
|
|
72
|
+
},
|
|
73
|
+
handler: async (input: unknown) => {
|
|
74
|
+
const result = await client.callTool({
|
|
75
|
+
name: tool.name,
|
|
76
|
+
arguments: input as Record<string, unknown>,
|
|
77
|
+
});
|
|
78
|
+
return result.content;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
name: config.name,
|
|
86
|
+
type: 'mcp',
|
|
87
|
+
functions,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Connects to multiple MCP servers.
|
|
93
|
+
* @param configs - Array of MCP server configurations
|
|
94
|
+
* @returns Array of APIGroupConfig objects
|
|
95
|
+
*/
|
|
96
|
+
async connectToMultipleServers(configs: MCPServerConfig[]): Promise<APIGroupConfig[]> {
|
|
97
|
+
return Promise.all(configs.map((config) => this.connectToMCPServer(config)));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Disconnects from all MCP servers.
|
|
102
|
+
*/
|
|
103
|
+
async disconnectAll(): Promise<void> {
|
|
104
|
+
const disconnectPromises = Array.from(this.clients.values()).map(async (client) => {
|
|
105
|
+
try {
|
|
106
|
+
await client.close();
|
|
107
|
+
} catch (error) {}
|
|
108
|
+
});
|
|
109
|
+
await Promise.all(disconnectPromises);
|
|
110
|
+
this.clients.clear();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gets a connected MCP client by name.
|
|
115
|
+
* @param name - Server name
|
|
116
|
+
* @returns MCP Client or undefined
|
|
117
|
+
*/
|
|
118
|
+
getClient(name: string): Client | undefined {
|
|
119
|
+
return this.clients.get(name);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Lists all tools from the currently connected MCP server.
|
|
124
|
+
* @returns Array of tools
|
|
125
|
+
*/
|
|
126
|
+
async listTools(): Promise<any[]> {
|
|
127
|
+
if (!this.currentClient) {
|
|
128
|
+
throw new Error('Not connected to any MCP server');
|
|
129
|
+
}
|
|
130
|
+
const toolsResult = await this.currentClient.listTools();
|
|
131
|
+
return toolsResult.tools || [];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Lists all prompts from the currently connected MCP server.
|
|
136
|
+
* @returns Array of prompts
|
|
137
|
+
*/
|
|
138
|
+
async listPrompts(): Promise<any[]> {
|
|
139
|
+
if (!this.currentClient) {
|
|
140
|
+
throw new Error('Not connected to any MCP server');
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const promptsResult = await this.currentClient.listPrompts();
|
|
144
|
+
return promptsResult.prompts || [];
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Calls a tool on the currently connected MCP server.
|
|
152
|
+
* @param name - Tool name
|
|
153
|
+
* @param input - Tool input parameters
|
|
154
|
+
* @returns Tool execution result
|
|
155
|
+
*/
|
|
156
|
+
async callTool(name: string, input: Record<string, unknown>): Promise<unknown> {
|
|
157
|
+
if (!this.currentClient) {
|
|
158
|
+
throw new Error('Not connected to any MCP server');
|
|
159
|
+
}
|
|
160
|
+
const result = await this.currentClient.callTool({
|
|
161
|
+
name,
|
|
162
|
+
arguments: input,
|
|
163
|
+
});
|
|
164
|
+
return result.content;
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for MCP Adapter
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface MCPTool {
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: string;
|
|
10
|
+
properties?: Record<string, unknown>;
|
|
11
|
+
required?: string[];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface MCPPrompt {
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
arguments?: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
required?: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
}
|