@verusidx/marketplace-mcp 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VerusIDX Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @verusidx/marketplace-mcp
2
+
3
+ MCP server for on-chain offers and trades on Verus. Supports identity swaps, currency offers, and decentralized atomic swaps — all four combinations: currency-for-currency, currency-for-identity, identity-for-currency, and identity-for-identity.
4
+
5
+ ## Setup
6
+
7
+ **Prerequisite:** `@verusidx/chain-mcp` must be configured and `refresh_chains` called at least once so the chain registry exists.
8
+
9
+ Add to your MCP client config (e.g., Claude Code `claude_desktop_config.json`):
10
+
11
+ ```json
12
+ {
13
+ "mcpServers": {
14
+ "verusidx-marketplace": {
15
+ "command": "npx",
16
+ "args": ["@verusidx/marketplace-mcp"],
17
+ "env": {}
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ **Alternative: local install.** If you prefer a pinned version or offline use, install into a project directory with `npm install @verusidx/marketplace-mcp` (or `pnpm add` / `yarn add`) and point your config at the local path instead of using `npx`.
24
+
25
+ ### Environment Variables
26
+
27
+ | Variable | Default | Description |
28
+ |---|---|---|
29
+ | `VERUSIDX_READ_ONLY` | `false` | Set to `true` to disable write tools. Read tools remain available. |
30
+ | `VERUSIDX_AUDIT_LOG` | `true` | Set to `false` to disable audit logging of write operations. |
31
+ | `VERUSIDX_AUDIT_DIR` | OS default | Custom directory for audit log files. |
32
+
33
+ ### Read-Only Mode
34
+
35
+ Set `VERUSIDX_READ_ONLY=true` to disable write tools. In read-only mode, 2 tools remain available:
36
+
37
+ - `getoffers` — browse offers on the market
38
+ - `listopenoffers` — list offers from the current wallet
39
+
40
+ Write tools (`makeoffer`, `takeoffer`, `closeoffers`) are not registered and won't appear in the tool list.
41
+
42
+ ## Tools
43
+
44
+ ### Always available (including read-only mode)
45
+
46
+ | Tool | Description |
47
+ |---|---|
48
+ | `getoffers` | Get all open offers for a specific currency or identity (buy and sell sides) |
49
+ | `listopenoffers` | List open offers from the current wallet, with expired/unexpired filter |
50
+
51
+ ### Write tools (disabled in read-only mode)
52
+
53
+ | Tool | Description |
54
+ |---|---|
55
+ | `makeoffer` | Create a new on-chain atomic swap offer |
56
+ | `takeoffer` | Accept an existing on-chain offer (atomic exchange) |
57
+ | `closeoffers` | Close/cancel open offers and reclaim locked funds |
58
+
59
+ ## Offer Types
60
+
61
+ All four swap combinations are supported:
62
+
63
+ | Offer | For | Example |
64
+ |---|---|---|
65
+ | Currency | Currency | Sell 1 BTC for 5000 VRSC |
66
+ | Currency | Identity | Offer 100 VRSC for an identity |
67
+ | Identity | Currency | Sell an identity for 50 VRSC |
68
+ | Identity | Identity | Swap two identities |
69
+
70
+ ### ID Control Tokens
71
+
72
+ Some identities have an associated control token (`flags: 5` in `getidentity`). These identities **cannot** be offered or requested directly — instead, offer/request the control token as a currency: `{"currency": "idname.parent", "amount": 0.00000001}`. There is exactly 1 satoshi of each control token.
73
+
74
+ ## Spending Limits
75
+
76
+ On first run, marketplace-mcp creates a default `spending-limits.json` if one doesn't exist:
77
+
78
+ ```json
79
+ {
80
+ "VRSC": 10
81
+ }
82
+ ```
83
+
84
+ This caps any single `makeoffer` or `takeoffer` call at 10 VRSC. Edit the file to adjust limits. To remove all limits, set the file contents to `{}` (empty object). See the root README for file location and configuration details.
85
+
86
+ ## Audit Logging
87
+
88
+ All write operations are logged to date-stamped JSONL files in the audit directory. Each entry records the tool name, chain, parameters, result, and success status. Logs are append-only with `0600` permissions.
89
+
90
+ ## Requirements
91
+
92
+ - Node.js >= 18.0.0
93
+ - `@verusidx/chain-mcp` installed and `refresh_chains` called (chain registry must exist)
94
+ - At least one Verus daemon running for RPC tools
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { ensureSpendingLimitsFile } from '@verusidx/shared';
5
+ import { registerTools } from './tools.js';
6
+ // Create default spending-limits.json if it doesn't exist yet
7
+ ensureSpendingLimitsFile();
8
+ const server = new McpServer({
9
+ name: 'verusidx-marketplace-mcp',
10
+ version: '0.1.0',
11
+ });
12
+ registerTools(server);
13
+ const transport = new StdioServerTransport();
14
+ await server.connect(transport);
15
+ process.on('SIGINT', async () => {
16
+ await server.close();
17
+ process.exit(0);
18
+ });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,8DAA8D;AAC9D,wBAAwB,EAAE,CAAC;AAE3B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,0BAA0B;IAChC,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,aAAa,CAAC,MAAM,CAAC,CAAC;AAEtB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAEhC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerTools(server: McpServer): void;
3
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwCzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmOrD"}
package/build/tools.js ADDED
@@ -0,0 +1,215 @@
1
+ import { z } from 'zod';
2
+ import { rpcCall, auditLog, isReadOnly, assertWriteEnabled, VerusError, checkSpendingLimits, } from '@verusidx/shared';
3
+ // ---------------------------------------------------------------------------
4
+ // Response helpers
5
+ // ---------------------------------------------------------------------------
6
+ function ok(data) {
7
+ return {
8
+ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
9
+ };
10
+ }
11
+ function fail(category, message) {
12
+ return {
13
+ content: [{ type: 'text', text: JSON.stringify({ error: category, message }, null, 2) }],
14
+ isError: true,
15
+ };
16
+ }
17
+ function handleError(err) {
18
+ if (err instanceof VerusError) {
19
+ return fail(err.category, err.message);
20
+ }
21
+ return fail('INTERNAL_ERROR', err instanceof Error ? err.message : 'Unknown error');
22
+ }
23
+ const SERVER_NAME = 'verusidx-marketplace-mcp';
24
+ // ---------------------------------------------------------------------------
25
+ // Tool registration
26
+ // ---------------------------------------------------------------------------
27
+ export function registerTools(server) {
28
+ // ------ Read-only tools (always registered) ------
29
+ server.tool('getoffers', 'Get all open offers for a specific currency or identity. Returns both buy and sell offers — offers of the asset and offers for the asset. Use iscurrency to switch between currency offers and identity offers. Response keys are dynamic and generated by the daemon based on the queried asset — parse them dynamically. Use this to discover what\'s available on the market before making or taking offers.', {
30
+ chain: z.string().describe('Chain to query (e.g., "VRSC", "vrsctest")'),
31
+ currencyorid: z.string().describe('Currency name/i-address or identity name/i-address to check for offers'),
32
+ iscurrency: z.boolean().optional().describe('If true, look for currency offers. If false (default), look for identity offers.'),
33
+ withtx: z.boolean().optional().describe('If true, include serialized hex of the exchange transaction for signing. Default: false.'),
34
+ }, async ({ chain, currencyorid, iscurrency, withtx }) => {
35
+ try {
36
+ // getoffers "currencyorid" (iscurrency) (withtx)
37
+ const params = [currencyorid];
38
+ if (iscurrency !== undefined || withtx !== undefined) {
39
+ params.push(iscurrency ?? false);
40
+ }
41
+ if (withtx !== undefined) {
42
+ params.push(withtx);
43
+ }
44
+ const result = await rpcCall(chain, 'getoffers', params);
45
+ return ok(result);
46
+ }
47
+ catch (err) {
48
+ return handleError(err);
49
+ }
50
+ });
51
+ server.tool('listopenoffers', 'List open offers from the current wallet. Shows what this wallet has offered on-chain. Can filter by expired/unexpired status. Use this to check the status of offers the agent has created, or to find offers that need to be closed.', {
52
+ chain: z.string().describe('Chain to query (e.g., "VRSC", "vrsctest")'),
53
+ unexpired: z.boolean().optional().describe('Include unexpired (active) offers. Default: true.'),
54
+ expired: z.boolean().optional().describe('Include expired offers. Default: true.'),
55
+ }, async ({ chain, unexpired, expired }) => {
56
+ try {
57
+ // listopenoffers (unexpired) (expired)
58
+ const params = [];
59
+ if (unexpired !== undefined || expired !== undefined) {
60
+ params.push(unexpired ?? true);
61
+ }
62
+ if (expired !== undefined) {
63
+ params.push(expired);
64
+ }
65
+ const result = await rpcCall(chain, 'listopenoffers', params);
66
+ return ok(result);
67
+ }
68
+ catch (err) {
69
+ return handleError(err);
70
+ }
71
+ });
72
+ // ------ Write tools (registered only when not read-only) ------
73
+ if (!isReadOnly()) {
74
+ server.tool('makeoffer', 'Create a new on-chain atomic swap offer. Offers are fully decentralized — no intermediary, no escrow. The offer transaction locks the offered asset on-chain until the offer is taken, expires, or is closed. Supports currency-for-currency, currency-for-identity, identity-for-currency, and identity-for-identity swaps. For currency offers, use {"currency": "name", "amount": n}. For identity offers (without control tokens), use {"identity": "name@"} or a full identity definition. If an identity has a control token (flags: 5), offer/request the control token as a currency instead: {"currency": "idname.parent", "amount": 0.00000001}. Always include parent in identity definitions.', {
75
+ chain: z.string().describe('Chain to transact on (e.g., "VRSC", "vrsctest")'),
76
+ fromaddress: z.string().describe('VerusID or wildcard address to send funds from ("*", "R*", or "i*").'),
77
+ offer: z.record(z.unknown()).describe('What to offer — {"currency": "name", "amount": n} for currency, or {"identity": "name@"} / full identity definition for identity.'),
78
+ changeaddress: z.string().describe('Transparent address or VerusID ("ID@") for change.'),
79
+ expiryheight: z.number().optional().describe('Block height at which this offer expires. Default: current height + 20 (~20 minutes). Set higher for marketplace listings.'),
80
+ for: z.record(z.unknown()).describe('What to accept in return — {"currency": "name", "amount": n, "address": "dest"} for currency (address is REQUIRED — can be R-address, VerusID name@, or i-address), or full identity definition (with parent) for identity.'),
81
+ returntx: z.boolean().optional().describe('If true, return signed transaction hex instead of broadcasting. Default: false.'),
82
+ feeamount: z.number().optional().describe('Custom fee amount. Default: 0.0001.'),
83
+ }, async ({ chain, fromaddress, offer, changeaddress, expiryheight, for: forObj, returntx, feeamount }) => {
84
+ try {
85
+ assertWriteEnabled();
86
+ // Spending limits check for currency offers
87
+ const offerRecord = offer;
88
+ if (offerRecord.currency && typeof offerRecord.amount === 'number') {
89
+ const amounts = new Map();
90
+ amounts.set(offerRecord.currency, offerRecord.amount);
91
+ checkSpendingLimits(amounts);
92
+ }
93
+ // makeoffer fromaddress '{"changeaddress":"...","expiryheight":n,"offer":{...},"for":{...}}' (returntx) (feeamount)
94
+ const offerObj = {
95
+ changeaddress,
96
+ offer,
97
+ for: forObj,
98
+ };
99
+ if (expiryheight !== undefined) {
100
+ offerObj.expiryheight = expiryheight;
101
+ }
102
+ const params = [fromaddress, offerObj];
103
+ if (returntx !== undefined || feeamount !== undefined) {
104
+ params.push(returntx ?? false);
105
+ }
106
+ if (feeamount !== undefined) {
107
+ params.push(feeamount);
108
+ }
109
+ const result = await rpcCall(chain, 'makeoffer', params);
110
+ auditLog({
111
+ server: SERVER_NAME,
112
+ tool: 'makeoffer',
113
+ chain,
114
+ params: { fromaddress, offer, for: forObj, expiryheight, returntx },
115
+ result,
116
+ success: true,
117
+ });
118
+ return ok(result);
119
+ }
120
+ catch (err) {
121
+ return handleError(err);
122
+ }
123
+ });
124
+ server.tool('takeoffer', 'Accept an existing on-chain offer. Creates and posts a transaction that atomically executes the exchange — both sides swap in a single transaction, or neither does. The offer transaction must have at least 1 confirmation before it can be taken. Before taking, verify the offer hasn\'t expired by checking blockexpiry against current block height. deliver is what you give, accept is what you get. For currency: deliver {"currency": "name", "amount": n}, accept {"address": "addr", "currency": "name", "amount": n}. For identity: deliver "name@" (string), accept is full identity definition with parent. If the identity has a control token, use control token currency instead.', {
125
+ chain: z.string().describe('Chain to transact on (e.g., "VRSC", "vrsctest")'),
126
+ fromaddress: z.string().describe('VerusID, Sapling address, or wildcard address to send funds/fees from.'),
127
+ txid: z.string().optional().describe('Transaction ID of the offer to accept (from getoffers or makeoffer). Either txid or tx is required.'),
128
+ tx: z.string().optional().describe('Hex transaction to complete (from makeoffer with returntx=true). Either txid or tx is required.'),
129
+ changeaddress: z.string().optional().describe('Transparent address or VerusID for change.'),
130
+ deliver: z.union([z.string(), z.record(z.unknown())]).describe('What the taker delivers — "name@" (identity) or {"currency": "name", "amount": n} (currency).'),
131
+ accept: z.record(z.unknown()).describe('What the taker receives — {"address": "addr", "currency": "name", "amount": n} (currency) or full identity definition (identity).'),
132
+ returntx: z.boolean().optional().describe('If true, return signed transaction hex instead of broadcasting. Default: false.'),
133
+ feeamount: z.number().optional().describe('Custom fee amount. Default: 0.0001.'),
134
+ }, async ({ chain, fromaddress, txid, tx, changeaddress, deliver, accept, returntx, feeamount }) => {
135
+ try {
136
+ assertWriteEnabled();
137
+ if (!txid && !tx) {
138
+ return fail('INVALID_PARAMS', 'Either txid or tx must be provided.');
139
+ }
140
+ // Spending limits check for currency delivery
141
+ if (typeof deliver === 'object' && deliver !== null) {
142
+ const deliverRecord = deliver;
143
+ if (deliverRecord.currency && typeof deliverRecord.amount === 'number') {
144
+ const amounts = new Map();
145
+ amounts.set(deliverRecord.currency, deliverRecord.amount);
146
+ checkSpendingLimits(amounts);
147
+ }
148
+ }
149
+ // takeoffer fromaddress '{"txid":"...","changeaddress":"...","deliver":{...},"accept":{...}}' (returntx) (feeamount)
150
+ const takeObj = {
151
+ deliver,
152
+ accept,
153
+ };
154
+ if (txid !== undefined)
155
+ takeObj.txid = txid;
156
+ if (tx !== undefined)
157
+ takeObj.tx = tx;
158
+ if (changeaddress !== undefined)
159
+ takeObj.changeaddress = changeaddress;
160
+ const params = [fromaddress, takeObj];
161
+ if (returntx !== undefined || feeamount !== undefined) {
162
+ params.push(returntx ?? false);
163
+ }
164
+ if (feeamount !== undefined) {
165
+ params.push(feeamount);
166
+ }
167
+ const result = await rpcCall(chain, 'takeoffer', params);
168
+ auditLog({
169
+ server: SERVER_NAME,
170
+ tool: 'takeoffer',
171
+ chain,
172
+ params: { fromaddress, txid: txid || '(hex)', deliver, accept: { ...accept, address: '...' }, returntx },
173
+ result,
174
+ success: true,
175
+ });
176
+ return ok(result);
177
+ }
178
+ catch (err) {
179
+ return handleError(err);
180
+ }
181
+ });
182
+ server.tool('closeoffers', 'Close (cancel) open offers and reclaim the locked funds. Returns null on success. Always closes expired offers automatically, even if no parameters are given. When specific offer txids are provided, closes only those offers. Use this to cancel offers that are no longer wanted, or as periodic cleanup to reclaim funds from expired offers.', {
183
+ chain: z.string().describe('Chain to transact on (e.g., "VRSC", "vrsctest")'),
184
+ txids: z.array(z.string()).optional().describe('Array of offer transaction IDs to close. If omitted, closes all expired offers.'),
185
+ destination: z.string().optional().describe('Transparent or private address to send reclaimed funds to.'),
186
+ privatefundsdestination: z.string().optional().describe('Private (Sapling) address for native funds only.'),
187
+ }, async ({ chain, txids, destination, privatefundsdestination }) => {
188
+ try {
189
+ assertWriteEnabled();
190
+ // closeoffers '["txid1","txid2"]' ("destination") ("privatefundsdestination")
191
+ const params = [txids ?? []];
192
+ if (destination !== undefined || privatefundsdestination !== undefined) {
193
+ params.push(destination ?? '');
194
+ }
195
+ if (privatefundsdestination !== undefined) {
196
+ params.push(privatefundsdestination);
197
+ }
198
+ const result = await rpcCall(chain, 'closeoffers', params);
199
+ auditLog({
200
+ server: SERVER_NAME,
201
+ tool: 'closeoffers',
202
+ chain,
203
+ params: { txids, destination },
204
+ result,
205
+ success: true,
206
+ });
207
+ return ok(result);
208
+ }
209
+ catch (err) {
210
+ return handleError(err);
211
+ }
212
+ });
213
+ }
214
+ }
215
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@verusidx/marketplace-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Verus on-chain marketplace — create, browse, accept, and close offers",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "verusidx-marketplace-mcp": "./build/index.js"
9
+ },
10
+ "files": [
11
+ "build"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18.0.0"
15
+ },
16
+ "dependencies": {
17
+ "@modelcontextprotocol/sdk": "^1.27.0",
18
+ "zod": "^3.23.0",
19
+ "@verusidx/shared": "0.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.0.0",
23
+ "typescript": "^5.7.0",
24
+ "vitest": "^3.0.0"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "test": "vitest run"
29
+ }
30
+ }