@justhandledlabs/agent-client 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/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +31 -0
- package/dist/client.d.ts +11 -0
- package/dist/client.js +78 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +48 -0
- package/package.json +69 -0
- package/server.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JustHandled Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# JustHandled Agent Client
|
|
2
|
+
|
|
3
|
+
A guarded CLI, JavaScript client, and local MCP server for the [JustHandled Agent Utility Gateway](https://justhandled-agent-gateway.netlify.app). The package exposes ten deterministic preflights. Each paid call costs exactly $0.05 USDC on Base mainnet and returns a versioned evidence receipt.
|
|
4
|
+
|
|
5
|
+
The client fails closed before signing. It accepts only the pinned JustHandled gateway, Base mainnet, the canonical Base USDC contract, a 50,000-base-unit price, and the published merchant receiver. Customer inputs are not persisted by the gateway.
|
|
6
|
+
|
|
7
|
+
## Inspect without a wallet
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx --package @justhandledlabs/agent-client justhandled-agent catalog
|
|
11
|
+
npx --package @justhandledlabs/agent-client justhandled-agent preview filename-portability-preflight --json '{"paths":["CON.txt"]}'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Preview performs an unpaid request and validates the returned x402 terms. It does not sign or spend.
|
|
15
|
+
|
|
16
|
+
## Execute one paid utility
|
|
17
|
+
|
|
18
|
+
Use a dedicated low-balance Base wallet. Never provide a primary wallet key.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
export JH_EVM_PRIVATE_KEY=0x...
|
|
22
|
+
npx --package @justhandledlabs/agent-client justhandled-agent call filename-portability-preflight --json '{"paths":["CON.txt"]}'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
PowerShell:
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
$env:JH_EVM_PRIVATE_KEY = "0x..."
|
|
29
|
+
npx.cmd --package @justhandledlabs/agent-client justhandled-agent call filename-portability-preflight --json '{"paths":["CON.txt"]}'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## MCP configuration
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"justhandled": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "@justhandledlabs/agent-client"],
|
|
40
|
+
"env": {
|
|
41
|
+
"JH_EVM_PRIVATE_KEY": "0xDEDICATED_LOW_BALANCE_WALLET_KEY"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The MCP server exposes a free catalog tool plus one paid tool per gateway utility. Missing wallet configuration produces an error instead of a payment attempt.
|
|
49
|
+
|
|
50
|
+
## Security model
|
|
51
|
+
|
|
52
|
+
- Price, chain, asset, receiver, and gateway origin are pinned in code.
|
|
53
|
+
- Every execution starts with an unpaid 402 preview.
|
|
54
|
+
- A mismatched term aborts before signing.
|
|
55
|
+
- The package never prints the private key.
|
|
56
|
+
- The gateway does not persist raw inputs or results.
|
|
57
|
+
- Treat all crypto transfers as irreversible and fund only a dedicated wallet.
|
|
58
|
+
|
|
59
|
+
## Development
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install
|
|
63
|
+
npm run check
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The gateway implementation is intentionally not included in this client repository.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { getCatalog, previewUtility, runPaidUtility } from "./client.js";
|
|
4
|
+
function value(flag) {
|
|
5
|
+
const index = process.argv.indexOf(flag);
|
|
6
|
+
return index >= 0 ? process.argv[index + 1] : undefined;
|
|
7
|
+
}
|
|
8
|
+
async function readInput() {
|
|
9
|
+
const json = value("--json");
|
|
10
|
+
const file = value("--file");
|
|
11
|
+
if ((json ? 1 : 0) + (file ? 1 : 0) !== 1)
|
|
12
|
+
throw new Error("provide exactly one of --json or --file");
|
|
13
|
+
return JSON.parse(json ?? await readFile(file, "utf8"));
|
|
14
|
+
}
|
|
15
|
+
const [command, utility] = process.argv.slice(2);
|
|
16
|
+
if (command === "catalog") {
|
|
17
|
+
console.log(JSON.stringify(await getCatalog(), null, 2));
|
|
18
|
+
}
|
|
19
|
+
else if (command === "preview" && utility) {
|
|
20
|
+
console.log(JSON.stringify(await previewUtility(utility, await readInput()), null, 2));
|
|
21
|
+
}
|
|
22
|
+
else if (command === "call" && utility) {
|
|
23
|
+
const key = process.env.JH_EVM_PRIVATE_KEY;
|
|
24
|
+
if (!key)
|
|
25
|
+
throw new Error("JH_EVM_PRIVATE_KEY is required for a paid call");
|
|
26
|
+
console.log(JSON.stringify(await runPaidUtility(utility, await readInput(), key), null, 2));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.error("usage:\n justhandled-agent catalog\n justhandled-agent preview <utility> (--json <json> | --file <path>)\n justhandled-agent call <utility> (--json <json> | --file <path>)");
|
|
30
|
+
process.exitCode = 2;
|
|
31
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { decodePaymentResponseHeader } from "@x402/core/http";
|
|
2
|
+
import type { PaymentRequired, PaymentRequirements } from "@x402/core/types";
|
|
3
|
+
import { type UtilityCatalog } from "./config.js";
|
|
4
|
+
export interface PaidUtilityResult {
|
|
5
|
+
result: Record<string, unknown>;
|
|
6
|
+
payment: ReturnType<typeof decodePaymentResponseHeader>;
|
|
7
|
+
}
|
|
8
|
+
export declare function getCatalog(fetchImpl?: typeof fetch): Promise<UtilityCatalog>;
|
|
9
|
+
export declare function selectGuardedRequirement(required: PaymentRequired, expectedResourceUrl?: string): PaymentRequirements;
|
|
10
|
+
export declare function previewUtility(utility: string, input: unknown, fetchImpl?: typeof fetch, source?: string): Promise<PaymentRequirements>;
|
|
11
|
+
export declare function runPaidUtility(utility: string, input: unknown, privateKey: `0x${string}`, fetchImpl?: typeof fetch, source?: string): Promise<PaidUtilityResult>;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { decodePaymentRequiredHeader, decodePaymentResponseHeader } from "@x402/core/http";
|
|
2
|
+
import { ExactEvmScheme } from "@x402/evm";
|
|
3
|
+
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
|
|
4
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
5
|
+
import { BASE_MAINNET, BASE_USDC, GATEWAY_ORIGIN, JUSTHANDLED_RECEIVER, PRICE_BASE_UNITS, PRICE_USDC, } from "./config.js";
|
|
6
|
+
const UTILITY_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
7
|
+
function endpointFor(utility) {
|
|
8
|
+
if (!UTILITY_ID.test(utility))
|
|
9
|
+
throw new Error("utility id must be lowercase kebab-case");
|
|
10
|
+
return `${GATEWAY_ORIGIN}/api/run/${utility}`;
|
|
11
|
+
}
|
|
12
|
+
function requestFor(input, source) {
|
|
13
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(source))
|
|
14
|
+
throw new Error("source must be a bounded lowercase attribution slug");
|
|
15
|
+
return {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: { "content-type": "application/json", "x-jh-source": source },
|
|
18
|
+
body: JSON.stringify(input),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function getCatalog(fetchImpl = fetch) {
|
|
22
|
+
const response = await fetchImpl(`${GATEWAY_ORIGIN}/api/catalog`);
|
|
23
|
+
if (!response.ok)
|
|
24
|
+
throw new Error(`catalog request failed with HTTP ${response.status}`);
|
|
25
|
+
const catalog = await response.json();
|
|
26
|
+
if (!Array.isArray(catalog.utilities) || catalog.count !== catalog.utilities.length)
|
|
27
|
+
throw new Error("gateway returned a malformed catalog");
|
|
28
|
+
for (const utility of catalog.utilities) {
|
|
29
|
+
const expectedEndpoint = `${GATEWAY_ORIGIN}/api/run/${utility.id}`;
|
|
30
|
+
if (!UTILITY_ID.test(utility.id) || utility.endpoint !== expectedEndpoint || utility.price !== PRICE_USDC) {
|
|
31
|
+
throw new Error("gateway catalog contains an untrusted utility endpoint or price");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return catalog;
|
|
35
|
+
}
|
|
36
|
+
export function selectGuardedRequirement(required, expectedResourceUrl) {
|
|
37
|
+
if (expectedResourceUrl && required.resource?.url !== expectedResourceUrl) {
|
|
38
|
+
throw new Error("refusing payment: payment resource does not match the requested JustHandled endpoint");
|
|
39
|
+
}
|
|
40
|
+
const requirement = required.accepts.find((candidate) => candidate.scheme === "exact" &&
|
|
41
|
+
candidate.network === BASE_MAINNET &&
|
|
42
|
+
candidate.asset.toLowerCase() === BASE_USDC.toLowerCase() &&
|
|
43
|
+
candidate.amount === PRICE_BASE_UNITS &&
|
|
44
|
+
candidate.payTo.toLowerCase() === JUSTHANDLED_RECEIVER.toLowerCase());
|
|
45
|
+
if (!requirement) {
|
|
46
|
+
throw new Error("refusing payment: gateway requirements do not match the pinned Base network, USDC asset, $0.05 amount, and JustHandled receiver");
|
|
47
|
+
}
|
|
48
|
+
return requirement;
|
|
49
|
+
}
|
|
50
|
+
export async function previewUtility(utility, input, fetchImpl = fetch, source = "npm-client") {
|
|
51
|
+
const endpoint = endpointFor(utility);
|
|
52
|
+
const response = await fetchImpl(endpoint, requestFor(input, source));
|
|
53
|
+
if (response.status !== 402)
|
|
54
|
+
throw new Error(`expected an unpaid 402 preview, received HTTP ${response.status}`);
|
|
55
|
+
const header = response.headers.get("payment-required");
|
|
56
|
+
if (!header)
|
|
57
|
+
throw new Error("gateway omitted the Payment-Required header");
|
|
58
|
+
return selectGuardedRequirement(decodePaymentRequiredHeader(header), endpoint);
|
|
59
|
+
}
|
|
60
|
+
export async function runPaidUtility(utility, input, privateKey, fetchImpl = fetch, source = "npm-client") {
|
|
61
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(privateKey))
|
|
62
|
+
throw new Error("JH_EVM_PRIVATE_KEY must be a 32-byte hex private key");
|
|
63
|
+
await previewUtility(utility, input, fetchImpl, source);
|
|
64
|
+
const account = privateKeyToAccount(privateKey);
|
|
65
|
+
const paidFetch = wrapFetchWithPaymentFromConfig(fetchImpl, {
|
|
66
|
+
schemes: [{ network: BASE_MAINNET, client: new ExactEvmScheme(account) }],
|
|
67
|
+
});
|
|
68
|
+
const response = await paidFetch(endpointFor(utility), requestFor(input, source));
|
|
69
|
+
const paymentHeader = response.headers.get("payment-response") ?? response.headers.get("x-payment-response");
|
|
70
|
+
if (response.status !== 200 || !paymentHeader) {
|
|
71
|
+
const detail = await response.text();
|
|
72
|
+
throw new Error(`paid request failed with HTTP ${response.status}${detail ? `: ${detail.slice(0, 300)}` : ""}`);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
result: await response.json(),
|
|
76
|
+
payment: decodePaymentResponseHeader(paymentHeader),
|
|
77
|
+
};
|
|
78
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const GATEWAY_ORIGIN = "https://justhandled-agent-gateway.netlify.app";
|
|
2
|
+
export declare const BASE_MAINNET = "eip155:8453";
|
|
3
|
+
export declare const BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
4
|
+
export declare const JUSTHANDLED_RECEIVER = "0xd7edc83c55c994850a14604a628639c3599665bc";
|
|
5
|
+
export declare const PRICE_BASE_UNITS = "50000";
|
|
6
|
+
export declare const PRICE_USDC = "$0.05";
|
|
7
|
+
export interface UtilityCatalogItem {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
version: string;
|
|
11
|
+
category: string;
|
|
12
|
+
summary: string;
|
|
13
|
+
price: string;
|
|
14
|
+
docsUrl: string;
|
|
15
|
+
limitations: string[];
|
|
16
|
+
inputSchema: Record<string, unknown>;
|
|
17
|
+
sampleInput: Record<string, unknown>;
|
|
18
|
+
endpoint: string;
|
|
19
|
+
}
|
|
20
|
+
export interface UtilityCatalog {
|
|
21
|
+
schemaVersion: string;
|
|
22
|
+
count: number;
|
|
23
|
+
utilities: UtilityCatalogItem[];
|
|
24
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const GATEWAY_ORIGIN = "https://justhandled-agent-gateway.netlify.app";
|
|
2
|
+
export const BASE_MAINNET = "eip155:8453";
|
|
3
|
+
export const BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
4
|
+
export const JUSTHANDLED_RECEIVER = "0xd7edc83c55c994850a14604a628639c3599665bc";
|
|
5
|
+
export const PRICE_BASE_UNITS = "50000";
|
|
6
|
+
export const PRICE_USDC = "$0.05";
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/mcp.d.ts
ADDED
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { getCatalog, runPaidUtility } from "./client.js";
|
|
6
|
+
import { PRICE_USDC } from "./config.js";
|
|
7
|
+
const server = new Server({ name: "justhandled-agent-gateway", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
8
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
9
|
+
const catalog = await getCatalog();
|
|
10
|
+
return {
|
|
11
|
+
tools: [
|
|
12
|
+
{
|
|
13
|
+
name: "justhandled_list_utilities",
|
|
14
|
+
description: "List JustHandled deterministic preflights, prices, and limitations.",
|
|
15
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
16
|
+
},
|
|
17
|
+
...catalog.utilities.map((utility) => ({
|
|
18
|
+
name: `justhandled_${utility.id.replace(/-/g, "_")}`,
|
|
19
|
+
description: `${utility.summary} Costs ${PRICE_USDC} USDC on Base mainnet.`,
|
|
20
|
+
inputSchema: utility.inputSchema,
|
|
21
|
+
})),
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
26
|
+
if (request.params.name === "justhandled_list_utilities") {
|
|
27
|
+
return { content: [{ type: "text", text: JSON.stringify(await getCatalog()) }] };
|
|
28
|
+
}
|
|
29
|
+
const catalog = await getCatalog();
|
|
30
|
+
const utility = catalog.utilities.find((candidate) => `justhandled_${candidate.id.replace(/-/g, "_")}` === request.params.name);
|
|
31
|
+
if (!utility)
|
|
32
|
+
return { content: [{ type: "text", text: "Unknown JustHandled utility" }], isError: true };
|
|
33
|
+
const key = process.env.JH_EVM_PRIVATE_KEY;
|
|
34
|
+
if (!key) {
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: "text", text: `Paid execution requires JH_EVM_PRIVATE_KEY. This tool will spend exactly ${PRICE_USDC} USDC only after validating the pinned Base network, USDC contract, price, and receiver.` }],
|
|
37
|
+
isError: true,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const output = await runPaidUtility(utility.id, request.params.arguments ?? {}, key, fetch, "npm-mcp");
|
|
42
|
+
return { content: [{ type: "text", text: JSON.stringify(output) }] };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true };
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
await server.connect(new StdioServerTransport());
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@justhandledlabs/agent-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Guarded CLI and MCP client for JustHandled's x402 utility gateway",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"mcpName": "com.justhandledlabs/agent-gateway",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/justhandledlabs/justhandled-agent-client.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://justhandled-agent-gateway.netlify.app",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/justhandledlabs/justhandled-agent-client/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai-agents",
|
|
18
|
+
"mcp",
|
|
19
|
+
"x402",
|
|
20
|
+
"base",
|
|
21
|
+
"usdc",
|
|
22
|
+
"preflight"
|
|
23
|
+
],
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"server.json"
|
|
29
|
+
],
|
|
30
|
+
"bin": {
|
|
31
|
+
"agent-client": "dist/mcp.js",
|
|
32
|
+
"justhandled-agent-client": "dist/mcp.js",
|
|
33
|
+
"justhandled-agent": "dist/cli.js",
|
|
34
|
+
"justhandled-agent-mcp": "dist/mcp.js"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/index.js"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "node scripts/clean.mjs && tsc -p tsconfig.json",
|
|
44
|
+
"test": "node --import tsx --test tests/*.test.ts",
|
|
45
|
+
"smoke:mcp": "npm run build && node scripts/smoke-mcp.mjs",
|
|
46
|
+
"check": "npm run build && npm test",
|
|
47
|
+
"prepack": "npm run check",
|
|
48
|
+
"prepublishOnly": "node scripts/assert-publish-ready.mjs"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@modelcontextprotocol/sdk": "latest",
|
|
52
|
+
"@x402/core": "latest",
|
|
53
|
+
"@x402/evm": "latest",
|
|
54
|
+
"@x402/fetch": "^2.20.0",
|
|
55
|
+
"viem": "^2.55.10"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "latest",
|
|
59
|
+
"tsx": "latest",
|
|
60
|
+
"typescript": "latest"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=22"
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public",
|
|
67
|
+
"provenance": true
|
|
68
|
+
}
|
|
69
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "com.justhandledlabs/agent-gateway",
|
|
4
|
+
"title": "JustHandled Agent Utility Gateway",
|
|
5
|
+
"description": "Ten deterministic preflights with guarded $0.05 USDC x402 execution.",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/justhandledlabs/justhandled-agent-client",
|
|
9
|
+
"source": "github"
|
|
10
|
+
},
|
|
11
|
+
"packages": [
|
|
12
|
+
{
|
|
13
|
+
"registryType": "npm",
|
|
14
|
+
"identifier": "@justhandledlabs/agent-client",
|
|
15
|
+
"version": "0.1.0",
|
|
16
|
+
"transport": {
|
|
17
|
+
"type": "stdio"
|
|
18
|
+
},
|
|
19
|
+
"environmentVariables": [
|
|
20
|
+
{
|
|
21
|
+
"name": "JH_EVM_PRIVATE_KEY",
|
|
22
|
+
"description": "Private key for a dedicated Base wallet funded with USDC. Never use a primary wallet.",
|
|
23
|
+
"isRequired": true,
|
|
24
|
+
"isSecret": true,
|
|
25
|
+
"format": "string"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|