@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 +48 -22
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
166760
|
-
|
|
166761
|
-
|
|
166762
|
-
|
|
166763
|
-
|
|
166764
|
-
|
|
166765
|
-
|
|
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);
|