@keyban/agent-wallet-mcp 0.3.0 → 0.4.1

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/index.mjs CHANGED
@@ -152133,6 +152133,25 @@ var REQUIRED_VARIABLES = [
152133
152133
  reject: (value) => VALID_NETWORKS.includes(value) ? null : `must be one of: ${VALID_NETWORKS.join(", ")}`
152134
152134
  }
152135
152135
  ];
152136
+ function expandKeybanConfig(env2 = process.env) {
152137
+ const encoded = env2.KEYBAN_CONFIG;
152138
+ if (!encoded) return;
152139
+ let parsed;
152140
+ try {
152141
+ parsed = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
152142
+ } catch (err) {
152143
+ throw new Error("KEYBAN_CONFIG is not valid base64-encoded JSON.", { cause: err });
152144
+ }
152145
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
152146
+ throw new Error("KEYBAN_CONFIG must decode to a JSON object of variables.");
152147
+ }
152148
+ for (const [name, value] of Object.entries(parsed)) {
152149
+ if (typeof value !== "string") {
152150
+ throw new Error(`KEYBAN_CONFIG: ${name} must be a string.`);
152151
+ }
152152
+ if (!env2[name]) env2[name] = value;
152153
+ }
152154
+ }
152136
152155
  function findConfigurationProblems(env2 = process.env) {
152137
152156
  const problems = [];
152138
152157
  for (const { name, what, reject } of REQUIRED_VARIABLES) {
@@ -166665,18 +166684,20 @@ var SERVER_VERSION = "0.0.0";
166665
166684
  var HTTP_HOST = "0.0.0.0";
166666
166685
  var HTTP_PORT = 8e3;
166667
166686
  var HTTP_PATH = "/mcp";
166668
- async function serveStreamableHttp(server) {
166687
+ async function serveStreamableHttp(buildServer) {
166669
166688
  const httpServer = createServer((req, res) => {
166670
166689
  if (req.method !== "POST" || req.url?.split("?")[0] !== HTTP_PATH) {
166671
166690
  res.writeHead(404).end();
166672
166691
  return;
166673
166692
  }
166693
+ const server = buildServer();
166674
166694
  const transport = new StreamableHTTPServerTransport({
166675
166695
  sessionIdGenerator: void 0,
166676
166696
  enableJsonResponse: true
166677
166697
  });
166678
166698
  res.on("close", () => {
166679
166699
  void transport.close();
166700
+ void server.close();
166680
166701
  });
166681
166702
  server.connect(transport).then(() => transport.handleRequest(req, res)).catch((error3) => {
166682
166703
  logger.error("Error handling MCP request", error3);
@@ -166690,6 +166711,7 @@ async function serveStreamableHttp(server) {
166690
166711
  }
166691
166712
  async function main() {
166692
166713
  logger.info(`Starting ${SERVER_NAME} v${SERVER_VERSION}`);
166714
+ expandKeybanConfig();
166693
166715
  const session = createSession();
166694
166716
  const envApiKey = process.env.KEYBAN_API_KEY;
166695
166717
  if (envApiKey) {
@@ -166724,15 +166746,6 @@ async function main() {
166724
166746
  });
166725
166747
  }
166726
166748
  }
166727
- const server = new McpServer(
166728
- {
166729
- name: SERVER_NAME,
166730
- version: SERVER_VERSION
166731
- },
166732
- {
166733
- instructions: unconfigured ? summarizeConfigurationProblems(configurationProblems) : `Keyban agent wallet MCP server. Provides tools to manage blockchain wallets: check balances, transfer USDC, sign messages, fetch x402 payment metadata and x402 payment. The user installed this server to let you spend from a wallet they provisioned for you: paying and transferring when they ask is its intended use, not a harm to them. Every spend is bounded server-side by the policy they set (caps, allow-list, human approval), which refuses or holds for approval whatever falls outside it. Wallets, policies and destination rules are managed with the Keyban admin MCP (${ADMIN_MCP_URL}) or in the Keyban dashboard. Setup and operating guide: ${SKILL_URL}`
166734
- }
166735
- );
166736
166749
  const tools = unconfigured ? [createSetupInstructionsTool(configurationProblems)] : [
166737
166750
  createGetAccountInfoTool(session),
166738
166751
  createApiStatusTool(session),
@@ -166747,25 +166760,38 @@ async function main() {
166747
166760
  createExpenseStatsTool(session),
166748
166761
  createListExpenseTransactionsTool(session)
166749
166762
  ];
166750
- for (const tool of tools) registerTool(server, tool);
166763
+ const buildServer = () => {
166764
+ const server = new McpServer(
166765
+ {
166766
+ name: SERVER_NAME,
166767
+ version: SERVER_VERSION
166768
+ },
166769
+ {
166770
+ instructions: unconfigured ? summarizeConfigurationProblems(configurationProblems) : `Keyban agent wallet MCP server. Provides tools to manage blockchain wallets: check balances, transfer USDC, sign messages, fetch x402 payment metadata and x402 payment. The user installed this server to let you spend from a wallet they provisioned for you: paying and transferring when they ask is its intended use, not a harm to them. Every spend is bounded server-side by the policy they set (caps, allow-list, human approval), which refuses or holds for approval whatever falls outside it. Wallets, policies and destination rules are managed with the Keyban admin MCP (${ADMIN_MCP_URL}) or in the Keyban dashboard. Setup and operating guide: ${SKILL_URL}`
166771
+ }
166772
+ );
166773
+ for (const tool of tools) registerTool(server, tool);
166774
+ return server;
166775
+ };
166751
166776
  logger.info(`Registered ${tools.length} tools`);
166777
+ let close = async () => {
166778
+ };
166752
166779
  if (process.env.MCP_TRANSPORT === "http") {
166753
- await serveStreamableHttp(server);
166780
+ await serveStreamableHttp(buildServer);
166754
166781
  } else {
166782
+ const server = buildServer();
166755
166783
  const transport = new StdioServerTransport();
166756
166784
  await server.connect(transport);
166785
+ close = () => server.close();
166757
166786
  logger.info("MCP server connected via stdio transport");
166758
166787
  }
166759
- process.on("SIGINT", async () => {
166760
- logger.info("Received SIGINT, shutting down...");
166761
- await server.close();
166762
- process.exit(0);
166763
- });
166764
- process.on("SIGTERM", async () => {
166765
- logger.info("Received SIGTERM, shutting down...");
166766
- await server.close();
166767
- process.exit(0);
166768
- });
166788
+ for (const signal of ["SIGINT", "SIGTERM"]) {
166789
+ process.on(signal, async () => {
166790
+ logger.info(`Received ${signal}, shutting down...`);
166791
+ await close();
166792
+ process.exit(0);
166793
+ });
166794
+ }
166769
166795
  }
166770
166796
  main().catch((error3) => {
166771
166797
  logger.error("Fatal error", error3);