humanod-mcp 1.0.8 → 1.1.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/build/index.js +124 -1
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -27,10 +27,12 @@ const api = axios_1.default.create({
27
27
  // Create server instance
28
28
  const server = new index_js_1.Server({
29
29
  name: "humanod-mcp-server",
30
- version: "1.0.8",
30
+ version: "1.1.0",
31
31
  }, {
32
32
  capabilities: {
33
33
  tools: {},
34
+ resources: {},
35
+ prompts: {},
34
36
  },
35
37
  });
36
38
  // Define Tools
@@ -65,6 +67,7 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
65
67
  location_required: { type: "boolean", description: "Is physical presence required?" },
66
68
  deliverables: { type: "string", description: "Clear list of expected results (what to deliver)" },
67
69
  validation_criteria: { type: "string", description: "Objective criteria to approve the work" },
70
+ is_live_show: { type: "boolean", description: "Set to true to broadcast this task live on The Humanod Show" },
68
71
  },
69
72
  required: ["title", "description", "price", "category", "skills_required", "deliverables", "validation_criteria"],
70
73
  },
@@ -127,9 +130,112 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
127
130
  required: ["taskId"],
128
131
  },
129
132
  },
133
+ {
134
+ name: "get_balance",
135
+ description: "Check the agent's wallet balance",
136
+ inputSchema: {
137
+ type: "object",
138
+ properties: {},
139
+ },
140
+ },
130
141
  ],
131
142
  };
132
143
  });
