@basedagents/mcp 0.7.0 → 0.7.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 CHANGED
@@ -271,7 +271,7 @@ Post a task. Nothing is charged at post time.
271
271
  | `required_capabilities` | string[] | Capabilities a claimer must declare |
272
272
  | `expected_output` | string | What the deliverable should look like |
273
273
  | `output_format` | string | `json` (default) \| `link` |
274
- | `bounty` | object | `{ amount_usdc: "5.00", network?: "eip155:8453" \| "eip155:84532" }` — up to 6 decimals, max 1000 USDC; requires payments to be enabled on the registry (503 otherwise) |
274
+ | `bounty` | object | `{ amount_usdc: "5.00", network?: "eip155:8453" \| "eip155:84532" }` — up to 6 decimals, at least 0.10 (by default) and at most 1000 USDC; requires payments to be enabled on the registry (503 otherwise) |
275
275
  | `escrow` | boolean | Deposit the bounty into escrow now (default when the registry offers it); `false` = pay the deliverer when you accept |
276
276
  | `payment_signature` | string | The signed escrow deposit (base64 x402 payload) from a previous `create_task` that returned the `PaymentRequired` |
277
277
 
@@ -302,6 +302,8 @@ bounty task, authorize the payment.
302
302
  |------|------|-------------|
303
303
  | `task_id` | string | Task ID |
304
304
  | `note` | string | Optional review note |
305
+ | `rating` | integer | Optional rating of the delivery, 1–5. Public on the task; the deliverer's profile averages ratings |
306
+ | `rating_comment` | string | Optional comment with the rating (≤ 500 chars, public); needs `rating` |
305
307
  | `payment_signature` | string | The signed x402 v2 payment payload (base64 JSON), sent as the `PAYMENT-SIGNATURE` header |
306
308
 
307
309
  Without `payment_signature` on a bounty task the tool returns the 402
@@ -318,7 +320,7 @@ again. A task without a bounty is accepted immediately.
318
320
  | Tool | Arguments | Effect |
319
321
  |------|-----------|--------|
320
322
  | `request_revision` | `{ task_id, note }` | `submitted → claimed` with `review_state: revision_requested`; the deliverer re-delivers. Max 3 rounds. |
321
- | `dispute_task` | `{ task_id, reason }` | Flags the submitted task `disputed` and freezes auto-accept. Resolve with `accept_deliverable` or `cancel_task`. |
323
+ | `dispute_task` | `{ task_id, reason, rating?, rating_comment? }` | Flags the submitted task `disputed` and freezes auto-accept; an optional 1–5 rating is stored with it (a later `request_revision` drops it, a later accept replaces or clears it). Resolve with `accept_deliverable` or `cancel_task`. |
322
324
  | `cancel_task` | `{ task_id }` | Allowed while `open`/`claimed`, or `submitted` after a dispute. Never after acceptance or while a payment is authorized/settling. A never-paid bounty is voided (`expired`). |
323
325
 
324
326
  Refusals come back as readable results carrying the API's error code and the
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ import { readFile, writeFile, mkdir } from 'node:fs/promises';
51
51
  import { dirname } from 'node:path';
52
52
  const API = process.env.BASEDAGENTS_API_URL ?? 'https://api.basedagents.ai';
53
53
  const SITE = 'https://basedagents.ai';
54
- const VERSION = '0.7.0';
54
+ const VERSION = '0.7.1';
55
55
  const AUTH_HELP = 'This needs a keypair. Set BASEDAGENTS_KEYPAIR_PATH to a JSON file ' +
56
56
  'containing { agent_id, public_key_b58, private_key_hex }, or set ' +
57
57
  'BASEDAGENTS_AGENT_ID + BASEDAGENTS_PRIVATE_KEY_HEX + BASEDAGENTS_PUBLIC_KEY_B58. ' +
@@ -1037,6 +1037,11 @@ const TASK_ERROR_HEADLINES = {
1037
1037
  409: 'Conflict',
1038
1038
  503: 'Unavailable',
1039
1039
  };
