cyberdyne-mcp 0.6.2 → 0.6.3
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/server.js +41 -49
- package/package.json +1 -1
- package/src/server.ts +41 -49
package/dist/server.js
CHANGED
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* get_deposit_address — GET /api/treasury/deposit → where to send real USDC (live)
|
|
14
14
|
* deposit — POST /api/treasury/deposit → credit treasury from a real USDC tx
|
|
15
15
|
* withdraw_treasury — POST /api/treasury/withdraw → pull unspent treasury back to your wallet (live)
|
|
16
|
-
* post_task — POST /api/tasks → open
|
|
17
|
-
*
|
|
18
|
-
* authorize_task — POST /api/tasks/[id]/authorize → open the escrow hold
|
|
16
|
+
* post_task — POST /api/tasks → open an FCFS pool bounty
|
|
17
|
+
* authorize_task — POST /api/tasks/[id]/authorize → sign budget + pay fee + freeze
|
|
19
18
|
* get_task — GET /api/tasks/[id] → status + submissions/claims
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* review_submission — POST /api/submissions/[id]/review → approve (pay one unit) / reject (reopen)
|
|
20
|
+
* close_task — POST /api/tasks/[id]/close → refund the unfilled budget
|
|
21
|
+
* assign_task — POST /api/tasks/[id]/assign → DEPRECATED (testnet-only; no direct hire)
|
|
22
|
+
* release_payment — POST /api/tasks/[id]/release → DEPRECATED (testnet-only; use review_submission)
|
|
23
23
|
*
|
|
24
24
|
* Auth: every networked tool sends the agent's `cyb_…` key. The REST routes take
|
|
25
25
|
* it as `Authorization: Bearer …`; search_humans goes through the a2a JSON-RPC
|
|
@@ -27,26 +27,24 @@
|
|
|
27
27
|
* `identity_token`.
|
|
28
28
|
*
|
|
29
29
|
* The HUMAN submit-proof step happens in the app/UI (human-only — agents cannot
|
|
30
|
-
* submit on a human's behalf). There
|
|
30
|
+
* submit on a human's behalf). There is ONE settlement model for real tokens:
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* →
|
|
32
|
+
* FCFS POOL BOUNTY (non-custodial pool escrow). There is NO direct hire and NO
|
|
33
|
+
* agent-picks-human. EVERY task is an open bounty: the agent freezes a budget once,
|
|
34
|
+
* ANY eligible human submits first-come-first-served, and the agent approves/rejects
|
|
35
|
+
* each submission — approved pays one unit in-token, rejected reopens the slot, and
|
|
36
|
+
* any unfilled budget is refunded on close.
|
|
37
|
+
* get_deposit_address → send USDC → deposit (optional, fund treasury)
|
|
38
|
+
* → post_task({ ..., quantity }) → returns { task, authIntent, deployFee }
|
|
39
|
+
* → authorize_task({ task_id, auth_intent, deploy_fee }) (sign budget + pay fee + freeze)
|
|
40
|
+
* → humans submit FCFS → poll get_task
|
|
41
|
+
* → review_submission per pending submission (approve → pay one unit;
|
|
42
|
+
* reject → the slot reopens)
|
|
43
|
+
* → close_task to refund the unfilled budget.
|
|
39
44
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* OFF today (server env ESCROW_POOL is not enabled), pending certification — so
|
|
44
|
-
* real-money non-custodial pool payouts are NOT live yet. When the server
|
|
45
|
-
* enables it, post_task returns an `authIntent` + a separate `deployFee`:
|
|
46
|
-
* post_task (quantity>1) → authorize_task (sign the budget + pay the deploy fee)
|
|
47
|
-
* → humans claim+submit FCFS → poll get_task
|
|
48
|
-
* → review_submission per pending submission (approve → capture one unit;
|
|
49
|
-
* reject → the slot reopens) → close_task to refund unfilled units.
|
|
45
|
+
* DEPRECATED (testnet-only): assign_task + release_payment were the old direct-hire
|
|
46
|
+
* path. There is no direct hire for real tokens — a real-token assign/release returns
|
|
47
|
+
* 409 direct_hire_retired. The tools remain only for the testnet/non-real demo rail.
|
|
50
48
|
*
|
|
51
49
|
* Config comes from the environment (see src/client.ts):
|
|
52
50
|
* CYBERDYNE_API_URL default "https://app.cyberdyne-os.xyz"
|
|
@@ -154,7 +152,7 @@ async function guard(fn) {
|
|
|
154
152
|
}
|
|
155
153
|
}
|
|
156
154
|
// ---- Server ---------------------------------------------------------------
|
|
157
|
-
const server = new McpServer({ name: "cyberdyne", version: "0.6.
|
|
155
|
+
const server = new McpServer({ name: "cyberdyne", version: "0.6.3" });
|
|
158
156
|
server.tool("list_categories", "List the kinds of real-world work CYBERDYNE humans can do. Static (no network). Use this to learn the valid `category` values before posting a task.", {}, async () => json(Object.entries(CATEGORIES).map(([id, blurb]) => ({ id, blurb }))));
|
|
159
157
|
server.tool("onboard", "BOOTSTRAP (works WITHOUT an existing key — the one tool that self-onboards). Zero-browser: generates a fresh wallet if you don't have one, signs in to CYBERDYNE with it (SIWE), mints your `cyb_` agent API key, and saves both to ~/.cyberdyne/config.json (0600) so every other tool here authenticates automatically. No web dashboard, no env vars. Returns your wallet address, the cyb_ key (shown once), and the next steps (fund via get_deposit_address+deposit → post_task → assign → authorize → release). The same generated wallet auto-signs pool budgets. Idempotent-ish: re-running with a saved wallet reuses it and mints a fresh key.", {}, async () => guard(async () => {
|
|
160
158
|
const r = await onboard();
|
|
@@ -189,7 +187,7 @@ server.tool("deposit", "Credit your treasury from a REAL on-chain USDC deposit (
|
|
|
189
187
|
.describe("The Base tx hash of your USDC transfer to the deposit address."),
|
|
190
188
|
}, async ({ tx_hash }) => guard(() => client.rest("POST", "/api/treasury/deposit", { body: { tx_hash } })));
|
|
191
189
|
server.tool("withdraw_treasury", "Recover UNSPENT treasury to your wallet (live rail): pull USDC out of your treasury back to your own VERIFIED deposit wallet on Base — no browser. Available balance is your treasury balance net of any open escrow holds. Funds can ONLY go to your verified wallet (no destination param), so a leaked key can't redirect them. Returns { ok, tx_hash, amount_usd, to }. 400 insufficient_treasury if the balance can't cover it; 403 withdraws_disabled on the demo rail.", { amount_usd: z.number().positive().describe("USD to withdraw from your treasury to your verified wallet.") }, async ({ amount_usd }) => guard(() => client.rest("POST", "/api/treasury/withdraw", { body: { amount_usd } })));
|
|
192
|
-
server.tool("post_task", "Open
|
|
190
|
+
server.tool("post_task", "Open an FCFS pool bounty on the marketplace. There is NO direct hire and NO agent-picks-human — every task is an open bounty: you freeze a budget, ANY eligible human submits first-come-first-served, and you approve/reject each submission. Funds are NOT charged at post — the budget is frozen later at authorize_task. `reward_usd` is the total budget; `quantity` is how many identical units (humans) it pays — each unit holds reward_usd/quantity (each unit must be >= $0.01). Returns the created task (with its id). REAL-TOKEN POOL rail (USDC/BNKR on Base): the response also includes `authIntent` (the budget authorization to sign) and `deployFee` { usd, bps, recipient, token } (a SEPARATE non-refundable fee tx) — pass BOTH to authorize_task. TESTNET/non-real token (CYOS): no on-chain freeze; response is just { task } (treasury-checked, 402 insufficient_treasury if low).", {
|
|
193
191
|
title: z.string().min(2).max(160).describe("Short task title."),
|
|
194
192
|
category: z.enum(TASK_CATEGORIES),
|
|
195
193
|
description: z.string().max(4000).optional().describe("What you need the human to do."),
|
|
@@ -201,11 +199,11 @@ server.tool("post_task", "Open a task on the marketplace. Funds are NOT charged
|
|
|
201
199
|
pay_token: z.enum(["USDC", "BNKR", "CYOS"]).optional().describe("Settlement token (default USDC)."),
|
|
202
200
|
deadline_hours: z.number().int().positive().optional(),
|
|
203
201
|
}, async (args) => guard(() => client.rest("POST", "/api/tasks", { body: args })));
|
|
204
|
-
server.tool("assign_task", "
|
|
202
|
+
server.tool("assign_task", "DEPRECATED — TESTNET/DEMO ONLY. There is NO direct hire: every real-token task is an open FCFS pool bounty, so a real-token assign returns 409 direct_hire_retired ('post with a budget; humans submit FCFS; review each submission'). Do NOT use this to hire — post_task + authorize_task + review_submission is the flow. This tool remains only for the testnet/non-real (CYOS) demo rail, where it assigns an open task to a chosen human and returns `{ task, authIntent: null }`.", {
|
|
205
203
|
task_id: z.string().uuid(),
|
|
206
204
|
human_id: z.string().uuid().describe("The human profile id (from search_humans / get_task claims)."),
|
|
207
205
|
}, async ({ task_id, human_id }) => guard(() => client.rest("POST", `/api/tasks/${task_id}/assign`, { body: { human_id } })));
|
|
208
|
-
server.tool("authorize_task", "
|
|
206
|
+
server.tool("authorize_task", "Freeze the bounty budget on-chain (the second step of the FCFS flow). REAL-TOKEN POOL rail: pass BOTH `auth_intent` (the authIntent from post_task) AND `deploy_fee` (the deployFee object from post_task) — with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the whole-budget authorization AND pays the separate 2.5% USDC / 5% other-token deploy fee tx from its wallet, then freezes the budget on the audited escrow; or pass a pre-signed `signed_payment` and a pre-paid `fee_tx_hash`. After this, any eligible human submits FCFS and you review_submission each. TESTNET/non-real (CYOS) rail: call with just { task_id } — the prefunded treasury opens a logical hold, no signature. Idempotent once frozen.", {
|
|
209
207
|
task_id: z.string().uuid(),
|
|
210
208
|
signed_payment: z.string().optional().describe("Pre-signed base64 auth-capture payload (external/Bankr signer)."),
|
|
211
209
|
auth_intent: z.unknown().optional().describe("The authIntent from assign_task/post — required for MCP wallet auto-signing."),
|
|
@@ -237,8 +235,8 @@ server.tool("authorize_task", "Open the escrow hold for a task. CUSTODIAL/MANUAL
|
|
|
237
235
|
},
|
|
238
236
|
});
|
|
239
237
|
}));
|
|
240
|
-
server.tool("get_task", "Get the live state of a task: the task row plus the submissions and per-unit claims the agent (as poster) may see. Poll this after authorize_task until a submission with status 'pending' appears — that is the human's proof, ready for
|
|
241
|
-
server.tool("release_payment", "
|
|
238
|
+
server.tool("get_task", "Get the live state of a task: the task row plus the submissions and per-unit claims the agent (as poster) may see. Poll this after authorize_task until a submission with status 'pending' appears — that is the human's proof, ready for review_submission (approve pays one unit; reject reopens the slot).", { task_id: z.string().uuid() }, async ({ task_id }) => guard(() => client.rest("GET", `/api/tasks/${task_id}`)));
|
|
239
|
+
server.tool("release_payment", "DEPRECATED — TESTNET/DEMO ONLY. There is NO direct hire: a real-token task is an FCFS pool bounty whose units settle ONE per approved submission, so a real-token release returns 409 direct_hire_retired — use review_submission instead (approve pays one unit, reject reopens the slot). This tool remains only for the testnet/non-real (CYOS) demo rail, where it settles a submitted proof for a single-human task: approve:true → pay net of fee, approve:false → reject/refund. `submission_id` auto-resolves to the latest pending one if omitted.", {
|
|
242
240
|
task_id: z.string().uuid(),
|
|
243
241
|
approve: z.boolean().describe("true = proof meets criteria → pay; false = reject/refund."),
|
|
244
242
|
submission_id: z
|
|
@@ -269,7 +267,7 @@ server.tool("release_payment", "DIRECT-HIRE settle (poster-only): settle a submi
|
|
|
269
267
|
},
|
|
270
268
|
});
|
|
271
269
|
}));
|
|
272
|
-
server.tool("review_submission", "
|
|
270
|
+
server.tool("review_submission", "THE settle tool (poster-only): approve or reject ONE submission on your FCFS pool bounty — this is how you pay humans (there is no direct hire). approve:true → CAPTURE one unit from the frozen budget to the human (full reward, in-token) and consume a slot; approve:false → reject (the slot reopens for the next submitter — no spot-blocking). Poll get_task for pending submissions and review each one. When the budget is consumed (or you're done) call close_task to refund the unfilled remainder.", {
|
|
273
271
|
submission_id: z.string().uuid().describe("The pending submission to review (from get_task)."),
|
|
274
272
|
approve: z.boolean().describe("true = proof meets criteria → capture one unit; false = reject (slot reopens)."),
|
|
275
273
|
score: z.number().int().min(1).max(5).optional().describe("Rating of the human's work (1–5)."),
|
|
@@ -283,14 +281,14 @@ server.tool("review_submission", "POOL / FCFS settle (poster-only): approve or r
|
|
|
283
281
|
...(reject_reason ? { reject_reason } : {}),
|
|
284
282
|
},
|
|
285
283
|
})));
|
|
286
|
-
server.tool("close_task", "Close
|
|
284
|
+
server.tool("close_task", "Close your FCFS pool bounty (poster-only): refund the unfilled budget back to your wallet on-chain (the uncaptured remainder = unfilled units × per-unit reward) and stop further submissions. The deploy fee is non-refundable. Idempotent on an already-closed task.", { task_id: z.string().uuid() }, async ({ task_id }) => guard(() => client.rest("POST", `/api/tasks/${task_id}/close`)));
|
|
287
285
|
// ---- Self-onboarding prompt -----------------------------------------------
|
|
288
286
|
// Surfaces as /mcp__cyberdyne__quickstart — the agent (or user) runs it once to
|
|
289
287
|
// learn the end-to-end campaign flow without reading docs. This is the "skill"
|
|
290
288
|
// shipped inside the MCP: guidance travels with the tools.
|
|
291
289
|
server.registerPrompt("quickstart", {
|
|
292
290
|
title: "CYBERDYNE quickstart",
|
|
293
|
-
description: "How to fund, post
|
|
291
|
+
description: "How to fund, post an FCFS pool bounty, and pay verified humans end-to-end.",
|
|
294
292
|
}, () => ({
|
|
295
293
|
messages: [
|
|
296
294
|
{
|
|
@@ -298,26 +296,20 @@ server.registerPrompt("quickstart", {
|
|
|
298
296
|
content: {
|
|
299
297
|
type: "text",
|
|
300
298
|
text: [
|
|
301
|
-
"You are connected to CYBERDYNE —
|
|
299
|
+
"You are connected to CYBERDYNE — pay verified humans for tasks AI can't do alone. There is ONE model: every task is an open FCFS pool bounty. There is NO direct hire and NO picking a human — you freeze a budget, ANY eligible human submits first-come-first-served, and you approve/reject each submission (approved = paid one unit in-token, rejected = the slot reopens). The live settlement rail is REAL tokens on Base (non-custodial freeze-at-deploy). The human submit-proof step is human-only, in the app; you drive everything else.",
|
|
302
300
|
"",
|
|
303
|
-
"FUND (
|
|
301
|
+
"FUND (optional — the pool freezes from your wallet at deploy, but a treasury can cover fees):",
|
|
304
302
|
"1. get_deposit_address -> the platform deposit address on Base.",
|
|
305
|
-
"2. Send USDC to it FROM your own verified wallet (
|
|
306
|
-
"
|
|
307
|
-
" (fund_treasury is demo/testnet only and is disabled on the live rail.)",
|
|
308
|
-
"Check get_treasury anytime for your balance.",
|
|
303
|
+
"2. Send USDC to it FROM your own verified wallet, then deposit({ tx_hash }) -> credits your treasury (idempotent).",
|
|
304
|
+
" (fund_treasury is demo/testnet only and is disabled on the live rail.) Check get_treasury anytime.",
|
|
309
305
|
"",
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"
|
|
306
|
+
"POST + PAY (the single FCFS flow):",
|
|
307
|
+
"3. post_task({ title, category, reward_usd, quantity, duration_min, difficulty }) -> returns { task, authIntent, deployFee }. reward_usd is the TOTAL budget; quantity is how many humans it pays (each unit must be >= $0.01). authIntent is the whole-budget authorization; deployFee is a SEPARATE non-refundable fee tx (2.5% USDC / 5% other token).",
|
|
308
|
+
"4. authorize_task({ task_id, auth_intent, deploy_fee }) -> with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the budget AND pays the deploy fee, then FREEZES the whole budget on the audited escrow (or pass pre-made signed_payment + fee_tx_hash).",
|
|
309
|
+
"5. Any eligible human submits FCFS. Poll get_task; for EACH pending submission call review_submission({ submission_id, approve, score }) -> approve captures one unit (full reward to the human, in-token); reject reopens the slot for the next submitter.",
|
|
310
|
+
"6. close_task({ task_id }) -> refunds the unfilled budget back to your wallet (the deploy fee is non-refundable).",
|
|
315
311
|
"",
|
|
316
|
-
"
|
|
317
|
-
"8. post_task({ ..., quantity: N }) -> returns { task, authIntent, deployFee }. authIntent is the budget authorization; deployFee is a SEPARATE non-refundable fee tx (2.5% USDC / 5% other token).",
|
|
318
|
-
"9. authorize_task({ task_id, auth_intent, deploy_fee }) -> with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the budget AND pays the deploy fee, then freezes the whole budget (or pass pre-made signed_payment + fee_tx_hash).",
|
|
319
|
-
"10. Humans claim+submit FCFS. Poll get_task; for each pending submission call review_submission({ submission_id, approve, score }) -> approve captures one unit; reject reopens the slot.",
|
|
320
|
-
"11. close_task({ task_id }) -> refund any still-unfilled units (the deploy fee is non-refundable).",
|
|
312
|
+
"DEPRECATED: assign_task + release_payment were the old direct-hire path and now return 409 direct_hire_retired for real tokens — use post_task + authorize_task + review_submission instead. They remain only for the testnet/non-real (CYOS) demo rail.",
|
|
321
313
|
"",
|
|
322
314
|
"Every payout and fee on the live rail is a real on-chain transaction.",
|
|
323
315
|
].join("\n"),
|
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* get_deposit_address — GET /api/treasury/deposit → where to send real USDC (live)
|
|
14
14
|
* deposit — POST /api/treasury/deposit → credit treasury from a real USDC tx
|
|
15
15
|
* withdraw_treasury — POST /api/treasury/withdraw → pull unspent treasury back to your wallet (live)
|
|
16
|
-
* post_task — POST /api/tasks → open
|
|
17
|
-
*
|
|
18
|
-
* authorize_task — POST /api/tasks/[id]/authorize → open the escrow hold
|
|
16
|
+
* post_task — POST /api/tasks → open an FCFS pool bounty
|
|
17
|
+
* authorize_task — POST /api/tasks/[id]/authorize → sign budget + pay fee + freeze
|
|
19
18
|
* get_task — GET /api/tasks/[id] → status + submissions/claims
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* review_submission — POST /api/submissions/[id]/review → approve (pay one unit) / reject (reopen)
|
|
20
|
+
* close_task — POST /api/tasks/[id]/close → refund the unfilled budget
|
|
21
|
+
* assign_task — POST /api/tasks/[id]/assign → DEPRECATED (testnet-only; no direct hire)
|
|
22
|
+
* release_payment — POST /api/tasks/[id]/release → DEPRECATED (testnet-only; use review_submission)
|
|
23
23
|
*
|
|
24
24
|
* Auth: every networked tool sends the agent's `cyb_…` key. The REST routes take
|
|
25
25
|
* it as `Authorization: Bearer …`; search_humans goes through the a2a JSON-RPC
|
|
@@ -27,26 +27,24 @@
|
|
|
27
27
|
* `identity_token`.
|
|
28
28
|
*
|
|
29
29
|
* The HUMAN submit-proof step happens in the app/UI (human-only — agents cannot
|
|
30
|
-
* submit on a human's behalf). There
|
|
30
|
+
* submit on a human's behalf). There is ONE settlement model for real tokens:
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* →
|
|
32
|
+
* FCFS POOL BOUNTY (non-custodial pool escrow). There is NO direct hire and NO
|
|
33
|
+
* agent-picks-human. EVERY task is an open bounty: the agent freezes a budget once,
|
|
34
|
+
* ANY eligible human submits first-come-first-served, and the agent approves/rejects
|
|
35
|
+
* each submission — approved pays one unit in-token, rejected reopens the slot, and
|
|
36
|
+
* any unfilled budget is refunded on close.
|
|
37
|
+
* get_deposit_address → send USDC → deposit (optional, fund treasury)
|
|
38
|
+
* → post_task({ ..., quantity }) → returns { task, authIntent, deployFee }
|
|
39
|
+
* → authorize_task({ task_id, auth_intent, deploy_fee }) (sign budget + pay fee + freeze)
|
|
40
|
+
* → humans submit FCFS → poll get_task
|
|
41
|
+
* → review_submission per pending submission (approve → pay one unit;
|
|
42
|
+
* reject → the slot reopens)
|
|
43
|
+
* → close_task to refund the unfilled budget.
|
|
39
44
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* OFF today (server env ESCROW_POOL is not enabled), pending certification — so
|
|
44
|
-
* real-money non-custodial pool payouts are NOT live yet. When the server
|
|
45
|
-
* enables it, post_task returns an `authIntent` + a separate `deployFee`:
|
|
46
|
-
* post_task (quantity>1) → authorize_task (sign the budget + pay the deploy fee)
|
|
47
|
-
* → humans claim+submit FCFS → poll get_task
|
|
48
|
-
* → review_submission per pending submission (approve → capture one unit;
|
|
49
|
-
* reject → the slot reopens) → close_task to refund unfilled units.
|
|
45
|
+
* DEPRECATED (testnet-only): assign_task + release_payment were the old direct-hire
|
|
46
|
+
* path. There is no direct hire for real tokens — a real-token assign/release returns
|
|
47
|
+
* 409 direct_hire_retired. The tools remain only for the testnet/non-real demo rail.
|
|
50
48
|
*
|
|
51
49
|
* Config comes from the environment (see src/client.ts):
|
|
52
50
|
* CYBERDYNE_API_URL default "https://app.cyberdyne-os.xyz"
|
|
@@ -166,7 +164,7 @@ async function guard<T>(fn: () => Promise<T>) {
|
|
|
166
164
|
|
|
167
165
|
// ---- Server ---------------------------------------------------------------
|
|
168
166
|
|
|
169
|
-
const server = new McpServer({ name: "cyberdyne", version: "0.6.
|
|
167
|
+
const server = new McpServer({ name: "cyberdyne", version: "0.6.3" });
|
|
170
168
|
|
|
171
169
|
server.tool(
|
|
172
170
|
"list_categories",
|
|
@@ -259,7 +257,7 @@ server.tool(
|
|
|
259
257
|
|
|
260
258
|
server.tool(
|
|
261
259
|
"post_task",
|
|
262
|
-
"Open
|
|
260
|
+
"Open an FCFS pool bounty on the marketplace. There is NO direct hire and NO agent-picks-human — every task is an open bounty: you freeze a budget, ANY eligible human submits first-come-first-served, and you approve/reject each submission. Funds are NOT charged at post — the budget is frozen later at authorize_task. `reward_usd` is the total budget; `quantity` is how many identical units (humans) it pays — each unit holds reward_usd/quantity (each unit must be >= $0.01). Returns the created task (with its id). REAL-TOKEN POOL rail (USDC/BNKR on Base): the response also includes `authIntent` (the budget authorization to sign) and `deployFee` { usd, bps, recipient, token } (a SEPARATE non-refundable fee tx) — pass BOTH to authorize_task. TESTNET/non-real token (CYOS): no on-chain freeze; response is just { task } (treasury-checked, 402 insufficient_treasury if low).",
|
|
263
261
|
{
|
|
264
262
|
title: z.string().min(2).max(160).describe("Short task title."),
|
|
265
263
|
category: z.enum(TASK_CATEGORIES),
|
|
@@ -277,7 +275,7 @@ server.tool(
|
|
|
277
275
|
|
|
278
276
|
server.tool(
|
|
279
277
|
"assign_task",
|
|
280
|
-
"
|
|
278
|
+
"DEPRECATED — TESTNET/DEMO ONLY. There is NO direct hire: every real-token task is an open FCFS pool bounty, so a real-token assign returns 409 direct_hire_retired ('post with a budget; humans submit FCFS; review each submission'). Do NOT use this to hire — post_task + authorize_task + review_submission is the flow. This tool remains only for the testnet/non-real (CYOS) demo rail, where it assigns an open task to a chosen human and returns `{ task, authIntent: null }`.",
|
|
281
279
|
{
|
|
282
280
|
task_id: z.string().uuid(),
|
|
283
281
|
human_id: z.string().uuid().describe("The human profile id (from search_humans / get_task claims)."),
|
|
@@ -288,7 +286,7 @@ server.tool(
|
|
|
288
286
|
|
|
289
287
|
server.tool(
|
|
290
288
|
"authorize_task",
|
|
291
|
-
"
|
|
289
|
+
"Freeze the bounty budget on-chain (the second step of the FCFS flow). REAL-TOKEN POOL rail: pass BOTH `auth_intent` (the authIntent from post_task) AND `deploy_fee` (the deployFee object from post_task) — with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the whole-budget authorization AND pays the separate 2.5% USDC / 5% other-token deploy fee tx from its wallet, then freezes the budget on the audited escrow; or pass a pre-signed `signed_payment` and a pre-paid `fee_tx_hash`. After this, any eligible human submits FCFS and you review_submission each. TESTNET/non-real (CYOS) rail: call with just { task_id } — the prefunded treasury opens a logical hold, no signature. Idempotent once frozen.",
|
|
292
290
|
{
|
|
293
291
|
task_id: z.string().uuid(),
|
|
294
292
|
signed_payment: z.string().optional().describe("Pre-signed base64 auth-capture payload (external/Bankr signer)."),
|
|
@@ -327,14 +325,14 @@ server.tool(
|
|
|
327
325
|
|
|
328
326
|
server.tool(
|
|
329
327
|
"get_task",
|
|
330
|
-
"Get the live state of a task: the task row plus the submissions and per-unit claims the agent (as poster) may see. Poll this after authorize_task until a submission with status 'pending' appears — that is the human's proof, ready for
|
|
328
|
+
"Get the live state of a task: the task row plus the submissions and per-unit claims the agent (as poster) may see. Poll this after authorize_task until a submission with status 'pending' appears — that is the human's proof, ready for review_submission (approve pays one unit; reject reopens the slot).",
|
|
331
329
|
{ task_id: z.string().uuid() },
|
|
332
330
|
async ({ task_id }) => guard(() => client.rest("GET", `/api/tasks/${task_id}`)),
|
|
333
331
|
);
|
|
334
332
|
|
|
335
333
|
server.tool(
|
|
336
334
|
"release_payment",
|
|
337
|
-
"
|
|
335
|
+
"DEPRECATED — TESTNET/DEMO ONLY. There is NO direct hire: a real-token task is an FCFS pool bounty whose units settle ONE per approved submission, so a real-token release returns 409 direct_hire_retired — use review_submission instead (approve pays one unit, reject reopens the slot). This tool remains only for the testnet/non-real (CYOS) demo rail, where it settles a submitted proof for a single-human task: approve:true → pay net of fee, approve:false → reject/refund. `submission_id` auto-resolves to the latest pending one if omitted.",
|
|
338
336
|
{
|
|
339
337
|
task_id: z.string().uuid(),
|
|
340
338
|
approve: z.boolean().describe("true = proof meets criteria → pay; false = reject/refund."),
|
|
@@ -379,7 +377,7 @@ server.tool(
|
|
|
379
377
|
|
|
380
378
|
server.tool(
|
|
381
379
|
"review_submission",
|
|
382
|
-
"
|
|
380
|
+
"THE settle tool (poster-only): approve or reject ONE submission on your FCFS pool bounty — this is how you pay humans (there is no direct hire). approve:true → CAPTURE one unit from the frozen budget to the human (full reward, in-token) and consume a slot; approve:false → reject (the slot reopens for the next submitter — no spot-blocking). Poll get_task for pending submissions and review each one. When the budget is consumed (or you're done) call close_task to refund the unfilled remainder.",
|
|
383
381
|
{
|
|
384
382
|
submission_id: z.string().uuid().describe("The pending submission to review (from get_task)."),
|
|
385
383
|
approve: z.boolean().describe("true = proof meets criteria → capture one unit; false = reject (slot reopens)."),
|
|
@@ -402,7 +400,7 @@ server.tool(
|
|
|
402
400
|
|
|
403
401
|
server.tool(
|
|
404
402
|
"close_task",
|
|
405
|
-
"Close
|
|
403
|
+
"Close your FCFS pool bounty (poster-only): refund the unfilled budget back to your wallet on-chain (the uncaptured remainder = unfilled units × per-unit reward) and stop further submissions. The deploy fee is non-refundable. Idempotent on an already-closed task.",
|
|
406
404
|
{ task_id: z.string().uuid() },
|
|
407
405
|
async ({ task_id }) => guard(() => client.rest("POST", `/api/tasks/${task_id}/close`)),
|
|
408
406
|
);
|
|
@@ -415,7 +413,7 @@ server.registerPrompt(
|
|
|
415
413
|
"quickstart",
|
|
416
414
|
{
|
|
417
415
|
title: "CYBERDYNE quickstart",
|
|
418
|
-
description: "How to fund, post
|
|
416
|
+
description: "How to fund, post an FCFS pool bounty, and pay verified humans end-to-end.",
|
|
419
417
|
},
|
|
420
418
|
() => ({
|
|
421
419
|
messages: [
|
|
@@ -424,26 +422,20 @@ server.registerPrompt(
|
|
|
424
422
|
content: {
|
|
425
423
|
type: "text",
|
|
426
424
|
text: [
|
|
427
|
-
"You are connected to CYBERDYNE —
|
|
425
|
+
"You are connected to CYBERDYNE — pay verified humans for tasks AI can't do alone. There is ONE model: every task is an open FCFS pool bounty. There is NO direct hire and NO picking a human — you freeze a budget, ANY eligible human submits first-come-first-served, and you approve/reject each submission (approved = paid one unit in-token, rejected = the slot reopens). The live settlement rail is REAL tokens on Base (non-custodial freeze-at-deploy). The human submit-proof step is human-only, in the app; you drive everything else.",
|
|
428
426
|
"",
|
|
429
|
-
"FUND (
|
|
427
|
+
"FUND (optional — the pool freezes from your wallet at deploy, but a treasury can cover fees):",
|
|
430
428
|
"1. get_deposit_address -> the platform deposit address on Base.",
|
|
431
|
-
"2. Send USDC to it FROM your own verified wallet (
|
|
432
|
-
"
|
|
433
|
-
" (fund_treasury is demo/testnet only and is disabled on the live rail.)",
|
|
434
|
-
"Check get_treasury anytime for your balance.",
|
|
429
|
+
"2. Send USDC to it FROM your own verified wallet, then deposit({ tx_hash }) -> credits your treasury (idempotent).",
|
|
430
|
+
" (fund_treasury is demo/testnet only and is disabled on the live rail.) Check get_treasury anytime.",
|
|
435
431
|
"",
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
440
|
-
"
|
|
432
|
+
"POST + PAY (the single FCFS flow):",
|
|
433
|
+
"3. post_task({ title, category, reward_usd, quantity, duration_min, difficulty }) -> returns { task, authIntent, deployFee }. reward_usd is the TOTAL budget; quantity is how many humans it pays (each unit must be >= $0.01). authIntent is the whole-budget authorization; deployFee is a SEPARATE non-refundable fee tx (2.5% USDC / 5% other token).",
|
|
434
|
+
"4. authorize_task({ task_id, auth_intent, deploy_fee }) -> with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the budget AND pays the deploy fee, then FREEZES the whole budget on the audited escrow (or pass pre-made signed_payment + fee_tx_hash).",
|
|
435
|
+
"5. Any eligible human submits FCFS. Poll get_task; for EACH pending submission call review_submission({ submission_id, approve, score }) -> approve captures one unit (full reward to the human, in-token); reject reopens the slot for the next submitter.",
|
|
436
|
+
"6. close_task({ task_id }) -> refunds the unfilled budget back to your wallet (the deploy fee is non-refundable).",
|
|
441
437
|
"",
|
|
442
|
-
"
|
|
443
|
-
"8. post_task({ ..., quantity: N }) -> returns { task, authIntent, deployFee }. authIntent is the budget authorization; deployFee is a SEPARATE non-refundable fee tx (2.5% USDC / 5% other token).",
|
|
444
|
-
"9. authorize_task({ task_id, auth_intent, deploy_fee }) -> with CYBERDYNE_EVM_PRIVATE_KEY set, the MCP signs the budget AND pays the deploy fee, then freezes the whole budget (or pass pre-made signed_payment + fee_tx_hash).",
|
|
445
|
-
"10. Humans claim+submit FCFS. Poll get_task; for each pending submission call review_submission({ submission_id, approve, score }) -> approve captures one unit; reject reopens the slot.",
|
|
446
|
-
"11. close_task({ task_id }) -> refund any still-unfilled units (the deploy fee is non-refundable).",
|
|
438
|
+
"DEPRECATED: assign_task + release_payment were the old direct-hire path and now return 409 direct_hire_retired for real tokens — use post_task + authorize_task + review_submission instead. They remain only for the testnet/non-real (CYOS) demo rail.",
|
|
447
439
|
"",
|
|
448
440
|
"Every payout and fee on the live rail is a real on-chain transaction.",
|
|
449
441
|
].join("\n"),
|