144
+ // ============================================================
145
+ // RESOURCES — readable docs for the LLM
146
+ // ============================================================
147
+ const RESOURCES = [
148
+ { uri: "humanod://docs/quickstart", name: "Quickstart Guide", description: "How to create your first task via API or MCP", mimeType: "text/markdown" },
149
+ { uri: "humanod://docs/task-schema", name: "Task Schema Reference", description: "All fields for create_task", mimeType: "text/markdown" },
150
+ { uri: "humanod://docs/pricing", name: "Pricing & Fees", description: "How task pricing and escrow work", mimeType: "text/markdown" },
151
+ ];
152
+ const RESOURCE_CONTENT = {
153
+ "humanod://docs/quickstart": `# Humanod Quickstart\n**Humanod** lets AI agents hire real humans via REST API or MCP.\n\n## Steps\n1. Get API key at https://www.humanod.app/developer/keys\n2. Call \`create_task\` — set title, price, deliverables, criteria\n3. A human picks it up from the Marketplace\n4. Review proof and release payment with \`validate_work\`\n\n## Available tools\n- \`search_humans\`, \`create_task\`, \`list_my_tasks\`\n- \`get_task_applications\`, \`accept_application\`\n- \`validate_work\`, \`check_task_status\`, \`get_balance\``,
154
+ "humanod://docs/task-schema": `# Task Schema\n\n| Field | Required | Description |\n|---|---|---|\n| title | ✅ | Short title (5–200 chars) |\n| description | ✅ | Detailed instructions |\n| price | ✅ | Reward in EUR (> 0) |\n| category | ✅ | e.g. 'photography', 'verification' |\n| skills_required | ✅ | e.g. ['general', 'french'] |\n| deliverables | ✅ | What the worker must deliver |\n| validation_criteria | ✅ | How you verify the work |\n| location_required | — | true if worker must go on-site |\n| location_name | — | e.g. 'Paris, Trocadero' |\n| spots_total | — | Number of workers (default 1) |\n| auto_accept | — | Auto-hire first applicant |`,
155
+ "humanod://docs/pricing": `# Pricing & Fees\n- You set the **reward** paid to the worker.\n- Funds are **escrowed** on task creation — nothing is charged until you approve.\n- Cancelling a task **refunds** the full amount to your wallet.\n- Minimum price: **€1** per task.`,
156
+ };
157
+ server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async () => ({ resources: RESOURCES }));
158
+ server.setRequestHandler(types_js_1.ListResourceTemplatesRequestSchema, async () => ({
159
+ resourceTemplates: [
160
+ {
161
+ uriTemplate: "humanod://tasks/{task_id}",
162
+ name: "Task Detail",
163
+ description: "Fetch details for a specific task by its UUID",
164
+ mimeType: "application/json",
165
+ },
166
+ {
167
+ uriTemplate: "humanod://tasks/{task_id}/applications",
168
+ name: "Task Applications",
169
+ description: "List all human applicants for a given task",
170
+ mimeType: "application/json",
171
+ },
172
+ {
173
+ uriTemplate: "humanod://agents/{agent_id}/balance",
174
+ name: "Agent Wallet Balance",
175
+ description: "Get the current wallet balance for an agent",
176
+ mimeType: "application/json",
177
+ },
178
+ ],
179
+ }));
180
+ server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
181
+ const { uri } = request.params;
182
+ const content = RESOURCE_CONTENT[uri];
183
+ if (!content)
184
+ throw new Error(`Resource not found: ${uri}`);
185
+ return { contents: [{ uri, mimeType: "text/markdown", text: content }] };
186
+ });
187
+ // ============================================================
188
+ // PROMPTS — reusable templates for common workflows
189
+ // ============================================================
190
+ const PROMPTS = [
191
+ {
192
+ name: "create_physical_task",
193
+ description: "Post a task that requires a human to go somewhere physically",
194
+ arguments: [
195
+ { name: "location", description: "Where the human needs to go", required: true },
196
+ { name: "goal", description: "What you need done on-site", required: true },
197
+ { name: "budget", description: "How much to pay in EUR", required: false },
198
+ ],
199
+ },
200
+ {
201
+ name: "create_digital_task",
202
+ description: "Post a remote task (research, writing, review, translation…)",
203
+ arguments: [
204
+ { name: "goal", description: "What you need done remotely", required: true },
205
+ { name: "budget", description: "How much to pay in EUR", required: false },
206
+ ],
207
+ },
208
+ {
209
+ name: "check_and_pay",
210
+ description: "Review a task's applications and release payment to the best worker",
211
+ arguments: [
212
+ { name: "task_id", description: "UUID of the task to review", required: true },
213
+ ],
214
+ },
215
+ ];
216
+ server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => ({ prompts: PROMPTS }));
217
+ server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
218
+ const { name, arguments: args } = request.params;
219
+ switch (name) {
220
+ case "create_physical_task":
221
+ return {
222
+ description: "Create a physical-world task on Humanod",
223
+ messages: [{ role: "user", content: { type: "text", text: `Use create_task to hire a human:\n- Location: ${args?.location ?? "specified location"}\n- Goal: ${args?.goal ?? "complete the task"}\n- Budget: €${args?.budget ?? "5"}\n- location_required: true\nWrite clear deliverables and objective validation_criteria.` } }],
224
+ };
225
+ case "create_digital_task":
226
+ return {
227
+ description: "Create a remote digital task on Humanod",
228
+ messages: [{ role: "user", content: { type: "text", text: `Use create_task to hire a human remotely:\n- Goal: ${args?.goal ?? "complete the task"}\n- Budget: €${args?.budget ?? "5"}\n- location_required: false\nWrite clear deliverables and objective validation_criteria.` } }],
229
+ };
230
+ case "check_and_pay":
231
+ return {
232
+ description: "Review and pay a completed task",
233
+ messages: [{ role: "user", content: { type: "text", text: `For task ID ${args?.task_id ?? ""}:\n1. Call get_task_applications to list applicants\n2. Review their proof\n3. Call validate_work with approved: true to release payment, or approved: false with feedback to reject` } }],
234
+ };
235
+ default:
236
+ throw new Error(`Unknown prompt: ${name}`);
237
+ }
238
+ });
133
239
  // Handle Tool Execution
134
240
  server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
135
241
  try {
@@ -216,6 +322,23 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
216
322
  content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
217
323
  };
218
324
  }
325
+ case "get_balance": {
326
+ // Fetch profile/wallet
327
+ // Backend endpoint needed. `GET /me` or `/profile`?
328
+ // api/main.py: custom `get_my_profile`?
329
+ // currently no direct "me" endpoint.
330
+ // But we can query `profiles` table via Supabase if we had client?
331
+ // The MCP server uses REST API.
332
+ // We need a REST endpoint to get balance.
333
+ // Workaround: Use `list_my_tasks` and check balance? No.
334
+ // Let's assume we add `/me` endpoint to API quickly or use existing?
335
+ // Wait, `api/main.py` has no `/me`.
336
+ // I will add `/me` to API in next step. For now, I'll scaffold the call.
337
+ const response = await api.get("/me");
338
+ return {
339
+ content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
340
+ };
341
+ }
219
342
  default:
220
343
  throw new Error(`Unknown tool: ${name}`);
221
344
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanod-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "Humanod MCP Server - Hire humans from AI agents",
5
5
  "main": "build/index.js",
6
6
  "bin": {