0nmcp 2.0.0 → 2.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/README.md +111 -47
- package/cli.js +274 -0
- package/index.js +8 -1
- package/lib/stats.json +1 -1
- package/package.json +18 -2
- package/vault/deed-collector.js +286 -0
- package/vault/deed-importer.js +277 -0
- package/vault/deed.js +319 -0
- package/vault/tools-deed.js +257 -0
package/vault/deed.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// 0nMCP — Vault: Business Deed
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Digital Business Asset Transfer System.
|
|
5
|
+
// Packages an entire business's digital assets (API keys, logins,
|
|
6
|
+
// credentials, configurations, workflows, AI prompts) into a
|
|
7
|
+
// single verifiable, transferable, encrypted .0nv container.
|
|
8
|
+
//
|
|
9
|
+
// Lifecycle: CREATE > PACKAGE > ESCROW > ACCEPT > IMPORT > FLIP
|
|
10
|
+
//
|
|
11
|
+
// Patent Pending: US Provisional Patent Application #63/990,046
|
|
12
|
+
// ============================================================
|
|
13
|
+
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { homedir } from "os";
|
|
16
|
+
import { existsSync, mkdirSync } from "fs";
|
|
17
|
+
import { assembleContainer, disassembleContainer, inspectContainer, saveContainer, loadContainer } from "./container.js";
|
|
18
|
+
import { LAYER_NAMES } from "./layers.js";
|
|
19
|
+
import { createSeal } from "./seal.js";
|
|
20
|
+
import { generateSigningKeyPair, sign, sha3Hex } from "./crypto-container.js";
|
|
21
|
+
import { registerTransfer, lookupTransfer } from "./registry.js";
|
|
22
|
+
import { collectCredentials } from "./deed-collector.js";
|
|
23
|
+
import { importDeedToSystem } from "./deed-importer.js";
|
|
24
|
+
|
|
25
|
+
const VAULT_DIR = join(homedir(), ".0n", "vault");
|
|
26
|
+
const DEED_VERSION = "1.0.0";
|
|
27
|
+
|
|
28
|
+
function ensureVaultDir() {
|
|
29
|
+
if (!existsSync(VAULT_DIR)) mkdirSync(VAULT_DIR, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ── Deed Metadata Builder ───────────────────────────────────
|
|
33
|
+
|
|
34
|
+
function buildDeedMetadata(options, services, credentialCount) {
|
|
35
|
+
return {
|
|
36
|
+
deed: {
|
|
37
|
+
version: DEED_VERSION,
|
|
38
|
+
type: "business_deed",
|
|
39
|
+
business: {
|
|
40
|
+
name: options.name || "Unnamed Business",
|
|
41
|
+
domain: options.domain || null,
|
|
42
|
+
description: options.description || null,
|
|
43
|
+
valuation: options.valuation || null,
|
|
44
|
+
currency: options.currency || "USD",
|
|
45
|
+
},
|
|
46
|
+
creator: {
|
|
47
|
+
name: options.creatorName || null,
|
|
48
|
+
email: options.creatorEmail || null,
|
|
49
|
+
},
|
|
50
|
+
services,
|
|
51
|
+
credential_count: credentialCount,
|
|
52
|
+
transfer_history: [],
|
|
53
|
+
created: new Date().toISOString(),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ── BusinessDeed Class ──────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export class BusinessDeed {
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create a new Business Deed — package credentials into a .0nv file.
|
|
64
|
+
*
|
|
65
|
+
* @param {Object} options
|
|
66
|
+
* @param {string} options.name - Business name
|
|
67
|
+
* @param {string} [options.domain] - Business domain
|
|
68
|
+
* @param {string} [options.description] - Business description
|
|
69
|
+
* @param {number} [options.valuation] - Business valuation
|
|
70
|
+
* @param {string} [options.currency] - Currency code (default: USD)
|
|
71
|
+
* @param {string} [options.creatorName] - Creator's name
|
|
72
|
+
* @param {string} [options.creatorEmail] - Creator's email
|
|
73
|
+
* @param {Object} [options.credentials] - Pre-structured credentials { service: { field: value } }
|
|
74
|
+
* @param {Array} [options.workflows] - Workflow definitions
|
|
75
|
+
* @param {Object} [options.envVars] - Environment variables
|
|
76
|
+
* @param {Object} [options.mcpConfigs] - MCP server configurations
|
|
77
|
+
* @param {Object} [options.siteProfiles] - Site/CRO profiles
|
|
78
|
+
* @param {Object} [options.aiBrain] - AI agent data, prompts, memory
|
|
79
|
+
* @param {string} options.passphrase - Encryption passphrase
|
|
80
|
+
* @param {string} [options.output] - Output file path
|
|
81
|
+
* @param {Array} [options.escrowParties] - Escrow party definitions
|
|
82
|
+
* @param {Object} [options.accessMatrix] - Per-party layer access
|
|
83
|
+
* @returns {Promise<Object>} Created deed info
|
|
84
|
+
*/
|
|
85
|
+
async create(options) {
|
|
86
|
+
const {
|
|
87
|
+
credentials = {},
|
|
88
|
+
workflows = [],
|
|
89
|
+
envVars = {},
|
|
90
|
+
mcpConfigs = {},
|
|
91
|
+
siteProfiles = {},
|
|
92
|
+
aiBrain = {},
|
|
93
|
+
passphrase,
|
|
94
|
+
output,
|
|
95
|
+
escrowParties = [],
|
|
96
|
+
accessMatrix = {},
|
|
97
|
+
} = options;
|
|
98
|
+
|
|
99
|
+
if (!passphrase) throw new Error("Passphrase is required");
|
|
100
|
+
|
|
101
|
+
// Determine services from credentials
|
|
102
|
+
const services = Object.keys(credentials);
|
|
103
|
+
const credentialCount = services.reduce((sum, svc) => sum + Object.keys(credentials[svc]).length, 0);
|
|
104
|
+
|
|
105
|
+
// Build deed metadata
|
|
106
|
+
const deedMeta = buildDeedMetadata(options, services, credentialCount);
|
|
107
|
+
|
|
108
|
+
// Assemble all 7 layers
|
|
109
|
+
const layers = {};
|
|
110
|
+
if (workflows.length > 0) layers.workflows = workflows;
|
|
111
|
+
if (Object.keys(credentials).length > 0) layers.credentials = credentials;
|
|
112
|
+
if (Object.keys(envVars).length > 0) layers.env_vars = envVars;
|
|
113
|
+
if (Object.keys(mcpConfigs).length > 0) layers.mcp_configs = mcpConfigs;
|
|
114
|
+
if (Object.keys(siteProfiles).length > 0) layers.site_profiles = siteProfiles;
|
|
115
|
+
if (Object.keys(aiBrain).length > 0) layers.ai_brain = aiBrain;
|
|
116
|
+
|
|
117
|
+
// Audit trail always includes deed metadata
|
|
118
|
+
layers.audit_trail = deedMeta;
|
|
119
|
+
|
|
120
|
+
// Ensure at least credentials or some layer has data
|
|
121
|
+
if (Object.keys(layers).length <= 1) {
|
|
122
|
+
throw new Error("Deed must contain at least one data layer (credentials, workflows, env_vars, etc.)");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const result = await assembleContainer({
|
|
126
|
+
layers,
|
|
127
|
+
passphrase,
|
|
128
|
+
escrowParties,
|
|
129
|
+
accessMatrix,
|
|
130
|
+
metadata: { type: "business_deed", business: options.name },
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Save to file
|
|
134
|
+
ensureVaultDir();
|
|
135
|
+
const filePath = output || join(VAULT_DIR, `deed-${result.transferId}.0nv`);
|
|
136
|
+
const savedPath = saveContainer(result.buffer, filePath);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
file: savedPath,
|
|
140
|
+
transferId: result.transferId,
|
|
141
|
+
sealHex: result.sealHex,
|
|
142
|
+
publicKey: result.publicKey.toString("hex"),
|
|
143
|
+
services,
|
|
144
|
+
credentialCount,
|
|
145
|
+
layerCount: result.layerCount,
|
|
146
|
+
layers: result.layers,
|
|
147
|
+
containerSize: result.buffer.length,
|
|
148
|
+
business: deedMeta.deed.business,
|
|
149
|
+
timestamp: new Date(result.timestamp).toISOString(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Open a deed — decrypt and return all layer data.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} filePath - Path to .0nv file
|
|
157
|
+
* @param {string} passphrase - Decryption passphrase
|
|
158
|
+
* @param {string[]} [onlyLayers] - Only decrypt these layers
|
|
159
|
+
* @returns {Promise<Object>}
|
|
160
|
+
*/
|
|
161
|
+
async open(filePath, passphrase, onlyLayers = null) {
|
|
162
|
+
const buffer = loadContainer(filePath);
|
|
163
|
+
const result = await disassembleContainer(buffer, passphrase, onlyLayers);
|
|
164
|
+
|
|
165
|
+
// Extract deed metadata from audit_trail
|
|
166
|
+
const deedMeta = result.layers.audit_trail?.deed || null;
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
...result,
|
|
170
|
+
deed: deedMeta,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Inspect a deed without decrypting — metadata + seal only.
|
|
176
|
+
*
|
|
177
|
+
* @param {string} filePath
|
|
178
|
+
* @returns {Object}
|
|
179
|
+
*/
|
|
180
|
+
inspect(filePath) {
|
|
181
|
+
const buffer = loadContainer(filePath);
|
|
182
|
+
const info = inspectContainer(buffer);
|
|
183
|
+
|
|
184
|
+
// Check registry for transfer history
|
|
185
|
+
const transfer = lookupTransfer(info.metadata.transferId);
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
...info,
|
|
189
|
+
type: "business_deed",
|
|
190
|
+
transfer: transfer.found ? transfer.transfer : null,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Verify deed integrity — Seal of Truth + Ed25519 signature.
|
|
196
|
+
*
|
|
197
|
+
* @param {string} filePath
|
|
198
|
+
* @returns {Object}
|
|
199
|
+
*/
|
|
200
|
+
verify(filePath) {
|
|
201
|
+
const buffer = loadContainer(filePath);
|
|
202
|
+
const info = inspectContainer(buffer);
|
|
203
|
+
const transfer = lookupTransfer(info.metadata.transferId);
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
verified: info.seal.valid && info.signature.valid,
|
|
207
|
+
seal: info.seal,
|
|
208
|
+
signature: info.signature,
|
|
209
|
+
transferId: info.metadata.transferId,
|
|
210
|
+
created: info.metadata.created,
|
|
211
|
+
transfer: transfer.found ? transfer.transfer : null,
|
|
212
|
+
patent: info.patent,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Accept a deed transfer — buyer signs acceptance with chain of custody.
|
|
218
|
+
* Opens the deed, records the acceptance in the audit trail,
|
|
219
|
+
* and creates a new container with updated transfer history.
|
|
220
|
+
*
|
|
221
|
+
* @param {string} filePath - Path to .0nv deed
|
|
222
|
+
* @param {string} passphrase - Deed passphrase
|
|
223
|
+
* @param {Object} buyer - { name, email }
|
|
224
|
+
* @param {string} [newPassphrase] - Optional new passphrase for re-encrypted deed
|
|
225
|
+
* @param {string} [outputPath] - Optional output path for accepted deed
|
|
226
|
+
* @returns {Promise<Object>}
|
|
227
|
+
*/
|
|
228
|
+
async accept(filePath, passphrase, buyer, newPassphrase = null, outputPath = null) {
|
|
229
|
+
// Open existing deed
|
|
230
|
+
const buffer = loadContainer(filePath);
|
|
231
|
+
const result = await disassembleContainer(buffer, passphrase);
|
|
232
|
+
|
|
233
|
+
if (!result.seal.valid || !result.signature.valid) {
|
|
234
|
+
throw new Error("Cannot accept deed — seal or signature verification failed");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const deedMeta = result.layers.audit_trail?.deed;
|
|
238
|
+
if (!deedMeta) {
|
|
239
|
+
throw new Error("Not a valid business deed — no deed metadata found in audit_trail");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Record acceptance in transfer history
|
|
243
|
+
const acceptanceRecord = {
|
|
244
|
+
action: "accept",
|
|
245
|
+
from: deedMeta.creator,
|
|
246
|
+
to: { name: buyer.name, email: buyer.email },
|
|
247
|
+
timestamp: new Date().toISOString(),
|
|
248
|
+
originalSeal: result.seal.hash,
|
|
249
|
+
originalTransferId: result.metadata.transferId,
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
deedMeta.transfer_history.push(acceptanceRecord);
|
|
253
|
+
deedMeta.creator = { name: buyer.name, email: buyer.email };
|
|
254
|
+
result.layers.audit_trail.deed = deedMeta;
|
|
255
|
+
|
|
256
|
+
// Re-create container with updated audit trail (optionally with new passphrase)
|
|
257
|
+
const usePassphrase = newPassphrase || passphrase;
|
|
258
|
+
const newResult = await assembleContainer({
|
|
259
|
+
layers: result.layers,
|
|
260
|
+
passphrase: usePassphrase,
|
|
261
|
+
metadata: { type: "business_deed_accepted", buyer: buyer.name },
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
ensureVaultDir();
|
|
265
|
+
const outPath = outputPath || join(VAULT_DIR, `deed-accepted-${newResult.transferId}.0nv`);
|
|
266
|
+
const savedPath = saveContainer(newResult.buffer, outPath);
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
file: savedPath,
|
|
270
|
+
transferId: newResult.transferId,
|
|
271
|
+
sealHex: newResult.sealHex,
|
|
272
|
+
previousTransferId: result.metadata.transferId,
|
|
273
|
+
previousSeal: result.seal.hash,
|
|
274
|
+
buyer,
|
|
275
|
+
services: deedMeta.services,
|
|
276
|
+
credentialCount: deedMeta.credential_count,
|
|
277
|
+
transferHistory: deedMeta.transfer_history,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Import a deed — decrypt and write to live system configuration.
|
|
283
|
+
*
|
|
284
|
+
* @param {string} filePath - Path to .0nv deed
|
|
285
|
+
* @param {string} passphrase - Decryption passphrase
|
|
286
|
+
* @param {string} [targetDir] - Target ~/.0n/ directory
|
|
287
|
+
* @returns {Promise<Object>} Import report
|
|
288
|
+
*/
|
|
289
|
+
async importDeed(filePath, passphrase, targetDir = null) {
|
|
290
|
+
const buffer = loadContainer(filePath);
|
|
291
|
+
const result = await disassembleContainer(buffer, passphrase);
|
|
292
|
+
|
|
293
|
+
if (!result.seal.valid || !result.signature.valid) {
|
|
294
|
+
throw new Error("Cannot import deed — seal or signature verification failed");
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return importDeedToSystem(result.layers, targetDir);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Export — collect credentials from sources and package as deed in one step.
|
|
302
|
+
*
|
|
303
|
+
* @param {Object} sources - { envFile, jsonFile, csvFile, connectionsDir, manual }
|
|
304
|
+
* @param {Object} options - Same as create() options
|
|
305
|
+
* @returns {Promise<Object>}
|
|
306
|
+
*/
|
|
307
|
+
async export(sources, options) {
|
|
308
|
+
const collected = await collectCredentials(sources);
|
|
309
|
+
|
|
310
|
+
return this.create({
|
|
311
|
+
...options,
|
|
312
|
+
credentials: collected.credentials,
|
|
313
|
+
envVars: collected.envVars,
|
|
314
|
+
services: collected.services,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export const DEED_VERSION_STR = DEED_VERSION;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// 0nMCP — Vault: Business Deed MCP Tools
|
|
3
|
+
// ============================================================
|
|
4
|
+
// 6 MCP tools for the Business Deed digital asset transfer system.
|
|
5
|
+
//
|
|
6
|
+
// Patent Pending: US Provisional Patent Application #63/990,046
|
|
7
|
+
// ============================================================
|
|
8
|
+
|
|
9
|
+
import { BusinessDeed } from "./deed.js";
|
|
10
|
+
import { collectCredentials, validateCollected } from "./deed-collector.js";
|
|
11
|
+
import { LAYER_NAMES } from "./layers.js";
|
|
12
|
+
|
|
13
|
+
const deed = new BusinessDeed();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register Business Deed tools on an MCP server.
|
|
17
|
+
*
|
|
18
|
+
* @param {import("@modelcontextprotocol/sdk/server/mcp.js").McpServer} server
|
|
19
|
+
* @param {import("zod").ZodType} z
|
|
20
|
+
*/
|
|
21
|
+
export function registerDeedTools(server, z) {
|
|
22
|
+
|
|
23
|
+
// ─── deed_create ────────────────────────────────────────────
|
|
24
|
+
server.tool(
|
|
25
|
+
"deed_create",
|
|
26
|
+
`Create a Business Deed — package an entire business's digital assets into a single
|
|
27
|
+
encrypted, verifiable .0nv container file. Includes API keys, credentials, workflows,
|
|
28
|
+
configs, and AI data across 7 semantic layers with Argon2id double-encryption for secrets.
|
|
29
|
+
|
|
30
|
+
This is the digital equivalent of signing over a business deed — one file that proves
|
|
31
|
+
ownership, packages all operational credentials, and enables instant activation.
|
|
32
|
+
|
|
33
|
+
Lifecycle: CREATE > PACKAGE > ESCROW > ACCEPT > IMPORT
|
|
34
|
+
|
|
35
|
+
Patent Pending: US Provisional Patent Application #63/990,046
|
|
36
|
+
|
|
37
|
+
Example: deed_create({
|
|
38
|
+
name: "My SaaS Business",
|
|
39
|
+
passphrase: "secure-pass",
|
|
40
|
+
credentials: { stripe: { apiKey: "sk_..." }, github: { token: "ghp_..." } },
|
|
41
|
+
envVars: { DATABASE_URL: "postgres://..." }
|
|
42
|
+
})`,
|
|
43
|
+
{
|
|
44
|
+
name: z.string().describe("Business name"),
|
|
45
|
+
passphrase: z.string().describe("Encryption passphrase for the deed"),
|
|
46
|
+
domain: z.string().optional().describe("Business domain (e.g., example.com)"),
|
|
47
|
+
description: z.string().optional().describe("Business description"),
|
|
48
|
+
valuation: z.number().optional().describe("Business valuation amount"),
|
|
49
|
+
currency: z.string().optional().describe("Currency code (default: USD)"),
|
|
50
|
+
creatorName: z.string().optional().describe("Creator's name"),
|
|
51
|
+
creatorEmail: z.string().optional().describe("Creator's email"),
|
|
52
|
+
credentials: z.record(z.record(z.string())).optional().describe("Service credentials: { service: { field: value } }"),
|
|
53
|
+
workflows: z.array(z.any()).optional().describe("Workflow definitions to include"),
|
|
54
|
+
envVars: z.record(z.string()).optional().describe("Environment variables to include"),
|
|
55
|
+
mcpConfigs: z.record(z.any()).optional().describe("MCP server configurations"),
|
|
56
|
+
siteProfiles: z.record(z.any()).optional().describe("Site/CRO profiles"),
|
|
57
|
+
aiBrain: z.record(z.any()).optional().describe("AI agent data, prompts, memory"),
|
|
58
|
+
output: z.string().optional().describe("Output .0nv file path"),
|
|
59
|
+
},
|
|
60
|
+
async (params) => {
|
|
61
|
+
try {
|
|
62
|
+
const result = await deed.create(params);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
66
|
+
success: true,
|
|
67
|
+
...result,
|
|
68
|
+
patent: "US Provisional #63/990,046",
|
|
69
|
+
}, null, 2) }],
|
|
70
|
+
};
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return {
|
|
73
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
74
|
+
success: false, error: err.message,
|
|
75
|
+
}, null, 2) }],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// ─── deed_open ──────────────────────────────────────────────
|
|
82
|
+
server.tool(
|
|
83
|
+
"deed_open",
|
|
84
|
+
`Open and decrypt a Business Deed (.0nv file).
|
|
85
|
+
Verifies Ed25519 signature and Seal of Truth, then decrypts all layers.
|
|
86
|
+
Returns credentials, workflows, configs, and deed metadata.
|
|
87
|
+
|
|
88
|
+
Example: deed_open({ file: "deed-abc123.0nv", passphrase: "secure-pass" })`,
|
|
89
|
+
{
|
|
90
|
+
file: z.string().describe("Path to .0nv deed file"),
|
|
91
|
+
passphrase: z.string().describe("Decryption passphrase"),
|
|
92
|
+
layers: z.array(z.string()).optional().describe("Only decrypt these layers (default: all)"),
|
|
93
|
+
},
|
|
94
|
+
async ({ file, passphrase, layers: onlyLayers }) => {
|
|
95
|
+
try {
|
|
96
|
+
const result = await deed.open(file, passphrase, onlyLayers || null);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
100
|
+
success: true,
|
|
101
|
+
...result,
|
|
102
|
+
}, null, 2) }],
|
|
103
|
+
};
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return {
|
|
106
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
107
|
+
success: false, error: err.message,
|
|
108
|
+
}, null, 2) }],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// ─── deed_inspect ───────────────────────────────────────────
|
|
115
|
+
server.tool(
|
|
116
|
+
"deed_inspect",
|
|
117
|
+
`Inspect a Business Deed without decrypting.
|
|
118
|
+
Shows business name, services, layer info, seal verification, and transfer history.
|
|
119
|
+
No passphrase required — all metadata is public.
|
|
120
|
+
|
|
121
|
+
Example: deed_inspect({ file: "deed-abc123.0nv" })`,
|
|
122
|
+
{
|
|
123
|
+
file: z.string().describe("Path to .0nv deed file"),
|
|
124
|
+
},
|
|
125
|
+
async ({ file }) => {
|
|
126
|
+
try {
|
|
127
|
+
const result = deed.inspect(file);
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
131
|
+
success: true,
|
|
132
|
+
...result,
|
|
133
|
+
}, null, 2) }],
|
|
134
|
+
};
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return {
|
|
137
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
138
|
+
success: false, error: err.message,
|
|
139
|
+
}, null, 2) }],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// ─── deed_verify ────────────────────────────────────────────
|
|
146
|
+
server.tool(
|
|
147
|
+
"deed_verify",
|
|
148
|
+
`Verify a Business Deed's Seal of Truth and Ed25519 signature.
|
|
149
|
+
Confirms the deed is authentic, unmodified, and from the original creator.
|
|
150
|
+
Also checks the transfer registry for chain of custody.
|
|
151
|
+
|
|
152
|
+
Example: deed_verify({ file: "deed-abc123.0nv" })`,
|
|
153
|
+
{
|
|
154
|
+
file: z.string().describe("Path to .0nv deed file"),
|
|
155
|
+
},
|
|
156
|
+
async ({ file }) => {
|
|
157
|
+
try {
|
|
158
|
+
const result = deed.verify(file);
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
162
|
+
success: true,
|
|
163
|
+
...result,
|
|
164
|
+
}, null, 2) }],
|
|
165
|
+
};
|
|
166
|
+
} catch (err) {
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
169
|
+
success: false, error: err.message,
|
|
170
|
+
}, null, 2) }],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// ─── deed_accept ────────────────────────────────────────────
|
|
177
|
+
server.tool(
|
|
178
|
+
"deed_accept",
|
|
179
|
+
`Accept a Business Deed transfer — buyer signs acceptance with chain of custody.
|
|
180
|
+
Creates a new deed container with updated transfer history and optionally re-encrypts
|
|
181
|
+
with a new passphrase for the buyer.
|
|
182
|
+
|
|
183
|
+
Example: deed_accept({
|
|
184
|
+
file: "deed-abc123.0nv",
|
|
185
|
+
passphrase: "seller-pass",
|
|
186
|
+
buyerName: "New Owner",
|
|
187
|
+
buyerEmail: "buyer@example.com"
|
|
188
|
+
})`,
|
|
189
|
+
{
|
|
190
|
+
file: z.string().describe("Path to .0nv deed file"),
|
|
191
|
+
passphrase: z.string().describe("Current deed passphrase"),
|
|
192
|
+
buyerName: z.string().describe("Buyer's name"),
|
|
193
|
+
buyerEmail: z.string().describe("Buyer's email"),
|
|
194
|
+
newPassphrase: z.string().optional().describe("New passphrase for re-encrypted deed"),
|
|
195
|
+
output: z.string().optional().describe("Output path for accepted deed"),
|
|
196
|
+
},
|
|
197
|
+
async ({ file, passphrase, buyerName, buyerEmail, newPassphrase, output }) => {
|
|
198
|
+
try {
|
|
199
|
+
const result = await deed.accept(
|
|
200
|
+
file,
|
|
201
|
+
passphrase,
|
|
202
|
+
{ name: buyerName, email: buyerEmail },
|
|
203
|
+
newPassphrase || null,
|
|
204
|
+
output || null
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
209
|
+
success: true,
|
|
210
|
+
...result,
|
|
211
|
+
}, null, 2) }],
|
|
212
|
+
};
|
|
213
|
+
} catch (err) {
|
|
214
|
+
return {
|
|
215
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
216
|
+
success: false, error: err.message,
|
|
217
|
+
}, null, 2) }],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// ─── deed_import ────────────────────────────────────────────
|
|
224
|
+
server.tool(
|
|
225
|
+
"deed_import",
|
|
226
|
+
`Import a Business Deed — decrypt and write credentials to live system config.
|
|
227
|
+
Writes .0n connection files, .env file, MCP configs, workflows, and AI brain data.
|
|
228
|
+
The deed's Seal of Truth and signature are verified before import.
|
|
229
|
+
|
|
230
|
+
Example: deed_import({ file: "deed-abc123.0nv", passphrase: "secure-pass" })`,
|
|
231
|
+
{
|
|
232
|
+
file: z.string().describe("Path to .0nv deed file"),
|
|
233
|
+
passphrase: z.string().describe("Decryption passphrase"),
|
|
234
|
+
targetDir: z.string().optional().describe("Target directory (default: ~/.0n/)"),
|
|
235
|
+
},
|
|
236
|
+
async ({ file, passphrase, targetDir }) => {
|
|
237
|
+
try {
|
|
238
|
+
const result = await deed.importDeed(file, passphrase, targetDir || null);
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
242
|
+
success: true,
|
|
243
|
+
...result,
|
|
244
|
+
}, null, 2) }],
|
|
245
|
+
};
|
|
246
|
+
} catch (err) {
|
|
247
|
+
return {
|
|
248
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
249
|
+
success: false, error: err.message,
|
|
250
|
+
}, null, 2) }],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export const DEED_TOOL_COUNT = 6;
|