cyberdyne-mcp 0.6.7 → 0.6.8

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/dist/onboard.js CHANGED
@@ -17,6 +17,8 @@
17
17
  * a DB row. The wallet private key is persisted but NEVER logged to stdout.
18
18
  */
19
19
  import { readFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { join } from "node:path";
20
22
  import { createInterface } from "node:readline";
21
23
  import { generatePrivateKey, privateKeyToAccount, mnemonicToAccount } from "viem/accounts";
22
24
  import { bytesToHex } from "viem";
@@ -111,6 +113,29 @@ function collectCookies(res, jar) {
111
113
  function cookieHeader(jar) {
112
114
  return [...jar.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
113
115
  }
116
+ /**
117
+ * Auto-discover the agent's Bankr `bk_` key WITHOUT requiring a flag — so a plain
118
+ * `npx cyberdyne-mcp onboard` links Bankr whenever the agent already has Bankr set up.
119
+ * Order: CYBERDYNE_BANKR_KEY → BANKR_API_KEY (Bankr's own standard env var) →
120
+ * ~/.bankr/config.json (any `bk_`-prefixed value — the same config file Bankr's CLI/SDK use).
121
+ * Returns undefined if nothing is configured (then onboard just skips Bankr linking).
122
+ */
123
+ function discoverBankrKey(env) {
124
+ const fromEnv = env.CYBERDYNE_BANKR_KEY?.trim() || env.BANKR_API_KEY?.trim();
125
+ if (fromEnv?.startsWith("bk_"))
126
+ return fromEnv;
127
+ try {
128
+ const cfg = JSON.parse(readFileSync(join(homedir(), ".bankr", "config.json"), "utf8"));
129
+ for (const v of Object.values(cfg)) {
130
+ if (typeof v === "string" && v.startsWith("bk_"))
131
+ return v.trim();
132
+ }
133
+ }
134
+ catch {
135
+ /* no ~/.bankr/config.json — fine, Bankr just isn't configured */
136
+ }
137
+ return undefined;
138
+ }
114
139
  /**
115
140
  * Run the full SIWE → mint chain and persist the credentials. Throws on any
116
141
  * non-2xx step (with the endpoint + status) so the caller can surface a clear error.
@@ -185,7 +210,7 @@ export async function onboard(env = process.env, opts = {}) {
185
210
  // via the fresh cyb_ key. Best-effort: a failure never blocks onboarding, and the
186
211
  // bk_ key is never stored (the backend uses it once and discards it).
187
212
  let bankr;
188
- const bankrKey = (opts.bankrKey ?? env.CYBERDYNE_BANKR_KEY ?? "").trim();
213
+ const bankrKey = (opts.bankrKey?.trim() || discoverBankrKey(env) || "");
189
214
  if (bankrKey.startsWith("bk_")) {
190
215
  try {
191
216
  const res = await fetch(`${apiUrl}/api/bankr/connect`, {
@@ -277,8 +302,10 @@ export const ONBOARD_USAGE = [
277
302
  " CYBERDYNE_IMPORT_KEY=0x<key> npx cyberdyne-mcp onboard --import",
278
303
  " (passing it as an argument leaves the secret in your shell history.)",
279
304
  " --create generate a fresh wallet (default in a non-interactive / CI shell).",
280
- " --bankr <bk_key> auto-link your Bankr project at onboard (or set CYBERDYNE_BANKR_KEY).",
281
- " The bk_ key is used ONCE server-side and never stored.",
305
+ " --bankr <bk_key> link your Bankr project at onboard. USUALLY UNNEEDED: onboard",
306
+ " auto-discovers your key from BANKR_API_KEY / ~/.bankr/config.json,",
307
+ " so a plain `onboard` links Bankr if you already use it. Used once,",
308
+ " server-side, and never stored.",
282
309
  " (no flag, in a terminal) you'll be prompted: paste a key/mnemonic, or press enter to create.",
283
310
  "",
284
311
  "Either way: SIWE sign-in → mint your cyb_ key → save wallet + key to ~/.cyberdyne/config.json (0600).",
package/dist/server.js CHANGED
@@ -151,7 +151,7 @@ async function guard(fn) {
151
151
  }
152
152
  }
153
153
  // ---- Server ---------------------------------------------------------------
154
- const server = new McpServer({ name: "cyberdyne", version: "0.6.7" });
154
+ const server = new McpServer({ name: "cyberdyne", version: "0.6.8" });
155
155
  server.tool("list_categories", "List the kinds of real-world work CYBERDYNE humans can do. Static (no network). Use this to learn the valid `category` values before posting a task.", {}, async () => json(Object.entries(CATEGORIES).map(([id, blurb]) => ({ id, blurb }))));
156
156
  server.tool("onboard", "BOOTSTRAP (works WITHOUT an existing key — the one tool that self-onboards). Zero-browser: generates a fresh wallet if you don't have one, signs in to CYBERDYNE with it (SIWE), mints your `cyb_` agent API key, and saves both to ~/.cyberdyne/config.json (0600) so every other tool here authenticates automatically. No web dashboard, no env vars. Returns your wallet address, the cyb_ key (shown once), and the next steps (fund your WALLET with USDC + a little ETH for gas on Base → post_task → authorize_task → review_submission → close_task). The non-custodial pool freezes the budget directly from your wallet at deploy — there is no platform treasury to deposit into. The same generated wallet auto-signs pool budgets. To bring your OWN wallet instead, use the CLI: `npx cyberdyne-mcp onboard --import <0xKEY | mnemonic>` (or --create for a fresh one). Idempotent-ish: re-running with a saved wallet reuses it and mints a fresh key.", {}, async () => guard(async () => {
157
157
  const r = await onboard();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberdyne-mcp",
3
- "version": "0.6.7",
3
+ "version": "0.6.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/onboard.ts CHANGED
@@ -17,6 +17,8 @@
17
17
  * a DB row. The wallet private key is persisted but NEVER logged to stdout.
18
18
  */
19
19
  import { readFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { join } from "node:path";
20
22
  import { createInterface } from "node:readline";
21
23
  import { generatePrivateKey, privateKeyToAccount, mnemonicToAccount } from "viem/accounts";
22
24
  import { bytesToHex } from "viem";
@@ -131,6 +133,27 @@ function cookieHeader(jar: Map<string, string>): string {
131
133
  return [...jar.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
132
134
  }
133
135
 
136
+ /**
137
+ * Auto-discover the agent's Bankr `bk_` key WITHOUT requiring a flag — so a plain
138
+ * `npx cyberdyne-mcp onboard` links Bankr whenever the agent already has Bankr set up.
139
+ * Order: CYBERDYNE_BANKR_KEY → BANKR_API_KEY (Bankr's own standard env var) →
140
+ * ~/.bankr/config.json (any `bk_`-prefixed value — the same config file Bankr's CLI/SDK use).
141
+ * Returns undefined if nothing is configured (then onboard just skips Bankr linking).
142
+ */
143
+ function discoverBankrKey(env: NodeJS.ProcessEnv): string | undefined {
144
+ const fromEnv = env.CYBERDYNE_BANKR_KEY?.trim() || env.BANKR_API_KEY?.trim();
145
+ if (fromEnv?.startsWith("bk_")) return fromEnv;
146
+ try {
147
+ const cfg = JSON.parse(readFileSync(join(homedir(), ".bankr", "config.json"), "utf8")) as Record<string, unknown>;
148
+ for (const v of Object.values(cfg)) {
149
+ if (typeof v === "string" && v.startsWith("bk_")) return v.trim();
150
+ }
151
+ } catch {
152
+ /* no ~/.bankr/config.json — fine, Bankr just isn't configured */
153
+ }
154
+ return undefined;
155
+ }
156
+
134
157
  export interface OnboardResult {
135
158
  address: string;
136
159
  apiKey: string;
@@ -234,7 +257,7 @@ export async function onboard(
234
257
  // via the fresh cyb_ key. Best-effort: a failure never blocks onboarding, and the
235
258
  // bk_ key is never stored (the backend uses it once and discards it).
236
259
  let bankr: OnboardResult["bankr"];
237
- const bankrKey = (opts.bankrKey ?? env.CYBERDYNE_BANKR_KEY ?? "").trim();
260
+ const bankrKey = (opts.bankrKey?.trim() || discoverBankrKey(env) || "");
238
261
  if (bankrKey.startsWith("bk_")) {
239
262
  try {
240
263
  const res = await fetch(`${apiUrl}/api/bankr/connect`, {
@@ -327,8 +350,10 @@ export const ONBOARD_USAGE = [
327
350
  " CYBERDYNE_IMPORT_KEY=0x<key> npx cyberdyne-mcp onboard --import",
328
351
  " (passing it as an argument leaves the secret in your shell history.)",
329
352
  " --create generate a fresh wallet (default in a non-interactive / CI shell).",
330
- " --bankr <bk_key> auto-link your Bankr project at onboard (or set CYBERDYNE_BANKR_KEY).",
331
- " The bk_ key is used ONCE server-side and never stored.",
353
+ " --bankr <bk_key> link your Bankr project at onboard. USUALLY UNNEEDED: onboard",
354
+ " auto-discovers your key from BANKR_API_KEY / ~/.bankr/config.json,",
355
+ " so a plain `onboard` links Bankr if you already use it. Used once,",
356
+ " server-side, and never stored.",
332
357
  " (no flag, in a terminal) you'll be prompted: paste a key/mnemonic, or press enter to create.",
333
358
  "",
334
359
  "Either way: SIWE sign-in → mint your cyb_ key → save wallet + key to ~/.cyberdyne/config.json (0600).",
package/src/server.ts CHANGED
@@ -163,7 +163,7 @@ async function guard<T>(fn: () => Promise<T>) {
163
163
 
164
164
  // ---- Server ---------------------------------------------------------------
165
165
 
166
- const server = new McpServer({ name: "cyberdyne", version: "0.6.7" });
166
+ const server = new McpServer({ name: "cyberdyne", version: "0.6.8" });
167
167
 
168
168
  server.tool(
169
169
  "list_categories",