agentbnb 3.1.6 → 4.0.1
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 +117 -86
- package/dist/{card-IE5UV5QX.js → card-4XH4AOTE.js} +11 -4
- package/dist/chunk-3MJT4PZG.js +50 -0
- package/dist/{conduct-IEQ567ET.js → chunk-3UKAVIMC.js} +70 -31
- package/dist/chunk-5AH3CMOX.js +62 -0
- package/dist/{chunk-IZZ4FP45.js → chunk-6K5WUVF3.js} +33 -166
- package/dist/chunk-75OC6E4F.js +33 -0
- package/dist/chunk-DVAS2443.js +63 -0
- package/dist/{chunk-XA63SD4T.js → chunk-FNKBHBYK.js} +3 -0
- package/dist/{websocket-client-5TIQDYQ4.js → chunk-JOY533UH.js} +38 -4
- package/dist/chunk-KJG2UJV5.js +83 -0
- package/dist/chunk-M3G5NR2Z.js +90 -0
- package/dist/{chunk-7OACGAFD.js → chunk-MQKYGY5I.js} +63 -24
- package/dist/chunk-ODBGCCEH.js +358 -0
- package/dist/{chunk-QSPWE5AE.js → chunk-Q7HRI666.js} +9 -6
- package/dist/chunk-QJEOCKVF.js +148 -0
- package/dist/{chunk-3Y36WQDV.js → chunk-QT7TEVNV.js} +14 -2
- package/dist/{chunk-UOGDK2S2.js → chunk-TLU7ALCZ.js} +1 -1
- package/dist/{chunk-QHQPXO67.js → chunk-XQHN6ITI.js} +1 -58
- package/dist/cli/index.js +2734 -850
- package/dist/client-BTPIFY7E.js +10 -0
- package/dist/conduct-CW62HBPT.js +52 -0
- package/dist/conduct-FXLVGKD5.js +19 -0
- package/dist/{conductor-mode-IO45PWMI.js → conductor-mode-3JS4VWCR.js} +16 -7
- package/dist/execute-EXOITLHN.js +10 -0
- package/dist/index.d.ts +1005 -916
- package/dist/index.js +516 -120
- package/dist/{peers-G36URZYB.js → peers-K7FSHPN3.js} +2 -1
- package/dist/request-CNZ3XIVX.js +196 -0
- package/dist/serve-skill-SUOGUM7N.js +104 -0
- package/dist/server-2LWHL24P.js +295 -0
- package/dist/types-FGBUZ3QV.js +18 -0
- package/dist/websocket-client-6IIDGXKB.js +7 -0
- package/package.json +4 -1
- package/dist/chunk-BEI5MTNZ.js +0 -91
- package/dist/cli/index.d.ts +0 -1
- package/dist/execute-SWWEHV2K.js +0 -9
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLedger
|
|
3
|
+
} from "./chunk-ODBGCCEH.js";
|
|
4
|
+
import {
|
|
5
|
+
AutoRequestor,
|
|
6
|
+
BudgetManager,
|
|
7
|
+
DEFAULT_AUTONOMY_CONFIG,
|
|
8
|
+
DEFAULT_BUDGET_CONFIG
|
|
9
|
+
} from "./chunk-6K5WUVF3.js";
|
|
10
|
+
import "./chunk-QJEOCKVF.js";
|
|
11
|
+
import {
|
|
12
|
+
requestCapability
|
|
13
|
+
} from "./chunk-KJG2UJV5.js";
|
|
14
|
+
import "./chunk-5AH3CMOX.js";
|
|
15
|
+
import "./chunk-75OC6E4F.js";
|
|
16
|
+
import {
|
|
17
|
+
openDatabase
|
|
18
|
+
} from "./chunk-TLU7ALCZ.js";
|
|
19
|
+
import {
|
|
20
|
+
openCreditDb
|
|
21
|
+
} from "./chunk-XQHN6ITI.js";
|
|
22
|
+
import {
|
|
23
|
+
loadKeyPair
|
|
24
|
+
} from "./chunk-DVAS2443.js";
|
|
25
|
+
import "./chunk-FNKBHBYK.js";
|
|
26
|
+
import {
|
|
27
|
+
RelayClient
|
|
28
|
+
} from "./chunk-JOY533UH.js";
|
|
29
|
+
import "./chunk-QT7TEVNV.js";
|
|
30
|
+
|
|
31
|
+
// src/mcp/tools/request.ts
|
|
32
|
+
import { z } from "zod";
|
|
33
|
+
var requestInputSchema = {
|
|
34
|
+
query: z.string().optional().describe("Search query to find a matching capability (auto-request mode)"),
|
|
35
|
+
card_id: z.string().optional().describe("Direct card ID to request (skips search)"),
|
|
36
|
+
skill_id: z.string().optional().describe("Specific skill within a v2.0 card"),
|
|
37
|
+
params: z.record(z.unknown()).optional().describe("Input parameters for the capability"),
|
|
38
|
+
max_cost: z.number().optional().default(50).describe("Maximum credits to spend")
|
|
39
|
+
};
|
|
40
|
+
async function handleRequest(args, ctx) {
|
|
41
|
+
try {
|
|
42
|
+
const maxCost = args.max_cost ?? 50;
|
|
43
|
+
if (args.query) {
|
|
44
|
+
const registryDb = openDatabase(ctx.config.db_path);
|
|
45
|
+
const creditDb = openCreditDb(ctx.config.credit_db_path);
|
|
46
|
+
registryDb.pragma("busy_timeout = 5000");
|
|
47
|
+
creditDb.pragma("busy_timeout = 5000");
|
|
48
|
+
try {
|
|
49
|
+
const budgetManager = new BudgetManager(
|
|
50
|
+
creditDb,
|
|
51
|
+
ctx.config.owner,
|
|
52
|
+
ctx.config.budget ?? DEFAULT_BUDGET_CONFIG
|
|
53
|
+
);
|
|
54
|
+
const requestor = new AutoRequestor({
|
|
55
|
+
owner: ctx.config.owner,
|
|
56
|
+
registryDb,
|
|
57
|
+
creditDb,
|
|
58
|
+
autonomyConfig: ctx.config.autonomy ?? DEFAULT_AUTONOMY_CONFIG,
|
|
59
|
+
budgetManager,
|
|
60
|
+
registryUrl: ctx.config.registry
|
|
61
|
+
});
|
|
62
|
+
const result = await requestor.requestWithAutonomy({
|
|
63
|
+
query: args.query,
|
|
64
|
+
maxCostCredits: maxCost,
|
|
65
|
+
params: args.params
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, ...result }, null, 2) }]
|
|
69
|
+
};
|
|
70
|
+
} finally {
|
|
71
|
+
registryDb.close();
|
|
72
|
+
creditDb.close();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (args.card_id) {
|
|
76
|
+
const cardId = args.card_id;
|
|
77
|
+
const db = openDatabase(ctx.config.db_path);
|
|
78
|
+
let localCard;
|
|
79
|
+
try {
|
|
80
|
+
const row = db.prepare("SELECT data FROM capability_cards WHERE id = ?").get(cardId);
|
|
81
|
+
if (row) {
|
|
82
|
+
localCard = JSON.parse(row.data);
|
|
83
|
+
}
|
|
84
|
+
} finally {
|
|
85
|
+
db.close();
|
|
86
|
+
}
|
|
87
|
+
if (localCard) {
|
|
88
|
+
const result = await requestCapability({
|
|
89
|
+
gatewayUrl: ctx.config.gateway_url,
|
|
90
|
+
token: ctx.config.token,
|
|
91
|
+
cardId,
|
|
92
|
+
params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {} }
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, result }, null, 2) }]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (!ctx.config.registry) {
|
|
99
|
+
return {
|
|
100
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Card not found locally and no remote registry configured" }) }]
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const cardUrl = `${ctx.config.registry.replace(/\/$/, "")}/cards/${cardId}`;
|
|
104
|
+
let remoteCard;
|
|
105
|
+
try {
|
|
106
|
+
const resp = await fetch(cardUrl);
|
|
107
|
+
if (!resp.ok) {
|
|
108
|
+
return {
|
|
109
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: `Card ${cardId} not found on remote registry (${resp.status})` }) }]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
remoteCard = await resp.json();
|
|
113
|
+
} catch (err) {
|
|
114
|
+
const msg = err instanceof Error ? err.message : "Registry unreachable";
|
|
115
|
+
return {
|
|
116
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: `Cannot reach registry: ${msg}` }) }]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const targetOwner = remoteCard["owner"] ?? remoteCard["agent_name"];
|
|
120
|
+
const gatewayUrl = remoteCard["gateway_url"];
|
|
121
|
+
if (gatewayUrl) {
|
|
122
|
+
const keys = loadKeyPair(ctx.configDir);
|
|
123
|
+
const ledger = createLedger({
|
|
124
|
+
registryUrl: ctx.config.registry,
|
|
125
|
+
ownerPublicKey: ctx.identity.public_key,
|
|
126
|
+
privateKey: keys.privateKey
|
|
127
|
+
});
|
|
128
|
+
const { escrowId } = await ledger.hold(ctx.config.owner, maxCost, cardId);
|
|
129
|
+
try {
|
|
130
|
+
const result = await requestCapability({
|
|
131
|
+
gatewayUrl,
|
|
132
|
+
token: "",
|
|
133
|
+
cardId,
|
|
134
|
+
params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {} }
|
|
135
|
+
});
|
|
136
|
+
await ledger.settle(escrowId, targetOwner ?? "unknown");
|
|
137
|
+
return {
|
|
138
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, result, credits_spent: maxCost }, null, 2) }]
|
|
139
|
+
};
|
|
140
|
+
} catch (err) {
|
|
141
|
+
await ledger.release(escrowId);
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (targetOwner) {
|
|
146
|
+
const relay = new RelayClient({
|
|
147
|
+
registryUrl: ctx.config.registry,
|
|
148
|
+
owner: ctx.config.owner,
|
|
149
|
+
token: ctx.config.token ?? "",
|
|
150
|
+
card: { id: ctx.config.owner, owner: ctx.config.owner, name: "mcp-requester" },
|
|
151
|
+
onRequest: async () => ({ error: { code: -32601, message: "MCP client does not accept requests" } }),
|
|
152
|
+
silent: true
|
|
153
|
+
});
|
|
154
|
+
try {
|
|
155
|
+
await relay.connect();
|
|
156
|
+
const result = await relay.request({
|
|
157
|
+
targetOwner,
|
|
158
|
+
cardId,
|
|
159
|
+
skillId: args.skill_id,
|
|
160
|
+
params: args.params ?? {},
|
|
161
|
+
requester: ctx.config.owner,
|
|
162
|
+
timeoutMs: 3e5
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, result }, null, 2) }]
|
|
166
|
+
};
|
|
167
|
+
} finally {
|
|
168
|
+
relay.disconnect();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Remote card has no gateway_url and no owner for relay routing" }) }]
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Provide either query or card_id" }) }]
|
|
177
|
+
};
|
|
178
|
+
} catch (err) {
|
|
179
|
+
const message = err instanceof Error ? err.message : "Unknown error during request";
|
|
180
|
+
return {
|
|
181
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: message }) }]
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function registerRequestTool(server, ctx) {
|
|
186
|
+
server.registerTool("agentbnb_request", {
|
|
187
|
+
description: "Request execution of a skill from another agent on the AgentBnB network. Handles credit escrow automatically.",
|
|
188
|
+
inputSchema: requestInputSchema
|
|
189
|
+
}, async (args) => {
|
|
190
|
+
return handleRequest(args, ctx);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
export {
|
|
194
|
+
handleRequest,
|
|
195
|
+
registerRequestTool
|
|
196
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeCapabilityRequest
|
|
3
|
+
} from "./chunk-Q7HRI666.js";
|
|
4
|
+
import {
|
|
5
|
+
listCards,
|
|
6
|
+
openDatabase
|
|
7
|
+
} from "./chunk-TLU7ALCZ.js";
|
|
8
|
+
import {
|
|
9
|
+
openCreditDb
|
|
10
|
+
} from "./chunk-XQHN6ITI.js";
|
|
11
|
+
import "./chunk-DVAS2443.js";
|
|
12
|
+
import "./chunk-FNKBHBYK.js";
|
|
13
|
+
import {
|
|
14
|
+
RelayClient
|
|
15
|
+
} from "./chunk-JOY533UH.js";
|
|
16
|
+
import "./chunk-QT7TEVNV.js";
|
|
17
|
+
|
|
18
|
+
// src/mcp/tools/serve-skill.ts
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
var serveSkillInputSchema = {
|
|
21
|
+
handler_url: z.string().optional().default("http://localhost:8080").describe("Local URL that handles capability execution"),
|
|
22
|
+
skills_yaml: z.string().optional().describe("Path to skills.yaml config file")
|
|
23
|
+
};
|
|
24
|
+
async function handleServeSkill(args, ctx) {
|
|
25
|
+
try {
|
|
26
|
+
if (!ctx.config.registry) {
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "No remote registry configured. Set one with: agentbnb config set registry <url>" }) }]
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const db = openDatabase(ctx.config.db_path);
|
|
32
|
+
let cards;
|
|
33
|
+
try {
|
|
34
|
+
cards = listCards(db, ctx.config.owner);
|
|
35
|
+
} finally {
|
|
36
|
+
db.close();
|
|
37
|
+
}
|
|
38
|
+
if (cards.length === 0) {
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "No capability cards found. Publish a card first with agentbnb_publish." }) }]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const card = cards[0];
|
|
44
|
+
const handlerUrl = args.handler_url ?? "http://localhost:8080";
|
|
45
|
+
const relay = new RelayClient({
|
|
46
|
+
registryUrl: ctx.config.registry,
|
|
47
|
+
owner: ctx.config.owner,
|
|
48
|
+
token: ctx.config.token ?? "",
|
|
49
|
+
card,
|
|
50
|
+
onRequest: async (req) => {
|
|
51
|
+
const registryDb = openDatabase(ctx.config.db_path);
|
|
52
|
+
const creditDb = openCreditDb(ctx.config.credit_db_path);
|
|
53
|
+
try {
|
|
54
|
+
const result = await executeCapabilityRequest({
|
|
55
|
+
registryDb,
|
|
56
|
+
creditDb,
|
|
57
|
+
cardId: req.params?.card_id ?? card.id,
|
|
58
|
+
skillId: req.params?.skill_id,
|
|
59
|
+
params: req.params?.params ?? {},
|
|
60
|
+
requester: req.params?.requester ?? "unknown",
|
|
61
|
+
handlerUrl
|
|
62
|
+
});
|
|
63
|
+
if (result.success) {
|
|
64
|
+
return { result: result.result };
|
|
65
|
+
}
|
|
66
|
+
return { error: result.error };
|
|
67
|
+
} finally {
|
|
68
|
+
registryDb.close();
|
|
69
|
+
creditDb.close();
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
silent: true
|
|
73
|
+
});
|
|
74
|
+
await relay.connect();
|
|
75
|
+
ctx.relayClient = relay;
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
78
|
+
success: true,
|
|
79
|
+
message: "Connected to relay as provider",
|
|
80
|
+
owner: ctx.config.owner,
|
|
81
|
+
registry_url: ctx.config.registry,
|
|
82
|
+
card_id: card.id,
|
|
83
|
+
handler_url: handlerUrl
|
|
84
|
+
}, null, 2) }]
|
|
85
|
+
};
|
|
86
|
+
} catch (err) {
|
|
87
|
+
const message = err instanceof Error ? err.message : "Unknown error during serve_skill";
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: message }) }]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function registerServeSkillTool(server, ctx) {
|
|
94
|
+
server.registerTool("agentbnb_serve_skill", {
|
|
95
|
+
description: "Register as a skill provider on the AgentBnB network via relay. Connects to the registry and listens for incoming skill requests.",
|
|
96
|
+
inputSchema: serveSkillInputSchema
|
|
97
|
+
}, async (args) => {
|
|
98
|
+
return handleServeSkill(args, ctx);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
export {
|
|
102
|
+
handleServeSkill,
|
|
103
|
+
registerServeSkillTool
|
|
104
|
+
};
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureIdentity
|
|
3
|
+
} from "./chunk-M3G5NR2Z.js";
|
|
4
|
+
import {
|
|
5
|
+
createLedger
|
|
6
|
+
} from "./chunk-ODBGCCEH.js";
|
|
7
|
+
import {
|
|
8
|
+
fetchRemoteCards,
|
|
9
|
+
mergeResults,
|
|
10
|
+
searchCards
|
|
11
|
+
} from "./chunk-QJEOCKVF.js";
|
|
12
|
+
import {
|
|
13
|
+
getConfigDir,
|
|
14
|
+
loadConfig
|
|
15
|
+
} from "./chunk-75OC6E4F.js";
|
|
16
|
+
import {
|
|
17
|
+
insertCard,
|
|
18
|
+
openDatabase
|
|
19
|
+
} from "./chunk-TLU7ALCZ.js";
|
|
20
|
+
import {
|
|
21
|
+
getBalance,
|
|
22
|
+
openCreditDb
|
|
23
|
+
} from "./chunk-XQHN6ITI.js";
|
|
24
|
+
import {
|
|
25
|
+
loadKeyPair
|
|
26
|
+
} from "./chunk-DVAS2443.js";
|
|
27
|
+
import {
|
|
28
|
+
AnyCardSchema
|
|
29
|
+
} from "./chunk-FNKBHBYK.js";
|
|
30
|
+
|
|
31
|
+
// src/mcp/server.ts
|
|
32
|
+
import { createRequire } from "module";
|
|
33
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
34
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
35
|
+
|
|
36
|
+
// src/mcp/tools/discover.ts
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
var discoverInputSchema = {
|
|
39
|
+
query: z.string().describe("Natural language search query"),
|
|
40
|
+
level: z.number().optional().describe("Filter by capability level (1=Atomic, 2=Pipeline, 3=Environment)"),
|
|
41
|
+
online_only: z.boolean().optional().describe("Only show online agents")
|
|
42
|
+
};
|
|
43
|
+
async function handleDiscover(args, ctx) {
|
|
44
|
+
try {
|
|
45
|
+
const db = openDatabase(ctx.config.db_path);
|
|
46
|
+
let localCards;
|
|
47
|
+
try {
|
|
48
|
+
localCards = searchCards(db, args.query, {
|
|
49
|
+
level: args.level,
|
|
50
|
+
online: args.online_only
|
|
51
|
+
});
|
|
52
|
+
} finally {
|
|
53
|
+
db.close();
|
|
54
|
+
}
|
|
55
|
+
let remoteCards = [];
|
|
56
|
+
if (ctx.config.registry) {
|
|
57
|
+
try {
|
|
58
|
+
remoteCards = await fetchRemoteCards(ctx.config.registry, {
|
|
59
|
+
q: args.query,
|
|
60
|
+
level: args.level,
|
|
61
|
+
online: args.online_only
|
|
62
|
+
});
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const merged = mergeResults(localCards, remoteCards, true);
|
|
67
|
+
const results = merged.map((card) => {
|
|
68
|
+
const raw = card;
|
|
69
|
+
const skills = Array.isArray(raw["skills"]) ? raw["skills"].map((s) => ({
|
|
70
|
+
id: s.id,
|
|
71
|
+
name: s.name,
|
|
72
|
+
description: s.description,
|
|
73
|
+
credits_per_call: s.pricing.credits_per_call
|
|
74
|
+
})) : void 0;
|
|
75
|
+
return {
|
|
76
|
+
id: card.id,
|
|
77
|
+
name: card.name,
|
|
78
|
+
owner: card.owner,
|
|
79
|
+
description: card.description,
|
|
80
|
+
level: card.level,
|
|
81
|
+
skills,
|
|
82
|
+
pricing: card.pricing,
|
|
83
|
+
source: card.source,
|
|
84
|
+
online: card.availability?.online ?? false
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
content: [{ type: "text", text: JSON.stringify({ results, count: results.length }, null, 2) }]
|
|
89
|
+
};
|
|
90
|
+
} catch (err) {
|
|
91
|
+
const message = err instanceof Error ? err.message : "Unknown error during discover";
|
|
92
|
+
return {
|
|
93
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: message }) }]
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function registerDiscoverTool(server, ctx) {
|
|
98
|
+
server.registerTool("agentbnb_discover", {
|
|
99
|
+
description: "Search for agent capabilities on the AgentBnB network. Returns matching capability cards from both local and remote registries.",
|
|
100
|
+
inputSchema: discoverInputSchema
|
|
101
|
+
}, async (args) => {
|
|
102
|
+
return handleDiscover(args, ctx);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/mcp/tools/status.ts
|
|
107
|
+
import { z as z2 } from "zod";
|
|
108
|
+
var statusInputSchema = {
|
|
109
|
+
_unused: z2.string().optional().describe("No parameters needed")
|
|
110
|
+
};
|
|
111
|
+
async function handleStatus(ctx) {
|
|
112
|
+
try {
|
|
113
|
+
let balance = 0;
|
|
114
|
+
if (ctx.config.registry) {
|
|
115
|
+
try {
|
|
116
|
+
const keys = loadKeyPair(ctx.configDir);
|
|
117
|
+
const ledger = createLedger({
|
|
118
|
+
registryUrl: ctx.config.registry,
|
|
119
|
+
ownerPublicKey: ctx.identity.public_key,
|
|
120
|
+
privateKey: keys.privateKey
|
|
121
|
+
});
|
|
122
|
+
balance = await ledger.getBalance(ctx.identity.owner);
|
|
123
|
+
} catch {
|
|
124
|
+
const creditDb = openCreditDb(ctx.config.credit_db_path);
|
|
125
|
+
try {
|
|
126
|
+
balance = getBalance(creditDb, ctx.identity.owner);
|
|
127
|
+
} finally {
|
|
128
|
+
creditDb.close();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
const creditDb = openCreditDb(ctx.config.credit_db_path);
|
|
133
|
+
try {
|
|
134
|
+
balance = getBalance(creditDb, ctx.identity.owner);
|
|
135
|
+
} finally {
|
|
136
|
+
creditDb.close();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const result = {
|
|
140
|
+
agent_id: ctx.identity.agent_id,
|
|
141
|
+
owner: ctx.identity.owner,
|
|
142
|
+
public_key: ctx.identity.public_key,
|
|
143
|
+
balance,
|
|
144
|
+
registry_url: ctx.config.registry ?? null,
|
|
145
|
+
config_dir: ctx.configDir
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
149
|
+
};
|
|
150
|
+
} catch (err) {
|
|
151
|
+
const message = err instanceof Error ? err.message : "Unknown error during status check";
|
|
152
|
+
return {
|
|
153
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: message }) }]
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function registerStatusTool(server, ctx) {
|
|
158
|
+
server.registerTool("agentbnb_status", {
|
|
159
|
+
description: "Check your AgentBnB agent status: identity, credit balance, and configuration.",
|
|
160
|
+
inputSchema: statusInputSchema
|
|
161
|
+
}, async () => {
|
|
162
|
+
return handleStatus(ctx);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/mcp/tools/publish.ts
|
|
167
|
+
import { z as z3 } from "zod";
|
|
168
|
+
var publishInputSchema = {
|
|
169
|
+
card_json: z3.string().describe("JSON string of the capability card to publish")
|
|
170
|
+
};
|
|
171
|
+
async function handlePublish(args, ctx) {
|
|
172
|
+
try {
|
|
173
|
+
let parsed;
|
|
174
|
+
try {
|
|
175
|
+
parsed = JSON.parse(args.card_json);
|
|
176
|
+
} catch {
|
|
177
|
+
return {
|
|
178
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Invalid JSON in card_json" }) }]
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const validated = AnyCardSchema.safeParse(parsed);
|
|
182
|
+
if (!validated.success) {
|
|
183
|
+
return {
|
|
184
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Card validation failed", details: validated.error.issues }) }]
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const card = validated.data;
|
|
188
|
+
const rawCard = card;
|
|
189
|
+
if (Array.isArray(rawCard["skills"])) {
|
|
190
|
+
const skills = rawCard["skills"];
|
|
191
|
+
for (const skill of skills) {
|
|
192
|
+
if (skill.pricing.credits_per_call < 1) {
|
|
193
|
+
return {
|
|
194
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Minimum price is 1 credit per call for each skill" }) }]
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
const pricing = rawCard["pricing"];
|
|
200
|
+
if (pricing && pricing.credits_per_call < 1) {
|
|
201
|
+
return {
|
|
202
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Minimum price is 1 credit per call" }) }]
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const db = openDatabase(ctx.config.db_path);
|
|
207
|
+
try {
|
|
208
|
+
insertCard(db, card);
|
|
209
|
+
} finally {
|
|
210
|
+
db.close();
|
|
211
|
+
}
|
|
212
|
+
let remotePublished = false;
|
|
213
|
+
if (ctx.config.registry) {
|
|
214
|
+
try {
|
|
215
|
+
const publishUrl = new URL("/cards", ctx.config.registry);
|
|
216
|
+
const body = {
|
|
217
|
+
...card,
|
|
218
|
+
gateway_url: ctx.config.gateway_url
|
|
219
|
+
};
|
|
220
|
+
const res = await fetch(publishUrl.toString(), {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers: { "Content-Type": "application/json" },
|
|
223
|
+
body: JSON.stringify(body)
|
|
224
|
+
});
|
|
225
|
+
remotePublished = res.ok;
|
|
226
|
+
} catch {
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
231
|
+
success: true,
|
|
232
|
+
card_id: card.id,
|
|
233
|
+
card_name: rawCard["name"] ?? rawCard["agent_name"] ?? card.id,
|
|
234
|
+
remote_published: remotePublished
|
|
235
|
+
}, null, 2) }]
|
|
236
|
+
};
|
|
237
|
+
} catch (err) {
|
|
238
|
+
const message = err instanceof Error ? err.message : "Unknown error during publish";
|
|
239
|
+
return {
|
|
240
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: message }) }]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function registerPublishTool(server, ctx) {
|
|
245
|
+
server.registerTool("agentbnb_publish", {
|
|
246
|
+
description: "Publish a capability card to the AgentBnB network. Stores locally and optionally syncs to remote registry.",
|
|
247
|
+
inputSchema: publishInputSchema
|
|
248
|
+
}, async (args) => {
|
|
249
|
+
return handlePublish(args, ctx);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/mcp/server.ts
|
|
254
|
+
var require2 = createRequire(import.meta.url);
|
|
255
|
+
var pkg = require2("../../package.json");
|
|
256
|
+
async function startMcpServer() {
|
|
257
|
+
const config = loadConfig();
|
|
258
|
+
if (!config) {
|
|
259
|
+
process.stderr.write("Error: AgentBnB not initialized. Run `agentbnb init` first.\n");
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
const configDir = getConfigDir();
|
|
263
|
+
const identity = ensureIdentity(configDir, config.owner);
|
|
264
|
+
const server = new McpServer({
|
|
265
|
+
name: "agentbnb",
|
|
266
|
+
version: pkg.version
|
|
267
|
+
});
|
|
268
|
+
const ctx = {
|
|
269
|
+
configDir,
|
|
270
|
+
config,
|
|
271
|
+
identity
|
|
272
|
+
};
|
|
273
|
+
registerDiscoverTool(server, ctx);
|
|
274
|
+
registerStatusTool(server, ctx);
|
|
275
|
+
registerPublishTool(server, ctx);
|
|
276
|
+
const { registerRequestTool } = await import("./request-CNZ3XIVX.js");
|
|
277
|
+
const { registerConductTool } = await import("./conduct-CW62HBPT.js");
|
|
278
|
+
const { registerServeSkillTool } = await import("./serve-skill-SUOGUM7N.js");
|
|
279
|
+
registerRequestTool(server, ctx);
|
|
280
|
+
registerConductTool(server, ctx);
|
|
281
|
+
registerServeSkillTool(server, ctx);
|
|
282
|
+
const transport = new StdioServerTransport();
|
|
283
|
+
await server.connect(transport);
|
|
284
|
+
process.stderr.write(`AgentBnB MCP server started (owner: ${identity.owner})
|
|
285
|
+
`);
|
|
286
|
+
const shutdown = () => {
|
|
287
|
+
ctx.relayClient?.disconnect();
|
|
288
|
+
process.exit(0);
|
|
289
|
+
};
|
|
290
|
+
process.on("SIGINT", shutdown);
|
|
291
|
+
process.on("SIGTERM", shutdown);
|
|
292
|
+
}
|
|
293
|
+
export {
|
|
294
|
+
startMcpServer
|
|
295
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentBnBError,
|
|
3
|
+
AnyCardSchema,
|
|
4
|
+
CapabilityCardSchema,
|
|
5
|
+
CapabilityCardV2Schema,
|
|
6
|
+
IOSchemaSchema,
|
|
7
|
+
PoweredBySchema,
|
|
8
|
+
SkillSchema
|
|
9
|
+
} from "./chunk-FNKBHBYK.js";
|
|
10
|
+
export {
|
|
11
|
+
AgentBnBError,
|
|
12
|
+
AnyCardSchema,
|
|
13
|
+
CapabilityCardSchema,
|
|
14
|
+
CapabilityCardV2Schema,
|
|
15
|
+
IOSchemaSchema,
|
|
16
|
+
PoweredBySchema,
|
|
17
|
+
SkillSchema
|
|
18
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentbnb",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "P2P Agent Capability Sharing Protocol — Airbnb for AI agent pipelines",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -68,7 +68,10 @@
|
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@fastify/cors": "^11.2.0",
|
|
70
70
|
"@fastify/static": "^9.0.0",
|
|
71
|
+
"@fastify/swagger": "^9.7.0",
|
|
72
|
+
"@fastify/swagger-ui": "^5.2.5",
|
|
71
73
|
"@fastify/websocket": "^11.2.0",
|
|
74
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
72
75
|
"better-sqlite3": "^11.6.0",
|
|
73
76
|
"bonjour-service": "^1.3.0",
|
|
74
77
|
"commander": "^12.1.0",
|