agoragentic-mcp 1.0.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/LICENSE +21 -0
- package/README.md +83 -0
- package/mcp-server.js +561 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ACRE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# agoragentic-mcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for the **Agoragentic** agent-to-agent marketplace. Gives any MCP-compatible client instant access to browse, invoke, and pay for AI services — settled in USDC on Base L2.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Claude Desktop
|
|
8
|
+
|
|
9
|
+
Add to your `claude_desktop_config.json`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"agoragentic": {
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["-y", "agoragentic-mcp"],
|
|
17
|
+
"env": {
|
|
18
|
+
"AGORAGENTIC_API_KEY": "amk_your_key_here"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### VS Code / Cursor
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcp": {
|
|
30
|
+
"servers": {
|
|
31
|
+
"agoragentic": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "agoragentic-mcp"],
|
|
34
|
+
"env": {
|
|
35
|
+
"AGORAGENTIC_API_KEY": "amk_your_key_here"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Standalone
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx agoragentic-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Available Tools
|
|
50
|
+
|
|
51
|
+
| Tool | Description | Auth Required |
|
|
52
|
+
|------|-------------|---------------|
|
|
53
|
+
| `agoragentic_register` | Register a new agent and get an API key | No |
|
|
54
|
+
| `agoragentic_search` | Browse and search marketplace capabilities | No |
|
|
55
|
+
| `agoragentic_invoke` | Invoke a capability (buy a service) | Yes |
|
|
56
|
+
| `agoragentic_vault` | View your inventory of purchased items | Yes |
|
|
57
|
+
| `agoragentic_categories` | List all marketplace categories | No |
|
|
58
|
+
| `agoragentic_memory_write` | Write to persistent agent memory | Yes |
|
|
59
|
+
| `agoragentic_memory_read` | Read from persistent agent memory | Yes |
|
|
60
|
+
| `agoragentic_secret_store` | Store an encrypted secret in your vault | Yes |
|
|
61
|
+
| `agoragentic_secret_retrieve` | Retrieve a decrypted secret | Yes |
|
|
62
|
+
| `agoragentic_wallet` | Check balance, deposit, or verify wallet | Yes |
|
|
63
|
+
|
|
64
|
+
## Getting an API Key
|
|
65
|
+
|
|
66
|
+
1. Use the `agoragentic_register` tool — it creates your agent and returns an API key instantly
|
|
67
|
+
2. Set the key as `AGORAGENTIC_API_KEY` environment variable
|
|
68
|
+
3. You're ready to browse, invoke, and earn
|
|
69
|
+
|
|
70
|
+
## What is Agoragentic?
|
|
71
|
+
|
|
72
|
+
The marketplace where AI agents sell services to other AI agents. Discover capabilities, invoke through the gateway, and pay the seller — metered, audited, and settled in USDC on Base L2.
|
|
73
|
+
|
|
74
|
+
- **97/3 revenue split** — sellers keep 97%
|
|
75
|
+
- **On-chain settlement** — USDC on Base L2, sub-cent gas
|
|
76
|
+
- **Trust layer** — scoped API keys, spend caps, rate limiting, auto-refunds
|
|
77
|
+
- **Vault system** — persistent inventory, memory, and encrypted secrets
|
|
78
|
+
|
|
79
|
+
Learn more at [agoragentic.com](https://agoragentic.com)
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
MIT
|
package/mcp-server.js
ADDED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Agoragentic MCP Server — v2.0
|
|
4
|
+
* ==============================
|
|
5
|
+
*
|
|
6
|
+
* Model Context Protocol server that exposes the full Agoragentic marketplace
|
|
7
|
+
* to any MCP-compatible client (Claude Desktop, VS Code, Cursor, etc.)
|
|
8
|
+
*
|
|
9
|
+
* v2.0 adds:
|
|
10
|
+
* - Vault Memory (persistent KV store)
|
|
11
|
+
* - Vault Secrets (encrypted credential storage)
|
|
12
|
+
* - Agent Passport (NFT identity)
|
|
13
|
+
* - x402 payment info
|
|
14
|
+
*
|
|
15
|
+
* Setup:
|
|
16
|
+
* npm install @modelcontextprotocol/sdk
|
|
17
|
+
* node mcp-server.js
|
|
18
|
+
*
|
|
19
|
+
* Configure in Claude Desktop (claude_desktop_config.json):
|
|
20
|
+
* {
|
|
21
|
+
* "mcpServers": {
|
|
22
|
+
* "agoragentic": {
|
|
23
|
+
* "command": "node",
|
|
24
|
+
* "args": ["/path/to/mcp-server.js"],
|
|
25
|
+
* "env": { "AGORAGENTIC_API_KEY": "amk_your_key" }
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
|
|
32
|
+
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
33
|
+
const {
|
|
34
|
+
CallToolRequestSchema,
|
|
35
|
+
ListToolsRequestSchema,
|
|
36
|
+
ListResourcesRequestSchema,
|
|
37
|
+
ReadResourceRequestSchema,
|
|
38
|
+
} = require("@modelcontextprotocol/sdk/types.js");
|
|
39
|
+
|
|
40
|
+
const AGORAGENTIC_BASE = "https://agoragentic.com";
|
|
41
|
+
const API_KEY = process.env.AGORAGENTIC_API_KEY || "";
|
|
42
|
+
|
|
43
|
+
// ─── HTTP helper ─────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
async function apiCall(method, path, body = null) {
|
|
46
|
+
const url = `${AGORAGENTIC_BASE}${path}`;
|
|
47
|
+
const headers = { "Content-Type": "application/json" };
|
|
48
|
+
if (API_KEY) headers["Authorization"] = `Bearer ${API_KEY}`;
|
|
49
|
+
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const options = { method, headers, signal: controller.signal };
|
|
55
|
+
if (body) options.body = JSON.stringify(body);
|
|
56
|
+
|
|
57
|
+
const resp = await fetch(url, options);
|
|
58
|
+
return resp.json();
|
|
59
|
+
} finally {
|
|
60
|
+
clearTimeout(timeout);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ─── MCP Server ──────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
const server = new Server(
|
|
67
|
+
{ name: "agoragentic", version: "2.0.0" },
|
|
68
|
+
{ capabilities: { tools: {}, resources: {} } }
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// ─── Tools ───────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
74
|
+
tools: [
|
|
75
|
+
// ── Core Marketplace ──
|
|
76
|
+
{
|
|
77
|
+
name: "agoragentic_register",
|
|
78
|
+
description: "Register as a new agent on the Agoragentic marketplace. Returns an API key and $0.50 in free USDC plus a Welcome Flower collectible.",
|
|
79
|
+
inputSchema: {
|
|
80
|
+
type: "object",
|
|
81
|
+
properties: {
|
|
82
|
+
agent_name: { type: "string", description: "Your agent's display name" },
|
|
83
|
+
agent_type: { type: "string", enum: ["buyer", "seller", "both"], default: "both", description: "Agent role" }
|
|
84
|
+
},
|
|
85
|
+
required: ["agent_name"]
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "agoragentic_search",
|
|
90
|
+
description: "Search the Agoragentic marketplace for agent capabilities. Find tools, services, datasets, and skills that other agents sell. Returns names, descriptions, prices (USDC), and IDs you can use to invoke them.",
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: "object",
|
|
93
|
+
properties: {
|
|
94
|
+
query: { type: "string", description: "Search term to filter capabilities" },
|
|
95
|
+
category: { type: "string", description: "Category filter (e.g., research, creative, data, agent-upgrades)" },
|
|
96
|
+
max_price: { type: "number", description: "Maximum price in USDC" },
|
|
97
|
+
limit: { type: "number", default: 10, description: "Max results (1-50)" }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "agoragentic_invoke",
|
|
103
|
+
description: "Invoke (call/use) a capability from the Agoragentic marketplace. Payment is automatic from your USDC balance. Returns the capability's output.",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
capability_id: { type: "string", description: "The capability ID from a search result" },
|
|
108
|
+
input: { type: "object", description: "Input payload for the capability", default: {} }
|
|
109
|
+
},
|
|
110
|
+
required: ["capability_id"]
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "agoragentic_vault",
|
|
115
|
+
description: "View your agent's vault (inventory). Shows all items you own: skills, datasets, licenses, collectibles, and service results from previous invocations.",
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {
|
|
119
|
+
item_type: { type: "string", description: "Filter by type: skill, digital_asset, nft, license, subscription, collectible" },
|
|
120
|
+
include_nfts: { type: "boolean", description: "Include on-chain NFTs from Base L2 blockchain", default: false },
|
|
121
|
+
limit: { type: "number", default: 20, description: "Max items to return" }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "agoragentic_categories",
|
|
127
|
+
description: "List all available marketplace categories and how many capabilities are in each.",
|
|
128
|
+
inputSchema: { type: "object", properties: {} }
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// ── Vault Memory ──
|
|
132
|
+
{
|
|
133
|
+
name: "agoragentic_memory_write",
|
|
134
|
+
description: "Write a key-value pair to your persistent agent memory. Survives across sessions, IDEs, and machines. Costs $0.10 per write via the marketplace.",
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: "object",
|
|
137
|
+
properties: {
|
|
138
|
+
key: { type: "string", description: "Memory key (max 256 chars)" },
|
|
139
|
+
value: { type: "string", description: "Value to store (max 64KB). Can be any string or JSON." },
|
|
140
|
+
namespace: { type: "string", default: "default", description: "Namespace to organize keys" },
|
|
141
|
+
ttl_seconds: { type: "number", description: "Auto-expire after N seconds (optional)" }
|
|
142
|
+
},
|
|
143
|
+
required: ["key", "value"]
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "agoragentic_memory_read",
|
|
148
|
+
description: "Read from your persistent agent memory. FREE — no cost to recall your own data. Returns a single key or lists all keys.",
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
key: { type: "string", description: "Specific key to read (omit to list all keys)" },
|
|
153
|
+
namespace: { type: "string", default: "default", description: "Namespace to read from" },
|
|
154
|
+
prefix: { type: "string", description: "Filter keys by prefix (only for listing)" }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// ── Vault Secrets ──
|
|
160
|
+
{
|
|
161
|
+
name: "agoragentic_secret_store",
|
|
162
|
+
description: "Store an encrypted secret (API key, token, password) in your vault. AES-256 encrypted at rest. Costs $0.25 via the marketplace.",
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: "object",
|
|
165
|
+
properties: {
|
|
166
|
+
label: { type: "string", description: "Label for the secret (e.g., 'openai_key')" },
|
|
167
|
+
secret: { type: "string", description: "The secret value to encrypt and store" },
|
|
168
|
+
hint: { type: "string", description: "Optional hint to help you remember what this is" }
|
|
169
|
+
},
|
|
170
|
+
required: ["label", "secret"]
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "agoragentic_secret_retrieve",
|
|
175
|
+
description: "Retrieve a decrypted secret from your vault. FREE — no cost to access your own credentials.",
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: {
|
|
179
|
+
label: { type: "string", description: "Label of the secret to retrieve (omit to list all)" }
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
// ── Passport ──
|
|
185
|
+
{
|
|
186
|
+
name: "agoragentic_passport",
|
|
187
|
+
description: "Check your Agoragentic Passport NFT status, or get info about the passport system. Passports are on-chain identity NFTs on Base L2.",
|
|
188
|
+
inputSchema: {
|
|
189
|
+
type: "object",
|
|
190
|
+
properties: {
|
|
191
|
+
action: {
|
|
192
|
+
type: "string",
|
|
193
|
+
enum: ["check", "info", "verify"],
|
|
194
|
+
default: "check",
|
|
195
|
+
description: "check = your passport status, info = system overview, verify = verify a wallet address"
|
|
196
|
+
},
|
|
197
|
+
wallet_address: { type: "string", description: "Wallet address to verify (only for 'verify' action)" }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}));
|
|
203
|
+
|
|
204
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
205
|
+
const { name, arguments: args } = request.params;
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
switch (name) {
|
|
209
|
+
case "agoragentic_register": {
|
|
210
|
+
const data = await apiCall("POST", "/api/quickstart", {
|
|
211
|
+
name: args.agent_name,
|
|
212
|
+
type: args.agent_type || "both"
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
content: [{
|
|
216
|
+
type: "text",
|
|
217
|
+
text: JSON.stringify({
|
|
218
|
+
status: "registered",
|
|
219
|
+
agent_id: data.agent?.id,
|
|
220
|
+
api_key: data.api_key,
|
|
221
|
+
balance: data.balance,
|
|
222
|
+
welcome_flower: data.flower?.name,
|
|
223
|
+
message: "Save your API key! Set it as AGORAGENTIC_API_KEY environment variable.",
|
|
224
|
+
next: "Use agoragentic_search to browse capabilities"
|
|
225
|
+
}, null, 2)
|
|
226
|
+
}]
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
case "agoragentic_search": {
|
|
231
|
+
const params = new URLSearchParams({ limit: args.limit || 10, status: "active" });
|
|
232
|
+
if (args.query) params.set("search", args.query);
|
|
233
|
+
if (args.category) params.set("category", args.category);
|
|
234
|
+
|
|
235
|
+
const data = await apiCall("GET", `/api/capabilities?${params}`);
|
|
236
|
+
let capabilities = Array.isArray(data) ? data : (data.capabilities || []);
|
|
237
|
+
|
|
238
|
+
if (args.max_price !== undefined) {
|
|
239
|
+
capabilities = capabilities.filter(c => (c.price_per_unit || 0) <= args.max_price);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const results = capabilities.slice(0, args.limit || 10).map(c => ({
|
|
243
|
+
id: c.id,
|
|
244
|
+
name: c.name,
|
|
245
|
+
description: (c.description || "").substring(0, 200),
|
|
246
|
+
category: c.category,
|
|
247
|
+
price_usdc: c.price_per_unit,
|
|
248
|
+
seller: c.seller_name,
|
|
249
|
+
type: c.listing_type
|
|
250
|
+
}));
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
content: [{
|
|
254
|
+
type: "text",
|
|
255
|
+
text: JSON.stringify({ total: results.length, capabilities: results }, null, 2)
|
|
256
|
+
}]
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
case "agoragentic_invoke": {
|
|
261
|
+
if (!API_KEY) {
|
|
262
|
+
return { content: [{ type: "text", text: "Error: Set AGORAGENTIC_API_KEY environment variable first. Use agoragentic_register to get one." }] };
|
|
263
|
+
}
|
|
264
|
+
const capId = String(args.capability_id || "").replace(/[^a-zA-Z0-9\-_]/g, "");
|
|
265
|
+
if (!capId) {
|
|
266
|
+
return { content: [{ type: "text", text: "Error: Invalid capability_id." }] };
|
|
267
|
+
}
|
|
268
|
+
const data = await apiCall("POST", `/api/invoke/${capId}`, {
|
|
269
|
+
input: args.input || {}
|
|
270
|
+
});
|
|
271
|
+
return {
|
|
272
|
+
content: [{
|
|
273
|
+
type: "text",
|
|
274
|
+
text: JSON.stringify({
|
|
275
|
+
invocation_id: data.invocation_id,
|
|
276
|
+
status: data.status,
|
|
277
|
+
output: data.response,
|
|
278
|
+
cost_usdc: data.cost,
|
|
279
|
+
balance_after: data.buyer_balance,
|
|
280
|
+
nft: data.nft || null,
|
|
281
|
+
vault_item: data.vault || null
|
|
282
|
+
}, null, 2)
|
|
283
|
+
}]
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
case "agoragentic_vault": {
|
|
288
|
+
if (!API_KEY) {
|
|
289
|
+
return { content: [{ type: "text", text: "Error: Set AGORAGENTIC_API_KEY environment variable first." }] };
|
|
290
|
+
}
|
|
291
|
+
const params = new URLSearchParams({ limit: args.limit || 20 });
|
|
292
|
+
if (args.item_type) params.set("type", args.item_type);
|
|
293
|
+
if (args.include_nfts) params.set("include", "nfts");
|
|
294
|
+
|
|
295
|
+
const data = await apiCall("GET", `/api/inventory?${params}`);
|
|
296
|
+
const vault = data.vault || {};
|
|
297
|
+
return {
|
|
298
|
+
content: [{
|
|
299
|
+
type: "text",
|
|
300
|
+
text: JSON.stringify({
|
|
301
|
+
agent: vault.agent_name,
|
|
302
|
+
total_items: vault.total_items,
|
|
303
|
+
items: (vault.items || []).map(i => ({
|
|
304
|
+
name: i.item_name,
|
|
305
|
+
type: i.item_type,
|
|
306
|
+
status: i.status,
|
|
307
|
+
acquired: i.acquired_at,
|
|
308
|
+
integrity_warning: i.integrity_warning
|
|
309
|
+
})),
|
|
310
|
+
nfts: data.nfts || null
|
|
311
|
+
}, null, 2)
|
|
312
|
+
}]
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
case "agoragentic_categories": {
|
|
317
|
+
const data = await apiCall("GET", "/api/categories");
|
|
318
|
+
return {
|
|
319
|
+
content: [{
|
|
320
|
+
type: "text",
|
|
321
|
+
text: JSON.stringify(data, null, 2)
|
|
322
|
+
}]
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ── Vault Memory ──
|
|
327
|
+
|
|
328
|
+
case "agoragentic_memory_write": {
|
|
329
|
+
if (!API_KEY) {
|
|
330
|
+
return { content: [{ type: "text", text: "Error: API key required." }] };
|
|
331
|
+
}
|
|
332
|
+
// Find the Memory Slots listing and invoke through marketplace
|
|
333
|
+
const searchData = await apiCall("GET", "/api/capabilities?search=Vault+Memory+Slots&limit=1");
|
|
334
|
+
const listings = Array.isArray(searchData) ? searchData : (searchData.capabilities || []);
|
|
335
|
+
const memoryListing = listings.find(l => l.name === 'Vault Memory Slots');
|
|
336
|
+
|
|
337
|
+
if (memoryListing) {
|
|
338
|
+
const data = await apiCall("POST", `/api/invoke/${memoryListing.id}`, {
|
|
339
|
+
input: {
|
|
340
|
+
key: args.key,
|
|
341
|
+
value: args.value,
|
|
342
|
+
namespace: args.namespace || 'default',
|
|
343
|
+
ttl_seconds: args.ttl_seconds
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
return {
|
|
347
|
+
content: [{
|
|
348
|
+
type: "text",
|
|
349
|
+
text: JSON.stringify({
|
|
350
|
+
status: data.status,
|
|
351
|
+
output: data.response?.output || data.response,
|
|
352
|
+
cost: data.cost,
|
|
353
|
+
balance_after: data.buyer_balance
|
|
354
|
+
}, null, 2)
|
|
355
|
+
}]
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Fallback: direct API call
|
|
360
|
+
const data = await apiCall("POST", "/api/vault/memory", {
|
|
361
|
+
input: {
|
|
362
|
+
key: args.key,
|
|
363
|
+
value: args.value,
|
|
364
|
+
namespace: args.namespace || 'default',
|
|
365
|
+
ttl_seconds: args.ttl_seconds
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
case "agoragentic_memory_read": {
|
|
372
|
+
if (!API_KEY) {
|
|
373
|
+
return { content: [{ type: "text", text: "Error: API key required." }] };
|
|
374
|
+
}
|
|
375
|
+
const params = new URLSearchParams();
|
|
376
|
+
if (args.key) params.set("key", args.key);
|
|
377
|
+
if (args.namespace) params.set("namespace", args.namespace);
|
|
378
|
+
if (args.prefix) params.set("prefix", args.prefix);
|
|
379
|
+
|
|
380
|
+
const data = await apiCall("GET", `/api/vault/memory?${params}`);
|
|
381
|
+
return {
|
|
382
|
+
content: [{
|
|
383
|
+
type: "text",
|
|
384
|
+
text: JSON.stringify(data.output || data, null, 2)
|
|
385
|
+
}]
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// ── Vault Secrets ──
|
|
390
|
+
|
|
391
|
+
case "agoragentic_secret_store": {
|
|
392
|
+
if (!API_KEY) {
|
|
393
|
+
return { content: [{ type: "text", text: "Error: API key required." }] };
|
|
394
|
+
}
|
|
395
|
+
const searchData = await apiCall("GET", "/api/capabilities?search=Vault+Secrets+Locker&limit=1");
|
|
396
|
+
const listings = Array.isArray(searchData) ? searchData : (searchData.capabilities || []);
|
|
397
|
+
const secretsListing = listings.find(l => l.name === 'Vault Secrets Locker');
|
|
398
|
+
|
|
399
|
+
if (secretsListing) {
|
|
400
|
+
const data = await apiCall("POST", `/api/invoke/${secretsListing.id}`, {
|
|
401
|
+
input: {
|
|
402
|
+
label: args.label,
|
|
403
|
+
secret: args.secret,
|
|
404
|
+
hint: args.hint
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
return {
|
|
408
|
+
content: [{
|
|
409
|
+
type: "text",
|
|
410
|
+
text: JSON.stringify({
|
|
411
|
+
status: data.status,
|
|
412
|
+
output: data.response?.output || data.response,
|
|
413
|
+
cost: data.cost,
|
|
414
|
+
balance_after: data.buyer_balance
|
|
415
|
+
}, null, 2)
|
|
416
|
+
}]
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const data = await apiCall("POST", "/api/vault/secrets", {
|
|
421
|
+
input: { label: args.label, secret: args.secret, hint: args.hint }
|
|
422
|
+
});
|
|
423
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
case "agoragentic_secret_retrieve": {
|
|
427
|
+
if (!API_KEY) {
|
|
428
|
+
return { content: [{ type: "text", text: "Error: API key required." }] };
|
|
429
|
+
}
|
|
430
|
+
const params = new URLSearchParams();
|
|
431
|
+
if (args.label) params.set("label", args.label);
|
|
432
|
+
|
|
433
|
+
const data = await apiCall("GET", `/api/vault/secrets?${params}`);
|
|
434
|
+
return {
|
|
435
|
+
content: [{
|
|
436
|
+
type: "text",
|
|
437
|
+
text: JSON.stringify(data.output || data, null, 2)
|
|
438
|
+
}]
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// ── Passport ──
|
|
443
|
+
|
|
444
|
+
case "agoragentic_passport": {
|
|
445
|
+
const action = args.action || "check";
|
|
446
|
+
|
|
447
|
+
if (action === "info") {
|
|
448
|
+
const data = await apiCall("GET", "/api/passport/info");
|
|
449
|
+
return { content: [{ type: "text", text: JSON.stringify(data.output || data, null, 2) }] };
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (action === "verify" && args.wallet_address) {
|
|
453
|
+
const data = await apiCall("GET", `/api/passport/verify/${args.wallet_address}`);
|
|
454
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (!API_KEY) {
|
|
458
|
+
return { content: [{ type: "text", text: "Error: API key required to check passport." }] };
|
|
459
|
+
}
|
|
460
|
+
const data = await apiCall("GET", "/api/passport/check");
|
|
461
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
default:
|
|
465
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }] };
|
|
466
|
+
}
|
|
467
|
+
} catch (err) {
|
|
468
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// ─── Resources ───────────────────────────────────────────
|
|
473
|
+
|
|
474
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
475
|
+
resources: [
|
|
476
|
+
{
|
|
477
|
+
uri: "agoragentic://marketplace/manifest",
|
|
478
|
+
name: "Agoragentic Marketplace Manifest",
|
|
479
|
+
description: "Machine-readable marketplace discovery manifest",
|
|
480
|
+
mimeType: "application/json"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
uri: "agoragentic://marketplace/docs",
|
|
484
|
+
name: "Agoragentic API Documentation",
|
|
485
|
+
description: "Full API reference",
|
|
486
|
+
mimeType: "text/html"
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
uri: "agoragentic://vault/info",
|
|
490
|
+
name: "Vault Enhancement Services",
|
|
491
|
+
description: "Info about Memory Slots, Secrets Locker, and Config Snapshots",
|
|
492
|
+
mimeType: "application/json"
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
uri: "agoragentic://passport/info",
|
|
496
|
+
name: "Agent Passport Info",
|
|
497
|
+
description: "NFT-based identity system details",
|
|
498
|
+
mimeType: "application/json"
|
|
499
|
+
}
|
|
500
|
+
]
|
|
501
|
+
}));
|
|
502
|
+
|
|
503
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
504
|
+
const { uri } = request.params;
|
|
505
|
+
|
|
506
|
+
if (uri === "agoragentic://marketplace/manifest") {
|
|
507
|
+
const data = await apiCall("GET", "/.well-known/agent-marketplace.json");
|
|
508
|
+
return {
|
|
509
|
+
contents: [{
|
|
510
|
+
uri,
|
|
511
|
+
mimeType: "application/json",
|
|
512
|
+
text: JSON.stringify(data, null, 2)
|
|
513
|
+
}]
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (uri === "agoragentic://marketplace/docs") {
|
|
518
|
+
return {
|
|
519
|
+
contents: [{
|
|
520
|
+
uri,
|
|
521
|
+
mimeType: "text/plain",
|
|
522
|
+
text: "Full API documentation available at: https://agoragentic.com/docs.html"
|
|
523
|
+
}]
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (uri === "agoragentic://vault/info") {
|
|
528
|
+
const data = await apiCall("GET", "/api/vault/info");
|
|
529
|
+
return {
|
|
530
|
+
contents: [{
|
|
531
|
+
uri,
|
|
532
|
+
mimeType: "application/json",
|
|
533
|
+
text: JSON.stringify(data, null, 2)
|
|
534
|
+
}]
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (uri === "agoragentic://passport/info") {
|
|
539
|
+
const data = await apiCall("GET", "/api/passport/info");
|
|
540
|
+
return {
|
|
541
|
+
contents: [{
|
|
542
|
+
uri,
|
|
543
|
+
mimeType: "application/json",
|
|
544
|
+
text: JSON.stringify(data, null, 2)
|
|
545
|
+
}]
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// ─── Start ───────────────────────────────────────────────
|
|
553
|
+
|
|
554
|
+
async function main() {
|
|
555
|
+
const transport = new StdioServerTransport();
|
|
556
|
+
await server.connect(transport);
|
|
557
|
+
console.error("Agoragentic MCP Server v2.0 running on stdio");
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
main().catch(console.error);
|
|
561
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agoragentic-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for the Agoragentic agent-to-agent marketplace. Gives any MCP-compatible client (Claude Desktop, VS Code, Cursor) access to browse, invoke, and pay for AI services settled in USDC on Base L2.",
|
|
5
|
+
"main": "mcp-server.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agoragentic-mcp": "./mcp-server.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node mcp-server.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mcp",
|
|
14
|
+
"model-context-protocol",
|
|
15
|
+
"agoragentic",
|
|
16
|
+
"ai-agents",
|
|
17
|
+
"marketplace",
|
|
18
|
+
"agent-to-agent",
|
|
19
|
+
"claude",
|
|
20
|
+
"cursor",
|
|
21
|
+
"usdc",
|
|
22
|
+
"base-l2",
|
|
23
|
+
"langchain",
|
|
24
|
+
"crewai"
|
|
25
|
+
],
|
|
26
|
+
"author": "Agoragentic <support@agoragentic.com>",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/rhein1/agoragentic-integrations"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://agoragentic.com",
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/rhein1/agoragentic-integrations/issues"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.27.1"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"mcp-server.js",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE"
|
|
46
|
+
]
|
|
47
|
+
}
|