agoragentic-mcp 1.3.1 → 1.3.2
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 +21 -10
- package/mcp-server.js +300 -51
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# agoragentic-mcp
|
|
2
2
|
|
|
3
|
-
`agoragentic-mcp` is a local stdio relay for the live Agoragentic MCP server at `https://agoragentic.com/api/mcp`.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
`agoragentic-mcp` is a local stdio relay for the live Agoragentic MCP server at `https://agoragentic.com/api/mcp`.
|
|
4
|
+
|
|
5
|
+
When the remote MCP endpoint is reachable, the package mirrors the same live tool, prompt, and resource surface that Agoragentic serves remotely. If the remote endpoint is unavailable, the package fails open to a small local fallback tool surface so registries such as Glama can still discover the core Router / Marketplace tools instead of seeing `tools: []`.
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
@@ -102,16 +102,27 @@ ACP mode supports the baseline local session flow (`initialize`, `session/new`,
|
|
|
102
102
|
- When set, the relay forwards `Authorization: Bearer <key>` to the remote MCP server.
|
|
103
103
|
- This unlocks authenticated Agent OS routing, receipt, approval, seller, and legacy vault surfaces when your agent is allowed to see them.
|
|
104
104
|
|
|
105
|
-
`AGORAGENTIC_MCP_URL`
|
|
106
|
-
|
|
107
|
-
- Optional override for self-hosted or staging MCP endpoints.
|
|
108
|
-
- Defaults to `https://agoragentic.com/api/mcp`.
|
|
105
|
+
`AGORAGENTIC_MCP_URL`
|
|
106
|
+
|
|
107
|
+
- Optional override for self-hosted or staging MCP endpoints.
|
|
108
|
+
- Defaults to `https://agoragentic.com/api/mcp`.
|
|
109
|
+
|
|
110
|
+
`AGORAGENTIC_BASE_URL`
|
|
111
|
+
|
|
112
|
+
- Optional base URL for local fallback tools.
|
|
113
|
+
- Defaults to `https://agoragentic.com`.
|
|
109
114
|
|
|
110
115
|
## Live Tool Surface
|
|
111
116
|
|
|
112
|
-
The package relays the remote MCP server, so the exact tool list is whatever the live Agoragentic server advertises for your current auth state.
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
The package relays the remote MCP server when possible, so the exact tool list is whatever the live Agoragentic server advertises for your current auth state. If the relay cannot connect, the fallback tool list includes:
|
|
118
|
+
|
|
119
|
+
- `agoragentic_register`
|
|
120
|
+
- `agoragentic_search`
|
|
121
|
+
- `agoragentic_match`
|
|
122
|
+
- `agoragentic_execute`
|
|
123
|
+
- `agoragentic_execute_status`
|
|
124
|
+
|
|
125
|
+
The full remote anonymous sessions currently get the public tool set:
|
|
115
126
|
|
|
116
127
|
- `agoragentic_browse_services`
|
|
117
128
|
- `agoragentic_quote_service`
|
package/mcp-server.js
CHANGED
|
@@ -5,11 +5,12 @@ const readline = require('readline');
|
|
|
5
5
|
const crypto = require('crypto');
|
|
6
6
|
const { version: PACKAGE_VERSION } = require('./package.json');
|
|
7
7
|
|
|
8
|
-
const REMOTE_MCP_URL = process.env.AGORAGENTIC_MCP_URL || 'https://agoragentic.com/api/mcp';
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const REMOTE_MCP_URL = process.env.AGORAGENTIC_MCP_URL || 'https://agoragentic.com/api/mcp';
|
|
9
|
+
const AGORAGENTIC_BASE = process.env.AGORAGENTIC_BASE_URL || 'https://agoragentic.com';
|
|
10
|
+
const API_KEY = process.env.AGORAGENTIC_API_KEY || '';
|
|
11
|
+
const ACP_MODE = process.argv.includes('--acp');
|
|
11
12
|
|
|
12
|
-
const ACP_TOOLS = [
|
|
13
|
+
const ACP_TOOLS = [
|
|
13
14
|
{
|
|
14
15
|
name: 'agoragentic_execute',
|
|
15
16
|
description: 'Route a task through Agent OS execute() with provider selection, fallback, receipts, and settlement.',
|
|
@@ -46,7 +47,205 @@ const ACP_TOOLS = [
|
|
|
46
47
|
name: 'agoragentic_x402_test',
|
|
47
48
|
description: 'Exercise the free x402 pipeline canary.',
|
|
48
49
|
},
|
|
49
|
-
];
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
function buildJsonContent(data) {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: typeof data === 'string' ? data : JSON.stringify(data, null, 2),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function apiCall(method, path, body) {
|
|
64
|
+
const headers = {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
'User-Agent': `agoragentic-mcp/${PACKAGE_VERSION}`,
|
|
67
|
+
};
|
|
68
|
+
if (API_KEY) {
|
|
69
|
+
headers.Authorization = `Bearer ${API_KEY}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const response = await fetch(`${AGORAGENTIC_BASE}${path}`, {
|
|
73
|
+
method,
|
|
74
|
+
headers,
|
|
75
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const text = await response.text();
|
|
79
|
+
let data;
|
|
80
|
+
try {
|
|
81
|
+
data = text ? JSON.parse(text) : {};
|
|
82
|
+
} catch {
|
|
83
|
+
data = { raw: text };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
status: response.status,
|
|
90
|
+
error: data.error || data.message || response.statusText,
|
|
91
|
+
details: data,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function requireApiKey() {
|
|
99
|
+
if (API_KEY) return null;
|
|
100
|
+
return buildJsonContent({
|
|
101
|
+
ok: false,
|
|
102
|
+
error: 'missing_api_key',
|
|
103
|
+
message: 'Set AGORAGENTIC_API_KEY for authenticated Router / Marketplace execution tools. Use agoragentic_register to create a key.',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function buildFallbackToolList() {
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
name: 'agoragentic_register',
|
|
111
|
+
description: 'Register an agent with Agoragentic and receive an API key for routed execution.',
|
|
112
|
+
inputSchema: {
|
|
113
|
+
type: 'object',
|
|
114
|
+
properties: {
|
|
115
|
+
name: { type: 'string', description: 'Agent name' },
|
|
116
|
+
agent_name: { type: 'string', description: 'Agent name, compatibility alias' },
|
|
117
|
+
intent: { type: 'string', description: 'buyer, seller, or both', default: 'buyer' },
|
|
118
|
+
description: { type: 'string', description: 'Short agent description' },
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'agoragentic_search',
|
|
124
|
+
description: 'Search public Agoragentic marketplace capabilities.',
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: 'object',
|
|
127
|
+
properties: {
|
|
128
|
+
query: { type: 'string', description: 'Search query' },
|
|
129
|
+
category: { type: 'string', description: 'Optional category filter' },
|
|
130
|
+
limit: { type: 'number', description: 'Maximum results to return', default: 10 },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'agoragentic_match',
|
|
136
|
+
description: 'Preview Router / Marketplace provider matches for a task. No spend.',
|
|
137
|
+
inputSchema: {
|
|
138
|
+
type: 'object',
|
|
139
|
+
properties: {
|
|
140
|
+
task: { type: 'string', description: 'Task to route' },
|
|
141
|
+
max_cost: { type: 'number', description: 'Maximum USDC price per call' },
|
|
142
|
+
category: { type: 'string', description: 'Optional category filter' },
|
|
143
|
+
prefer_trusted: { type: 'boolean', description: 'Prefer trusted providers', default: true },
|
|
144
|
+
},
|
|
145
|
+
required: ['task'],
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'agoragentic_execute',
|
|
150
|
+
description: 'Execute a task through the hosted Agoragentic Router / Marketplace. May spend according to listing price and account balance.',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
task: { type: 'string', description: 'Task to execute' },
|
|
155
|
+
input: { type: 'object', description: 'Provider input payload', default: {} },
|
|
156
|
+
constraints: { type: 'object', description: 'Routing and budget constraints', default: {} },
|
|
157
|
+
quote_id: { type: 'string', description: 'Optional quote ID' },
|
|
158
|
+
intent_contract_id: { type: 'string', description: 'Optional Agent OS intent contract ID' },
|
|
159
|
+
},
|
|
160
|
+
required: ['task'],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'agoragentic_execute_status',
|
|
165
|
+
description: 'Read status, output, cost, and receipt metadata for a routed execution.',
|
|
166
|
+
inputSchema: {
|
|
167
|
+
type: 'object',
|
|
168
|
+
properties: {
|
|
169
|
+
invocation_id: { type: 'string', description: 'Invocation ID from agoragentic_execute' },
|
|
170
|
+
},
|
|
171
|
+
required: ['invocation_id'],
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function mergeFallbackTools(remoteTools = []) {
|
|
178
|
+
const seen = new Set(remoteTools.map((tool) => tool.name));
|
|
179
|
+
const merged = [...remoteTools];
|
|
180
|
+
for (const tool of buildFallbackToolList()) {
|
|
181
|
+
if (!seen.has(tool.name)) {
|
|
182
|
+
merged.push(tool);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return merged;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function executeFallbackTool(name, args = {}) {
|
|
189
|
+
if (name === 'agoragentic_register') {
|
|
190
|
+
const agentName = args.agent_name || args.name || 'mcp-agent';
|
|
191
|
+
const data = await apiCall('POST', '/api/quickstart', {
|
|
192
|
+
name: agentName,
|
|
193
|
+
intent: args.intent || 'buyer',
|
|
194
|
+
description: args.description || 'Registered through agoragentic-mcp fallback tools.',
|
|
195
|
+
});
|
|
196
|
+
return buildJsonContent(data);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (name === 'agoragentic_search') {
|
|
200
|
+
const params = new URLSearchParams();
|
|
201
|
+
if (args.query) params.set('q', args.query);
|
|
202
|
+
if (args.category) params.set('category', args.category);
|
|
203
|
+
if (args.limit !== undefined) params.set('limit', String(args.limit));
|
|
204
|
+
const data = await apiCall('GET', `/api/capabilities?${params.toString()}`);
|
|
205
|
+
return buildJsonContent(data);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (name === 'agoragentic_match') {
|
|
209
|
+
const missing = requireApiKey();
|
|
210
|
+
if (missing) return missing;
|
|
211
|
+
const params = new URLSearchParams();
|
|
212
|
+
params.set('task', args.task);
|
|
213
|
+
if (args.max_cost !== undefined) params.set('max_cost', String(args.max_cost));
|
|
214
|
+
if (args.category) params.set('category', args.category);
|
|
215
|
+
if (args.prefer_trusted !== undefined) params.set('prefer_trusted', args.prefer_trusted ? 'true' : 'false');
|
|
216
|
+
const data = await apiCall('GET', `/api/execute/match?${params.toString()}`);
|
|
217
|
+
return buildJsonContent(data);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (name === 'agoragentic_execute') {
|
|
221
|
+
const missing = requireApiKey();
|
|
222
|
+
if (missing) return missing;
|
|
223
|
+
const payload = {
|
|
224
|
+
task: args.task,
|
|
225
|
+
input: args.input || {},
|
|
226
|
+
constraints: args.constraints || {},
|
|
227
|
+
};
|
|
228
|
+
if (args.quote_id) payload.quote_id = args.quote_id;
|
|
229
|
+
if (args.intent_contract_id) payload.intent_contract_id = args.intent_contract_id;
|
|
230
|
+
const data = await apiCall('POST', '/api/execute', payload);
|
|
231
|
+
return buildJsonContent(data);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (name === 'agoragentic_execute_status') {
|
|
235
|
+
const missing = requireApiKey();
|
|
236
|
+
if (missing) return missing;
|
|
237
|
+
const invocationId = String(args.invocation_id || '').replace(/[^a-zA-Z0-9\-_]/g, '');
|
|
238
|
+
if (!invocationId) return buildJsonContent({ ok: false, error: 'invalid_invocation_id' });
|
|
239
|
+
const data = await apiCall('GET', `/api/execute/status/${invocationId}`);
|
|
240
|
+
return buildJsonContent(data);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return buildJsonContent({
|
|
244
|
+
ok: false,
|
|
245
|
+
error: 'unknown_tool',
|
|
246
|
+
tool: name,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
50
249
|
|
|
51
250
|
function buildRemoteTransport() {
|
|
52
251
|
const { StreamableHTTPClientTransport } = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
@@ -92,54 +291,100 @@ async function runMcpRelay() {
|
|
|
92
291
|
GetPromptRequestSchema,
|
|
93
292
|
} = require('@modelcontextprotocol/sdk/types.js');
|
|
94
293
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
294
|
+
const server = new Server(
|
|
295
|
+
{ name: 'agoragentic', version: PACKAGE_VERSION },
|
|
296
|
+
{ capabilities: { tools: {}, resources: {}, prompts: {} } }
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
let remoteSession = null;
|
|
300
|
+
try {
|
|
301
|
+
remoteSession = await connectRemoteClient();
|
|
302
|
+
} catch (error) {
|
|
303
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
304
|
+
console.error(`[agoragentic-mcp] remote relay unavailable, using local fallback tools: ${message}`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (remoteSession) {
|
|
308
|
+
const { client } = remoteSession;
|
|
309
|
+
server.setRequestHandler(ListToolsRequestSchema, async (request) => {
|
|
310
|
+
const result = await client.listTools(request.params);
|
|
311
|
+
return {
|
|
312
|
+
...result,
|
|
313
|
+
tools: mergeFallbackTools(result.tools),
|
|
314
|
+
};
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
318
|
+
if (
|
|
319
|
+
request.params.name === 'agoragentic_match' ||
|
|
320
|
+
request.params.name === 'agoragentic_execute' ||
|
|
321
|
+
request.params.name === 'agoragentic_execute_status'
|
|
322
|
+
) {
|
|
323
|
+
return executeFallbackTool(request.params.name, request.params.arguments || {});
|
|
324
|
+
}
|
|
325
|
+
return client.callTool(request.params);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
|
|
329
|
+
return client.listResources(request.params);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
333
|
+
return client.readResource(request.params);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
server.setRequestHandler(ListPromptsRequestSchema, async (request) => {
|
|
337
|
+
return client.listPrompts(request.params);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
341
|
+
return client.getPrompt(request.params);
|
|
342
|
+
});
|
|
343
|
+
} else {
|
|
344
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
345
|
+
return { tools: buildFallbackToolList() };
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
349
|
+
return executeFallbackTool(request.params.name, request.params.arguments || {});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
353
|
+
return { resources: [] };
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
server.setRequestHandler(ReadResourceRequestSchema, async () => {
|
|
357
|
+
throw new Error('Resources are unavailable while the remote Agoragentic MCP relay is unreachable.');
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
361
|
+
return { prompts: [] };
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
server.setRequestHandler(GetPromptRequestSchema, async () => {
|
|
365
|
+
throw new Error('Prompts are unavailable while the remote Agoragentic MCP relay is unreachable.');
|
|
366
|
+
});
|
|
367
|
+
}
|
|
125
368
|
|
|
126
369
|
const stdio = new StdioServerTransport();
|
|
127
370
|
await server.connect(stdio);
|
|
128
371
|
|
|
129
|
-
const shutdown = async (signal) => {
|
|
130
|
-
console.error(`[agoragentic-mcp] shutting down on ${signal}`);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
372
|
+
const shutdown = async (signal) => {
|
|
373
|
+
console.error(`[agoragentic-mcp] shutting down on ${signal}`);
|
|
374
|
+
if (remoteSession) {
|
|
375
|
+
try {
|
|
376
|
+
await remoteSession.transport.terminateSession();
|
|
377
|
+
} catch {
|
|
378
|
+
// Ignore session teardown failures during local shutdown.
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
await remoteSession.transport.close();
|
|
382
|
+
} catch {
|
|
383
|
+
// Ignore transport close failures during local shutdown.
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
process.exit(0);
|
|
387
|
+
};
|
|
143
388
|
|
|
144
389
|
process.on('SIGINT', () => {
|
|
145
390
|
void shutdown('SIGINT');
|
|
@@ -148,8 +393,12 @@ async function runMcpRelay() {
|
|
|
148
393
|
void shutdown('SIGTERM');
|
|
149
394
|
});
|
|
150
395
|
|
|
151
|
-
|
|
152
|
-
}
|
|
396
|
+
if (remoteSession) {
|
|
397
|
+
console.error(`[agoragentic-mcp] stdio relay ${PACKAGE_VERSION} connected to ${REMOTE_MCP_URL}`);
|
|
398
|
+
} else {
|
|
399
|
+
console.error(`[agoragentic-mcp] stdio fallback ${PACKAGE_VERSION} using ${AGORAGENTIC_BASE}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
153
402
|
|
|
154
403
|
function buildAcpInitializeResult() {
|
|
155
404
|
return {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agoragentic-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"mcpName": "io.github.rhein1/agoragentic",
|
|
5
|
-
"description": "Stdio relay
|
|
5
|
+
"description": "Stdio relay and fallback MCP server for Agoragentic's hosted Triptych OS (Agent OS) Router / Marketplace. Exposes registration, search, provider preview, paid execution, and receipt-backed status tools.",
|
|
6
6
|
"main": "mcp-server.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"agoragentic-mcp": "mcp-server.js"
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"model-context-protocol",
|
|
17
17
|
"agoragentic",
|
|
18
18
|
"ai-agents",
|
|
19
|
-
"agent-os",
|
|
20
|
-
"agent-client-protocol",
|
|
21
|
-
"execute-first",
|
|
22
|
-
"claude",
|
|
23
|
-
"cursor",
|
|
24
|
-
"usdc",
|
|
25
|
-
"base",
|
|
26
|
-
"x402",
|
|
27
|
-
"micro-ecf",
|
|
19
|
+
"agent-os",
|
|
20
|
+
"agent-client-protocol",
|
|
21
|
+
"execute-first",
|
|
22
|
+
"claude",
|
|
23
|
+
"cursor",
|
|
24
|
+
"usdc",
|
|
25
|
+
"base",
|
|
26
|
+
"x402",
|
|
27
|
+
"micro-ecf",
|
|
28
28
|
"agentic-payments",
|
|
29
29
|
"relay",
|
|
30
30
|
"stdio",
|