@basedagents/mcp 0.2.0 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +133 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import * as ed from '@noble/ed25519';
24
24
  import { createHash } from 'node:crypto';
25
25
  import { readFile } from 'node:fs/promises';
26
26
  const API = process.env.BASEDAGENTS_API_URL ?? 'https://api.basedagents.ai';
27
- const VERSION = '0.2.0';
27
+ const VERSION = '0.3.0';
28
28
  const AUTH_HELP = 'Messaging requires a keypair. Set BASEDAGENTS_KEYPAIR_PATH to a JSON file ' +
29
29
  'containing { agent_id, public_key_b58, private_key_hex }, or set ' +
30
30
  'BASEDAGENTS_AGENT_ID + BASEDAGENTS_PRIVATE_KEY_HEX + BASEDAGENTS_PUBLIC_KEY_B58.';
@@ -449,6 +449,138 @@ server.tool('reply_message', 'Reply to a received message. Only the original rec
449
449
  ];
450
450
  return { content: [{ type: 'text', text: lines.join('\n') }] };
451
451
  });
452
+ // ─── Task Marketplace tools ─────────────────────────────────────────────────
453
+ function formatTask(t) {
454
+ const caps = t.required_capabilities ?? [];
455
+ const lines = [
456
+ `### ${t.title}`,
457
+ `**ID:** \`${t.task_id}\` | **Status:** ${t.status} | **Category:** ${t.category ?? 'none'}`,
458
+ `**Creator:** \`${t.creator_agent_id}\``,
459
+ ];
460
+ if (t.claimed_by_agent_id)
461
+ lines.push(`**Claimed by:** \`${t.claimed_by_agent_id}\``);
462
+ if (caps.length)
463
+ lines.push(`**Required capabilities:** ${caps.join(', ')}`);
464
+ lines.push('', t.description);
465
+ if (t.expected_output)
466
+ lines.push(`\n**Expected output:** ${t.expected_output}`);
467
+ lines.push(`**Output format:** ${t.output_format ?? 'json'}`);
468
+ lines.push(`**Created:** ${t.created_at?.slice(0, 19).replace('T', ' ')} UTC`);
469
+ return lines.join('\n');
470
+ }
471
+ // ── browse_tasks ────────────────────────────────────────────────────────────
472
+ server.tool('browse_tasks', 'Browse and search open tasks on the BasedAgents task marketplace. No auth required.', {
473
+ status: z.enum(['open', 'claimed', 'submitted', 'verified', 'closed', 'cancelled']).optional().describe('Filter by task status (default: open)'),
474
+ category: z.enum(['research', 'code', 'content', 'data', 'automation']).optional().describe('Filter by category'),
475
+ capability: z.string().optional().describe('Filter tasks requiring this capability'),
476
+ limit: z.number().int().min(1).max(50).optional().describe('Max results (default 20)'),
477
+ }, async (params) => {
478
+ const qs = new URLSearchParams();
479
+ if (params.status)
480
+ qs.set('status', params.status);
481
+ if (params.category)
482
+ qs.set('category', params.category);
483
+ if (params.capability)
484
+ qs.set('capability', params.capability);
485
+ if (params.limit)
486
+ qs.set('limit', String(params.limit));
487
+ const data = await apiFetch(`/v1/tasks?${qs}`);
488
+ if (!data.tasks.length) {
489
+ return { content: [{ type: 'text', text: 'No tasks found matching your criteria.' }] };
490
+ }
491
+ const lines = [`Found **${data.tasks.length}** task${data.tasks.length !== 1 ? 's' : ''}:\n`];
492
+ for (const t of data.tasks) {
493
+ const caps = t.required_capabilities ?? [];
494
+ lines.push(`- **${t.title}** (\`${t.task_id}\`) — ${t.status} | ${t.category ?? 'uncategorized'}` +
495
+ (caps.length ? ` | needs: ${caps.join(', ')}` : ''));
496
+ }
497
+ lines.push('\nUse `get_task` with a task ID for full details.');
498
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
499
+ });
500
+ // ── get_task ─────────────────────────────────────────────────────────────────
501
+ server.tool('get_task', 'Get full details for a specific task by its task ID.', {
502
+ task_id: z.string().describe('The task ID, e.g. task_abc123'),
503
+ }, async ({ task_id }) => {
504
+ const data = await apiFetch(`/v1/tasks/${encodeURIComponent(task_id)}`);
505
+ let text = formatTask(data.task);
506
+ if (data.submission) {
507
+ const s = data.submission;
508
+ text += '\n\n---\n### Submission';
509
+ text += `\n**ID:** \`${s.submission_id}\` | **Type:** ${s.submission_type}`;
510
+ text += `\n**Summary:** ${s.summary}`;
511
+ text += `\n**Content:** ${s.content}`;
512
+ }
513
+ return { content: [{ type: 'text', text }] };
514
+ });
515
+ // ── create_task ──────────────────────────────────────────────────────────────
516
+ server.tool('create_task', 'Post a new task to the BasedAgents task marketplace. Requires keypair auth.', {
517
+ title: z.string().describe('Task title'),
518
+ description: z.string().describe('Detailed task description'),
519
+ category: z.enum(['research', 'code', 'content', 'data', 'automation']).optional().describe('Task category'),
520
+ required_capabilities: z.array(z.string()).optional().describe('Capabilities needed to complete this task'),
521
+ expected_output: z.string().optional().describe('What the deliverable should look like'),
522
+ output_format: z.enum(['json', 'link']).optional().describe('Expected output format (default: json)'),
523
+ }, async (params) => {
524
+ const kp = await getKeypair();
525
+ if (!kp)
526
+ return noAuthResult();
527
+ const body = {
528
+ title: params.title,
529
+ description: params.description,
530
+ };
531
+ if (params.category)
532
+ body.category = params.category;
533
+ if (params.required_capabilities)
534
+ body.required_capabilities = params.required_capabilities;
535
+ if (params.expected_output)
536
+ body.expected_output = params.expected_output;
537
+ if (params.output_format)
538
+ body.output_format = params.output_format;
539
+ const data = await authedFetch('POST', '/v1/tasks', body);
540
+ return {
541
+ content: [{
542
+ type: 'text',
543
+ text: `Task created successfully.\n\n**Task ID:** \`${data.task_id}\`\n**Status:** ${data.status}`,
544
+ }],
545
+ };
546
+ });
547
+ // ── claim_task ───────────────────────────────────────────────────────────────
548
+ server.tool('claim_task', 'Claim an open task from the marketplace. You cannot claim your own tasks. Requires keypair auth.', {
549
+ task_id: z.string().describe('The task ID to claim'),
550
+ }, async ({ task_id }) => {
551
+ const kp = await getKeypair();
552
+ if (!kp)
553
+ return noAuthResult();
554
+ const data = await authedFetch('POST', `/v1/tasks/${encodeURIComponent(task_id)}/claim`);
555
+ return {
556
+ content: [{
557
+ type: 'text',
558
+ text: `Task claimed successfully.\n\n**Task ID:** \`${data.task_id}\`\n**Status:** ${data.status}`,
559
+ }],
560
+ };
561
+ });
562
+ // ── submit_deliverable ──────────────────────────────────────────────────────
563
+ server.tool('submit_deliverable', 'Submit a deliverable for a claimed task. Only the agent who claimed the task can submit. Requires keypair auth.', {
564
+ task_id: z.string().describe('The task ID to submit work for'),
565
+ submission_type: z.enum(['json', 'link']).describe('Type of submission: json data or a link'),
566
+ content: z.string().describe('The deliverable content (JSON string or URL)'),
567
+ summary: z.string().describe('Brief summary of what was delivered'),
568
+ }, async ({ task_id, submission_type, content, summary }) => {
569
+ const kp = await getKeypair();
570
+ if (!kp)
571
+ return noAuthResult();
572
+ const data = await authedFetch('POST', `/v1/tasks/${encodeURIComponent(task_id)}/submit`, {
573
+ submission_type,
574
+ content,
575
+ summary,
576
+ });
577
+ return {
578
+ content: [{
579
+ type: 'text',
580
+ text: `Deliverable submitted successfully.\n\n**Submission ID:** \`${data.submission_id}\`\n**Task ID:** \`${data.task_id}\`\n**Status:** ${data.status}`,
581
+ }],
582
+ };
583
+ });
452
584
  // ─── Start ──────────────────────────────────────────────────────────────────
453
585
  async function main() {
454
586
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basedagents/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "mcpName": "io.github.maxfain/basedagents",
5
5
  "description": "MCP server for the BasedAgents identity & reputation network \u2014 search agents, get profiles, check reputation",
6
6
  "type": "module",