@aibtc/mcp-server 1.60.0 → 1.61.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/dist/tools/index.js
CHANGED
|
@@ -34,6 +34,7 @@ import { registerOrdinalsMarketplaceTools } from "./ordinals-marketplace.tools.j
|
|
|
34
34
|
import { registerTaprootMultisigTools } from "./taproot-multisig.tools.js";
|
|
35
35
|
import { registerJingswapTools } from "./jingswap.tools.js";
|
|
36
36
|
import { registerSigningTools } from "./signing.tools.js";
|
|
37
|
+
import { registerInferenceMarketplaceTools } from "./inference-marketplace.tools.js";
|
|
37
38
|
import { registerNewsTools } from "./news.tools.js";
|
|
38
39
|
import { registerIdentityTools } from "./identity.tools.js";
|
|
39
40
|
import { registerCredentialsTools } from "./credentials.tools.js";
|
|
@@ -160,6 +161,8 @@ export function registerAllTools(server) {
|
|
|
160
161
|
registerJingswapTools(server);
|
|
161
162
|
// Message Signing (BTC BIP-322, Stacks SIWS, SIP-018 structured data, Nostr NIP-01)
|
|
162
163
|
registerSigningTools(server);
|
|
164
|
+
// AIBTC Inference Marketplace (list/manage a paid model endpoint via wallet signature)
|
|
165
|
+
registerInferenceMarketplaceTools(server);
|
|
163
166
|
// AIBTC News (signal feed, leaderboard, file signals)
|
|
164
167
|
registerNewsTools(server);
|
|
165
168
|
// Identity (ERC-8004 on-chain agent identity management)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIBTC Inference Marketplace Tools
|
|
3
|
+
*
|
|
4
|
+
* List an OpenAI-compatible model endpoint on the marketplace and manage it, all
|
|
5
|
+
* authorized by a wallet signature (the same wallet that receives sBTC payouts).
|
|
6
|
+
* Ownership is proven by signing a short message with the payout wallet — no
|
|
7
|
+
* accounts, no API keys. These tools sign locally with the unlocked wallet and
|
|
8
|
+
* call the gateway, so an agent can register/update/check in one step.
|
|
9
|
+
*
|
|
10
|
+
* - inference_register_provider: verify + list an endpoint (signed)
|
|
11
|
+
* - inference_update_provider: change name/models/payout/endpoint in place (signed)
|
|
12
|
+
* - inference_reveal_key: reveal or rotate the gateway↔endpoint shared key (signed)
|
|
13
|
+
* - inference_check_provider: re-run the health/functional probe (unsigned)
|
|
14
|
+
* - inference_list_providers: list registered providers + health (unsigned)
|
|
15
|
+
*
|
|
16
|
+
* The gateway verifies the signature recovers to `payoutAddress` (which also
|
|
17
|
+
* enforces the network), that the endpoint is reachable AND serving inference,
|
|
18
|
+
* and that model ids are real, text-generation, commercially-licensed HF repos.
|
|
19
|
+
*/
|
|
20
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
21
|
+
type AuthAction = "register" | "update" | "reveal-key";
|
|
22
|
+
/** The exact message the gateway rebuilds and verifies. Must match byte-for-byte. */
|
|
23
|
+
export declare function authMessage(action: AuthAction, providerId: string, timestamp: number): string;
|
|
24
|
+
/** Sign an auth message with the unlocked wallet and return the gateway headers. */
|
|
25
|
+
export declare function signAuthHeaders(account: {
|
|
26
|
+
privateKey: string;
|
|
27
|
+
}, action: AuthAction, providerId: string): Record<string, string>;
|
|
28
|
+
export declare function registerInferenceMarketplaceTools(server: McpServer): void;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=inference-marketplace.tools.d.ts.map
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIBTC Inference Marketplace Tools
|
|
3
|
+
*
|
|
4
|
+
* List an OpenAI-compatible model endpoint on the marketplace and manage it, all
|
|
5
|
+
* authorized by a wallet signature (the same wallet that receives sBTC payouts).
|
|
6
|
+
* Ownership is proven by signing a short message with the payout wallet — no
|
|
7
|
+
* accounts, no API keys. These tools sign locally with the unlocked wallet and
|
|
8
|
+
* call the gateway, so an agent can register/update/check in one step.
|
|
9
|
+
*
|
|
10
|
+
* - inference_register_provider: verify + list an endpoint (signed)
|
|
11
|
+
* - inference_update_provider: change name/models/payout/endpoint in place (signed)
|
|
12
|
+
* - inference_reveal_key: reveal or rotate the gateway↔endpoint shared key (signed)
|
|
13
|
+
* - inference_check_provider: re-run the health/functional probe (unsigned)
|
|
14
|
+
* - inference_list_providers: list registered providers + health (unsigned)
|
|
15
|
+
*
|
|
16
|
+
* The gateway verifies the signature recovers to `payoutAddress` (which also
|
|
17
|
+
* enforces the network), that the endpoint is reachable AND serving inference,
|
|
18
|
+
* and that model ids are real, text-generation, commercially-licensed HF repos.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
import { signMessageHashRsv, privateKeyToPublic, compressPublicKey, } from "@stacks/transactions";
|
|
22
|
+
import { hashMessage } from "@stacks/encryption";
|
|
23
|
+
import { bytesToHex } from "@stacks/common";
|
|
24
|
+
import { createJsonResponse, createErrorResponse } from "../utils/index.js";
|
|
25
|
+
import { getWalletManager } from "../services/wallet-manager.js";
|
|
26
|
+
/** Default marketplace gateway; override with the `gateway` arg for local dev. */
|
|
27
|
+
const DEFAULT_GATEWAY = "https://inference.aibtc.com";
|
|
28
|
+
/** Bound network calls so a hung endpoint can't block the tool call forever. */
|
|
29
|
+
const GATEWAY_TIMEOUT_MS = 15_000;
|
|
30
|
+
/** Loopback hosts always allowed for local dev. */
|
|
31
|
+
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
32
|
+
/**
|
|
33
|
+
* These tools sign an ownership message with the payout wallet and may forward
|
|
34
|
+
* the endpoint's own `apiKey` — both secrets. If the gateway destination were
|
|
35
|
+
* free-form, a prompt-injected "use gateway https://attacker.example" could
|
|
36
|
+
* redirect that signed request and leak the signature + apiKey. So the override
|
|
37
|
+
* is restricted to localhost and the marketplace (`*.aibtc.com`); any other host
|
|
38
|
+
* requires an explicit `allowUnsafeGateway: true`, which natural language alone
|
|
39
|
+
* won't set.
|
|
40
|
+
*/
|
|
41
|
+
function isAllowedGatewayHost(hostname) {
|
|
42
|
+
const host = hostname.toLowerCase();
|
|
43
|
+
if (LOOPBACK_HOSTS.has(host))
|
|
44
|
+
return true;
|
|
45
|
+
return host === "aibtc.com" || host.endsWith(".aibtc.com");
|
|
46
|
+
}
|
|
47
|
+
/** Validate + normalize the gateway base URL (trailing slash stripped). */
|
|
48
|
+
function resolveGateway(gateway, allowUnsafe) {
|
|
49
|
+
const base = (gateway ?? DEFAULT_GATEWAY).replace(/\/$/, "");
|
|
50
|
+
let url;
|
|
51
|
+
try {
|
|
52
|
+
url = new URL(base);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error(`Invalid gateway URL: ${base}`);
|
|
56
|
+
}
|
|
57
|
+
if (!allowUnsafe && !isAllowedGatewayHost(url.hostname)) {
|
|
58
|
+
throw new Error(`Gateway host "${url.hostname}" is not allowed. Wallet-signed headers and your endpoint apiKey ` +
|
|
59
|
+
`are only sent to the marketplace (*.aibtc.com) or localhost. To target another host on ` +
|
|
60
|
+
`purpose, pass allowUnsafeGateway: true.`);
|
|
61
|
+
}
|
|
62
|
+
return base;
|
|
63
|
+
}
|
|
64
|
+
function requireUnlockedWallet() {
|
|
65
|
+
const account = getWalletManager().getActiveAccount();
|
|
66
|
+
if (!account) {
|
|
67
|
+
throw new Error("Wallet is not unlocked. Use wallet_unlock first to enable signing.");
|
|
68
|
+
}
|
|
69
|
+
return account;
|
|
70
|
+
}
|
|
71
|
+
/** The exact message the gateway rebuilds and verifies. Must match byte-for-byte. */
|
|
72
|
+
export function authMessage(action, providerId, timestamp) {
|
|
73
|
+
return `Inference Marketplace\nAction: ${action}\nProvider: ${providerId}\nTimestamp: ${timestamp}`;
|
|
74
|
+
}
|
|
75
|
+
/** Sign an auth message with the unlocked wallet and return the gateway headers. */
|
|
76
|
+
export function signAuthHeaders(account, action, providerId) {
|
|
77
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
78
|
+
const message = authMessage(action, providerId, timestamp);
|
|
79
|
+
const signature = signMessageHashRsv({
|
|
80
|
+
messageHash: bytesToHex(hashMessage(message)),
|
|
81
|
+
privateKey: account.privateKey,
|
|
82
|
+
});
|
|
83
|
+
const publicKey = compressPublicKey(privateKeyToPublic(account.privateKey));
|
|
84
|
+
return {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
"X-Stacks-Signature": signature,
|
|
87
|
+
"X-Stacks-Public-Key": publicKey,
|
|
88
|
+
"X-Stacks-Timestamp": String(timestamp),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function gatewayFetch(url, init) {
|
|
92
|
+
const res = await fetch(url, { ...init, signal: AbortSignal.timeout(GATEWAY_TIMEOUT_MS) });
|
|
93
|
+
const text = await res.text();
|
|
94
|
+
let body;
|
|
95
|
+
try {
|
|
96
|
+
body = JSON.parse(text);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
body = { raw: text };
|
|
100
|
+
}
|
|
101
|
+
return { ok: res.ok, status: res.status, body };
|
|
102
|
+
}
|
|
103
|
+
const gatewayArg = z
|
|
104
|
+
.string()
|
|
105
|
+
.url()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe(`Marketplace gateway base URL. Defaults to ${DEFAULT_GATEWAY}. Use http://localhost:8787 for local dev.`);
|
|
108
|
+
const allowUnsafeGatewayArg = z
|
|
109
|
+
.boolean()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("Allow a gateway host outside localhost / *.aibtc.com. Required to send wallet-signed headers " +
|
|
112
|
+
"(and any apiKey) to an arbitrary host — leave unset unless you deliberately self-host the gateway.");
|
|
113
|
+
export function registerInferenceMarketplaceTools(server) {
|
|
114
|
+
// Register (verify + list) an endpoint — signed
|
|
115
|
+
server.registerTool("inference_register_provider", {
|
|
116
|
+
description: "List an OpenAI-compatible model endpoint on the AIBTC Inference Marketplace and get paid per request in sBTC. " +
|
|
117
|
+
"Signs a registration message with the unlocked payout wallet (proving ownership) and POSTs it. " +
|
|
118
|
+
"The gateway verifies the signature recovers to payoutAddress, that the endpoint is reachable AND actually " +
|
|
119
|
+
"serving inference, and that model ids are real/commercial Hugging Face repos — then lists it. " +
|
|
120
|
+
"Requires an unlocked wallet on the gateway's network.",
|
|
121
|
+
inputSchema: {
|
|
122
|
+
name: z.string().describe("Display name for your node, e.g. \"Alice's Qwen node\"."),
|
|
123
|
+
endpoint: z
|
|
124
|
+
.string()
|
|
125
|
+
.url()
|
|
126
|
+
.describe("OpenAI-compatible base URL, e.g. https://my-host/v1 (must expose /models and /chat/completions)."),
|
|
127
|
+
models: z
|
|
128
|
+
.array(z.string())
|
|
129
|
+
.min(1)
|
|
130
|
+
.describe("Hugging Face repo ids you serve, e.g. [\"Qwen/Qwen2.5-7B-Instruct\"]."),
|
|
131
|
+
payoutAddress: z
|
|
132
|
+
.string()
|
|
133
|
+
.optional()
|
|
134
|
+
.describe("Stacks address that receives sBTC. Defaults to the unlocked wallet's address (must match the gateway network)."),
|
|
135
|
+
apiKey: z
|
|
136
|
+
.string()
|
|
137
|
+
.optional()
|
|
138
|
+
.describe("Optional: a key your endpoint requires. Locks the endpoint so only the gateway (which presents it) can call it."),
|
|
139
|
+
gateway: gatewayArg,
|
|
140
|
+
allowUnsafeGateway: allowUnsafeGatewayArg,
|
|
141
|
+
},
|
|
142
|
+
}, async ({ name, endpoint, models, payoutAddress, apiKey, gateway, allowUnsafeGateway }) => {
|
|
143
|
+
try {
|
|
144
|
+
const account = requireUnlockedWallet();
|
|
145
|
+
const base = resolveGateway(gateway, allowUnsafeGateway ?? false);
|
|
146
|
+
const payout = payoutAddress ?? account.address;
|
|
147
|
+
const headers = signAuthHeaders(account, "register", endpoint);
|
|
148
|
+
const { ok, status, body } = await gatewayFetch(`${base}/v1/providers`, {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers,
|
|
151
|
+
body: JSON.stringify({
|
|
152
|
+
name,
|
|
153
|
+
endpoint,
|
|
154
|
+
payoutAddress: payout,
|
|
155
|
+
models,
|
|
156
|
+
...(apiKey ? { apiKey } : {}),
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
return createJsonResponse({
|
|
160
|
+
success: ok,
|
|
161
|
+
status,
|
|
162
|
+
payoutAddress: payout,
|
|
163
|
+
gateway: base,
|
|
164
|
+
result: body,
|
|
165
|
+
note: ok
|
|
166
|
+
? "Registered and verified. Your endpoint is listed and callable."
|
|
167
|
+
: "Registration failed — see result.error (e.g. wrong network, endpoint unreachable, or invalid model id).",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return createErrorResponse(error);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// Update a listing in place — signed
|
|
175
|
+
server.registerTool("inference_update_provider", {
|
|
176
|
+
description: "Update your marketplace listing in place — name, models, payout address, endpoint, or description — no delete/re-add. " +
|
|
177
|
+
"Signs an update message with the unlocked payout wallet and PATCHes it. Only fields you pass change. " +
|
|
178
|
+
"Changing the endpoint re-verifies reachability before taking effect. Requires an unlocked wallet.",
|
|
179
|
+
inputSchema: {
|
|
180
|
+
providerId: z.string().describe("The provider id returned at registration (from inference_list_providers)."),
|
|
181
|
+
name: z.string().optional().describe("New display name."),
|
|
182
|
+
endpoint: z.string().url().optional().describe("New OpenAI-compatible base URL (re-verified before it takes effect)."),
|
|
183
|
+
models: z.array(z.string()).optional().describe("New Hugging Face repo id list."),
|
|
184
|
+
payoutAddress: z.string().optional().describe("New payout address (must match the gateway network)."),
|
|
185
|
+
description: z.string().optional().describe("New description."),
|
|
186
|
+
apiKey: z.string().optional().describe("Set/replace the key your endpoint requires (locks the endpoint)."),
|
|
187
|
+
gateway: gatewayArg,
|
|
188
|
+
allowUnsafeGateway: allowUnsafeGatewayArg,
|
|
189
|
+
},
|
|
190
|
+
}, async ({ providerId, name, endpoint, models, payoutAddress, description, apiKey, gateway, allowUnsafeGateway }) => {
|
|
191
|
+
try {
|
|
192
|
+
const account = requireUnlockedWallet();
|
|
193
|
+
const base = resolveGateway(gateway, allowUnsafeGateway ?? false);
|
|
194
|
+
const patch = {};
|
|
195
|
+
if (name !== undefined)
|
|
196
|
+
patch.name = name;
|
|
197
|
+
if (endpoint !== undefined)
|
|
198
|
+
patch.endpoint = endpoint;
|
|
199
|
+
if (models !== undefined)
|
|
200
|
+
patch.models = models;
|
|
201
|
+
if (payoutAddress !== undefined)
|
|
202
|
+
patch.payoutAddress = payoutAddress;
|
|
203
|
+
if (description !== undefined)
|
|
204
|
+
patch.description = description;
|
|
205
|
+
if (apiKey !== undefined)
|
|
206
|
+
patch.apiKey = apiKey;
|
|
207
|
+
if (Object.keys(patch).length === 0) {
|
|
208
|
+
throw new Error("Nothing to update — pass at least one of name/endpoint/models/payoutAddress/description/apiKey.");
|
|
209
|
+
}
|
|
210
|
+
const headers = signAuthHeaders(account, "update", providerId);
|
|
211
|
+
const { ok, status, body } = await gatewayFetch(`${base}/v1/providers/${providerId}`, {
|
|
212
|
+
method: "PATCH",
|
|
213
|
+
headers,
|
|
214
|
+
body: JSON.stringify(patch),
|
|
215
|
+
});
|
|
216
|
+
return createJsonResponse({
|
|
217
|
+
success: ok,
|
|
218
|
+
status,
|
|
219
|
+
gateway: base,
|
|
220
|
+
result: body,
|
|
221
|
+
note: ok ? "Listing updated." : "Update failed — see result.error.",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return createErrorResponse(error);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// Reveal or rotate the shared key — signed
|
|
229
|
+
server.registerTool("inference_reveal_key", {
|
|
230
|
+
description: "Reveal or rotate your provider's shared key — the gateway↔endpoint credential the gateway presents when it " +
|
|
231
|
+
"calls your endpoint (NOT an ownership token; ownership is your wallet). The gateway stores it write-only, so a " +
|
|
232
|
+
"wallet signature is the only way to read it back. Pass rotate=true to issue a new one. Requires an unlocked wallet.",
|
|
233
|
+
inputSchema: {
|
|
234
|
+
providerId: z.string().describe("The provider id (from inference_list_providers)."),
|
|
235
|
+
rotate: z.boolean().optional().describe("true = generate and return a NEW key (invalidates the old one). false/omitted = reveal the current key."),
|
|
236
|
+
gateway: gatewayArg,
|
|
237
|
+
allowUnsafeGateway: allowUnsafeGatewayArg,
|
|
238
|
+
},
|
|
239
|
+
}, async ({ providerId, rotate, gateway, allowUnsafeGateway }) => {
|
|
240
|
+
try {
|
|
241
|
+
const account = requireUnlockedWallet();
|
|
242
|
+
const base = resolveGateway(gateway, allowUnsafeGateway ?? false);
|
|
243
|
+
const headers = signAuthHeaders(account, "reveal-key", providerId);
|
|
244
|
+
const { ok, status, body } = await gatewayFetch(`${base}/v1/providers/${providerId}/key`, {
|
|
245
|
+
method: "POST",
|
|
246
|
+
headers,
|
|
247
|
+
body: JSON.stringify(rotate ? { rotate: true } : {}),
|
|
248
|
+
});
|
|
249
|
+
return createJsonResponse({
|
|
250
|
+
success: ok,
|
|
251
|
+
status,
|
|
252
|
+
gateway: base,
|
|
253
|
+
result: body,
|
|
254
|
+
note: ok
|
|
255
|
+
? "Your endpoint must REQUIRE this key (proxy / Cloudflare Access) for it to prevent freeloading — an open endpoint ignores it."
|
|
256
|
+
: "Reveal/rotate failed — see result.error.",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
return createErrorResponse(error);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
// Re-run the health/functional probe — unsigned
|
|
264
|
+
server.registerTool("inference_check_provider", {
|
|
265
|
+
description: "Re-run the marketplace's health + functional probe for a provider on demand (checks the endpoint is reachable and " +
|
|
266
|
+
"actually returns a completion). No signature required. Useful right after (re)starting your node or tunnel.",
|
|
267
|
+
inputSchema: {
|
|
268
|
+
providerId: z.string().describe("The provider id to check."),
|
|
269
|
+
gateway: gatewayArg,
|
|
270
|
+
allowUnsafeGateway: allowUnsafeGatewayArg,
|
|
271
|
+
},
|
|
272
|
+
}, async ({ providerId, gateway, allowUnsafeGateway }) => {
|
|
273
|
+
try {
|
|
274
|
+
const base = resolveGateway(gateway, allowUnsafeGateway ?? false);
|
|
275
|
+
const { ok, status, body } = await gatewayFetch(`${base}/v1/providers/${providerId}/check`, {
|
|
276
|
+
method: "POST",
|
|
277
|
+
});
|
|
278
|
+
return createJsonResponse({ success: ok, status, gateway: base, result: body });
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
return createErrorResponse(error);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
// List registered providers — unsigned
|
|
285
|
+
server.registerTool("inference_list_providers", {
|
|
286
|
+
description: "List providers registered on the marketplace with their models, health/status, and flagged state. No signature " +
|
|
287
|
+
"required. Use it to find your provider id (match on payoutAddress) after registering.",
|
|
288
|
+
inputSchema: {
|
|
289
|
+
gateway: gatewayArg,
|
|
290
|
+
allowUnsafeGateway: allowUnsafeGatewayArg,
|
|
291
|
+
},
|
|
292
|
+
}, async ({ gateway, allowUnsafeGateway }) => {
|
|
293
|
+
try {
|
|
294
|
+
const base = resolveGateway(gateway, allowUnsafeGateway ?? false);
|
|
295
|
+
const { ok, status, body } = await gatewayFetch(`${base}/v1/providers`, { method: "GET" });
|
|
296
|
+
return createJsonResponse({ success: ok, status, gateway: base, result: body });
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
return createErrorResponse(error);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=inference-marketplace.tools.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aibtc/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.61.0",
|
|
4
4
|
"description": "Bitcoin-native MCP server for AI agents: BTC/STX wallets, DeFi yield, sBTC peg, NFTs, and x402 payments.",
|
|
5
5
|
"mcpName": "io.github.aibtcdev/mcp-server",
|
|
6
6
|
"type": "module",
|
package/skill/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Bitcoin L1 wallet for agents - check balances, send BTC, manage UTX
|
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: aibtcdev
|
|
7
|
-
version: 1.
|
|
7
|
+
version: 1.61.0 # x-release-please-version
|
|
8
8
|
npm: "@aibtc/mcp-server"
|
|
9
9
|
github: https://github.com/aibtcdev/aibtc-mcp-server
|
|
10
10
|
---
|
|
@@ -214,6 +214,33 @@ Always probe before executing paid endpoints. Never call `execute_x402_endpoint`
|
|
|
214
214
|
See: [references/stacks-defi.md](references/stacks-defi.md) for endpoint catalog
|
|
215
215
|
See: [references/x402-inbox.md](references/x402-inbox.md) for inbox-specific flow details
|
|
216
216
|
|
|
217
|
+
### Inference Marketplace (earn sBTC serving models)
|
|
218
|
+
|
|
219
|
+
List an OpenAI-compatible model endpoint on the AIBTC Inference Marketplace and
|
|
220
|
+
get paid per request in sBTC. Ownership is proven by a wallet signature — the
|
|
221
|
+
same wallet that receives payouts — so there are no accounts or API keys. The
|
|
222
|
+
tools sign locally with the unlocked wallet and call the gateway, so an agent can
|
|
223
|
+
register and manage a listing in one step.
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
"Register my endpoint https://my-host/v1 serving Qwen/Qwen2.5-7B-Instruct on the inference marketplace"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
| Tool | Description | Signed |
|
|
230
|
+
|------|-------------|:------:|
|
|
231
|
+
| `inference_register_provider` | Verify + list an endpoint (name, models, payout, optional apiKey) | ✅ |
|
|
232
|
+
| `inference_update_provider` | Change name/models/payout/endpoint/description/apiKey in place | ✅ |
|
|
233
|
+
| `inference_reveal_key` | Reveal or rotate the gateway↔endpoint shared key (`rotate: true`) | ✅ |
|
|
234
|
+
| `inference_check_provider` | Re-run the health/functional probe | — |
|
|
235
|
+
| `inference_list_providers` | List providers + health (find your id by `payoutAddress`) | — |
|
|
236
|
+
|
|
237
|
+
The gateway verifies the signature recovers to `payoutAddress` (which also fixes
|
|
238
|
+
the network), that the endpoint is reachable AND actually serving inference, and
|
|
239
|
+
that model ids are real, commercially-licensed Hugging Face repos. Requires an
|
|
240
|
+
unlocked wallet on the gateway's network. Every tool takes an optional `gateway`
|
|
241
|
+
arg (defaults to `https://inference.aibtc.com`; use `http://localhost:8787` for
|
|
242
|
+
local dev).
|
|
243
|
+
|
|
217
244
|
### Genesis Lifecycle
|
|
218
245
|
|
|
219
246
|
Agent identity and reputation on Bitcoin and Stacks:
|