humanpages 1.2.4 → 1.4.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 +33 -12
- package/dist/tools.js +276 -61
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Human Pages MCP Server
|
|
2
2
|
|
|
3
|
-
MCP server (+ [OpenClaw SKILL.md](openclaw-skill/humanpages/SKILL.md)) that gives AI agents access to real-world people who listed themselves to be hired by agents.
|
|
3
|
+
MCP server (+ [OpenClaw SKILL.md](openclaw-skill/humanpages/SKILL.md)) that gives AI agents access to real-world people who listed themselves to be hired by agents. 33 tools including search by skill/location/equipment, job offers, job board listings, in-job messaging, streaming payments, and task delegation playbooks. Free tier available, with optional Pro subscription and x402 pay-per-use. Payments default to crypto (USDC) + other crypto + fiat supported.
|
|
4
4
|
|
|
5
5
|
Visit [humanpages.ai](https://humanpages.ai) to learn more. Available on [ClawHub](https://clawhub.com/skills/humanpages) | [npm](https://www.npmjs.com/package/humanpages).
|
|
6
6
|
|
|
@@ -116,7 +116,7 @@ If no humans match, the response suggests using `create_listing` to post a job l
|
|
|
116
116
|
- `language` (string, optional): Filter by language ISO code (e.g., "en", "es")
|
|
117
117
|
- `location` (string, optional): Filter by location name
|
|
118
118
|
- `lat`, `lng`, `radius` (number, optional): Radius search in km
|
|
119
|
-
- `max_rate` (number, optional): Maximum hourly rate in
|
|
119
|
+
- `max_rate` (number, optional): Maximum hourly rate in USD
|
|
120
120
|
- `available_only` (boolean, default: true): Only show available humans
|
|
121
121
|
|
|
122
122
|
### get_human
|
|
@@ -126,7 +126,7 @@ Get basic information about a specific human (bio, skills, services). Contact in
|
|
|
126
126
|
- `id` (string, required): The human's ID
|
|
127
127
|
|
|
128
128
|
### get_human_profile
|
|
129
|
-
Get the full profile of a human including contact info,
|
|
129
|
+
Get the full profile of a human including contact info, payment methods (crypto wallets and fiat options), and social links. **Requires an ACTIVE agent or x402 platform fee ($0.05).**
|
|
130
130
|
|
|
131
131
|
**Parameters:**
|
|
132
132
|
- `human_id` (string, required): The human's ID
|
|
@@ -176,13 +176,13 @@ Verify on-chain payment for optional payment verification trust badge.
|
|
|
176
176
|
- `network` (string, required): Blockchain network
|
|
177
177
|
|
|
178
178
|
### create_job_offer
|
|
179
|
-
Create a job offer for a human. **Requires agent API key or x402
|
|
179
|
+
Create a job offer for a human. **Requires agent API key or x402 platform fee ($0.25).** Rate limits: PRO = 15/day. x402 bypasses rate limits. Prices in USD, payment method flexible.
|
|
180
180
|
|
|
181
181
|
**Parameters:**
|
|
182
182
|
- `human_id` (string, required): The human's ID
|
|
183
183
|
- `title` (string, required): Job title
|
|
184
184
|
- `description` (string, required): What needs to be done
|
|
185
|
-
- `
|
|
185
|
+
- `price_usd` (number, required): Price in USD (payment method is flexible)
|
|
186
186
|
- `agent_id` (string, required): Your agent identifier
|
|
187
187
|
- `agent_key` (string, required): Your agent API key
|
|
188
188
|
|
|
@@ -193,13 +193,14 @@ Check the status of a job offer.
|
|
|
193
193
|
- `job_id` (string, required): The job ID
|
|
194
194
|
|
|
195
195
|
### mark_job_paid
|
|
196
|
-
Record payment for an accepted job.
|
|
196
|
+
Record payment for an accepted job. Supports crypto (verified on-chain) and fiat (human confirms receipt).
|
|
197
197
|
|
|
198
198
|
**Parameters:**
|
|
199
199
|
- `job_id` (string, required): The job ID
|
|
200
|
-
- `
|
|
201
|
-
- `
|
|
202
|
-
- `payment_amount` (number, required): Amount paid in
|
|
200
|
+
- `payment_method` (string, required): How you paid — `"usdc"`, `"eth"`, `"sol"`, `"paypal"`, `"bank_transfer"`, `"venmo"`, `"cashapp"`, `"other_crypto"`, `"other_fiat"`
|
|
201
|
+
- `payment_reference` (string, required): Transaction hash (crypto) or receipt ID (fiat)
|
|
202
|
+
- `payment_amount` (number, required): Amount paid in USD equivalent
|
|
203
|
+
- `payment_network` (string, optional): Blockchain network — required for crypto, ignored for fiat
|
|
203
204
|
|
|
204
205
|
### send_job_message
|
|
205
206
|
Send a message on a job. Works on PENDING, ACCEPTED, PAID, STREAMING, and PAUSED jobs. The human receives email and Telegram notifications.
|
|
@@ -245,13 +246,13 @@ Check the humanity verification status for a specific human.
|
|
|
245
246
|
- `human_id` (string, required): The human's ID
|
|
246
247
|
|
|
247
248
|
### create_listing
|
|
248
|
-
Post a job listing on the job board for humans to discover and apply to. **Requires agent API key or x402
|
|
249
|
+
Post a job listing on the job board for humans to discover and apply to. **Requires agent API key or x402 platform fee ($0.50).** Rate limits: PRO = 5/day.
|
|
249
250
|
|
|
250
251
|
**Parameters:**
|
|
251
252
|
- `agent_key` (string, required): Your agent API key
|
|
252
253
|
- `title` (string, required): Listing title
|
|
253
254
|
- `description` (string, required): Detailed description of the work
|
|
254
|
-
- `
|
|
255
|
+
- `budget_usd` (number, required): Budget in USD (minimum $5)
|
|
255
256
|
- `expires_at` (string, required): ISO 8601 expiration date (max 90 days)
|
|
256
257
|
- `category` (string, optional): Category (e.g., "photography", "research")
|
|
257
258
|
- `required_skills` (array, optional): Skills applicants should have
|
|
@@ -267,7 +268,7 @@ Browse open job listings. Supports filtering by skill, category, work mode, budg
|
|
|
267
268
|
- `skill` (string, optional): Filter by required skill
|
|
268
269
|
- `category` (string, optional): Filter by category
|
|
269
270
|
- `work_mode` (string, optional): `"REMOTE"`, `"ONSITE"`, or `"HYBRID"`
|
|
270
|
-
- `min_budget`, `max_budget` (number, optional): Budget range in
|
|
271
|
+
- `min_budget`, `max_budget` (number, optional): Budget range in USD
|
|
271
272
|
- `lat`, `lng`, `radius` (number, optional): Location-based filtering
|
|
272
273
|
|
|
273
274
|
### get_listing
|
|
@@ -298,6 +299,22 @@ Cancel an open listing. All pending applications will be rejected.
|
|
|
298
299
|
- `listing_id` (string, required): The listing ID
|
|
299
300
|
- `agent_key` (string, required): Your agent API key
|
|
300
301
|
|
|
302
|
+
### list_playbooks
|
|
303
|
+
List available task delegation playbooks. Each playbook contains step-by-step instructions for hiring a human to do a specific type of work. No parameters required.
|
|
304
|
+
|
|
305
|
+
**Available playbooks:**
|
|
306
|
+
- `directory-submissions` — Submit to 80+ directories (includes curated list)
|
|
307
|
+
- `qa-testing` — Real-device QA testing with bug reports
|
|
308
|
+
- `competitor-monitoring` — Track competitor pricing and features
|
|
309
|
+
- `localization` — Native speaker translation review
|
|
310
|
+
- `community-management` — Discord/Reddit/forum moderation
|
|
311
|
+
|
|
312
|
+
### get_playbook
|
|
313
|
+
Get the full content of a delegation playbook with search criteria, pricing, job templates, and verification steps.
|
|
314
|
+
|
|
315
|
+
**Parameters:**
|
|
316
|
+
- `task_type` (string, required): One of: `qa-testing`, `competitor-monitoring`, `localization`, `directory-submissions`, `community-management`
|
|
317
|
+
|
|
301
318
|
### get_promo_status
|
|
302
319
|
Check the launch promo status (legacy — all agents now get free PRO at registration).
|
|
303
320
|
|
|
@@ -361,6 +378,10 @@ Once installed, you can ask Claude:
|
|
|
361
378
|
|
|
362
379
|
> "Check the launch promo — are there free PRO slots left?"
|
|
363
380
|
|
|
381
|
+
> "Show me available playbooks for delegating tasks to humans"
|
|
382
|
+
|
|
383
|
+
> "I need someone to submit my app to directories — get the playbook"
|
|
384
|
+
|
|
364
385
|
## Environment Variables
|
|
365
386
|
|
|
366
387
|
| Variable | Description | Default |
|
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
2
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
-
const API_BASE = process.env.API_BASE_URL || '
|
|
3
|
+
const API_BASE = process.env.API_BASE_URL || 'https://api.humanpages.ai';
|
|
4
4
|
async function searchHumans(params) {
|
|
5
5
|
const query = new URLSearchParams();
|
|
6
6
|
if (params.skill)
|
|
@@ -27,6 +27,8 @@ async function searchHumans(params) {
|
|
|
27
27
|
query.set('verified', params.verified);
|
|
28
28
|
if (params.min_experience)
|
|
29
29
|
query.set('minExperience', params.min_experience.toString());
|
|
30
|
+
if (params.fiat_platform)
|
|
31
|
+
query.set('fiatPlatform', params.fiat_platform);
|
|
30
32
|
const res = await fetch(`${API_BASE}/api/humans/search?${query}`);
|
|
31
33
|
if (!res.ok) {
|
|
32
34
|
throw new Error(`API error: ${res.status}`);
|
|
@@ -53,13 +55,13 @@ export function createServer() {
|
|
|
53
55
|
tools: [
|
|
54
56
|
{
|
|
55
57
|
name: 'search_humans',
|
|
56
|
-
description: 'Search for humans available for hire. Supports filtering by skill, equipment, language, location (text or coordinates), and rate.
|
|
58
|
+
description: 'Search for humans available for hire. Supports filtering by skill, equipment, language, location (text or coordinates with radius), and rate. When using text location, provide a fully-qualified name (e.g., "Richmond, Virginia, USA" not just "Richmond") for accurate geocoding. The response includes a resolvedLocation field showing what location was matched — verify this is correct. Default search radius is 30km. Contact info available via get_human_profile (requires registered agent).',
|
|
57
59
|
inputSchema: {
|
|
58
60
|
type: 'object',
|
|
59
61
|
properties: {
|
|
60
62
|
skill: {
|
|
61
63
|
type: 'string',
|
|
62
|
-
description: 'Filter by skill tag (e.g., "photography", "driving", "notary")',
|
|
64
|
+
description: 'Filter by skill tag (e.g., "photography", "driving", "cleaning", "notary")',
|
|
63
65
|
},
|
|
64
66
|
equipment: {
|
|
65
67
|
type: 'string',
|
|
@@ -71,7 +73,7 @@ export function createServer() {
|
|
|
71
73
|
},
|
|
72
74
|
location: {
|
|
73
75
|
type: 'string',
|
|
74
|
-
description: 'Filter by location
|
|
76
|
+
description: 'Filter by location. Use fully-qualified names for best results (e.g., "San Francisco, California, USA" not just "San Francisco"). When provided without lat/lng, the server geocodes the text and searches within a radius (default 30km). Check resolvedLocation in the response to verify the correct city was matched.',
|
|
75
77
|
},
|
|
76
78
|
lat: {
|
|
77
79
|
type: 'number',
|
|
@@ -83,7 +85,7 @@ export function createServer() {
|
|
|
83
85
|
},
|
|
84
86
|
radius: {
|
|
85
87
|
type: 'number',
|
|
86
|
-
description: 'Search radius in kilometers (
|
|
88
|
+
description: 'Search radius in kilometers (default: 30km). Works with both text location and explicit lat/lng coordinates.',
|
|
87
89
|
},
|
|
88
90
|
max_rate: {
|
|
89
91
|
type: 'number',
|
|
@@ -108,6 +110,10 @@ export function createServer() {
|
|
|
108
110
|
type: 'number',
|
|
109
111
|
description: 'Minimum years of professional experience',
|
|
110
112
|
},
|
|
113
|
+
fiat_platform: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Filter by fiat payment platform the human accepts (e.g., "WISE", "PAYPAL", "VENMO", "REVOLUT", "CASHAPP", "ZELLE", "MONZO", "N26", "MERCADOPAGO")',
|
|
116
|
+
},
|
|
111
117
|
},
|
|
112
118
|
},
|
|
113
119
|
},
|
|
@@ -151,6 +157,10 @@ export function createServer() {
|
|
|
151
157
|
type: 'string',
|
|
152
158
|
description: 'Webhook URL for receiving platform events (new job matches, status changes, announcements). Must be a public HTTPS endpoint.',
|
|
153
159
|
},
|
|
160
|
+
wallet_address: {
|
|
161
|
+
type: 'string',
|
|
162
|
+
description: 'Optional EVM wallet address (0x...) for USDC payments. Can also be set later with set_wallet.',
|
|
163
|
+
},
|
|
154
164
|
},
|
|
155
165
|
required: ['name'],
|
|
156
166
|
},
|
|
@@ -169,6 +179,51 @@ export function createServer() {
|
|
|
169
179
|
required: ['agent_id'],
|
|
170
180
|
},
|
|
171
181
|
},
|
|
182
|
+
{
|
|
183
|
+
name: 'set_wallet',
|
|
184
|
+
description: 'Set the wallet address for a registered agent. This is used for receiving USDC payments and checking balance. The address must be a valid EVM address (0x + 40 hex chars). Network defaults to "base" (recommended for low fees).',
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: 'object',
|
|
187
|
+
properties: {
|
|
188
|
+
agent_id: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
description: 'Your registered agent ID',
|
|
191
|
+
},
|
|
192
|
+
agent_key: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
description: 'Your agent API key (starts with hp_)',
|
|
195
|
+
},
|
|
196
|
+
wallet_address: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
description: 'EVM wallet address (0x...)',
|
|
199
|
+
},
|
|
200
|
+
wallet_network: {
|
|
201
|
+
type: 'string',
|
|
202
|
+
enum: ['base', 'ethereum', 'polygon', 'arbitrum', 'base-sepolia'],
|
|
203
|
+
description: 'Blockchain network (default: "base"). Options: base, ethereum, polygon, arbitrum',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
required: ['agent_id', 'agent_key', 'wallet_address'],
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'get_funding_info',
|
|
211
|
+
description: 'Get funding instructions and current wallet balance for a registered agent. Returns structured info about how the developer can fund the agent with USDC, or alternatively pay workers directly via fiat platforms. Present this to the developer when they need to fund the agent for hiring workers. Think about what you know about the developer — their country, existing accounts, crypto experience, friends with crypto — and tailor your recommendation of which option fits them best.',
|
|
212
|
+
inputSchema: {
|
|
213
|
+
type: 'object',
|
|
214
|
+
properties: {
|
|
215
|
+
agent_id: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Your registered agent ID',
|
|
218
|
+
},
|
|
219
|
+
agent_key: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
description: 'Your agent API key (starts with hp_)',
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
required: ['agent_id', 'agent_key'],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
172
227
|
{
|
|
173
228
|
name: 'verify_agent_domain',
|
|
174
229
|
description: 'Verify domain ownership for a registered agent. The agent must have a websiteUrl set. Supports two methods: "well-known" (place a file at /.well-known/humanpages-verify.txt) or "dns" (add a TXT record at _humanpages.yourdomain.com).',
|
|
@@ -194,7 +249,7 @@ export function createServer() {
|
|
|
194
249
|
},
|
|
195
250
|
{
|
|
196
251
|
name: 'create_job_offer',
|
|
197
|
-
description: 'Create a job offer for a human. Requires a registered agent API key or x402
|
|
252
|
+
description: 'Create a job offer for a human. Requires a registered agent API key or x402 platform fee ($0.25 via x402 protocol). RATE LIMITS: PRO tier = 15 offers/day. x402 payments bypass tier limits. Prices are denominated in USD — payment method (crypto or fiat) is flexible and agreed between agent and human after acceptance. SPAM FILTERS: Humans can set minOfferPrice and maxOfferDistance - if your offer violates these, it will be rejected with a specific error code.',
|
|
198
253
|
inputSchema: {
|
|
199
254
|
type: 'object',
|
|
200
255
|
properties: {
|
|
@@ -212,11 +267,11 @@ export function createServer() {
|
|
|
212
267
|
},
|
|
213
268
|
category: {
|
|
214
269
|
type: 'string',
|
|
215
|
-
description: 'Category of the task (e.g., "photography", "research", "delivery")',
|
|
270
|
+
description: 'Category of the task (e.g., "photography", "research", "delivery", "cleaning")',
|
|
216
271
|
},
|
|
217
|
-
|
|
272
|
+
price_usd: {
|
|
218
273
|
type: 'number',
|
|
219
|
-
description: 'Agreed price in
|
|
274
|
+
description: 'Agreed price in USD. Must meet the human\'s minOfferPrice if set. Payment method (crypto or fiat) is flexible — agreed after acceptance.',
|
|
220
275
|
},
|
|
221
276
|
agent_id: {
|
|
222
277
|
type: 'string',
|
|
@@ -266,16 +321,21 @@ export function createServer() {
|
|
|
266
321
|
enum: ['HOURLY', 'DAILY', 'WEEKLY'],
|
|
267
322
|
description: 'How often payments are made/checkpointed. Required when payment_mode=STREAM.',
|
|
268
323
|
},
|
|
269
|
-
|
|
324
|
+
stream_rate_usd: {
|
|
270
325
|
type: 'number',
|
|
271
|
-
description: '
|
|
326
|
+
description: 'USD amount per interval (e.g., 10 = $10/day if interval=DAILY). Required when payment_mode=STREAM. Stream payments use crypto (USDC) on-chain.',
|
|
272
327
|
},
|
|
273
328
|
stream_max_ticks: {
|
|
274
329
|
type: 'number',
|
|
275
330
|
description: 'Optional cap on number of payment intervals. Null = indefinite.',
|
|
276
331
|
},
|
|
332
|
+
preferred_payment_method: {
|
|
333
|
+
type: 'string',
|
|
334
|
+
enum: ['crypto', 'fiat', 'any'],
|
|
335
|
+
description: 'Signal to the human what payment methods you support. "crypto" = on-chain only, "fiat" = traditional payment only, "any" = flexible (default). The human sees this when deciding whether to accept.',
|
|
336
|
+
},
|
|
277
337
|
},
|
|
278
|
-
required: ['human_id', 'title', 'description', '
|
|
338
|
+
required: ['human_id', 'title', 'description', 'price_usd', 'agent_id', 'agent_key'],
|
|
279
339
|
},
|
|
280
340
|
},
|
|
281
341
|
{
|
|
@@ -294,7 +354,7 @@ export function createServer() {
|
|
|
294
354
|
},
|
|
295
355
|
{
|
|
296
356
|
name: 'mark_job_paid',
|
|
297
|
-
description: 'Record that payment has been sent for an ACCEPTED job.
|
|
357
|
+
description: 'Record that payment has been sent for an ACCEPTED job. Supports both crypto (verified on-chain) and fiat (self-reported, human confirms receipt). For crypto payments, provide a transaction hash and network for on-chain verification. For fiat payments (PayPal, bank transfer, etc.), provide a payment reference — the human will be asked to confirm receipt.',
|
|
298
358
|
inputSchema: {
|
|
299
359
|
type: 'object',
|
|
300
360
|
properties: {
|
|
@@ -302,20 +362,25 @@ export function createServer() {
|
|
|
302
362
|
type: 'string',
|
|
303
363
|
description: 'The job ID',
|
|
304
364
|
},
|
|
305
|
-
|
|
365
|
+
payment_method: {
|
|
366
|
+
type: 'string',
|
|
367
|
+
enum: ['usdc', 'eth', 'sol', 'paypal', 'bank_transfer', 'venmo', 'cashapp', 'other_crypto', 'other_fiat'],
|
|
368
|
+
description: 'How you paid the human. Crypto methods (usdc, eth, sol, other_crypto) are verified on-chain. Fiat methods (paypal, bank_transfer, venmo, cashapp, other_fiat) require human confirmation.',
|
|
369
|
+
},
|
|
370
|
+
payment_reference: {
|
|
306
371
|
type: 'string',
|
|
307
|
-
description: '
|
|
372
|
+
description: 'Proof of payment. For crypto: the on-chain transaction hash. For fiat: PayPal transaction ID, bank reference number, or other receipt identifier.',
|
|
308
373
|
},
|
|
309
374
|
payment_network: {
|
|
310
375
|
type: 'string',
|
|
311
|
-
description: '
|
|
376
|
+
description: 'Blockchain network (e.g., "base", "ethereum", "solana"). Required for crypto payments, ignored for fiat.',
|
|
312
377
|
},
|
|
313
378
|
payment_amount: {
|
|
314
379
|
type: 'number',
|
|
315
|
-
description: 'The amount paid in
|
|
380
|
+
description: 'The amount paid in USD equivalent',
|
|
316
381
|
},
|
|
317
382
|
},
|
|
318
|
-
required: ['job_id', '
|
|
383
|
+
required: ['job_id', 'payment_method', 'payment_reference', 'payment_amount'],
|
|
319
384
|
},
|
|
320
385
|
},
|
|
321
386
|
{
|
|
@@ -396,7 +461,7 @@ export function createServer() {
|
|
|
396
461
|
},
|
|
397
462
|
{
|
|
398
463
|
name: 'get_human_profile',
|
|
399
|
-
description: 'Get the full profile of a human including contact info,
|
|
464
|
+
description: 'Get the full profile of a human including contact info, payment methods (crypto wallets and fiat options like PayPal), and social links. Requires a registered agent API key. Alternative: pay $0.05 per view via x402 platform fee. Note: crypto addresses are shown directly; fiat payment details (PayPal, Venmo handles) are shown if the human opted to share them. Full bank details are never exposed — the human provides those directly after job acceptance.',
|
|
400
465
|
inputSchema: {
|
|
401
466
|
type: 'object',
|
|
402
467
|
properties: {
|
|
@@ -496,7 +561,7 @@ export function createServer() {
|
|
|
496
561
|
},
|
|
497
562
|
{
|
|
498
563
|
name: 'start_stream',
|
|
499
|
-
description: 'Start a stream payment for an ACCEPTED stream job. For Superfluid: you must FIRST create the on-chain flow, then call this to verify it. Steps: (1) Wrap USDC to USDCx at the Super Token address for the chain, (2) Call createFlow() on CFAv1Forwarder (0xcfA132E353cB4E398080B9700609bb008eceB125) with token=USDCx, receiver=human wallet, flowRate=calculated rate, (3) Call start_stream with your sender address — backend verifies the flow on-chain. For micro-transfer: locks network/token and creates the first pending tick. Prefer L2s (Base, Arbitrum, Polygon) for lower gas costs.',
|
|
564
|
+
description: 'Start a stream payment for an ACCEPTED stream job. Stream payments require crypto (on-chain). For Superfluid: you must FIRST create the on-chain flow, then call this to verify it. Steps: (1) Wrap USDC to USDCx at the Super Token address for the chain, (2) Call createFlow() on CFAv1Forwarder (0xcfA132E353cB4E398080B9700609bb008eceB125) with token=USDCx, receiver=human wallet, flowRate=calculated rate, (3) Call start_stream with your sender address — backend verifies the flow on-chain. For micro-transfer: locks network/token and creates the first pending tick. Prefer L2s (Base, Arbitrum, Polygon) for lower gas costs.',
|
|
500
565
|
inputSchema: {
|
|
501
566
|
type: 'object',
|
|
502
567
|
properties: {
|
|
@@ -601,7 +666,7 @@ export function createServer() {
|
|
|
601
666
|
},
|
|
602
667
|
{
|
|
603
668
|
name: 'create_listing',
|
|
604
|
-
description: 'Post a job listing on the Human Pages job board for humans to discover and apply to. Unlike create_job_offer (which targets a specific human), listings let you describe work and wait for qualified humans to come to you. Requires a registered agent or x402
|
|
669
|
+
description: 'Post a job listing on the Human Pages job board for humans to discover and apply to. Unlike create_job_offer (which targets a specific human), listings let you describe work and wait for qualified humans to come to you. Requires a registered agent or x402 platform fee ($0.50). RATE LIMITS: PRO = 5 listings/day. x402 bypasses limits.',
|
|
605
670
|
inputSchema: {
|
|
606
671
|
type: 'object',
|
|
607
672
|
properties: {
|
|
@@ -617,9 +682,9 @@ export function createServer() {
|
|
|
617
682
|
type: 'string',
|
|
618
683
|
description: 'Detailed description of the work, expectations, and deliverables',
|
|
619
684
|
},
|
|
620
|
-
|
|
685
|
+
budget_usd: {
|
|
621
686
|
type: 'number',
|
|
622
|
-
description: 'Budget in
|
|
687
|
+
description: 'Budget in USD (minimum $5). Payment method is flexible — agreed between agent and human.',
|
|
623
688
|
},
|
|
624
689
|
category: {
|
|
625
690
|
type: 'string',
|
|
@@ -673,7 +738,7 @@ export function createServer() {
|
|
|
673
738
|
description: 'Secret for HMAC-SHA256 webhook signature (min 16 chars)',
|
|
674
739
|
},
|
|
675
740
|
},
|
|
676
|
-
required: ['agent_key', 'title', 'description', '
|
|
741
|
+
required: ['agent_key', 'title', 'description', 'budget_usd', 'expires_at'],
|
|
677
742
|
},
|
|
678
743
|
},
|
|
679
744
|
{
|
|
@@ -705,11 +770,11 @@ export function createServer() {
|
|
|
705
770
|
},
|
|
706
771
|
min_budget: {
|
|
707
772
|
type: 'number',
|
|
708
|
-
description: 'Minimum budget in
|
|
773
|
+
description: 'Minimum budget in USD',
|
|
709
774
|
},
|
|
710
775
|
max_budget: {
|
|
711
776
|
type: 'number',
|
|
712
|
-
description: 'Maximum budget in
|
|
777
|
+
description: 'Maximum budget in USD',
|
|
713
778
|
},
|
|
714
779
|
lat: {
|
|
715
780
|
type: 'number',
|
|
@@ -826,7 +891,7 @@ export function createServer() {
|
|
|
826
891
|
const { name, arguments: args } = request.params;
|
|
827
892
|
try {
|
|
828
893
|
if (name === 'search_humans') {
|
|
829
|
-
const
|
|
894
|
+
const response = await searchHumans({
|
|
830
895
|
skill: args?.skill,
|
|
831
896
|
equipment: args?.equipment,
|
|
832
897
|
language: args?.language,
|
|
@@ -839,10 +904,15 @@ export function createServer() {
|
|
|
839
904
|
work_mode: args?.work_mode,
|
|
840
905
|
verified: args?.verified,
|
|
841
906
|
min_experience: args?.min_experience,
|
|
907
|
+
fiat_platform: args?.fiat_platform,
|
|
842
908
|
});
|
|
909
|
+
const humans = response.results;
|
|
910
|
+
const locationNote = response.resolvedLocation
|
|
911
|
+
? `\nLocation resolved to: "${response.resolvedLocation}" (${response.searchRadius?.radiusKm || 30}km radius). If this isn't the right place, try a more specific location name (e.g., "City, State, Country").`
|
|
912
|
+
: '';
|
|
843
913
|
if (humans.length === 0) {
|
|
844
914
|
return {
|
|
845
|
-
content: [{ type: 'text', text:
|
|
915
|
+
content: [{ type: 'text', text: `No humans found matching the criteria.${locationNote} You can use \`create_listing\` to post a job listing on the Human Pages job board — qualified humans will discover it and apply to you.` }],
|
|
846
916
|
};
|
|
847
917
|
}
|
|
848
918
|
const summary = humans
|
|
@@ -868,11 +938,12 @@ export function createServer() {
|
|
|
868
938
|
Equipment: ${h.equipment.join(', ') || 'None listed'}
|
|
869
939
|
Languages: ${h.languages.join(', ') || 'Not specified'}
|
|
870
940
|
Experience: ${h.yearsOfExperience ? `${h.yearsOfExperience} years` : 'Not specified'}
|
|
941
|
+
Payment methods: ${h.paymentMethods && h.paymentMethods.length > 0 ? h.paymentMethods.join(', ') : 'Not specified'}
|
|
871
942
|
Jobs completed: ${rep?.jobsCompleted || 0}`;
|
|
872
943
|
})
|
|
873
944
|
.join('\n\n');
|
|
874
945
|
return {
|
|
875
|
-
content: [{ type: 'text', text: `Found ${humans.length} human(s)
|
|
946
|
+
content: [{ type: 'text', text: `Found ${humans.length} human(s):${locationNote}\n\n${summary}\n\n_Contact info and wallets available via get_human_profile (requires registered agent)._` }],
|
|
876
947
|
};
|
|
877
948
|
}
|
|
878
949
|
if (name === 'get_human') {
|
|
@@ -947,6 +1018,7 @@ ${servicesInfo || 'No services listed'}`;
|
|
|
947
1018
|
websiteUrl: args?.website_url,
|
|
948
1019
|
contactEmail: args?.contact_email,
|
|
949
1020
|
webhookUrl: args?.webhook_url,
|
|
1021
|
+
walletAddress: args?.wallet_address,
|
|
950
1022
|
}),
|
|
951
1023
|
});
|
|
952
1024
|
if (!res.ok) {
|
|
@@ -1005,6 +1077,102 @@ To get a verified badge, set up domain verification using \`verify_agent_domain\
|
|
|
1005
1077
|
content: [{ type: 'text', text: details }],
|
|
1006
1078
|
};
|
|
1007
1079
|
}
|
|
1080
|
+
if (name === 'set_wallet') {
|
|
1081
|
+
const agentKey = args?.agent_key;
|
|
1082
|
+
if (!agentKey) {
|
|
1083
|
+
throw new Error('agent_key is required.');
|
|
1084
|
+
}
|
|
1085
|
+
const res = await fetch(`${API_BASE}/api/agents/${args?.agent_id}/wallet`, {
|
|
1086
|
+
method: 'PATCH',
|
|
1087
|
+
headers: {
|
|
1088
|
+
'Content-Type': 'application/json',
|
|
1089
|
+
'X-Agent-Key': agentKey,
|
|
1090
|
+
},
|
|
1091
|
+
body: JSON.stringify({
|
|
1092
|
+
walletAddress: args?.wallet_address,
|
|
1093
|
+
walletNetwork: args?.wallet_network || 'base',
|
|
1094
|
+
}),
|
|
1095
|
+
});
|
|
1096
|
+
if (!res.ok) {
|
|
1097
|
+
const error = await res.json();
|
|
1098
|
+
throw new Error(error.error || `API error: ${res.status}`);
|
|
1099
|
+
}
|
|
1100
|
+
const result = await res.json();
|
|
1101
|
+
return {
|
|
1102
|
+
content: [{
|
|
1103
|
+
type: 'text',
|
|
1104
|
+
text: `**Wallet Set!**
|
|
1105
|
+
|
|
1106
|
+
**Agent:** ${result.name}
|
|
1107
|
+
**Wallet Address:** \`${result.walletAddress}\`
|
|
1108
|
+
**Network:** ${result.walletNetwork}
|
|
1109
|
+
|
|
1110
|
+
Your wallet is now configured. Use \`get_funding_info\` to check your balance and get funding instructions for your developer.`,
|
|
1111
|
+
}],
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
if (name === 'get_funding_info') {
|
|
1115
|
+
const agentKey = args?.agent_key;
|
|
1116
|
+
if (!agentKey) {
|
|
1117
|
+
throw new Error('agent_key is required.');
|
|
1118
|
+
}
|
|
1119
|
+
// Fetch balance
|
|
1120
|
+
const balanceRes = await fetch(`${API_BASE}/api/agents/${args?.agent_id}/balance`);
|
|
1121
|
+
if (!balanceRes.ok) {
|
|
1122
|
+
throw new Error(`Could not fetch balance: ${balanceRes.status}`);
|
|
1123
|
+
}
|
|
1124
|
+
const balanceData = await balanceRes.json();
|
|
1125
|
+
const hasWallet = balanceData.walletAddress != null;
|
|
1126
|
+
const balance = balanceData.balance ?? '0.00';
|
|
1127
|
+
const network = balanceData.network || 'base';
|
|
1128
|
+
const addr = balanceData.walletAddress || '(not set)';
|
|
1129
|
+
// Build Transak URL (pre-filled with wallet, params encoded for safety)
|
|
1130
|
+
const transakUrl = hasWallet
|
|
1131
|
+
? `https://global.transak.com/?cryptoCurrencyCode=USDC&network=${encodeURIComponent(network)}&walletAddress=${encodeURIComponent(addr)}`
|
|
1132
|
+
: 'https://global.transak.com/?cryptoCurrencyCode=USDC&network=base';
|
|
1133
|
+
const fundingMethods = [
|
|
1134
|
+
{ method: 'crypto_transfer', label: 'Send USDC', description: `Send USDC to ${addr} on ${network}` },
|
|
1135
|
+
{ method: 'credit_card', label: 'Buy with card', provider: 'Transak', url: transakUrl },
|
|
1136
|
+
{ method: 'peer_exchange', label: 'Convert via Peer', provider: 'Peer (peer.xyz)', url: 'https://peer.xyz', description: 'Convert from Wise, PayPal, Venmo, or 15+ other platforms to USDC' },
|
|
1137
|
+
{ method: 'ask_friend', label: 'Ask someone with crypto', description: `Have them send USDC to ${addr}` },
|
|
1138
|
+
];
|
|
1139
|
+
const fiatAlternative = {
|
|
1140
|
+
description: 'You can also pay workers directly via shared payment platforms (Wise, PayPal, Venmo, Revolut, etc.) without needing crypto. Search for workers who accept your preferred platform.',
|
|
1141
|
+
useSearchParam: 'fiat_platform',
|
|
1142
|
+
};
|
|
1143
|
+
const message = `I need funding to hire workers on your behalf.
|
|
1144
|
+
|
|
1145
|
+
Current balance: $${balance} USDC${hasWallet ? '' : ' (no wallet set — use set_wallet first)'}
|
|
1146
|
+
Wallet address: ${addr}
|
|
1147
|
+
Network: ${network}
|
|
1148
|
+
|
|
1149
|
+
**Option A — Fund with USDC (for crypto payments):**
|
|
1150
|
+
|
|
1151
|
+
1. Already have crypto? Send USDC to my wallet address above on ${network}.
|
|
1152
|
+
2. Buy with card: [Transak](${transakUrl})
|
|
1153
|
+
3. Convert from Wise/PayPal/Venmo/etc: [Peer (peer.xyz)](https://peer.xyz)
|
|
1154
|
+
4. Know someone with crypto? Ask them to send USDC to my address.
|
|
1155
|
+
|
|
1156
|
+
**Option B — Pay workers directly with fiat:**
|
|
1157
|
+
I can find workers who accept payment platforms you already use (Wise, PayPal, Venmo, Revolut, etc.). You'd pay them directly — no crypto needed.
|
|
1158
|
+
|
|
1159
|
+
**Think about what works best for you** — consider what accounts you already have, whether you or anyone you know holds crypto, and what payment methods are common where you are. I can help figure out the easiest path.
|
|
1160
|
+
|
|
1161
|
+
Which option works best for you?`;
|
|
1162
|
+
return {
|
|
1163
|
+
content: [{
|
|
1164
|
+
type: 'text',
|
|
1165
|
+
text: JSON.stringify({
|
|
1166
|
+
currentBalance: balance,
|
|
1167
|
+
walletAddress: addr,
|
|
1168
|
+
walletNetwork: network,
|
|
1169
|
+
fundingMethods,
|
|
1170
|
+
fiatAlternative,
|
|
1171
|
+
message,
|
|
1172
|
+
}, null, 2),
|
|
1173
|
+
}],
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1008
1176
|
if (name === 'verify_agent_domain') {
|
|
1009
1177
|
const res = await fetch(`${API_BASE}/api/agents/${args?.agent_id}/verify-domain`, {
|
|
1010
1178
|
method: 'POST',
|
|
@@ -1053,13 +1221,14 @@ Your agent profile now shows a verified badge. Humans will see this when reviewi
|
|
|
1053
1221
|
title: args?.title,
|
|
1054
1222
|
description: args?.description,
|
|
1055
1223
|
category: args?.category,
|
|
1056
|
-
priceUsdc: args?.
|
|
1224
|
+
priceUsdc: args?.price_usd,
|
|
1057
1225
|
paymentMode: args?.payment_mode,
|
|
1058
1226
|
paymentTiming: args?.payment_timing,
|
|
1059
1227
|
streamMethod: args?.stream_method,
|
|
1060
1228
|
streamInterval: args?.stream_interval,
|
|
1061
|
-
streamRateUsdc: args?.
|
|
1229
|
+
streamRateUsdc: args?.stream_rate_usd,
|
|
1062
1230
|
streamMaxTicks: args?.stream_max_ticks,
|
|
1231
|
+
preferredPaymentMethod: args?.preferred_payment_method,
|
|
1063
1232
|
callbackUrl: args?.callback_url,
|
|
1064
1233
|
callbackSecret: args?.callback_secret,
|
|
1065
1234
|
}),
|
|
@@ -1085,11 +1254,11 @@ Your agent profile now shows a verified badge. Humans will see this when reviewi
|
|
|
1085
1254
|
**Job ID:** ${job.id}
|
|
1086
1255
|
**Status:** ${job.status}
|
|
1087
1256
|
**Human:** ${human.name}
|
|
1088
|
-
**Price:** $${args?.
|
|
1257
|
+
**Price:** $${args?.price_usd}${args?.preferred_payment_method ? `\n**Payment Preference:** ${args.preferred_payment_method}` : ''}
|
|
1089
1258
|
|
|
1090
1259
|
⏳ **Next Step:** Wait for ${human.name} to accept the offer.${webhookNote}
|
|
1091
1260
|
|
|
1092
|
-
Once accepted, you
|
|
1261
|
+
Once accepted, you'll see their accepted payment methods (crypto wallets, PayPal, etc.) and can pay via any method they support. Use \`mark_job_paid\` to record the transaction.`,
|
|
1093
1262
|
},
|
|
1094
1263
|
],
|
|
1095
1264
|
};
|
|
@@ -1104,12 +1273,14 @@ Once accepted, you can send payment to their wallet and use \`mark_job_paid\` to
|
|
|
1104
1273
|
PENDING: '⏳',
|
|
1105
1274
|
ACCEPTED: '✅',
|
|
1106
1275
|
REJECTED: '❌',
|
|
1276
|
+
PAYMENT_PENDING_CONFIRMATION: '🔔',
|
|
1107
1277
|
PAID: '💰',
|
|
1108
1278
|
STREAMING: '🔄',
|
|
1109
1279
|
PAUSED: '⏸️',
|
|
1110
1280
|
COMPLETED: '🎉',
|
|
1111
1281
|
CANCELLED: '🚫',
|
|
1112
1282
|
DISPUTED: '⚠️',
|
|
1283
|
+
PAYMENT_EXPIRED: '⌛',
|
|
1113
1284
|
};
|
|
1114
1285
|
const isStream = job.paymentMode === 'STREAM';
|
|
1115
1286
|
const streamSummary = job.streamSummary;
|
|
@@ -1126,9 +1297,7 @@ Once accepted, you can send payment to their wallet and use \`mark_job_paid\` to
|
|
|
1126
1297
|
: 'Human accepted! Use `start_stream` to lock the network/token and start sending payments.';
|
|
1127
1298
|
}
|
|
1128
1299
|
else {
|
|
1129
|
-
nextStep = job.
|
|
1130
|
-
? `Human accepted! Contact info was sent to your webhook. Send $${job.priceUsdc} USDC to their wallet, then use \`mark_job_paid\` with the transaction hash.`
|
|
1131
|
-
: `Human accepted! Send $${job.priceUsdc} USDC to their wallet, then use \`mark_job_paid\` with the transaction hash.`;
|
|
1300
|
+
nextStep = `Human accepted! Pay $${job.priceUsdc} via any of their accepted payment methods (use \`get_human_profile\` to see their crypto wallets and fiat options), then use \`mark_job_paid\` to record the payment.`;
|
|
1132
1301
|
}
|
|
1133
1302
|
break;
|
|
1134
1303
|
case 'REJECTED':
|
|
@@ -1139,15 +1308,21 @@ Once accepted, you can send payment to their wallet and use \`mark_job_paid\` to
|
|
|
1139
1308
|
break;
|
|
1140
1309
|
case 'STREAMING':
|
|
1141
1310
|
if (streamSummary?.method === 'SUPERFLUID') {
|
|
1142
|
-
nextStep = `Stream active via Superfluid. Total streamed: $${streamSummary?.totalPaid || '0'}
|
|
1311
|
+
nextStep = `Stream active via Superfluid. Total streamed: $${streamSummary?.totalPaid || '0'}. Use \`pause_stream\` or \`stop_stream\` to manage.`;
|
|
1143
1312
|
}
|
|
1144
1313
|
else {
|
|
1145
|
-
nextStep = `Stream active via micro-transfer. Total paid: $${streamSummary?.totalPaid || '0'}
|
|
1314
|
+
nextStep = `Stream active via micro-transfer. Total paid: $${streamSummary?.totalPaid || '0'}. Use \`record_stream_tick\` to submit each payment.`;
|
|
1146
1315
|
}
|
|
1147
1316
|
break;
|
|
1148
1317
|
case 'PAUSED':
|
|
1149
1318
|
nextStep = 'Stream is paused. Use `resume_stream` to continue or `stop_stream` to end permanently.';
|
|
1150
1319
|
break;
|
|
1320
|
+
case 'PAYMENT_PENDING_CONFIRMATION':
|
|
1321
|
+
nextStep = 'Waiting for the human to confirm they received your fiat payment. They have 7 days to confirm or dispute. Use `get_job_status` to check.';
|
|
1322
|
+
break;
|
|
1323
|
+
case 'PAYMENT_EXPIRED':
|
|
1324
|
+
nextStep = 'The human did not confirm receipt of your payment within 7 days. The payment claim has expired. If you did pay, contact the human directly to resolve.';
|
|
1325
|
+
break;
|
|
1151
1326
|
case 'COMPLETED':
|
|
1152
1327
|
nextStep = job.review
|
|
1153
1328
|
? `Review submitted: ${job.review.rating}/5 stars`
|
|
@@ -1163,7 +1338,7 @@ Once accepted, you can send payment to their wallet and use \`mark_job_paid\` to
|
|
|
1163
1338
|
if (isStream && streamSummary) {
|
|
1164
1339
|
streamInfo = `\n**Payment Mode:** STREAM (${streamSummary.method})
|
|
1165
1340
|
**Rate:** $${streamSummary.rateUsdc || '?'}/${(streamSummary.interval || 'DAILY').toLowerCase()}
|
|
1166
|
-
**Total Paid:** $${streamSummary.totalPaid || '0'}
|
|
1341
|
+
**Total Paid:** $${streamSummary.totalPaid || '0'}
|
|
1167
1342
|
**Ticks:** ${streamSummary.tickCount || 0}${streamSummary.maxTicks ? `/${streamSummary.maxTicks}` : ''}
|
|
1168
1343
|
**Network:** ${streamSummary.network || 'Not set'}`;
|
|
1169
1344
|
}
|
|
@@ -1176,7 +1351,7 @@ Once accepted, you can send payment to their wallet and use \`mark_job_paid\` to
|
|
|
1176
1351
|
**Job ID:** ${job.id}
|
|
1177
1352
|
**Status:** ${statusEmoji[job.status] || ''} ${job.status}
|
|
1178
1353
|
**Title:** ${job.title}
|
|
1179
|
-
**Price:** $${job.priceUsdc}
|
|
1354
|
+
**Price:** $${job.priceUsdc}
|
|
1180
1355
|
**Human:** ${job.human.name}
|
|
1181
1356
|
${agentInfo ? agentInfo + '\n' : ''}${streamInfo}
|
|
1182
1357
|
**Next Step:** ${nextStep}`,
|
|
@@ -1185,13 +1360,16 @@ ${agentInfo ? agentInfo + '\n' : ''}${streamInfo}
|
|
|
1185
1360
|
};
|
|
1186
1361
|
}
|
|
1187
1362
|
if (name === 'mark_job_paid') {
|
|
1363
|
+
const paymentMethod = args?.payment_method;
|
|
1364
|
+
const isCrypto = ['usdc', 'eth', 'sol', 'other_crypto'].includes(paymentMethod);
|
|
1188
1365
|
const res = await fetch(`${API_BASE}/api/jobs/${args?.job_id}/paid`, {
|
|
1189
1366
|
method: 'PATCH',
|
|
1190
1367
|
headers: { 'Content-Type': 'application/json' },
|
|
1191
1368
|
body: JSON.stringify({
|
|
1192
|
-
paymentTxHash: args?.
|
|
1193
|
-
paymentNetwork: args?.payment_network,
|
|
1369
|
+
paymentTxHash: args?.payment_reference,
|
|
1370
|
+
paymentNetwork: isCrypto ? (args?.payment_network || 'base') : (paymentMethod || 'fiat'),
|
|
1194
1371
|
paymentAmount: args?.payment_amount,
|
|
1372
|
+
paymentMethod: paymentMethod,
|
|
1195
1373
|
}),
|
|
1196
1374
|
});
|
|
1197
1375
|
if (!res.ok) {
|
|
@@ -1199,23 +1377,50 @@ ${agentInfo ? agentInfo + '\n' : ''}${streamInfo}
|
|
|
1199
1377
|
throw new Error(error.reason || error.error || `API error: ${res.status}`);
|
|
1200
1378
|
}
|
|
1201
1379
|
const result = await res.json();
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1380
|
+
if (isCrypto) {
|
|
1381
|
+
return {
|
|
1382
|
+
content: [
|
|
1383
|
+
{
|
|
1384
|
+
type: 'text',
|
|
1385
|
+
text: `**Payment Verified On-Chain!**
|
|
1207
1386
|
|
|
1208
1387
|
**Job ID:** ${result.id}
|
|
1209
1388
|
**Status:** ${result.status}
|
|
1210
|
-
**
|
|
1389
|
+
**Method:** ${paymentMethod.toUpperCase()}
|
|
1390
|
+
**Transaction:** ${args?.payment_reference}
|
|
1211
1391
|
**Network:** ${args?.payment_network}
|
|
1212
|
-
**Amount:** $${args?.payment_amount}
|
|
1392
|
+
**Amount:** $${args?.payment_amount}
|
|
1213
1393
|
|
|
1214
1394
|
The human can now begin work. They will mark the job as complete when finished.
|
|
1215
1395
|
After completion, you can leave a review using \`leave_review\`.`,
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1396
|
+
},
|
|
1397
|
+
],
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
else {
|
|
1401
|
+
return {
|
|
1402
|
+
content: [
|
|
1403
|
+
{
|
|
1404
|
+
type: 'text',
|
|
1405
|
+
text: `**Fiat Payment Recorded (Pending Human Confirmation)**
|
|
1406
|
+
|
|
1407
|
+
**Job ID:** ${result.id}
|
|
1408
|
+
**Status:** PAYMENT_PENDING_CONFIRMATION
|
|
1409
|
+
**Method:** ${paymentMethod.replace('_', ' ')}
|
|
1410
|
+
**Reference:** ${args?.payment_reference}
|
|
1411
|
+
**Amount:** $${args?.payment_amount}
|
|
1412
|
+
|
|
1413
|
+
The human has been notified to confirm they received the payment. Fiat payments require human confirmation since they cannot be verified on-chain.
|
|
1414
|
+
|
|
1415
|
+
- If confirmed: job moves to PAID and work can begin.
|
|
1416
|
+
- If disputed: job moves to DISPUTED.
|
|
1417
|
+
- If no response within 7 days: payment claim expires automatically.
|
|
1418
|
+
|
|
1419
|
+
Use \`get_job_status\` to check for confirmation.`,
|
|
1420
|
+
},
|
|
1421
|
+
],
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1219
1424
|
}
|
|
1220
1425
|
if (name === 'approve_completion') {
|
|
1221
1426
|
const res = await fetch(`${API_BASE}/api/jobs/${args?.job_id}/approve-completion`, {
|
|
@@ -1320,8 +1525,17 @@ ${human.humanityVerified
|
|
|
1320
1525
|
.map((w) => `- ${w.chain || w.network}${w.label ? ` (${w.label})` : ''}${w.isPrimary ? ' ⭐' : ''}: ${w.address}`)
|
|
1321
1526
|
.join('\n');
|
|
1322
1527
|
const primaryWallet = (human.wallets || []).find((w) => w.isPrimary) || (human.wallets || [])[0];
|
|
1528
|
+
// Tiered fiat visibility: show semi-public handles (PayPal.me, Venmo, CashApp)
|
|
1529
|
+
// but redact sensitive bank details — human provides those directly after job acceptance
|
|
1530
|
+
const sensitivePatterns = /bank|iban|swift|routing|account.*number/i;
|
|
1323
1531
|
const fiatInfo = (human.fiatPaymentMethods || [])
|
|
1324
|
-
.map((f) =>
|
|
1532
|
+
.map((f) => {
|
|
1533
|
+
const isSensitive = sensitivePatterns.test(f.platform) || sensitivePatterns.test(f.label || '');
|
|
1534
|
+
if (isSensitive) {
|
|
1535
|
+
return `- ${f.platform}${f.label ? ` (${f.label})` : ''}${f.isPrimary ? ' ⭐' : ''}: Available — human will provide details after job acceptance`;
|
|
1536
|
+
}
|
|
1537
|
+
return `- ${f.platform}${f.label ? ` (${f.label})` : ''}${f.isPrimary ? ' ⭐' : ''}: ${f.handle}`;
|
|
1538
|
+
})
|
|
1325
1539
|
.join('\n');
|
|
1326
1540
|
const fmtFollowers = (n) => n != null ? ` (${n.toLocaleString()} followers)` : '';
|
|
1327
1541
|
const socialLinks = [
|
|
@@ -1341,12 +1555,13 @@ ${human.humanityVerified
|
|
|
1341
1555
|
- Telegram: ${human.telegram || 'Not provided'}
|
|
1342
1556
|
- Signal: ${human.signal || 'Not provided'}
|
|
1343
1557
|
|
|
1344
|
-
##
|
|
1558
|
+
## Crypto Wallets
|
|
1345
1559
|
${walletInfo || 'No wallets added'}
|
|
1346
1560
|
${primaryWallet ? `\n**Preferred wallet:** ${primaryWallet.chain || primaryWallet.network} - ${primaryWallet.address}` : ''}
|
|
1347
1561
|
|
|
1348
1562
|
## Fiat Payment Methods
|
|
1349
|
-
${fiatInfo || 'No fiat payment methods
|
|
1563
|
+
${fiatInfo || 'No fiat payment methods listed'}
|
|
1564
|
+
${(human.fiatPaymentMethods || []).length > 0 ? '\n_Note: Fiat payments are self-reported. The human must confirm receipt before the job is marked as paid._' : ''}
|
|
1350
1565
|
|
|
1351
1566
|
## Social Profiles
|
|
1352
1567
|
${socialLinks || 'No social profiles added'}`;
|
|
@@ -1458,7 +1673,7 @@ You can now create job offers and view full human profiles using \`get_human_pro
|
|
|
1458
1673
|
**Activated:** ${result.activatedAt || 'Not yet'}
|
|
1459
1674
|
**Expires:** ${result.activationExpiresAt || 'N/A'}
|
|
1460
1675
|
**Profile views:** ${limits?.profileViewsPerDay ?? 'N/A'}/day
|
|
1461
|
-
**Job offers:** ${jobLimit}${result.x402?.enabled ? `\n**x402 pay-per-use:** profile view ${result.x402.prices.profile_view}, job offer ${result.x402.prices.job_offer}` : ''}`,
|
|
1676
|
+
**Job offers:** ${jobLimit}${result.x402?.enabled ? `\n**x402 platform fees (pay-per-use):** profile view ${result.x402.prices.profile_view}, job offer ${result.x402.prices.job_offer} — these are platform access fees (USDC on Base), separate from payment you arrange with the human` : ''}`,
|
|
1462
1677
|
},
|
|
1463
1678
|
],
|
|
1464
1679
|
};
|
|
@@ -1583,7 +1798,7 @@ You can now create up to 15 job offers per day and view up to 50 full human prof
|
|
|
1583
1798
|
return {
|
|
1584
1799
|
content: [{
|
|
1585
1800
|
type: 'text',
|
|
1586
|
-
text: `**Tick Verified!**\n\n**Job ID:** ${result.id}\n**Status:** ${result.status}\n**Tick:** #${result.tick?.tickNumber}\n**Amount:** $${result.tick?.amount}
|
|
1801
|
+
text: `**Tick Verified!**\n\n**Job ID:** ${result.id}\n**Status:** ${result.status}\n**Tick:** #${result.tick?.tickNumber}\n**Amount:** $${result.tick?.amount}\n**Total Paid:** $${result.totalPaid}${result.nextTick ? `\n\n**Next payment due:** ${result.nextTick.expectedAt}` : ''}`,
|
|
1587
1802
|
}],
|
|
1588
1803
|
};
|
|
1589
1804
|
}
|
|
@@ -1655,7 +1870,7 @@ You can now create up to 15 job offers per day and view up to 50 full human prof
|
|
|
1655
1870
|
return {
|
|
1656
1871
|
content: [{
|
|
1657
1872
|
type: 'text',
|
|
1658
|
-
text: `**Stream Stopped**\n\n**Job ID:** ${result.id}\n**Status:** ${result.status}\n**Total Paid:** $${result.totalPaid || '0'}
|
|
1873
|
+
text: `**Stream Stopped**\n\n**Job ID:** ${result.id}\n**Status:** ${result.status}\n**Total Paid:** $${result.totalPaid || '0'}\n\nThe stream has ended. You can now use \`leave_review\` to rate the human.`,
|
|
1659
1874
|
}],
|
|
1660
1875
|
};
|
|
1661
1876
|
}
|
|
@@ -1721,7 +1936,7 @@ You can now create up to 15 job offers per day and view up to 50 full human prof
|
|
|
1721
1936
|
body: JSON.stringify({
|
|
1722
1937
|
title: args?.title,
|
|
1723
1938
|
description: args?.description,
|
|
1724
|
-
budgetUsdc: args?.
|
|
1939
|
+
budgetUsdc: args?.budget_usd,
|
|
1725
1940
|
category: args?.category,
|
|
1726
1941
|
requiredSkills: args?.required_skills || [],
|
|
1727
1942
|
requiredEquipment: args?.required_equipment || [],
|
|
@@ -1797,7 +2012,7 @@ You can now create up to 15 job offers per day and view up to 50 full human prof
|
|
|
1797
2012
|
const rep = l.agentReputation;
|
|
1798
2013
|
const agentInfo = agent ? `${agent.name}${agent.domainVerified ? ' ✅' : ''}` : 'Unknown';
|
|
1799
2014
|
const repInfo = rep?.completedJobs > 0 ? ` | ${rep.completedJobs} jobs, ${rep.avgRating ? `${rep.avgRating.toFixed(1)}★` : 'no ratings'}` : '';
|
|
1800
|
-
return `- **${l.title}** [$${l.budgetUsdc}
|
|
2015
|
+
return `- **${l.title}** [$${l.budgetUsdc}]${l.isPro ? ' 🏆 PRO' : ''}
|
|
1801
2016
|
Agent: ${agentInfo}${repInfo}
|
|
1802
2017
|
${l.category ? `Category: ${l.category} | ` : ''}${l.workMode || 'Any'} | ${l._count?.applications || 0} applicant(s)
|
|
1803
2018
|
${l.requiredSkills?.length > 0 ? `Skills: ${l.requiredSkills.join(', ')}` : ''}
|
|
@@ -1826,7 +2041,7 @@ You can now create up to 15 job offers per day and view up to 50 full human prof
|
|
|
1826
2041
|
|
|
1827
2042
|
**Listing ID:** ${listing.id}
|
|
1828
2043
|
**Status:** ${listing.status}
|
|
1829
|
-
**Budget:** $${listing.budgetUsdc}
|
|
2044
|
+
**Budget:** $${listing.budgetUsdc}
|
|
1830
2045
|
**Category:** ${listing.category || 'Not specified'}
|
|
1831
2046
|
**Work Mode:** ${listing.workMode || 'Any'}
|
|
1832
2047
|
**Expires:** ${listing.expiresAt}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "humanpages",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"mcpName": "io.github.human-pages-ai/humanpages",
|
|
5
|
-
"description": "MCP server (+ OpenClaw SKILL.md) that gives AI agents access to real-world people who listed themselves to be hired by agents. 31 tools including search by skill/location/equipment, job offers, job board listings, in-job messaging, and
|
|
5
|
+
"description": "MCP server (+ OpenClaw SKILL.md) that gives AI agents access to real-world people who listed themselves to be hired by agents. 31 tools including search by skill/location/equipment, job offers, job board listings, in-job messaging, streaming payments, and agent funding.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|