@prismnetwork/mcp 0.2.0 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +21 -1
  2. package/package.json +1 -1
  3. package/server.mjs +41 -9
package/README.md CHANGED
@@ -1,9 +1,29 @@
1
1
  # @prismnetwork/mcp
2
2
 
3
- An MCP server that lets Claude (or any MCP client) lease and run on real GPUs through [Prism Network](https://prismnetwork.tech). Give it a wallet; it handles auth, on-chain payment, provisioning, and SSH.
3
+ An MCP server that lets Claude (or any MCP client) see and lease real GPUs through [Prism Network](https://prismnetwork.tech). Give it a wallet and it handles auth, onchain payment, provisioning, and SSH.
4
+
5
+ ## Try it without a wallet
6
+
7
+ Looking costs nothing and needs no configuration:
8
+
9
+ ```sh
10
+ claude mcp add prism -- npx -y @prismnetwork/mcp
11
+ ```
12
+
13
+ Then ask what you can rent. `prism_list_gpus` answers from live capacity with
14
+ real prices. Leasing spends money, so those tools ask for a wallet and say so.
4
15
 
5
16
  ## Tools
6
17
 
18
+ | Tool | Wallet |
19
+ | --- | --- |
20
+ | `prism_list_gpus` | no |
21
+ | `prism_wallet` | yes |
22
+ | `prism_lease_and_run` | yes |
23
+ | `prism_lease` | yes |
24
+ | `prism_run` | yes |
25
+ | `prism_end_lease` | yes |
26
+
7
27
  - `prism_wallet`: the agent's address and USDG/ETH balances.
8
28
  - `prism_list_gpus`: GPUs available to lease, with price per second and per hour.
9
29
  - `prism_lease_and_run`: lease a GPU, run a command, return the output (one shot).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismnetwork/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP server for leasing and running on Prism Network GPUs.",
5
5
  "mcpName": "io.github.prismnetwork-tech/mcp",
6
6
  "type": "module",
package/server.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
- // Prism Network MCP server: lets an MCP client (Claude, agents) lease and run on
3
- // real GPUs. Configure with a wallet: PRISM_AGENT_KEY, PRISM_ESCROW.
2
+ // Prism Network MCP server: lets an MCP client (Claude, agents) see and lease
3
+ // real GPUs. Looking is free and needs no configuration. Leasing spends money,
4
+ // so it needs a wallet: PRISM_AGENT_KEY, PRISM_ESCROW.
4
5
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
7
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
@@ -14,7 +15,12 @@ function requireEnv(name) {
14
15
  return value;
15
16
  }
16
17
 
17
- let agent;
18
+ const PUBLIC_API = process.env.PRISM_PUBLIC_API ?? "https://api.prismnetwork.tech";
19
+
20
+ // Refusing to start without a wallet meant nobody could ask what a GPU costs
21
+ // without first producing a private key, which is a strange thing to demand of
22
+ // someone deciding whether to use you at all.
23
+ let agent = null;
18
24
  try {
19
25
  agent = new PrismAgent({
20
26
  privateKey: requireEnv("PRISM_AGENT_KEY"),
@@ -22,9 +28,28 @@ try {
22
28
  apiBase: process.env.PRISM_API_BASE ?? "https://prismnetwork.tech",
23
29
  rpcUrl: process.env.PRISM_RPC_URL,
24
30
  });
25
- } catch (err) {
26
- console.error(`prism mcp config error: ${err.message}. Set PRISM_AGENT_KEY and PRISM_ESCROW in the server env.`);
27
- process.exit(1);
31
+ } catch {
32
+ console.error(
33
+ "prism mcp: no wallet configured, so capacity and pricing are readable and leasing is not. " +
34
+ "Set PRISM_AGENT_KEY and PRISM_ESCROW to lease.",
35
+ );
36
+ }
37
+
38
+ function requireWallet(tool) {
39
+ if (!agent) {
40
+ throw new Error(
41
+ `${tool} spends money, so it needs a wallet. Set PRISM_AGENT_KEY and PRISM_ESCROW in this server's environment and restart it.`,
42
+ );
43
+ }
44
+ return agent;
45
+ }
46
+
47
+ async function publicOffers(minTrust) {
48
+ const url = new URL("/v1/offers", PUBLIC_API);
49
+ if (minTrust) url.searchParams.set("min_trust", minTrust);
50
+ const response = await fetch(url, { headers: { accept: "application/json" } });
51
+ if (!response.ok) throw new Error(`prism offers unavailable (${response.status})`);
52
+ return response.json();
28
53
  }
29
54
 
30
55
  const leases = new Map();
@@ -127,12 +152,18 @@ const TOOLS = [
127
152
 
128
153
  async function handle(name, args) {
129
154
  if (name === "prism_wallet") {
130
- const b = await agent.balances();
155
+ const b = await requireWallet("prism_wallet").balances();
131
156
  return { address: b.address, usdg: usdg(b.usdg), eth_wei: b.eth };
132
157
  }
133
158
  if (name === "prism_list_gpus") {
134
- await ensureAuth();
135
- const offers = await agent.offers({ minTrust: args.min_trust ?? "open" });
159
+ const minTrust = args.min_trust ?? "open";
160
+ let offers;
161
+ if (agent) {
162
+ await ensureAuth();
163
+ offers = await agent.offers({ minTrust });
164
+ } else {
165
+ offers = await publicOffers(minTrust);
166
+ }
136
167
  return {
137
168
  available: offers.length,
138
169
  gpus: offers.map((o) => ({
@@ -146,6 +177,7 @@ async function handle(name, args) {
146
177
  }
147
178
  if (name === "prism_lease_and_run" || name === "prism_lease") {
148
179
  if (name === "prism_lease_and_run" && !args.command) throw new Error("command is required");
180
+ requireWallet(name);
149
181
  await ensureAuth();
150
182
  sweepExpiredLeases();
151
183
  const lease = await agent.lease({