🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

aproxproxy-mcp

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aproxproxy-mcp - npm Package Compare versions

Comparing version
0.1.1
to
0.1.2
+63
-6
dist/index.js

@@ -104,2 +104,39 @@ #!/usr/bin/env node

}
/**
* Free discovery of ISO exit countries accepted by create_session `region`.
* Uses plain fetch (no x402) — same pattern as closeSession.
*/
async listCountries() {
const res = await fetch(`${this.baseUrl}/v1/countries`, {
method: "GET",
headers: { [CLIENT_SOURCE_HEADER]: CLIENT_SOURCE_VALUE }
});
const text = await res.text();
if (res.status >= 400) {
return { ok: false, error: await this.toHttpError(res.status, text) };
}
try {
const parsed = JSON.parse(text);
if (!Array.isArray(parsed.countries)) {
return {
ok: false,
error: {
status: res.status,
error: "countries response missing countries array",
body: text.slice(0, 500)
}
};
}
return { ok: true, data: parsed };
} catch {
return {
ok: false,
error: {
status: res.status,
error: "invalid JSON in countries response",
body: text.slice(0, 500)
}
};
}
}
async extendSession(sessionId) {

@@ -247,9 +284,10 @@ const res = await this.request(

region: z2.string().optional().describe(
"Preferred exit region (e.g. us, eu). Not yet supported by the proxy API \u2014 accepted and ignored for now."
"Exit country for product A is not enforced yet (accepted and ignored). For country-pinned sticky IPs use create_session with region after list_countries."
)
};
var listCountriesInputSchema = {};
var createSessionInputSchema = {
duration_minutes: z2.union([z2.literal(30), z2.literal(60)]).optional().describe("Session TTL in minutes (30 or 60). Default 30."),
region: z2.string().optional().describe(
"Preferred exit region (e.g. us, eu). Not yet supported by the proxy API \u2014 accepted and ignored for now."
"ISO 3166-1 alpha-2 exit country (e.g. us, de). Optional; omit for any-country pool. Call list_countries first for the allowlist. No surcharge."
)

@@ -272,3 +310,3 @@ };

var MCP_SERVER_NAME = "aproxproxy";
var MCP_SERVER_VERSION = "0.1.0";
var MCP_SERVER_VERSION = "0.1.2";
var MAX_BODY_CHARS = 1e5;

@@ -298,6 +336,25 @@ function errorResult(err) {

server.registerTool(
"list_countries",
{
title: "List exit countries",
description: "Free discovery: return ISO 3166-1 alpha-2 exit countries accepted by create_session `region` (OFAC codes excluded). Call before create_session when you need a specific country. No payment.",
inputSchema: listCountriesInputSchema,
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: true
}
},
async () => {
const result = await client.listCountries();
if (!result.ok) return errorResult(result.error);
return okJson(result.data);
}
);
server.registerTool(
"proxy_get",
{
title: "Proxy GET",
description: "Fetch a URL through AproxPay residential proxy (product A). Pays ~$0.003 USDC via x402 per request (2MB cap). Sticky session is on by default.",
description: "Fetch a URL through AproxPay residential proxy (product A). Pays ~$0.003 USDC via x402 per request (2MB cap). Sticky session is on by default. For a country-pinned exit IP use create_session instead.",
inputSchema: proxyGetInputSchema,

@@ -331,3 +388,3 @@ annotations: {

title: "Create session pass",
description: "Buy a session pass (~$0.50 USDC via x402) and receive ephemeral CONNECT/SOCKS credentials for Playwright or curl. Includes ~250MB byte cap. No automatic refund on close.",
description: "Buy a session pass (~$0.50 USDC via x402) and receive ephemeral CONNECT credentials for Playwright or curl (~250MB). Optional `region` (ISO country from list_countries) pins the exit country with no surcharge. No automatic refund on close.",
inputSchema: createSessionInputSchema,

@@ -354,3 +411,3 @@ annotations: {

title: "Extend session",
description: "Top up an existing session (+30 min TTL and +250MB cap) without changing the exit IP. Pays ~$0.50 USDC via x402. Must be called from the same buyer wallet that created the session.",
description: "Top up an existing session (+30 min TTL and +250MB cap) without changing the exit IP or country. Pays ~$0.50 USDC via x402. Must be called from the same buyer wallet that created the session.",
inputSchema: extendSessionInputSchema,

@@ -357,0 +414,0 @@ annotations: {

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/env.ts","../src/server.ts","../src/schemas.ts"],"sourcesContent":["/**\n * aproxproxy-mcp entrypoint.\n\n *\n * Default: stdio transport (Claude Desktop / local agents).\n * Optional: `aproxproxy-mcp --http` starts Streamable HTTP on\n * APROXPROXY_HTTP_HOST:APROXPROXY_HTTP_PORT (self-hosted only — the buyer\n * private key must stay on the operator's machine).\n */\nimport { createServer } from \"node:http\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { AproxProxyClient } from \"./client.js\";\nimport { loadEnv } from \"./env.js\";\nimport { createMcpServer } from \"./server.js\";\n\n/** Log to stderr only — stdout is reserved for MCP JSON-RPC on stdio. */\nfunction log(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n\nfunction wantsHttp(argv: string[]): boolean {\n return argv.includes(\"--http\");\n}\n\nasync function runStdio(client: AproxProxyClient): Promise<void> {\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log(\"aproxproxy-mcp listening on stdio\");\n}\n\nasync function runHttp(\n client: AproxProxyClient,\n host: string,\n port: number,\n): Promise<void> {\n const httpServer = createServer((req, res) => {\n void (async () => {\n const url = req.url ?? \"/\";\n const path = url.split(\"?\")[0] ?? \"/\";\n if (path !== \"/mcp\" && path !== \"/mcp/\") {\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"Not found\");\n return;\n }\n\n if (req.method !== \"POST\") {\n res.writeHead(405, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Method not allowed.\" },\n id: null,\n }),\n );\n return;\n }\n\n // Stateless mode: fresh server + transport per request (self-hosted).\n // Omit sessionIdGenerator (SDK treats missing generator as stateless).\n const server = createMcpServer(client);\n const transport = new StreamableHTTPServerTransport();\n try {\n // SDK optional callbacks are typed incompatibly with\n // exactOptionalPropertyTypes; runtime contract is fine.\n await server.connect(transport as Parameters<McpServer[\"connect\"]>[0]);\n await transport.handleRequest(req, res);\n } catch (err) {\n log(\n `HTTP MCP error: ${err instanceof Error ? err.message : String(err)}`,\n );\n if (!res.headersSent) {\n res.writeHead(500, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n }),\n );\n }\n } finally {\n res.on(\"close\", () => {\n void transport.close();\n void server.close();\n });\n }\n })();\n });\n\n await new Promise<void>((resolve, reject) => {\n httpServer.once(\"error\", reject);\n httpServer.listen(port, host, () => resolve());\n });\n log(`aproxproxy-mcp Streamable HTTP on http://${host}:${port}/mcp`);\n log(\n \"Self-hosted only: APROXPROXY_PRIVATE_KEY stays on this machine (non-custodial).\",\n );\n}\n\nasync function main(): Promise<void> {\n const env = loadEnv();\n const client = new AproxProxyClient({\n baseUrl: env.APROXPROXY_BASE_URL,\n privateKey: env.APROXPROXY_PRIVATE_KEY as `0x${string}`,\n });\n\n if (wantsHttp(process.argv.slice(2))) {\n await runHttp(client, env.APROXPROXY_HTTP_HOST, env.APROXPROXY_HTTP_PORT);\n return;\n }\n\n await runStdio(client);\n}\n\nmain().catch((err) => {\n log(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { x402Client } from \"@x402/core/client\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\nimport { wrapFetchWithPayment } from \"@x402/fetch\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\n/** Channel attribution header — must stay in sync with proxy funnel parser. */\nexport const CLIENT_SOURCE_HEADER = \"X-Client-Source\";\nexport const CLIENT_SOURCE_VALUE = \"mcp\";\n\nexport interface SessionCredentials {\n username: string;\n password: string;\n}\n\nexport interface SessionPass {\n host: string;\n port: number;\n username: string;\n password: string;\n sessionId: string;\n expiresAt: string;\n byteCap: number;\n}\n\nexport interface ProxyGetParams {\n url: string;\n sticky?: boolean;\n /** Accepted for API compatibility; not yet enforced by the proxy backend. */\n region?: string;\n}\n\nexport interface CreateSessionParams {\n durationMinutes?: 30 | 60;\n /** Accepted for API compatibility; not yet enforced by the proxy backend. */\n region?: string;\n}\n\nexport interface ToolHttpError {\n status: number;\n error: string;\n hint?: string;\n body?: string;\n}\n\nexport type ToolHttpResult<T> =\n | { ok: true; data: T }\n | { ok: false; error: ToolHttpError };\n\nexport interface AproxProxyClientOptions {\n baseUrl: string;\n /**\n * Buyer wallet private key (0x…). Required unless `fetchImpl` is injected\n * (tests). Never log this value.\n */\n privateKey?: `0x${string}`;\n /** Test seam: skip x402 wrapping and use this fetch instead. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Thin HTTP client over the AproxPay proxy API.\n * Paid routes use `@x402/fetch`; every request sets `X-Client-Source: mcp`.\n */\nexport class AproxProxyClient {\n private readonly baseUrl: string;\n private readonly fetchFn: typeof fetch;\n private readonly sessionCreds = new Map<string, SessionCredentials>();\n\n constructor(opts: AproxProxyClientOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n if (opts.fetchImpl) {\n this.fetchFn = opts.fetchImpl;\n return;\n }\n if (!opts.privateKey) {\n throw new Error(\"privateKey is required when fetchImpl is not provided\");\n }\n const signer = privateKeyToAccount(opts.privateKey);\n const client = new x402Client();\n client.register(\"eip155:*\", new ExactEvmScheme(signer));\n this.fetchFn = wrapFetchWithPayment(fetch, client);\n }\n\n /** In-memory cache of ephemeral gateway credentials (process-local). */\n getCachedCredentials(sessionId: string): SessionCredentials | undefined {\n return this.sessionCreds.get(sessionId);\n }\n\n clearCachedCredentials(sessionId: string): void {\n this.sessionCreds.delete(sessionId);\n }\n\n async proxyGet(\n params: ProxyGetParams,\n ): Promise<ToolHttpResult<{ status: number; body: string }>> {\n const body: Record<string, unknown> = {\n url: params.url,\n sticky: params.sticky ?? true,\n };\n // Forward region when present so a future backend field lights up without\n // an MCP package bump. Current proxy Zod schema strips unknown keys.\n if (params.region !== undefined) {\n body.region = params.region;\n }\n\n const res = await this.request(\"/v1/proxy\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n return { ok: true, data: { status: res.status, body: text } };\n }\n\n async createSession(\n params: CreateSessionParams = {},\n ): Promise<ToolHttpResult<SessionPass>> {\n const body: Record<string, unknown> = {\n duration: params.durationMinutes ?? 30,\n };\n if (params.region !== undefined) {\n body.region = params.region;\n }\n\n const res = await this.request(\"/v1/session\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n\n let parsed: SessionPass;\n try {\n parsed = JSON.parse(text) as SessionPass;\n } catch {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"invalid JSON in session response\",\n body: text.slice(0, 500),\n },\n };\n }\n\n if (\n typeof parsed.sessionId !== \"string\" ||\n typeof parsed.username !== \"string\" ||\n typeof parsed.password !== \"string\"\n ) {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"session response missing credentials\",\n body: text.slice(0, 500),\n },\n };\n }\n\n this.sessionCreds.set(parsed.sessionId, {\n username: parsed.username,\n password: parsed.password,\n });\n return { ok: true, data: parsed };\n }\n\n async extendSession(\n sessionId: string,\n ): Promise<\n ToolHttpResult<{ sessionId: string; expiresAt: string; byteCap: number }>\n > {\n const res = await this.request(\n `/v1/session/${encodeURIComponent(sessionId)}/extend`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: \"{}\",\n },\n );\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n try {\n return {\n ok: true,\n data: JSON.parse(text) as {\n sessionId: string;\n expiresAt: string;\n byteCap: number;\n },\n };\n } catch {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"invalid JSON in extend response\",\n body: text.slice(0, 500),\n },\n };\n }\n }\n\n async closeSession(\n sessionId: string,\n credentials?: SessionCredentials,\n ): Promise<ToolHttpResult<{ sessionId: string; closed: boolean }>> {\n const creds = credentials ?? this.sessionCreds.get(sessionId);\n if (!creds) {\n return {\n ok: false,\n error: {\n status: 400,\n error:\n \"missing session credentials: pass username/password or call create_session in this process first\",\n },\n };\n }\n\n const token = Buffer.from(\n `${creds.username}:${creds.password}`,\n \"utf8\",\n ).toString(\"base64\");\n\n // close is free (Basic-auth) — use plain fetch so we never attempt x402.\n const res = await fetch(\n `${this.baseUrl}/v1/session/${encodeURIComponent(sessionId)}/close`,\n {\n method: \"POST\",\n headers: {\n authorization: `Basic ${token}`,\n [CLIENT_SOURCE_HEADER]: CLIENT_SOURCE_VALUE,\n },\n },\n );\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n\n this.sessionCreds.delete(sessionId);\n try {\n return {\n ok: true,\n data: JSON.parse(text) as { sessionId: string; closed: boolean },\n };\n } catch {\n return { ok: true, data: { sessionId, closed: true } };\n }\n }\n\n private async request(path: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set(CLIENT_SOURCE_HEADER, CLIENT_SOURCE_VALUE);\n return this.fetchFn(`${this.baseUrl}${path}`, { ...init, headers });\n }\n\n private async toHttpError(\n status: number,\n text: string,\n ): Promise<ToolHttpError> {\n let error = `proxy returned ${status}`;\n let hint: string | undefined;\n try {\n const json = JSON.parse(text) as { error?: unknown; hint?: unknown };\n if (typeof json.error === \"string\") {\n error = json.error;\n }\n if (typeof json.hint === \"string\") {\n hint = json.hint;\n }\n } catch {\n // keep default message; attach truncated body below\n }\n\n if (status === 413 && !hint) {\n hint =\n \"response exceeded byte cap — try create_session for larger transfers\";\n }\n\n const result: ToolHttpError = { status, error };\n if (hint !== undefined) {\n result.hint = hint;\n }\n if (text.length > 0 && text.length <= 500) {\n result.body = text;\n } else if (text.length > 500) {\n result.body = `${text.slice(0, 500)}…`;\n }\n return result;\n }\n}\n","import { z } from \"zod\";\n\nconst DEFAULT_BASE_URL = \"https://proxy.aproxpay.com\";\nconst DEFAULT_HTTP_PORT = 3100;\nconst DEFAULT_HTTP_HOST = \"127.0.0.1\";\n\nconst privateKeySchema = z\n .string()\n .regex(\n /^0x[0-9a-fA-F]{64}$/,\n \"must be a 0x-prefixed 32-byte hex private key\",\n );\n\nconst envSchema = z.object({\n APROXPROXY_BASE_URL: z.url().default(DEFAULT_BASE_URL),\n APROXPROXY_PRIVATE_KEY: privateKeySchema,\n APROXPROXY_HTTP_PORT: z.coerce\n .number()\n .int()\n .positive()\n .default(DEFAULT_HTTP_PORT),\n APROXPROXY_HTTP_HOST: z.string().min(1).default(DEFAULT_HTTP_HOST),\n});\n\nexport type McpEnv = z.infer<typeof envSchema>;\n\n/**\n * Parse and validate MCP server env. Fail-fast on missing private key —\n * every paid tool signs an EIP-3009 transfer with it.\n */\nexport function loadEnv(source: NodeJS.ProcessEnv = process.env): McpEnv {\n const parsed = envSchema.safeParse({\n APROXPROXY_BASE_URL: source.APROXPROXY_BASE_URL,\n APROXPROXY_PRIVATE_KEY: source.APROXPROXY_PRIVATE_KEY,\n APROXPROXY_HTTP_PORT: source.APROXPROXY_HTTP_PORT,\n APROXPROXY_HTTP_HOST: source.APROXPROXY_HTTP_HOST,\n });\n if (!parsed.success) {\n const details = parsed.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \");\n throw new Error(`Invalid MCP server environment: ${details}`);\n }\n return parsed.data;\n}\n\nexport { DEFAULT_BASE_URL, DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AproxProxyClient, ToolHttpError } from \"./client.js\";\nimport {\n closeSessionInputSchema,\n createSessionInputSchema,\n extendSessionInputSchema,\n proxyGetInputSchema,\n} from \"./schemas.js\";\n\nexport const MCP_SERVER_NAME = \"aproxproxy\";\nexport const MCP_SERVER_VERSION = \"0.1.0\";\n\n/** Max characters of proxied body returned to the agent (keeps tool results bounded). */\nconst MAX_BODY_CHARS = 100_000;\n\nfunction errorResult(err: ToolHttpError): CallToolResult {\n const payload: Record<string, unknown> = {\n status: err.status,\n error: err.error,\n };\n if (err.hint !== undefined) payload.hint = err.hint;\n if (err.body !== undefined) payload.body = err.body;\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n };\n}\n\nfunction okJson(data: unknown): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n}\n\n/**\n * Build a configured MCP server with the four AproxPay tools.\n * The same factory is used for stdio and Streamable HTTP transports.\n */\nexport function createMcpServer(client: AproxProxyClient): McpServer {\n const server = new McpServer({\n name: MCP_SERVER_NAME,\n version: MCP_SERVER_VERSION,\n });\n\n server.registerTool(\n \"proxy_get\",\n {\n title: \"Proxy GET\",\n description:\n \"Fetch a URL through AproxPay residential proxy (product A). Pays ~$0.003 USDC via x402 per request (2MB cap). Sticky session is on by default.\",\n inputSchema: proxyGetInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ url, sticky, region }) => {\n const result = await client.proxyGet({\n url,\n ...(sticky !== undefined ? { sticky } : {}),\n ...(region !== undefined ? { region } : {}),\n });\n if (!result.ok) return errorResult(result.error);\n\n const body =\n result.data.body.length > MAX_BODY_CHARS\n ? `${result.data.body.slice(0, MAX_BODY_CHARS)}\\n…[truncated]`\n : result.data.body;\n\n return okJson({\n status: result.data.status,\n body,\n truncated: result.data.body.length > MAX_BODY_CHARS,\n });\n },\n );\n\n server.registerTool(\n \"create_session\",\n {\n title: \"Create session pass\",\n description:\n \"Buy a session pass (~$0.50 USDC via x402) and receive ephemeral CONNECT/SOCKS credentials for Playwright or curl. Includes ~250MB byte cap. No automatic refund on close.\",\n inputSchema: createSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ duration_minutes, region }) => {\n const result = await client.createSession({\n ...(duration_minutes !== undefined\n ? { durationMinutes: duration_minutes }\n : {}),\n ...(region !== undefined ? { region } : {}),\n });\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n server.registerTool(\n \"extend_session\",\n {\n title: \"Extend session\",\n description:\n \"Top up an existing session (+30 min TTL and +250MB cap) without changing the exit IP. Pays ~$0.50 USDC via x402. Must be called from the same buyer wallet that created the session.\",\n inputSchema: extendSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ session_id }) => {\n const result = await client.extendSession(session_id);\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n server.registerTool(\n \"close_session\",\n {\n title: \"Close session\",\n description:\n \"Revoke ephemeral credentials and the upstream sub-user early. Free (no x402). Does NOT refund the session payment in MVP — x402 settlements are irreversible.\",\n inputSchema: closeSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n async ({ session_id, username, password }) => {\n const hasUser = typeof username === \"string\" && username.length > 0;\n const hasPass = typeof password === \"string\" && password.length > 0;\n if (hasUser !== hasPass) {\n return errorResult({\n status: 400,\n error: \"username and password must both be provided together\",\n });\n }\n\n const result = await client.closeSession(\n session_id,\n hasUser && hasPass\n ? { username: username as string, password: password as string }\n : undefined,\n );\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n return server;\n}\n","import { z } from \"zod\";\n\nexport const proxyGetInputSchema = {\n url: z\n .string()\n .url()\n .describe(\"Target URL to fetch through the residential proxy (http/https)\"),\n sticky: z\n .boolean()\n .optional()\n .describe(\n \"Reuse the same exit IP for this wallet (implicit sticky session). Default true.\",\n ),\n region: z\n .string()\n .optional()\n .describe(\n \"Preferred exit region (e.g. us, eu). Not yet supported by the proxy API — accepted and ignored for now.\",\n ),\n};\n\nexport const createSessionInputSchema = {\n duration_minutes: z\n .union([z.literal(30), z.literal(60)])\n .optional()\n .describe(\"Session TTL in minutes (30 or 60). Default 30.\"),\n region: z\n .string()\n .optional()\n .describe(\n \"Preferred exit region (e.g. us, eu). Not yet supported by the proxy API — accepted and ignored for now.\",\n ),\n};\n\nexport const extendSessionInputSchema = {\n session_id: z\n .string()\n .min(1)\n .describe(\"Session ID returned by create_session\"),\n};\n\nexport const closeSessionInputSchema = {\n session_id: z\n .string()\n .min(1)\n .describe(\"Session ID returned by create_session\"),\n username: z\n .string()\n .optional()\n .describe(\n \"Ephemeral gateway username (s_{sessionId}). Optional if create_session ran in this process.\",\n ),\n password: z\n .string()\n .optional()\n .describe(\n \"Ephemeral gateway password. Optional if create_session ran in this process.\",\n ),\n};\n"],"mappings":"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","names":["z"]}
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/env.ts","../src/server.ts","../src/schemas.ts"],"sourcesContent":["/**\n * aproxproxy-mcp entrypoint.\n\n *\n * Default: stdio transport (Claude Desktop / local agents).\n * Optional: `aproxproxy-mcp --http` starts Streamable HTTP on\n * APROXPROXY_HTTP_HOST:APROXPROXY_HTTP_PORT (self-hosted only — the buyer\n * private key must stay on the operator's machine).\n */\nimport { createServer } from \"node:http\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { AproxProxyClient } from \"./client.js\";\nimport { loadEnv } from \"./env.js\";\nimport { createMcpServer } from \"./server.js\";\n\n/** Log to stderr only — stdout is reserved for MCP JSON-RPC on stdio. */\nfunction log(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n\nfunction wantsHttp(argv: string[]): boolean {\n return argv.includes(\"--http\");\n}\n\nasync function runStdio(client: AproxProxyClient): Promise<void> {\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log(\"aproxproxy-mcp listening on stdio\");\n}\n\nasync function runHttp(\n client: AproxProxyClient,\n host: string,\n port: number,\n): Promise<void> {\n const httpServer = createServer((req, res) => {\n void (async () => {\n const url = req.url ?? \"/\";\n const path = url.split(\"?\")[0] ?? \"/\";\n if (path !== \"/mcp\" && path !== \"/mcp/\") {\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"Not found\");\n return;\n }\n\n if (req.method !== \"POST\") {\n res.writeHead(405, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Method not allowed.\" },\n id: null,\n }),\n );\n return;\n }\n\n // Stateless mode: fresh server + transport per request (self-hosted).\n // Omit sessionIdGenerator (SDK treats missing generator as stateless).\n const server = createMcpServer(client);\n const transport = new StreamableHTTPServerTransport();\n try {\n // SDK optional callbacks are typed incompatibly with\n // exactOptionalPropertyTypes; runtime contract is fine.\n await server.connect(transport as Parameters<McpServer[\"connect\"]>[0]);\n await transport.handleRequest(req, res);\n } catch (err) {\n log(\n `HTTP MCP error: ${err instanceof Error ? err.message : String(err)}`,\n );\n if (!res.headersSent) {\n res.writeHead(500, { \"content-type\": \"application/json\" });\n res.end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n }),\n );\n }\n } finally {\n res.on(\"close\", () => {\n void transport.close();\n void server.close();\n });\n }\n })();\n });\n\n await new Promise<void>((resolve, reject) => {\n httpServer.once(\"error\", reject);\n httpServer.listen(port, host, () => resolve());\n });\n log(`aproxproxy-mcp Streamable HTTP on http://${host}:${port}/mcp`);\n log(\n \"Self-hosted only: APROXPROXY_PRIVATE_KEY stays on this machine (non-custodial).\",\n );\n}\n\nasync function main(): Promise<void> {\n const env = loadEnv();\n const client = new AproxProxyClient({\n baseUrl: env.APROXPROXY_BASE_URL,\n privateKey: env.APROXPROXY_PRIVATE_KEY as `0x${string}`,\n });\n\n if (wantsHttp(process.argv.slice(2))) {\n await runHttp(client, env.APROXPROXY_HTTP_HOST, env.APROXPROXY_HTTP_PORT);\n return;\n }\n\n await runStdio(client);\n}\n\nmain().catch((err) => {\n log(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { x402Client } from \"@x402/core/client\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\nimport { wrapFetchWithPayment } from \"@x402/fetch\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\n/** Channel attribution header — must stay in sync with proxy funnel parser. */\nexport const CLIENT_SOURCE_HEADER = \"X-Client-Source\";\nexport const CLIENT_SOURCE_VALUE = \"mcp\";\n\nexport interface SessionCredentials {\n username: string;\n password: string;\n}\n\nexport interface SessionPass {\n host: string;\n port: number;\n username: string;\n password: string;\n sessionId: string;\n expiresAt: string;\n byteCap: number;\n /** Echoed when create_session was called with a region. */\n region?: string;\n}\n\nexport interface CountriesList {\n countries: string[];\n default: string;\n}\n\nexport interface ProxyGetParams {\n url: string;\n sticky?: boolean;\n /** Accepted for API compatibility; product A does not enforce region yet. */\n region?: string;\n}\n\nexport interface CreateSessionParams {\n durationMinutes?: 30 | 60;\n /** ISO 3166-1 alpha-2 exit country (product B). See listCountries(). */\n region?: string;\n}\n\nexport interface ToolHttpError {\n status: number;\n error: string;\n hint?: string;\n body?: string;\n}\n\nexport type ToolHttpResult<T> =\n | { ok: true; data: T }\n | { ok: false; error: ToolHttpError };\n\nexport interface AproxProxyClientOptions {\n baseUrl: string;\n /**\n * Buyer wallet private key (0x…). Required unless `fetchImpl` is injected\n * (tests). Never log this value.\n */\n privateKey?: `0x${string}`;\n /** Test seam: skip x402 wrapping and use this fetch instead. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Thin HTTP client over the AproxPay proxy API.\n * Paid routes use `@x402/fetch`; every request sets `X-Client-Source: mcp`.\n */\nexport class AproxProxyClient {\n private readonly baseUrl: string;\n private readonly fetchFn: typeof fetch;\n private readonly sessionCreds = new Map<string, SessionCredentials>();\n\n constructor(opts: AproxProxyClientOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n if (opts.fetchImpl) {\n this.fetchFn = opts.fetchImpl;\n return;\n }\n if (!opts.privateKey) {\n throw new Error(\"privateKey is required when fetchImpl is not provided\");\n }\n const signer = privateKeyToAccount(opts.privateKey);\n const client = new x402Client();\n client.register(\"eip155:*\", new ExactEvmScheme(signer));\n this.fetchFn = wrapFetchWithPayment(fetch, client);\n }\n\n /** In-memory cache of ephemeral gateway credentials (process-local). */\n getCachedCredentials(sessionId: string): SessionCredentials | undefined {\n return this.sessionCreds.get(sessionId);\n }\n\n clearCachedCredentials(sessionId: string): void {\n this.sessionCreds.delete(sessionId);\n }\n\n async proxyGet(\n params: ProxyGetParams,\n ): Promise<ToolHttpResult<{ status: number; body: string }>> {\n const body: Record<string, unknown> = {\n url: params.url,\n sticky: params.sticky ?? true,\n };\n // Forward region when present so a future backend field lights up without\n // an MCP package bump. Current proxy Zod schema strips unknown keys.\n if (params.region !== undefined) {\n body.region = params.region;\n }\n\n const res = await this.request(\"/v1/proxy\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n return { ok: true, data: { status: res.status, body: text } };\n }\n\n async createSession(\n params: CreateSessionParams = {},\n ): Promise<ToolHttpResult<SessionPass>> {\n const body: Record<string, unknown> = {\n duration: params.durationMinutes ?? 30,\n };\n if (params.region !== undefined) {\n body.region = params.region;\n }\n\n const res = await this.request(\"/v1/session\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n\n let parsed: SessionPass;\n try {\n parsed = JSON.parse(text) as SessionPass;\n } catch {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"invalid JSON in session response\",\n body: text.slice(0, 500),\n },\n };\n }\n\n if (\n typeof parsed.sessionId !== \"string\" ||\n typeof parsed.username !== \"string\" ||\n typeof parsed.password !== \"string\"\n ) {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"session response missing credentials\",\n body: text.slice(0, 500),\n },\n };\n }\n\n this.sessionCreds.set(parsed.sessionId, {\n username: parsed.username,\n password: parsed.password,\n });\n return { ok: true, data: parsed };\n }\n\n /**\n * Free discovery of ISO exit countries accepted by create_session `region`.\n * Uses plain fetch (no x402) — same pattern as closeSession.\n */\n async listCountries(): Promise<ToolHttpResult<CountriesList>> {\n const res = await fetch(`${this.baseUrl}/v1/countries`, {\n method: \"GET\",\n headers: { [CLIENT_SOURCE_HEADER]: CLIENT_SOURCE_VALUE },\n });\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n try {\n const parsed = JSON.parse(text) as CountriesList;\n if (!Array.isArray(parsed.countries)) {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"countries response missing countries array\",\n body: text.slice(0, 500),\n },\n };\n }\n return { ok: true, data: parsed };\n } catch {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"invalid JSON in countries response\",\n body: text.slice(0, 500),\n },\n };\n }\n }\n\n async extendSession(\n sessionId: string,\n ): Promise<\n ToolHttpResult<{ sessionId: string; expiresAt: string; byteCap: number }>\n > {\n const res = await this.request(\n `/v1/session/${encodeURIComponent(sessionId)}/extend`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: \"{}\",\n },\n );\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n try {\n return {\n ok: true,\n data: JSON.parse(text) as {\n sessionId: string;\n expiresAt: string;\n byteCap: number;\n },\n };\n } catch {\n return {\n ok: false,\n error: {\n status: res.status,\n error: \"invalid JSON in extend response\",\n body: text.slice(0, 500),\n },\n };\n }\n }\n\n async closeSession(\n sessionId: string,\n credentials?: SessionCredentials,\n ): Promise<ToolHttpResult<{ sessionId: string; closed: boolean }>> {\n const creds = credentials ?? this.sessionCreds.get(sessionId);\n if (!creds) {\n return {\n ok: false,\n error: {\n status: 400,\n error:\n \"missing session credentials: pass username/password or call create_session in this process first\",\n },\n };\n }\n\n const token = Buffer.from(\n `${creds.username}:${creds.password}`,\n \"utf8\",\n ).toString(\"base64\");\n\n // close is free (Basic-auth) — use plain fetch so we never attempt x402.\n const res = await fetch(\n `${this.baseUrl}/v1/session/${encodeURIComponent(sessionId)}/close`,\n {\n method: \"POST\",\n headers: {\n authorization: `Basic ${token}`,\n [CLIENT_SOURCE_HEADER]: CLIENT_SOURCE_VALUE,\n },\n },\n );\n const text = await res.text();\n if (res.status >= 400) {\n return { ok: false, error: await this.toHttpError(res.status, text) };\n }\n\n this.sessionCreds.delete(sessionId);\n try {\n return {\n ok: true,\n data: JSON.parse(text) as { sessionId: string; closed: boolean },\n };\n } catch {\n return { ok: true, data: { sessionId, closed: true } };\n }\n }\n\n private async request(path: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set(CLIENT_SOURCE_HEADER, CLIENT_SOURCE_VALUE);\n return this.fetchFn(`${this.baseUrl}${path}`, { ...init, headers });\n }\n\n private async toHttpError(\n status: number,\n text: string,\n ): Promise<ToolHttpError> {\n let error = `proxy returned ${status}`;\n let hint: string | undefined;\n try {\n const json = JSON.parse(text) as { error?: unknown; hint?: unknown };\n if (typeof json.error === \"string\") {\n error = json.error;\n }\n if (typeof json.hint === \"string\") {\n hint = json.hint;\n }\n } catch {\n // keep default message; attach truncated body below\n }\n\n if (status === 413 && !hint) {\n hint =\n \"response exceeded byte cap — try create_session for larger transfers\";\n }\n\n const result: ToolHttpError = { status, error };\n if (hint !== undefined) {\n result.hint = hint;\n }\n if (text.length > 0 && text.length <= 500) {\n result.body = text;\n } else if (text.length > 500) {\n result.body = `${text.slice(0, 500)}…`;\n }\n return result;\n }\n}\n","import { z } from \"zod\";\n\nconst DEFAULT_BASE_URL = \"https://proxy.aproxpay.com\";\nconst DEFAULT_HTTP_PORT = 3100;\nconst DEFAULT_HTTP_HOST = \"127.0.0.1\";\n\nconst privateKeySchema = z\n .string()\n .regex(\n /^0x[0-9a-fA-F]{64}$/,\n \"must be a 0x-prefixed 32-byte hex private key\",\n );\n\nconst envSchema = z.object({\n APROXPROXY_BASE_URL: z.url().default(DEFAULT_BASE_URL),\n APROXPROXY_PRIVATE_KEY: privateKeySchema,\n APROXPROXY_HTTP_PORT: z.coerce\n .number()\n .int()\n .positive()\n .default(DEFAULT_HTTP_PORT),\n APROXPROXY_HTTP_HOST: z.string().min(1).default(DEFAULT_HTTP_HOST),\n});\n\nexport type McpEnv = z.infer<typeof envSchema>;\n\n/**\n * Parse and validate MCP server env. Fail-fast on missing private key —\n * every paid tool signs an EIP-3009 transfer with it.\n */\nexport function loadEnv(source: NodeJS.ProcessEnv = process.env): McpEnv {\n const parsed = envSchema.safeParse({\n APROXPROXY_BASE_URL: source.APROXPROXY_BASE_URL,\n APROXPROXY_PRIVATE_KEY: source.APROXPROXY_PRIVATE_KEY,\n APROXPROXY_HTTP_PORT: source.APROXPROXY_HTTP_PORT,\n APROXPROXY_HTTP_HOST: source.APROXPROXY_HTTP_HOST,\n });\n if (!parsed.success) {\n const details = parsed.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \");\n throw new Error(`Invalid MCP server environment: ${details}`);\n }\n return parsed.data;\n}\n\nexport { DEFAULT_BASE_URL, DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AproxProxyClient, ToolHttpError } from \"./client.js\";\nimport {\n closeSessionInputSchema,\n createSessionInputSchema,\n extendSessionInputSchema,\n listCountriesInputSchema,\n proxyGetInputSchema,\n} from \"./schemas.js\";\n\nexport const MCP_SERVER_NAME = \"aproxproxy\";\nexport const MCP_SERVER_VERSION = \"0.1.2\";\n\n/** Max characters of proxied body returned to the agent (keeps tool results bounded). */\nconst MAX_BODY_CHARS = 100_000;\n\nfunction errorResult(err: ToolHttpError): CallToolResult {\n const payload: Record<string, unknown> = {\n status: err.status,\n error: err.error,\n };\n if (err.hint !== undefined) payload.hint = err.hint;\n if (err.body !== undefined) payload.body = err.body;\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(payload, null, 2) }],\n };\n}\n\nfunction okJson(data: unknown): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n };\n}\n\n/**\n * Build a configured MCP server with the AproxPay tools.\n * The same factory is used for stdio and Streamable HTTP transports.\n */\nexport function createMcpServer(client: AproxProxyClient): McpServer {\n const server = new McpServer({\n name: MCP_SERVER_NAME,\n version: MCP_SERVER_VERSION,\n });\n\n server.registerTool(\n \"list_countries\",\n {\n title: \"List exit countries\",\n description:\n \"Free discovery: return ISO 3166-1 alpha-2 exit countries accepted by create_session `region` (OFAC codes excluded). Call before create_session when you need a specific country. No payment.\",\n inputSchema: listCountriesInputSchema,\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n async () => {\n const result = await client.listCountries();\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n server.registerTool(\n \"proxy_get\",\n {\n title: \"Proxy GET\",\n description:\n \"Fetch a URL through AproxPay residential proxy (product A). Pays ~$0.003 USDC via x402 per request (2MB cap). Sticky session is on by default. For a country-pinned exit IP use create_session instead.\",\n inputSchema: proxyGetInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ url, sticky, region }) => {\n const result = await client.proxyGet({\n url,\n ...(sticky !== undefined ? { sticky } : {}),\n ...(region !== undefined ? { region } : {}),\n });\n if (!result.ok) return errorResult(result.error);\n\n const body =\n result.data.body.length > MAX_BODY_CHARS\n ? `${result.data.body.slice(0, MAX_BODY_CHARS)}\\n…[truncated]`\n : result.data.body;\n\n return okJson({\n status: result.data.status,\n body,\n truncated: result.data.body.length > MAX_BODY_CHARS,\n });\n },\n );\n\n server.registerTool(\n \"create_session\",\n {\n title: \"Create session pass\",\n description:\n \"Buy a session pass (~$0.50 USDC via x402) and receive ephemeral CONNECT credentials for Playwright or curl (~250MB). Optional `region` (ISO country from list_countries) pins the exit country with no surcharge. No automatic refund on close.\",\n inputSchema: createSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ duration_minutes, region }) => {\n const result = await client.createSession({\n ...(duration_minutes !== undefined\n ? { durationMinutes: duration_minutes }\n : {}),\n ...(region !== undefined ? { region } : {}),\n });\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n server.registerTool(\n \"extend_session\",\n {\n title: \"Extend session\",\n description:\n \"Top up an existing session (+30 min TTL and +250MB cap) without changing the exit IP or country. Pays ~$0.50 USDC via x402. Must be called from the same buyer wallet that created the session.\",\n inputSchema: extendSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async ({ session_id }) => {\n const result = await client.extendSession(session_id);\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n server.registerTool(\n \"close_session\",\n {\n title: \"Close session\",\n description:\n \"Revoke ephemeral credentials and the upstream sub-user early. Free (no x402). Does NOT refund the session payment in MVP — x402 settlements are irreversible.\",\n inputSchema: closeSessionInputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: true,\n },\n },\n async ({ session_id, username, password }) => {\n const hasUser = typeof username === \"string\" && username.length > 0;\n const hasPass = typeof password === \"string\" && password.length > 0;\n if (hasUser !== hasPass) {\n return errorResult({\n status: 400,\n error: \"username and password must both be provided together\",\n });\n }\n\n const result = await client.closeSession(\n session_id,\n hasUser && hasPass\n ? { username: username as string, password: password as string }\n : undefined,\n );\n if (!result.ok) return errorResult(result.error);\n return okJson(result.data);\n },\n );\n\n return server;\n}\n","import { z } from \"zod\";\n\nexport const proxyGetInputSchema = {\n url: z\n .string()\n .url()\n .describe(\"Target URL to fetch through the residential proxy (http/https)\"),\n sticky: z\n .boolean()\n .optional()\n .describe(\n \"Reuse the same exit IP for this wallet (implicit sticky session). Default true.\",\n ),\n region: z\n .string()\n .optional()\n .describe(\n \"Exit country for product A is not enforced yet (accepted and ignored). For country-pinned sticky IPs use create_session with region after list_countries.\",\n ),\n};\n\nexport const listCountriesInputSchema = {};\n\nexport const createSessionInputSchema = {\n duration_minutes: z\n .union([z.literal(30), z.literal(60)])\n .optional()\n .describe(\"Session TTL in minutes (30 or 60). Default 30.\"),\n region: z\n .string()\n .optional()\n .describe(\n \"ISO 3166-1 alpha-2 exit country (e.g. us, de). Optional; omit for any-country pool. Call list_countries first for the allowlist. No surcharge.\",\n ),\n};\n\nexport const extendSessionInputSchema = {\n session_id: z\n .string()\n .min(1)\n .describe(\"Session ID returned by create_session\"),\n};\n\nexport const closeSessionInputSchema = {\n session_id: z\n .string()\n .min(1)\n .describe(\"Session ID returned by create_session\"),\n username: z\n .string()\n .optional()\n .describe(\n \"Ephemeral gateway username (s_{sessionId}). Optional if create_session ran in this process.\",\n ),\n password: z\n .string()\n .optional()\n .describe(\n \"Ephemeral gateway password. Optional if create_session ran in this process.\",\n ),\n};\n"],"mappings":"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","names":["z"]}
{
"name": "aproxproxy-mcp",
"version": "0.1.1",
"description": "MCP server for AproxPay residential proxy — pay-per-request and session passes via x402",
"version": "0.1.2",
"description": "MCP server for AproxPay residential proxy — pay-per-request and session passes via x402 (optional exit country)",
"type": "module",

@@ -6,0 +6,0 @@ "mcpName": "io.github.aproxpay/aproxproxy",

@@ -11,7 +11,16 @@ # aproxproxy-mcp

|---|---|---|
| `list_countries` | free | ISO exit countries accepted by `create_session` `region` |
| `proxy_get` | ~$0.003 | Fetch a URL through residential IP (2MB cap, sticky by default) |
| `create_session` | ~$0.50 | Buy a 30/60‑min session pass + ephemeral CONNECT credentials (~250MB) |
| `extend_session` | ~$0.50 | Top up TTL/byte cap **without changing exit IP** |
| `create_session` | ~$0.50 | Buy a 30/60‑min session pass + ephemeral CONNECT credentials (~250MB); optional `region` |
| `extend_session` | ~$0.50 | Top up TTL/byte cap **without changing exit IP or country** |
| `close_session` | free | Revoke credentials early (**no automatic refund** in MVP) |
### Region (exit country)
1. Call `list_countries` (free) → curated ISO 3166-1 alpha-2 codes (OFAC codes excluded).
2. Call `create_session` with `region: "us"` (or another code) — no surcharge; the CONNECT gateway pins DataImpulse `cr.{code}` for the whole session.
3. `extend_session` keeps the same country and sticky exit IP.
`proxy_get` still accepts `region` for forward-compat, but product A does not enforce it yet — use a session pass when you need a country-pinned IP.
Every request to the proxy API includes `X-Client-Source: mcp` for channel attribution.

@@ -38,3 +47,3 @@

Then ask Claude to call `proxy_get` with `url: "https://example.com"`.
Then ask Claude to call `list_countries`, or `create_session` with `region: "us"`, or `proxy_get` with `url: "https://example.com"`.

@@ -55,3 +64,3 @@ ### Environment

3. Set `APROXPROXY_BASE_URL=http://localhost:8080` and the testnet private key.
4. Call `proxy_get`.
4. Call `list_countries`, then `create_session` with a `region`, or `proxy_get`.

@@ -58,0 +67,0 @@ ## Transports

@@ -5,4 +5,4 @@ {

"title": "AproxPay Proxy",
"description": "Residential proxy for AI agents via x402 — per-request fetch and sticky session passes",
"version": "0.1.1",
"description": "Residential proxy for AI agents via x402 — per-request fetch, sticky session passes, and optional exit-country selection",
"version": "0.1.2",
"websiteUrl": "https://aproxpay.com",

@@ -13,3 +13,3 @@ "packages": [

"identifier": "aproxproxy-mcp",
"version": "0.1.1",
"version": "0.1.2",
"transport": {

@@ -16,0 +16,0 @@ "type": "stdio"