@toknbase/mcp-server 1.0.0 → 1.2.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.
- package/index.js +8 -64
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Required env vars:
|
|
7
7
|
* TOKNBASE_AGENT_TOKEN -- your agt_ scoped agent token from the Toknbase dashboard
|
|
8
|
-
* TOKNBASE_CANISTER_ID -- your Toknbase canister ID (e.g. xxxxx-xxxxx-cai)
|
|
9
8
|
*
|
|
10
9
|
* Optional:
|
|
11
|
-
*
|
|
10
|
+
* TOKNBASE_CANISTER_ID -- your Toknbase canister ID (defaults to production)
|
|
11
|
+
* TOKNBASE_IC_HOST -- IC host (default: https://icp-api.io)
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -22,17 +22,13 @@ import { IDL } from "@dfinity/candid";
|
|
|
22
22
|
|
|
23
23
|
// ── Config ──────────────────────────────────────────────────────────────────
|
|
24
24
|
const TOKEN = process.env.TOKNBASE_AGENT_TOKEN;
|
|
25
|
-
const CANISTER_ID = process.env.TOKNBASE_CANISTER_ID;
|
|
26
|
-
const IC_HOST = process.env.TOKNBASE_IC_HOST ?? "https://
|
|
25
|
+
const CANISTER_ID = process.env.TOKNBASE_CANISTER_ID ?? "xi7mc-uaaaa-aaaan-q5raa-cai";
|
|
26
|
+
const IC_HOST = process.env.TOKNBASE_IC_HOST ?? "https://icp-api.io";
|
|
27
27
|
|
|
28
28
|
if (!TOKEN) {
|
|
29
29
|
console.error("[toknbase-mcp] Missing TOKNBASE_AGENT_TOKEN environment variable.");
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
|
-
if (!CANISTER_ID) {
|
|
33
|
-
console.error("[toknbase-mcp] Missing TOKNBASE_CANISTER_ID environment variable.");
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
32
|
|
|
37
33
|
// ── Candid IDL (agent-token surface only) ───────────────────────────────────
|
|
38
34
|
const idlFactory = ({ IDL: I }) => {
|
|
@@ -53,17 +49,15 @@ const idlFactory = ({ IDL: I }) => {
|
|
|
53
49
|
[]
|
|
54
50
|
),
|
|
55
51
|
updateSecretByAgentToken: I.Func([I.Text, I.Text, I.Text], [I.Bool], []),
|
|
56
|
-
deleteSecretByAgentToken: I.Func([I.Text, I.Text], [I.Bool], []),
|
|
57
52
|
listFoldersByAgentToken: I.Func([I.Text], [I.Vec(FolderMeta)], ["query"]),
|
|
58
53
|
assignFolderByAgentToken: I.Func([I.Text, I.Nat, I.Text], [I.Bool], []),
|
|
59
|
-
getSecretByAgentToken: I.Func([I.Text, I.Text], [I.Opt(I.Text)], ["query"]),
|
|
60
54
|
});
|
|
61
55
|
};
|
|
62
56
|
|
|
63
57
|
// ── IC Actor ─────────────────────────────────────────────────────────────────
|
|
64
58
|
const agent = new HttpAgent({ host: IC_HOST });
|
|
65
|
-
//
|
|
66
|
-
if (IC_HOST
|
|
59
|
+
// Only fetch root key on local replica, not on mainnet
|
|
60
|
+
if (!IC_HOST.includes("icp-api.io") && !IC_HOST.includes("ic0.app")) {
|
|
67
61
|
await agent.fetchRootKey();
|
|
68
62
|
}
|
|
69
63
|
|
|
@@ -71,7 +65,7 @@ const backend = Actor.createActor(idlFactory, { agent, canisterId: CANISTER_ID }
|
|
|
71
65
|
|
|
72
66
|
// ── MCP Server ───────────────────────────────────────────────────────────────
|
|
73
67
|
const server = new Server(
|
|
74
|
-
{ name: "toknbase", version: "1.
|
|
68
|
+
{ name: "toknbase", version: "1.2.0" },
|
|
75
69
|
{ capabilities: { tools: {} } }
|
|
76
70
|
);
|
|
77
71
|
|
|
@@ -80,20 +74,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
80
74
|
tools: [
|
|
81
75
|
{
|
|
82
76
|
name: "toknbase_list_secrets",
|
|
83
|
-
description: "List all secrets you have access to. Returns names, descriptions, and environments -- never plaintext values.",
|
|
77
|
+
description: "List all secrets you have access to. Returns names, descriptions, and environments -- never plaintext values. Toknbase is zero-knowledge: secret values are encrypted client-side and the server never sees them.",
|
|
84
78
|
inputSchema: { type: "object", properties: {}, required: [] },
|
|
85
79
|
},
|
|
86
|
-
{
|
|
87
|
-
name: "toknbase_reveal_secret",
|
|
88
|
-
description: "Reveal the encrypted value of a specific secret by name. Use this only when you need the actual value.",
|
|
89
|
-
inputSchema: {
|
|
90
|
-
type: "object",
|
|
91
|
-
properties: {
|
|
92
|
-
name: { type: "string", description: "The exact secret name" },
|
|
93
|
-
},
|
|
94
|
-
required: ["name"],
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
80
|
{
|
|
98
81
|
name: "toknbase_create_secret",
|
|
99
82
|
description: "Add a new secret to the vault. Requires read_write or full_access scope.",
|
|
@@ -124,17 +107,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
124
107
|
required: ["name", "value"],
|
|
125
108
|
},
|
|
126
109
|
},
|
|
127
|
-
{
|
|
128
|
-
name: "toknbase_delete_secret",
|
|
129
|
-
description: "Permanently delete a secret from the vault. Requires full_access scope. This cannot be undone.",
|
|
130
|
-
inputSchema: {
|
|
131
|
-
type: "object",
|
|
132
|
-
properties: {
|
|
133
|
-
name: { type: "string", description: "The exact secret name to delete" },
|
|
134
|
-
},
|
|
135
|
-
required: ["name"],
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
110
|
{
|
|
139
111
|
name: "toknbase_list_folders",
|
|
140
112
|
description: "List all folders in the vault.",
|
|
@@ -173,19 +145,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
173
145
|
};
|
|
174
146
|
}
|
|
175
147
|
|
|
176
|
-
case "toknbase_reveal_secret": {
|
|
177
|
-
const result = await backend.getSecretByAgentToken(args.name, TOKEN);
|
|
178
|
-
if (result.length === 0 || result[0] === undefined) {
|
|
179
|
-
return {
|
|
180
|
-
content: [{ type: "text", text: `Secret '${args.name}' not found or access denied.` }],
|
|
181
|
-
isError: true,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
return {
|
|
185
|
-
content: [{ type: "text", text: result[0] }],
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
148
|
case "toknbase_create_secret": {
|
|
190
149
|
const ok = await backend.createSecretByAgentToken(
|
|
191
150
|
args.name,
|
|
@@ -222,21 +181,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
222
181
|
};
|
|
223
182
|
}
|
|
224
183
|
|
|
225
|
-
case "toknbase_delete_secret": {
|
|
226
|
-
const ok = await backend.deleteSecretByAgentToken(args.name, TOKEN);
|
|
227
|
-
return {
|
|
228
|
-
content: [
|
|
229
|
-
{
|
|
230
|
-
type: "text",
|
|
231
|
-
text: ok
|
|
232
|
-
? `Secret '${args.name}' deleted.`
|
|
233
|
-
: `Failed to delete secret '${args.name}'. Check that it exists and your token scope (requires full_access).`,
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
isError: !ok,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
184
|
case "toknbase_list_folders": {
|
|
241
185
|
const folders = await backend.listFoldersByAgentToken(TOKEN);
|
|
242
186
|
return {
|