@sendahuman/mcp-server 0.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.
- package/README.md +54 -0
- package/build/index.js +119 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# @sendahuman/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server for [sendahuman.ai](https://sendahuman.vercel.app) – let AI agents find and book humans for real-world tasks.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
| Tool | Description |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| `search_humans` | Search for available humans by skill, city, country |
|
|
10
|
+
| `get_human` | Get a human's full profile by ID |
|
|
11
|
+
| `book_human` | Book a human for a task |
|
|
12
|
+
|
|
13
|
+
## Setup with Claude Desktop
|
|
14
|
+
|
|
15
|
+
Add to your `claude_desktop_config.json`:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"sendahuman": {
|
|
21
|
+
"command": "npx",
|
|
22
|
+
"args": ["-y", "@sendahuman/mcp-server"]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with a custom API URL:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"sendahuman": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["-y", "@sendahuman/mcp-server"],
|
|
36
|
+
"env": {
|
|
37
|
+
"SENDAHUMAN_API_URL": "https://sendahuman.vercel.app"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Example
|
|
45
|
+
|
|
46
|
+
Ask Claude:
|
|
47
|
+
|
|
48
|
+
> "Find me a plumber in Berlin and book them for tomorrow at 10am"
|
|
49
|
+
|
|
50
|
+
Claude will use the MCP tools to search for available humans with plumbing skills in Berlin and create a booking.
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
MIT
|
package/build/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
const BASE_URL = process.env.SENDAHUMAN_API_URL || 'https://sendahuman.vercel.app';
|
|
6
|
+
async function apiRequest(path, options = {}) {
|
|
7
|
+
const response = await fetch(`${BASE_URL}${path}`, {
|
|
8
|
+
...options,
|
|
9
|
+
headers: {
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
...options.headers,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
const data = await response.json();
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
throw new Error(data.error || `API error: HTTP ${response.status}`);
|
|
17
|
+
}
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
20
|
+
const server = new McpServer({
|
|
21
|
+
name: 'sendahuman',
|
|
22
|
+
version: '0.1.0',
|
|
23
|
+
});
|
|
24
|
+
// ─── search_humans ───────────────────────────────────────────
|
|
25
|
+
server.registerTool('search_humans', {
|
|
26
|
+
description: 'Search for available humans on sendahuman.ai. Filter by skill, city, country, or verification status. Returns a list of humans with their profiles.',
|
|
27
|
+
inputSchema: {
|
|
28
|
+
skill: z.string().optional().describe('Filter by skill (e.g. "plumbing", "elderly care", "translation")'),
|
|
29
|
+
city: z.string().optional().describe('Filter by city (e.g. "Berlin", "Munich")'),
|
|
30
|
+
country: z.string().optional().describe('Filter by country (e.g. "Germany", "Austria")'),
|
|
31
|
+
verified: z.boolean().optional().describe('Only return verified humans'),
|
|
32
|
+
limit: z.number().min(1).max(100).optional().describe('Max results to return (default 50, max 100)'),
|
|
33
|
+
},
|
|
34
|
+
}, async ({ skill, city, country, verified, limit }) => {
|
|
35
|
+
const params = new URLSearchParams();
|
|
36
|
+
if (skill)
|
|
37
|
+
params.set('skill', skill);
|
|
38
|
+
if (city)
|
|
39
|
+
params.set('city', city);
|
|
40
|
+
if (country)
|
|
41
|
+
params.set('country', country);
|
|
42
|
+
if (verified !== undefined)
|
|
43
|
+
params.set('verified', String(verified));
|
|
44
|
+
if (limit)
|
|
45
|
+
params.set('limit', String(limit));
|
|
46
|
+
const query = params.toString();
|
|
47
|
+
const data = await apiRequest(`/api/humans${query ? `?${query}` : ''}`);
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: JSON.stringify(data, null, 2),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
// ─── get_human ───────────────────────────────────────────────
|
|
58
|
+
server.registerTool('get_human', {
|
|
59
|
+
description: 'Get the full profile of a specific human by their ID. Returns detailed information including bio, skills, languages, hourly rate, and availability.',
|
|
60
|
+
inputSchema: {
|
|
61
|
+
human_id: z.string().describe('The UUID of the human to look up'),
|
|
62
|
+
},
|
|
63
|
+
}, async ({ human_id }) => {
|
|
64
|
+
const data = await apiRequest(`/api/humans/${human_id}`);
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: 'text',
|
|
69
|
+
text: JSON.stringify(data, null, 2),
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
// ─── book_human ──────────────────────────────────────────────
|
|
75
|
+
server.registerTool('book_human', {
|
|
76
|
+
description: 'Book a human for a real-world task. Creates a booking request that the human can accept or decline. Provide a clear title and description of what you need done.',
|
|
77
|
+
inputSchema: {
|
|
78
|
+
human_id: z.string().describe('UUID of the human to book'),
|
|
79
|
+
agent_id: z.string().describe('Your agent identifier (e.g. "claude-desktop", "my-agent-v1")'),
|
|
80
|
+
title: z.string().describe('Short title for the task (e.g. "Deliver package to Alexanderplatz")'),
|
|
81
|
+
description: z.string().optional().describe('Detailed description of what needs to be done'),
|
|
82
|
+
start_time: z.string().optional().describe('Desired start time in ISO 8601 format'),
|
|
83
|
+
duration_minutes: z.number().optional().describe('Estimated duration in minutes'),
|
|
84
|
+
amount: z.number().optional().describe('Offered payment amount'),
|
|
85
|
+
currency: z.string().optional().describe('Currency code (default: EUR)'),
|
|
86
|
+
},
|
|
87
|
+
}, async ({ human_id, agent_id, title, description, start_time, duration_minutes, amount, currency }) => {
|
|
88
|
+
const data = await apiRequest('/api/bookings', {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
human_id,
|
|
92
|
+
agent_id,
|
|
93
|
+
title,
|
|
94
|
+
description,
|
|
95
|
+
start_time,
|
|
96
|
+
duration_minutes,
|
|
97
|
+
amount,
|
|
98
|
+
currency,
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: 'text',
|
|
105
|
+
text: JSON.stringify(data, null, 2),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
// ─── Start server ────────────────────────────────────────────
|
|
111
|
+
async function main() {
|
|
112
|
+
const transport = new StdioServerTransport();
|
|
113
|
+
await server.connect(transport);
|
|
114
|
+
console.error('sendahuman MCP server running on stdio');
|
|
115
|
+
}
|
|
116
|
+
main().catch((error) => {
|
|
117
|
+
console.error('Fatal error:', error);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sendahuman/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for sendahuman.ai – let AI agents find and book humans for real-world tasks",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sendahuman-mcp": "./build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./build/index.js",
|
|
10
|
+
"author": "CodeLax IT GmbH <info@codelax.de>",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"homepage": "https://sendahuman.ai/mcp",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/karlvonbonin/sendahuman.git",
|
|
16
|
+
"directory": "packages/mcp-server"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"build/",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "tsc --watch",
|
|
28
|
+
"start": "node build/index.js",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"mcp",
|
|
33
|
+
"model-context-protocol",
|
|
34
|
+
"ai-agents",
|
|
35
|
+
"human-tasks",
|
|
36
|
+
"sendahuman",
|
|
37
|
+
"human-in-the-loop",
|
|
38
|
+
"marketplace",
|
|
39
|
+
"automation",
|
|
40
|
+
"claude",
|
|
41
|
+
"cursor"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
45
|
+
"zod": "^3.25.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^20.11.24",
|
|
49
|
+
"typescript": "^5.3.3"
|
|
50
|
+
}
|
|
51
|
+
}
|