@vultisig/mcp 0.1.14 → 0.1.16
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/CHANGELOG.md +19 -0
- package/README.md +5 -1
- package/dist/bin/mcp-server.js +126 -67
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @vultisig/mcp
|
|
2
2
|
|
|
3
|
+
## 0.1.16
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#683](https://github.com/vultisig/vultisig-sdk/pull/683) [`4561129`](https://github.com/vultisig/vultisig-sdk/commit/45611297a55da72d3c56b1a2ffe6522da1b64d7b) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Update SDK package dependencies and Yarn tooling.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`4561129`](https://github.com/vultisig/vultisig-sdk/commit/45611297a55da72d3c56b1a2ffe6522da1b64d7b)]:
|
|
10
|
+
- @vultisig/client-shared@0.2.14
|
|
11
|
+
- @vultisig/sdk@1.8.10
|
|
12
|
+
|
|
13
|
+
## 0.1.15
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#642](https://github.com/vultisig/vultisig-sdk/pull/642) [`cc7fc61`](https://github.com/vultisig/vultisig-sdk/commit/cc7fc61f7720f8c218bccc90b276808c71263651) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Accept documented `vmcp --vault <id-or-path>` arguments and reject unknown MCP CLI options.
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`72bbcd1`](https://github.com/vultisig/vultisig-sdk/commit/72bbcd17ee5327390c98784f861b7c6b8829cf2f)]:
|
|
20
|
+
- @vultisig/sdk@1.8.2
|
|
21
|
+
|
|
3
22
|
## 0.1.14
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -14,11 +14,15 @@ npm install -g @vultisig/mcp
|
|
|
14
14
|
# Set up credentials via the CLI first
|
|
15
15
|
vsig auth setup
|
|
16
16
|
|
|
17
|
-
# Then run the MCP server (stdio)
|
|
17
|
+
# Then run the MCP server (stdio) by vault ID or file path
|
|
18
18
|
vmcp --vault <id-or-path>
|
|
19
19
|
|
|
20
20
|
# Read-only profile (disables send/swap)
|
|
21
21
|
vmcp --vault <id-or-path> --profile harness
|
|
22
|
+
|
|
23
|
+
# Explicit forms are also supported
|
|
24
|
+
vmcp --vault-id <id>
|
|
25
|
+
vmcp --vault-file <path>
|
|
22
26
|
```
|
|
23
27
|
|
|
24
28
|
## Tools
|
package/dist/bin/mcp-server.js
CHANGED
|
@@ -5,6 +5,126 @@ import { readFileSync } from "node:fs";
|
|
|
5
5
|
import { executeAuthSetup as executeAuthSetup2, getServerPassword as getServerPassword2 } from "@vultisig/client-shared";
|
|
6
6
|
import { Vultisig } from "@vultisig/sdk";
|
|
7
7
|
|
|
8
|
+
// src/args.ts
|
|
9
|
+
var PROFILES = ["harness", "defi"];
|
|
10
|
+
function formatMcpHelp() {
|
|
11
|
+
return `
|
|
12
|
+
vultisig-mcp - MCP server for Vultisig wallet operations
|
|
13
|
+
|
|
14
|
+
SETUP (first time):
|
|
15
|
+
vmcp --setup Import a vault and store credentials interactively
|
|
16
|
+
vmcp --setup --vault-file <path> Import a specific vault file
|
|
17
|
+
vmcp --setup --vault <path> Import a specific vault file
|
|
18
|
+
|
|
19
|
+
USAGE:
|
|
20
|
+
vmcp [options]
|
|
21
|
+
|
|
22
|
+
OPTIONS:
|
|
23
|
+
--profile <harness|defi> Tool profile (default: defi)
|
|
24
|
+
harness = read-only tools only
|
|
25
|
+
defi = all tools including send/swap
|
|
26
|
+
--vault <id-or-path> Use a vault by ID, or load a path-like/.vult file
|
|
27
|
+
--vault-id <id> Use a specific vault (default: first found)
|
|
28
|
+
--setup Run interactive auth setup, then exit
|
|
29
|
+
|
|
30
|
+
CI / HEADLESS (skip interactive auth):
|
|
31
|
+
--vault-file <path> Load vault directly from a .vult file
|
|
32
|
+
Requires VAULT_PASSWORD and/or VAULT_DECRYPT_PASSWORD
|
|
33
|
+
environment variables for encrypted vaults
|
|
34
|
+
|
|
35
|
+
EXAMPLES:
|
|
36
|
+
# First time setup:
|
|
37
|
+
vmcp --setup
|
|
38
|
+
|
|
39
|
+
# Start the server:
|
|
40
|
+
vmcp
|
|
41
|
+
vmcp --vault my-vault-id
|
|
42
|
+
vmcp --profile harness
|
|
43
|
+
|
|
44
|
+
# Claude Code integration:
|
|
45
|
+
claude mcp add vultisig -- vmcp
|
|
46
|
+
claude mcp add vultisig -- npx @vultisig/mcp
|
|
47
|
+
|
|
48
|
+
# CI / headless:
|
|
49
|
+
VAULT_PASSWORD=xxx vmcp --vault-file ./vault.vult
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
function parseMcpArgs(args) {
|
|
53
|
+
let profile = "defi";
|
|
54
|
+
let vaultId;
|
|
55
|
+
let vaultFile;
|
|
56
|
+
let setup = false;
|
|
57
|
+
const assignVaultId = (value) => {
|
|
58
|
+
if (vaultId || vaultFile) {
|
|
59
|
+
throw new Error("Specify only one of --vault, --vault-id, or --vault-file.");
|
|
60
|
+
}
|
|
61
|
+
vaultId = value;
|
|
62
|
+
};
|
|
63
|
+
const assignVaultFile = (value) => {
|
|
64
|
+
if (vaultId || vaultFile) {
|
|
65
|
+
throw new Error("Specify only one of --vault, --vault-id, or --vault-file.");
|
|
66
|
+
}
|
|
67
|
+
vaultFile = value;
|
|
68
|
+
};
|
|
69
|
+
for (let i = 0; i < args.length; i++) {
|
|
70
|
+
const arg = args[i];
|
|
71
|
+
if (arg === "--help" || arg === "-h") {
|
|
72
|
+
return { profile, help: true };
|
|
73
|
+
}
|
|
74
|
+
if (arg === "--setup") {
|
|
75
|
+
setup = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (arg === "--profile") {
|
|
79
|
+
const value = readOptionValue(args, i, arg);
|
|
80
|
+
i++;
|
|
81
|
+
if (!PROFILES.includes(value)) {
|
|
82
|
+
throw new Error(`Invalid profile "${value}". Must be one of: ${PROFILES.join(", ")}.`);
|
|
83
|
+
}
|
|
84
|
+
profile = value;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (arg === "--vault-id") {
|
|
88
|
+
assignVaultId(readOptionValue(args, i, arg));
|
|
89
|
+
i++;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (arg === "--vault-file") {
|
|
93
|
+
assignVaultFile(readOptionValue(args, i, arg));
|
|
94
|
+
i++;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (arg === "--vault") {
|
|
98
|
+
const value = readOptionValue(args, i, arg);
|
|
99
|
+
i++;
|
|
100
|
+
if (isVaultFileValue(value)) {
|
|
101
|
+
assignVaultFile(value);
|
|
102
|
+
} else {
|
|
103
|
+
assignVaultId(value);
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (arg.startsWith("-")) {
|
|
108
|
+
throw new Error(`Unknown option "${arg}".`);
|
|
109
|
+
}
|
|
110
|
+
throw new Error(`Unexpected argument "${arg}".`);
|
|
111
|
+
}
|
|
112
|
+
if (setup && vaultId) {
|
|
113
|
+
throw new Error("Setup can only import a vault file. Use --vault-file <path> or --vault <path>.");
|
|
114
|
+
}
|
|
115
|
+
return { profile, vaultId, vaultFile, setup };
|
|
116
|
+
}
|
|
117
|
+
function readOptionValue(args, index, option) {
|
|
118
|
+
const value = args[index + 1];
|
|
119
|
+
if (!value || value.startsWith("-")) {
|
|
120
|
+
throw new Error(`Missing value for ${option}.`);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
function isVaultFileValue(value) {
|
|
125
|
+
return value.endsWith(".vult") || value.includes("/") || value.includes("\\") || value.startsWith("~");
|
|
126
|
+
}
|
|
127
|
+
|
|
8
128
|
// src/index.ts
|
|
9
129
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
130
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -207,71 +327,6 @@ var toStderr = (...args) => {
|
|
|
207
327
|
console.log = toStderr;
|
|
208
328
|
console.info = toStderr;
|
|
209
329
|
console.warn = toStderr;
|
|
210
|
-
var PROFILES = ["harness", "defi"];
|
|
211
|
-
function parseArgs() {
|
|
212
|
-
const args = process.argv.slice(2);
|
|
213
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
214
|
-
process.stderr.write(`
|
|
215
|
-
vultisig-mcp \u2014 MCP server for Vultisig wallet operations
|
|
216
|
-
|
|
217
|
-
SETUP (first time):
|
|
218
|
-
vmcp --setup Import a vault and store credentials interactively
|
|
219
|
-
vmcp --setup --vault-file <path> Import a specific vault file
|
|
220
|
-
|
|
221
|
-
USAGE:
|
|
222
|
-
vmcp [options]
|
|
223
|
-
|
|
224
|
-
OPTIONS:
|
|
225
|
-
--profile <harness|defi> Tool profile (default: defi)
|
|
226
|
-
harness = read-only tools only
|
|
227
|
-
defi = all tools including send/swap
|
|
228
|
-
--vault-id <id> Use a specific vault (default: first found)
|
|
229
|
-
--setup Run interactive auth setup, then exit
|
|
230
|
-
|
|
231
|
-
CI / HEADLESS (skip interactive auth):
|
|
232
|
-
--vault-file <path> Load vault directly from a .vult file
|
|
233
|
-
Requires VAULT_PASSWORD and/or VAULT_DECRYPT_PASSWORD
|
|
234
|
-
environment variables for encrypted vaults
|
|
235
|
-
|
|
236
|
-
EXAMPLES:
|
|
237
|
-
# First time setup:
|
|
238
|
-
vmcp --setup
|
|
239
|
-
|
|
240
|
-
# Start the server:
|
|
241
|
-
vmcp
|
|
242
|
-
vmcp --profile harness
|
|
243
|
-
|
|
244
|
-
# Claude Code integration:
|
|
245
|
-
claude mcp add vultisig -- vmcp
|
|
246
|
-
claude mcp add vultisig -- npx @vultisig/mcp
|
|
247
|
-
|
|
248
|
-
# CI / headless:
|
|
249
|
-
VAULT_PASSWORD=xxx vmcp --vault-file ./vault.vult
|
|
250
|
-
`);
|
|
251
|
-
process.exit(0);
|
|
252
|
-
}
|
|
253
|
-
let profile = "defi";
|
|
254
|
-
let vaultId;
|
|
255
|
-
let vaultFile;
|
|
256
|
-
const setup = args.includes("--setup");
|
|
257
|
-
for (let i = 0; i < args.length; i++) {
|
|
258
|
-
const arg = args[i];
|
|
259
|
-
if (arg === "--profile" && args[i + 1]) {
|
|
260
|
-
const value = args[++i];
|
|
261
|
-
if (!PROFILES.includes(value)) {
|
|
262
|
-
process.stderr.write(`Invalid profile "${value}". Must be one of: ${PROFILES.join(", ")}
|
|
263
|
-
`);
|
|
264
|
-
process.exit(1);
|
|
265
|
-
}
|
|
266
|
-
profile = value;
|
|
267
|
-
} else if (arg === "--vault-id" && args[i + 1]) {
|
|
268
|
-
vaultId = args[++i];
|
|
269
|
-
} else if (arg === "--vault-file" && args[i + 1]) {
|
|
270
|
-
vaultFile = args[++i];
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return { profile, vaultId, vaultFile, setup };
|
|
274
|
-
}
|
|
275
330
|
async function runSetup(vaultFile) {
|
|
276
331
|
console.log = process.stdout.write.bind(process.stdout);
|
|
277
332
|
process.stderr.write("[vultisig-mcp] Running auth setup...\n");
|
|
@@ -283,7 +338,11 @@ async function runSetup(vaultFile) {
|
|
|
283
338
|
);
|
|
284
339
|
}
|
|
285
340
|
async function main() {
|
|
286
|
-
const { profile, vaultId, vaultFile, setup } =
|
|
341
|
+
const { profile, vaultId, vaultFile, setup, help } = parseMcpArgs(process.argv.slice(2));
|
|
342
|
+
if (help) {
|
|
343
|
+
process.stderr.write(formatMcpHelp());
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
287
346
|
if (setup) {
|
|
288
347
|
await runSetup(vaultFile);
|
|
289
348
|
return;
|
|
@@ -345,7 +404,7 @@ Run vmcp --help for more options.
|
|
|
345
404
|
await startMcpServer(vault, profile);
|
|
346
405
|
}
|
|
347
406
|
main().catch((err) => {
|
|
348
|
-
process.stderr.write(`${err}
|
|
407
|
+
process.stderr.write(`${err instanceof Error ? err.message : err}
|
|
349
408
|
`);
|
|
350
409
|
process.exit(1);
|
|
351
410
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "MCP server for Vultisig SDK - Model Context Protocol wrapper over wallet operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@modelcontextprotocol/sdk": "~1.29.0",
|
|
44
44
|
"@napi-rs/keyring": "^1.3.0",
|
|
45
|
-
"@vultisig/client-shared": "^0.2.
|
|
46
|
-
"@vultisig/sdk": "^1.
|
|
47
|
-
"zod": "^4.3
|
|
45
|
+
"@vultisig/client-shared": "^0.2.14",
|
|
46
|
+
"@vultisig/sdk": "^1.8.10",
|
|
47
|
+
"zod": "^4.4.3"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/node": "^25.
|
|
51
|
-
"esbuild": "^0.
|
|
52
|
-
"tsx": "^4.22.
|
|
50
|
+
"@types/node": "^25.9.2",
|
|
51
|
+
"esbuild": "^0.28.0",
|
|
52
|
+
"tsx": "^4.22.4",
|
|
53
53
|
"typescript": "^6.0.3",
|
|
54
|
-
"vitest": "^4.1.
|
|
54
|
+
"vitest": "^4.1.8"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=20.0.0"
|