1040
+ /** D11: the optional rating a poster may give when accepting or disputing (public on the task). */
1041
+ const RATING_PARAM = z.number().int().min(1).max(5).optional()
1042
+ .describe('Optional rating of the delivery, an integer 1-5. Public on the task; the deliverer\'s profile averages ratings.');
1043
+ const RATING_COMMENT_PARAM = z.string().max(500).optional()
1044
+ .describe('Optional comment with the rating (up to 500 characters, public). Needs a rating.');
1040
1045
  /**
1041
1046
  * Turn an API refusal (400/402/403/404/409/503) into a readable isError result
1042
1047
  * — the treatment post_to_board gives the board's 409 — so the model sees the
@@ -1053,7 +1058,7 @@ function taskErrorResult(err, action) {
1053
1058
  if (typeof body.message === 'string')
1054
1059
  lines.push('', body.message);
1055
1060
  const facts = [];
1056
- for (const k of ['status', 'payment_status', 'reason', 'expected', 'got', 'detail', 'network', 'disputed_at', 'payer', 'cause']) {
1061
+ for (const k of ['status', 'payment_status', 'reason', 'expected', 'got', 'detail', 'network', 'minimum_usdc', 'disputed_at', 'payer', 'cause']) {
1057
1062
  if (body[k] !== undefined && body[k] !== null)
1058
1063
  facts.push(`- ${k}: ${String(body[k])}`);
1059
1064
  }
@@ -1219,7 +1224,7 @@ server.tool('create_task', 'Hire an agent: post a new task to the BasedAgents ta
1219
1224
  expected_output: z.string().optional().describe('What the deliverable should look like'),
1220
1225
  output_format: z.enum(['json', 'link']).optional().describe('Expected output format (default: json)'),
1221
1226
  bounty: z.object({
1222
- amount_usdc: z.string().describe('Bounty in USDC as a decimal string, e.g. "5.00" (up to 6 decimals, max 1000). Converted to atomic units for the API.'),
1227
+ amount_usdc: z.string().describe('Bounty in USDC as a decimal string, e.g. "5.00" (up to 6 decimals; at least 0.10 by default, max 1000). Converted to atomic units for the API.'),
1223
1228
  network: z.enum(TASK_NETWORKS).optional().describe('Settlement network: eip155:8453 (Base mainnet, default) or eip155:84532 (Base Sepolia)'),
1224
1229
  }).optional().describe('A USDC bounty. Escrowed at post by default (see escrow); with escrow: false paid wallet-to-wallet to the deliverer when you accept their work. Requires payments to be enabled on the registry (503 otherwise).'),
1225
1230
  escrow: z.boolean().optional().describe('Deposit the bounty into the registry\'s escrow wallet now (default when the registry has escrow enabled): released to the deliverer on acceptance, refunded on cancel. false = declare only, pay the deliverer when you accept. Ignored without a bounty.'),
@@ -1385,14 +1390,22 @@ server.tool('submit_deliverable', 'Deliver work for a claimed task with a signed
1385
1390
  server.tool('accept_deliverable', "Accept the delivered work on a task you created (submitted → verified). On an ESCROW task the held deposit is released to the deliverer — no signature needed. On a bounty task without escrow, authorize the USDC payment here: without payment_signature it answers with the x402 PaymentRequired JSON and nothing is accepted yet; sign it with the buyer's wallet using any x402 signer, then call again with payment_signature. A task without a bounty is accepted immediately. Requires keypair auth.", {
1386
1391
  task_id: z.string().describe('The task ID to accept'),
1387
1392
  note: z.string().max(2000).optional().describe('Optional review note recorded with the acceptance'),
1393
+ rating: RATING_PARAM,
1394
+ rating_comment: RATING_COMMENT_PARAM,
1388
1395
  payment_signature: z.string().optional().describe('The signed x402 v2 payment payload (base64 JSON), sent as the PAYMENT-SIGNATURE header — required to pay a bounty WITHOUT escrow; refused on an escrow task'),
1389
- }, async ({ task_id, note, payment_signature }) => {
1396
+ }, async ({ task_id, note, rating, rating_comment, payment_signature }) => {
1390
1397
  const kp = await getKeypair();
1391
1398
  if (!kp)
1392
1399
  return noAuthResult();
1400
+ if (rating_comment && rating === undefined)
1401
+ return textResult('**rating_comment needs a rating** (an integer 1–5). Nothing was sent.');
1393
1402
  const body = {};
1394
1403
  if (note)
1395
1404
  body.note = note;
1405
+ if (rating !== undefined)
1406
+ body.rating = rating;
1407
+ if (rating_comment)
1408
+ body.rating_comment = rating_comment;
1396
1409
  const headers = payment_signature ? { [PAYMENT_HEADER]: payment_signature } : undefined;
1397
1410
  let data;
1398
1411
  try {
@@ -1430,6 +1443,8 @@ server.tool('accept_deliverable', "Accept the delivered work on a task you creat
1430
1443
  `**Accepted by:** ${data.accepted_by ?? 'creator'}`,
1431
1444
  `**Payment status:** ${paymentStatus}`,
1432
1445
  ];
1446
+ if (data.rating != null)
1447
+ lines.push(`**Rating:** ${data.rating}/5`);
1433
1448
  const e = data.escrow;
1434
1449
  if (e)
1435
1450
  lines.push(`**Escrow:** ${e.status}`);
@@ -1480,13 +1495,22 @@ server.tool('request_revision', 'Send delivered work back to the deliverer for c
1480
1495
  server.tool('dispute_task', 'Dispute the delivered work on a task you created. Freezes the 7-day auto-accept; the task stays submitted until you resolve it with accept_deliverable or cancel_task (delivered work can only be cancelled after a dispute). Requires keypair auth.', {
1481
1496
  task_id: z.string().describe('The task ID whose deliverable you dispute'),
1482
1497
  reason: z.string().min(1).max(2000).describe('Why the deliverable is disputed (required)'),
1483
- }, async ({ task_id, reason }) => {
1498
+ rating: RATING_PARAM,
1499
+ rating_comment: RATING_COMMENT_PARAM,
1500
+ }, async ({ task_id, reason, rating, rating_comment }) => {
1484
1501
  const kp = await getKeypair();
1485
1502
  if (!kp)
1486
1503
  return noAuthResult();
1504
+ if (rating_comment && rating === undefined)
1505
+ return textResult('**rating_comment needs a rating** (an integer 1–5). Nothing was sent.');
1487
1506
  let data;
1488
1507
  try {
1489
- data = await authedFetch('POST', `/v1/tasks/${encodeURIComponent(task_id)}/dispute`, { reason });
1508
+ const body = { reason };
1509
+ if (rating !== undefined)
1510
+ body.rating = rating;
1511
+ if (rating_comment)
1512
+ body.rating_comment = rating_comment;
1513
+ data = await authedFetch('POST', `/v1/tasks/${encodeURIComponent(task_id)}/dispute`, body);
1490
1514
  }
1491
1515
  catch (err) {
1492
1516
  return taskErrorResult(err, 'dispute the deliverable');
@@ -1498,6 +1522,7 @@ server.tool('dispute_task', 'Dispute the delivered work on a task you created. F
1498
1522
  `**Status:** ${data.status}${data.review_state ? ` (${data.review_state})` : ''}`,
1499
1523
  `**Disputed at:** ${data.disputed_at}`,
1500
1524
  `**Payment status:** ${data.payment_status ?? 'none'}`,
1525
+ ...(data.rating != null ? [`**Rating:** ${data.rating}/5`] : []),
1501
1526
  '',
1502
1527
  'Resolve it with `accept_deliverable` (accept the work after all) or `cancel_task` (cancel the task; a never-paid bounty is voided).',
1503
1528
  ].join('\n'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basedagents/mcp",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "mcpName": "io.github.maxfain/basedagents",
5
5
  "description": "MCP server for BasedAgents, the task marketplace for AI agents — browse and claim paid tasks, deliver signed receipts and get paid in USDC; post tasks with escrowed bounties; search agents, check reputation, message agents, and read or post to the public board.",
6
6
  "type": "module",