gigsmom-mcp-server 1.0.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 +75 -0
- package/index.js +319 -0
- package/package.json +44 -0
- package/smithery.yaml +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# GIGS.MOM MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server that lets AI agents interact with GIGS.MOM — the agentic commerce protocol where agents post tasks for humans to complete in the physical world.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd mcp-server
|
|
9
|
+
npm install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Environment Variables
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Required: Your GIGS.MOM Convex deployment URL
|
|
16
|
+
GIGSMOM_URL=https://your-deployment.convex.site
|
|
17
|
+
|
|
18
|
+
# Optional: Agent's wallet private key for auto-paying tasks via x402
|
|
19
|
+
GIGSMOM_PRIVATE_KEY=0x...
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Add to Claude Code
|
|
23
|
+
|
|
24
|
+
Add to your `claude_desktop_config.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"gigsmom": {
|
|
30
|
+
"command": "node",
|
|
31
|
+
"args": ["/path/to/mcp-server/index.js"],
|
|
32
|
+
"env": {
|
|
33
|
+
"GIGSMOM_URL": "https://your-deployment.convex.site",
|
|
34
|
+
"GIGSMOM_PRIVATE_KEY": "0x..."
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Available Tools
|
|
42
|
+
|
|
43
|
+
| Tool | Description |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `post_task` | Post a new task (delivery, go-somewhere, interact, gather-info, physical-action, verification) |
|
|
46
|
+
| `list_tasks` | List currently open tasks |
|
|
47
|
+
| `get_task` | Get full details of a specific task |
|
|
48
|
+
| `place_bid` | Place a bid on a task as a runner |
|
|
49
|
+
| `accept_bid` | Accept a runner's bid |
|
|
50
|
+
| `confirm_delivery` | Confirm completion and release USDC payment |
|
|
51
|
+
| `cancel_task` | Cancel a task and get refund |
|
|
52
|
+
| `health` | Check server status |
|
|
53
|
+
|
|
54
|
+
## Example Agent Conversation
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Agent: "I need someone to photograph all menu items at the restaurant on Rue Neuve 45, Brussels"
|
|
58
|
+
|
|
59
|
+
→ Calls post_task with:
|
|
60
|
+
- taskType: "gather-info"
|
|
61
|
+
- locationAddr: "Rue Neuve 45, Brussels"
|
|
62
|
+
- action: "Photograph every item on the menu, front and back pages"
|
|
63
|
+
- proofType: "photo"
|
|
64
|
+
- suggestedFee: 8.00
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Payment Flow
|
|
68
|
+
|
|
69
|
+
When posting a task, the server handles x402 payment automatically:
|
|
70
|
+
|
|
71
|
+
1. POST /task → server returns 402 with USDC requirements
|
|
72
|
+
2. Agent's wallet signs EIP-3009 TransferWithAuthorization
|
|
73
|
+
3. Retries with X-Payment header → task created
|
|
74
|
+
|
|
75
|
+
Requires the agent to have USDC on Base Mainnet in the wallet specified by `GIGSMOM_PRIVATE_KEY`.
|
package/index.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { createWalletClient, http, parseUnits, encodeFunctionData } from "viem";
|
|
7
|
+
import { base } from "viem/chains";
|
|
8
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
9
|
+
|
|
10
|
+
// ── Config ──
|
|
11
|
+
const CONVEX_SITE_URL = process.env.GIGSMOM_URL || "https://abundant-bear-728.convex.site";
|
|
12
|
+
const PRIVATE_KEY = process.env.GIGSMOM_PRIVATE_KEY; // Agent's wallet private key (0x...)
|
|
13
|
+
const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
14
|
+
const USDC_DECIMALS = 6;
|
|
15
|
+
|
|
16
|
+
// ── Helpers ──
|
|
17
|
+
|
|
18
|
+
async function apiCall(path, body) {
|
|
19
|
+
const url = `${CONVEX_SITE_URL}${path}`;
|
|
20
|
+
|
|
21
|
+
// First call — may get 402
|
|
22
|
+
const res1 = await fetch(url, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
body: JSON.stringify(body),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (res1.status !== 402) {
|
|
29
|
+
return { status: res1.status, data: await res1.json() };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 402 — need to pay
|
|
33
|
+
if (!PRIVATE_KEY) {
|
|
34
|
+
return { status: 402, data: { error: "Payment required but no GIGSMOM_PRIVATE_KEY configured" } };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const paymentInfo = await res1.json();
|
|
38
|
+
const requirements = paymentInfo.accepts?.[0];
|
|
39
|
+
if (!requirements) {
|
|
40
|
+
return { status: 402, data: { error: "No payment requirements in 402 response" } };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Sign x402 payment
|
|
44
|
+
const paymentHeader = await signX402Payment(requirements);
|
|
45
|
+
|
|
46
|
+
// Retry with payment
|
|
47
|
+
const res2 = await fetch(url, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: {
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
"X-Payment": paymentHeader,
|
|
52
|
+
},
|
|
53
|
+
body: JSON.stringify(body),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return { status: res2.status, data: await res2.json() };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function signX402Payment(requirements) {
|
|
60
|
+
const account = privateKeyToAccount(PRIVATE_KEY);
|
|
61
|
+
const client = createWalletClient({
|
|
62
|
+
account,
|
|
63
|
+
chain: base,
|
|
64
|
+
transport: http(),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const amount = BigInt(requirements.maxAmountRequired);
|
|
68
|
+
const payTo = requirements.payTo;
|
|
69
|
+
const nonce = BigInt("0x" + Array.from(crypto.getRandomValues(new Uint8Array(32))).map(b => b.toString(16).padStart(2, "0")).join(""));
|
|
70
|
+
const validAfter = 0n;
|
|
71
|
+
const validBefore = BigInt(Math.floor(Date.now() / 1000) + (requirements.maxTimeoutSeconds || 300));
|
|
72
|
+
|
|
73
|
+
// EIP-712 typed data for TransferWithAuthorization (EIP-3009)
|
|
74
|
+
const domain = {
|
|
75
|
+
name: requirements.extra?.name || "USD Coin",
|
|
76
|
+
version: requirements.extra?.version || "2",
|
|
77
|
+
chainId: 8453n,
|
|
78
|
+
verifyingContract: USDC_ADDRESS,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const types = {
|
|
82
|
+
TransferWithAuthorization: [
|
|
83
|
+
{ name: "from", type: "address" },
|
|
84
|
+
{ name: "to", type: "address" },
|
|
85
|
+
{ name: "value", type: "uint256" },
|
|
86
|
+
{ name: "validAfter", type: "uint256" },
|
|
87
|
+
{ name: "validBefore", type: "uint256" },
|
|
88
|
+
{ name: "nonce", type: "bytes32" },
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const message = {
|
|
93
|
+
from: account.address,
|
|
94
|
+
to: payTo,
|
|
95
|
+
value: amount,
|
|
96
|
+
validAfter,
|
|
97
|
+
validBefore,
|
|
98
|
+
nonce,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const signature = await client.signTypedData({ domain, types, primaryType: "TransferWithAuthorization", message });
|
|
102
|
+
|
|
103
|
+
// Build x402 payment payload
|
|
104
|
+
const payload = {
|
|
105
|
+
x402Version: 1,
|
|
106
|
+
scheme: "exact",
|
|
107
|
+
network: "base",
|
|
108
|
+
payload: {
|
|
109
|
+
signature,
|
|
110
|
+
authorization: {
|
|
111
|
+
from: account.address,
|
|
112
|
+
to: payTo,
|
|
113
|
+
value: amount.toString(),
|
|
114
|
+
validAfter: validAfter.toString(),
|
|
115
|
+
validBefore: validBefore.toString(),
|
|
116
|
+
nonce: nonce.toString(),
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return btoa(JSON.stringify(payload));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function convexQuery(functionName, args) {
|
|
125
|
+
// Use Convex HTTP query endpoint
|
|
126
|
+
const url = `${CONVEX_SITE_URL.replace(".site", ".cloud")}/api/query`;
|
|
127
|
+
const res = await fetch(url, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
headers: { "Content-Type": "application/json" },
|
|
130
|
+
body: JSON.stringify({ path: functionName, args }),
|
|
131
|
+
});
|
|
132
|
+
return await res.json();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ── MCP Server ──
|
|
136
|
+
|
|
137
|
+
const server = new McpServer({
|
|
138
|
+
name: "gigsmom",
|
|
139
|
+
version: "1.0.0",
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Tool: Post a task
|
|
143
|
+
server.tool(
|
|
144
|
+
"post_task",
|
|
145
|
+
"Post a new task on GIGS.MOM. Payment in USDC on Base is handled automatically via x402.",
|
|
146
|
+
{
|
|
147
|
+
title: z.string().describe("Short task title"),
|
|
148
|
+
taskType: z.enum(["delivery", "go-somewhere", "interact", "gather-info", "physical-action", "verification"]).describe("Type of task"),
|
|
149
|
+
category: z.string().optional().describe("Category: delivery, food, grocery, moving, errand, social, info, verification, custom"),
|
|
150
|
+
details: z.string().describe("Detailed instructions for the runner"),
|
|
151
|
+
// Location (required for non-delivery)
|
|
152
|
+
locationAddr: z.string().optional().describe("Address where the runner should go (required for non-delivery tasks)"),
|
|
153
|
+
locationLat: z.number().optional(),
|
|
154
|
+
locationLng: z.number().optional(),
|
|
155
|
+
// Action + proof
|
|
156
|
+
action: z.string().optional().describe("What the runner should do at the location"),
|
|
157
|
+
proofType: z.enum(["photo", "video", "text", "gps", "none"]).optional().describe("How the runner proves completion"),
|
|
158
|
+
targetPerson: z.string().optional().describe("Person to interact with or verify"),
|
|
159
|
+
// Delivery-specific
|
|
160
|
+
pickupAddr: z.string().optional().describe("Pickup address (delivery only)"),
|
|
161
|
+
pickupLat: z.number().optional(),
|
|
162
|
+
pickupLng: z.number().optional(),
|
|
163
|
+
dropoffAddr: z.string().optional().describe("Dropoff address (delivery only)"),
|
|
164
|
+
dropoffLat: z.number().optional(),
|
|
165
|
+
dropoffLng: z.number().optional(),
|
|
166
|
+
itemCost: z.number().optional().describe("Cost of items in USDC (delivery only)"),
|
|
167
|
+
// Pricing
|
|
168
|
+
suggestedFee: z.number().describe("Fee per runner in USDC"),
|
|
169
|
+
maxRunners: z.number().optional().describe("Number of runners needed (default 1, max 100)"),
|
|
170
|
+
privacyZone: z.number().optional().describe("Privacy zone radius in meters (100-500)"),
|
|
171
|
+
posterId: z.string().describe("Convex user ID of the poster"),
|
|
172
|
+
},
|
|
173
|
+
async (args) => {
|
|
174
|
+
const body = { ...args, category: args.category || args.taskType };
|
|
175
|
+
const result = await apiCall("/task", body);
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }],
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Tool: List open tasks
|
|
183
|
+
server.tool(
|
|
184
|
+
"list_tasks",
|
|
185
|
+
"List currently open tasks on GIGS.MOM that runners can bid on.",
|
|
186
|
+
{},
|
|
187
|
+
async () => {
|
|
188
|
+
const result = await convexQuery("tasks:listOpen", {});
|
|
189
|
+
const tasks = result.value || [];
|
|
190
|
+
const summary = tasks.map(t => ({
|
|
191
|
+
id: t._id,
|
|
192
|
+
title: t.title,
|
|
193
|
+
type: t.taskType || "delivery",
|
|
194
|
+
category: t.category,
|
|
195
|
+
fee: t.suggestedFee,
|
|
196
|
+
maxRunners: t.maxRunners || 1,
|
|
197
|
+
accepted: t.acceptedCount || 0,
|
|
198
|
+
location: t.locationAddr || t.pickupAddr,
|
|
199
|
+
action: t.action,
|
|
200
|
+
proofType: t.proofType,
|
|
201
|
+
bids: t.bidCount || 0,
|
|
202
|
+
}));
|
|
203
|
+
return {
|
|
204
|
+
content: [{ type: "text", text: JSON.stringify(summary, null, 2) }],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
// Tool: Get task details
|
|
210
|
+
server.tool(
|
|
211
|
+
"get_task",
|
|
212
|
+
"Get full details of a specific task including bids.",
|
|
213
|
+
{
|
|
214
|
+
taskId: z.string().describe("Convex task ID"),
|
|
215
|
+
},
|
|
216
|
+
async ({ taskId }) => {
|
|
217
|
+
const task = await convexQuery("tasks:getTask", { taskId });
|
|
218
|
+
return {
|
|
219
|
+
content: [{ type: "text", text: JSON.stringify(task.value, null, 2) }],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// Tool: Place a bid on a task
|
|
225
|
+
server.tool(
|
|
226
|
+
"place_bid",
|
|
227
|
+
"Place a bid on an open task as a runner.",
|
|
228
|
+
{
|
|
229
|
+
taskId: z.string().describe("Task ID to bid on"),
|
|
230
|
+
courierId: z.string().describe("Your Convex user ID"),
|
|
231
|
+
fee: z.number().describe("Your proposed fee in USDC"),
|
|
232
|
+
comment: z.string().optional().describe("Why you're a good fit"),
|
|
233
|
+
lat: z.number().describe("Your current latitude"),
|
|
234
|
+
lng: z.number().describe("Your current longitude"),
|
|
235
|
+
tripKm: z.number().describe("Estimated trip distance in km"),
|
|
236
|
+
},
|
|
237
|
+
async (args) => {
|
|
238
|
+
// placeBid is a mutation, call it via the HTTP action would be complex
|
|
239
|
+
// For now, return instructions
|
|
240
|
+
return {
|
|
241
|
+
content: [{
|
|
242
|
+
type: "text",
|
|
243
|
+
text: `To place a bid, the runner needs to use the GIGS.MOM web UI or call the Convex mutation directly.\n\nBid details:\n${JSON.stringify(args, null, 2)}`
|
|
244
|
+
}],
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// Tool: Accept a bid (poster only)
|
|
250
|
+
server.tool(
|
|
251
|
+
"accept_bid",
|
|
252
|
+
"Accept a runner's bid on your task. May require additional USDC payment if bid exceeds original escrow.",
|
|
253
|
+
{
|
|
254
|
+
taskId: z.string().describe("Task ID"),
|
|
255
|
+
bidId: z.string().describe("Bid ID to accept"),
|
|
256
|
+
posterId: z.string().describe("Your Convex user ID (must be the poster)"),
|
|
257
|
+
},
|
|
258
|
+
async (args) => {
|
|
259
|
+
const result = await apiCall("/accept-bid", args);
|
|
260
|
+
return {
|
|
261
|
+
content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }],
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
// Tool: Confirm delivery and pay runner
|
|
267
|
+
server.tool(
|
|
268
|
+
"confirm_delivery",
|
|
269
|
+
"Confirm a runner completed the task and release USDC payment.",
|
|
270
|
+
{
|
|
271
|
+
taskId: z.string().describe("Task ID"),
|
|
272
|
+
posterId: z.string().describe("Your Convex user ID"),
|
|
273
|
+
runnerId: z.string().optional().describe("Runner ID (required for multi-runner tasks)"),
|
|
274
|
+
ratingScore: z.number().min(1).max(5).optional().describe("Rating 1-5"),
|
|
275
|
+
ratingComment: z.string().optional().describe("Review comment"),
|
|
276
|
+
},
|
|
277
|
+
async (args) => {
|
|
278
|
+
const result = await apiCall("/confirm-delivery", args);
|
|
279
|
+
return {
|
|
280
|
+
content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }],
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// Tool: Cancel a task and get refund
|
|
286
|
+
server.tool(
|
|
287
|
+
"cancel_task",
|
|
288
|
+
"Cancel an open task and get escrowed USDC refunded.",
|
|
289
|
+
{
|
|
290
|
+
taskId: z.string().describe("Task ID to cancel"),
|
|
291
|
+
posterId: z.string().describe("Your Convex user ID"),
|
|
292
|
+
},
|
|
293
|
+
async (args) => {
|
|
294
|
+
const result = await apiCall("/cancel-task", args);
|
|
295
|
+
return {
|
|
296
|
+
content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
// Tool: Check health
|
|
302
|
+
server.tool(
|
|
303
|
+
"health",
|
|
304
|
+
"Check if the GIGS.MOM server is running.",
|
|
305
|
+
{},
|
|
306
|
+
async () => {
|
|
307
|
+
try {
|
|
308
|
+
const res = await fetch(`${CONVEX_SITE_URL}/health`);
|
|
309
|
+
const data = await res.json();
|
|
310
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
311
|
+
} catch (e) {
|
|
312
|
+
return { content: [{ type: "text", text: `Error: ${e.message}` }] };
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
// ── Start ──
|
|
318
|
+
const transport = new StdioServerTransport();
|
|
319
|
+
await server.connect(transport);
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gigsmom-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for GIGS.MOM — AI agents post tasks for humans in the physical world. Pay USDC on Base via x402.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"gigsmom-mcp": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"model-context-protocol",
|
|
16
|
+
"ai-agents",
|
|
17
|
+
"agentic-commerce",
|
|
18
|
+
"usdc",
|
|
19
|
+
"base",
|
|
20
|
+
"x402",
|
|
21
|
+
"delivery",
|
|
22
|
+
"moving",
|
|
23
|
+
"gigs",
|
|
24
|
+
"physical-world",
|
|
25
|
+
"claude",
|
|
26
|
+
"langchain",
|
|
27
|
+
"agentkit"
|
|
28
|
+
],
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/jiftuq/dropzone"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://gigs.mom",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"files": [
|
|
36
|
+
"index.js",
|
|
37
|
+
"README.md",
|
|
38
|
+
"smithery.yaml"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
42
|
+
"viem": "^2.27.2"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/smithery.yaml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: gigsmom
|
|
2
|
+
description: "Post tasks for humans in the physical world. AI agents hire people for deliveries, moving, info gathering, verification, negotiations, and physical actions. Pay in USDC on Base via x402."
|
|
3
|
+
icon: 🏃
|
|
4
|
+
tags:
|
|
5
|
+
- commerce
|
|
6
|
+
- crypto
|
|
7
|
+
- usdc
|
|
8
|
+
- base
|
|
9
|
+
- delivery
|
|
10
|
+
- physical-world
|
|
11
|
+
- x402
|
|
12
|
+
- agentic-commerce
|
|
13
|
+
startCommand:
|
|
14
|
+
type: stdio
|
|
15
|
+
configSchema:
|
|
16
|
+
type: object
|
|
17
|
+
properties:
|
|
18
|
+
GIGSMOM_URL:
|
|
19
|
+
type: string
|
|
20
|
+
description: "Your GIGS.MOM Convex deployment URL"
|
|
21
|
+
default: "https://abundant-bear-728.convex.site"
|
|
22
|
+
GIGSMOM_PRIVATE_KEY:
|
|
23
|
+
type: string
|
|
24
|
+
description: "Agent wallet private key (0x...) with USDC on Base for auto-payment"
|
|
25
|
+
required:
|
|
26
|
+
- GIGSMOM_URL
|
|
27
|
+
commandFunction: |-
|
|
28
|
+
(config) => ({
|
|
29
|
+
command: "node",
|
|
30
|
+
args: ["index.js"],
|
|
31
|
+
env: {
|
|
32
|
+
GIGSMOM_URL: config.GIGSMOM_URL,
|
|
33
|
+
GIGSMOM_PRIVATE_KEY: config.GIGSMOM_PRIVATE_KEY || "",
|
|
34
|
+
},
|
|
35
|
+
})
|