@rubytech/create-maxy-code 0.1.59 → 0.1.60
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/package.json +1 -1
- package/payload/platform/plugins/loop/PLUGIN.md +13 -1
- package/payload/platform/plugins/loop/mcp/dist/index.js +8 -7
- package/payload/platform/plugins/loop/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts +3 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts.map +1 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js +48 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js.map +1 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts +22 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts.map +1 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js +165 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js.map +1 -0
- package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts +1 -1
- package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js +4 -39
- package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js +5 -15
- package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts.map +1 -1
- package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js +11 -28
- package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js.map +1 -1
- package/payload/platform/plugins/loop/mcp/src/index.ts +10 -7
- package/payload/platform/plugins/loop/mcp/src/lib/file-crypto.ts +54 -0
- package/payload/platform/plugins/loop/mcp/src/lib/key-store.ts +221 -0
- package/payload/platform/plugins/loop/mcp/src/lib/loop-api.ts +5 -42
- package/payload/platform/plugins/loop/mcp/src/tools/key-deregister.ts +5 -20
- package/payload/platform/plugins/loop/mcp/src/tools/key-register.ts +14 -39
- package/payload/platform/plugins/property-data/PLUGIN.md +14 -1
- package/payload/platform/plugins/property-data/mcp/dist/index.js +14 -11
- package/payload/platform/plugins/property-data/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts +3 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js +49 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts +15 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js +135 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +0 -1
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +11 -22
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +2 -2
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +5 -15
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -1
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +30 -23
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -1
- package/payload/platform/plugins/property-data/mcp/src/index.ts +16 -11
- package/payload/platform/plugins/property-data/mcp/src/lib/file-crypto.ts +55 -0
- package/payload/platform/plugins/property-data/mcp/src/lib/key-store.ts +181 -0
- package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +9 -24
- package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +2 -2
- package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +5 -17
- package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +29 -33
- package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +13 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js +8 -7
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.d.ts +3 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.js +48 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.d.ts +22 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.js +165 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js +4 -39
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.js +5 -15
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.js +11 -28
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/index.ts +10 -7
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/file-crypto.ts +54 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/key-store.ts +221 -0
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/loop-api.ts +5 -42
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/key-deregister.ts +5 -20
- package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/key-register.ts +14 -39
- package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +14 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js +14 -11
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.d.ts +3 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.js +49 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.d.ts +15 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.js +135 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +0 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js +11 -22
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js +2 -2
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js +5 -15
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js +30 -23
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/index.ts +16 -11
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/file-crypto.ts +55 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/key-store.ts +181 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/propertydata-api.ts +9 -24
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/endpoints.ts +2 -2
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-deregister.ts +5 -17
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-register.ts +29 -33
- package/payload/server/public/assets/{admin-nqCBFiSl.js → admin-Bp-BjBCX.js} +51 -51
- package/payload/server/public/index.html +1 -1
- package/payload/server/server.js +4 -3
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts +0 -51
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js +0 -196
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js.map +0 -1
- package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/package.json +0 -7
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { resolve, dirname } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { getSession } from "./neo4j.js";
|
|
5
|
+
import { encrypt, decrypt } from "./crypto.js";
|
|
6
|
+
import { encryptWith, decryptWith } from "./file-crypto.js";
|
|
7
|
+
class Neo4jKeyStore {
|
|
8
|
+
backendName = "neo4j";
|
|
9
|
+
backendPath = process.env.NEO4J_URI ?? "<unset>";
|
|
10
|
+
async load(accountId) {
|
|
11
|
+
const session = getSession();
|
|
12
|
+
try {
|
|
13
|
+
const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
|
|
14
|
+
RETURN k.encryptedKey AS encryptedKey,
|
|
15
|
+
k.createdAt AS createdAt,
|
|
16
|
+
k.updatedAt AS updatedAt`, { accountId });
|
|
17
|
+
if (result.records.length === 0)
|
|
18
|
+
return null;
|
|
19
|
+
const r = result.records[0];
|
|
20
|
+
return {
|
|
21
|
+
apiKey: decrypt(r.get("encryptedKey")),
|
|
22
|
+
createdAt: r.get("createdAt") ?? "",
|
|
23
|
+
updatedAt: r.get("updatedAt") ?? "",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
await session.close();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async save(accountId, apiKey) {
|
|
31
|
+
const encryptedKey = encrypt(apiKey);
|
|
32
|
+
const now = new Date().toISOString();
|
|
33
|
+
const session = getSession();
|
|
34
|
+
try {
|
|
35
|
+
await session.run(`CREATE INDEX property_data_key_account IF NOT EXISTS
|
|
36
|
+
FOR (k:PropertyDataKey) ON (k.accountId)`, {});
|
|
37
|
+
await session.run(`MERGE (k:PropertyDataKey {accountId: $accountId})
|
|
38
|
+
ON CREATE SET k.encryptedKey = $encryptedKey, k.createdAt = $now, k.updatedAt = $now
|
|
39
|
+
ON MATCH SET k.encryptedKey = $encryptedKey, k.updatedAt = $now`, { accountId, encryptedKey, now });
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await session.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async delete(accountId) {
|
|
46
|
+
const session = getSession();
|
|
47
|
+
try {
|
|
48
|
+
const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
|
|
49
|
+
DELETE k
|
|
50
|
+
RETURN count(k) AS deleted`, { accountId });
|
|
51
|
+
const deleted = result.records[0]?.get("deleted")?.toNumber?.() ?? 0;
|
|
52
|
+
return deleted > 0;
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
await session.close();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const LABEL = "property-data";
|
|
60
|
+
class FileKeyStore {
|
|
61
|
+
backendName = "file";
|
|
62
|
+
backendPath;
|
|
63
|
+
storePath;
|
|
64
|
+
keyFilePath;
|
|
65
|
+
constructor() {
|
|
66
|
+
const home = homedir();
|
|
67
|
+
this.storePath = resolve(home, ".claude/.realagent-property-data-key.enc");
|
|
68
|
+
this.keyFilePath = resolve(home, ".claude/.realagent-property-data-encryption-key");
|
|
69
|
+
this.backendPath = this.storePath;
|
|
70
|
+
}
|
|
71
|
+
ensureDir() {
|
|
72
|
+
mkdirSync(dirname(this.storePath), { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
readAll() {
|
|
75
|
+
if (!existsSync(this.storePath))
|
|
76
|
+
return {};
|
|
77
|
+
const blob = readFileSync(this.storePath, "utf-8").trim();
|
|
78
|
+
if (!blob)
|
|
79
|
+
return {};
|
|
80
|
+
const json = decryptWith(blob, this.keyFilePath, LABEL);
|
|
81
|
+
return JSON.parse(json);
|
|
82
|
+
}
|
|
83
|
+
writeAll(env) {
|
|
84
|
+
this.ensureDir();
|
|
85
|
+
const blob = encryptWith(JSON.stringify(env), this.keyFilePath, LABEL);
|
|
86
|
+
writeFileSync(this.storePath, blob, { mode: 0o600 });
|
|
87
|
+
}
|
|
88
|
+
async load(accountId) {
|
|
89
|
+
const env = this.readAll();
|
|
90
|
+
const entry = env[accountId];
|
|
91
|
+
if (!entry)
|
|
92
|
+
return null;
|
|
93
|
+
// The encryptedKey field is double-encrypted: the file blob is decrypted
|
|
94
|
+
// above, the inner field is the original AES-GCM-wrapped key. Keep the
|
|
95
|
+
// inner layer so an unauthenticated read of decrypted JSON still doesn't
|
|
96
|
+
// expose the API key directly in process memory until decryptWith runs.
|
|
97
|
+
return {
|
|
98
|
+
apiKey: decryptWith(entry.encryptedKey, this.keyFilePath, LABEL),
|
|
99
|
+
createdAt: entry.createdAt,
|
|
100
|
+
updatedAt: entry.updatedAt,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async save(accountId, apiKey) {
|
|
104
|
+
const env = this.readAll();
|
|
105
|
+
const now = new Date().toISOString();
|
|
106
|
+
const encryptedKey = encryptWith(apiKey, this.keyFilePath, LABEL);
|
|
107
|
+
const prev = env[accountId];
|
|
108
|
+
env[accountId] = {
|
|
109
|
+
encryptedKey,
|
|
110
|
+
createdAt: prev?.createdAt ?? now,
|
|
111
|
+
updatedAt: now,
|
|
112
|
+
};
|
|
113
|
+
this.writeAll(env);
|
|
114
|
+
}
|
|
115
|
+
async delete(accountId) {
|
|
116
|
+
const env = this.readAll();
|
|
117
|
+
if (!(accountId in env))
|
|
118
|
+
return false;
|
|
119
|
+
delete env[accountId];
|
|
120
|
+
this.writeAll(env);
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
let cached = null;
|
|
125
|
+
export function selectKeyStore() {
|
|
126
|
+
if (cached)
|
|
127
|
+
return cached;
|
|
128
|
+
cached = process.env.PROPERTY_DATA_STANDALONE === "1" ? new FileKeyStore() : new Neo4jKeyStore();
|
|
129
|
+
return cached;
|
|
130
|
+
}
|
|
131
|
+
// Test seam — used by unit tests to reset the cached store between cases.
|
|
132
|
+
export function _resetKeyStoreForTests() {
|
|
133
|
+
cached = null;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=key-store.js.map
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-store.js","sourceRoot":"","sources":["../../src/lib/key-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propertydata-api.d.ts","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"propertydata-api.d.ts","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"AAiBA,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAChB,eAAe,EAAE,MAAM;gBAFvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM;CAK1C;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,QAAQ,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;gBAAhD,QAAQ,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAI7E;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAIvF;AAED,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDzE"}
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { decrypt } from "./crypto.js";
|
|
1
|
+
import { selectKeyStore } from "./key-store.js";
|
|
3
2
|
// PropertyData API V1 client. Every endpoint is a GET against
|
|
4
3
|
// https://api.propertydata.co.uk/<endpoint> with `key=<api-key>` plus
|
|
5
4
|
// endpoint-specific query params. Response envelope:
|
|
@@ -42,30 +41,20 @@ export class BadResponseError extends Error {
|
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
export async function loadAccountKey(accountId) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
k.createdAt AS createdAt,
|
|
50
|
-
k.updatedAt AS updatedAt`, { accountId });
|
|
51
|
-
if (result.records.length === 0)
|
|
52
|
-
return null;
|
|
53
|
-
const r = result.records[0];
|
|
54
|
-
return {
|
|
55
|
-
encryptedKey: r.get("encryptedKey"),
|
|
56
|
-
createdAt: r.get("createdAt") ?? "",
|
|
57
|
-
updatedAt: r.get("updatedAt") ?? "",
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
await session.close();
|
|
62
|
-
}
|
|
44
|
+
const stored = await selectKeyStore().load(accountId);
|
|
45
|
+
if (!stored)
|
|
46
|
+
return null;
|
|
47
|
+
return { createdAt: stored.createdAt, updatedAt: stored.updatedAt };
|
|
63
48
|
}
|
|
64
49
|
export async function resolveAccountApiKey(accountId) {
|
|
65
|
-
|
|
50
|
+
// Bypass for one-shot CLI runs: explicit env var beats stored key.
|
|
51
|
+
const envKey = process.env.PROPERTY_DATA_API_KEY;
|
|
52
|
+
if (envKey && envKey.trim())
|
|
53
|
+
return envKey.trim();
|
|
54
|
+
const stored = await selectKeyStore().load(accountId);
|
|
66
55
|
if (!stored)
|
|
67
56
|
throw new KeyNotRegisteredError();
|
|
68
|
-
return
|
|
57
|
+
return stored.apiKey;
|
|
69
58
|
}
|
|
70
59
|
export async function propertyDataCall(opts) {
|
|
71
60
|
const { endpoint, toolName, accountId, params } = opts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propertydata-api.js","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"propertydata-api.js","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"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"}
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"AAMA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5D,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"AAMA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5D,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAkD,CAAC;AACrF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,WAAW,GAAI,GAAG,IAAI,oBAA2D,CAAC;AAM/F,eAAO,MAAM,YAAY,GAAI,GAAG,IAAI,oBACuB,CAAC;AAC5D,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AACtE,eAAO,MAAM,KAAK,GAAI,GAAG,IAAI,oBAA4C,CAAC;AAC1E,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,oBAAoB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AAC1E,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC2B,CAAC;AACpE,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBACsB,CAAC"}
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js
CHANGED
|
@@ -11,12 +11,12 @@ function call(toolName, endpoint, args) {
|
|
|
11
11
|
export const valuationSale = (a) => call("property-data-valuation-sale", "valuation-sale", a);
|
|
12
12
|
export const valuationRent = (a) => call("property-data-valuation-rent", "valuation-rent", a);
|
|
13
13
|
export const prices = (a) => call("property-data-prices", "prices", a);
|
|
14
|
-
export const pricesRent = (a) => call("property-data-prices-rent", "
|
|
14
|
+
export const pricesRent = (a) => call("property-data-prices-rent", "rents", a);
|
|
15
15
|
export const soldPrices = (a) => call("property-data-sold-prices", "sold-prices", a);
|
|
16
16
|
export const demand = (a) => call("property-data-demand", "demand", a);
|
|
17
17
|
export const yields = (a) => call("property-data-yields", "yields", a);
|
|
18
18
|
export const growth = (a) => call("property-data-growth", "growth", a);
|
|
19
|
-
export const nationalHpi = (a) => call("property-data-national-hpi", "national-
|
|
19
|
+
export const nationalHpi = (a) => call("property-data-national-hpi", "national-data", a);
|
|
20
20
|
// Task 144 — 10 additional read endpoints (£/sqft, area risk,
|
|
21
21
|
// planning precedent, UPRN, demand-rent, property-type mix).
|
|
22
22
|
// All inherit the same observability + error contract as above.
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAQ9D,SAAS,IAAI,CAAC,QAAgB,EAAE,QAAgB,EAAE,IAAU;IAC1D,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IACpC,OAAO,gBAAgB,CAAC;QACtB,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,MAAM,EAAE,IAAmD;KAC5D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;AACpG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;AACpG,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,IAAI,CAAC,2BAA2B,EAAE,
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-deregister.d.ts","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAEA,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"key-deregister.d.ts","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAEA,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhF"}
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { selectKeyStore } from "../lib/key-store.js";
|
|
2
2
|
export async function keyDeregister(params) {
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
|
|
7
|
-
DELETE k
|
|
8
|
-
RETURN count(k) AS deleted`, { accountId });
|
|
9
|
-
const deleted = result.records[0]?.get("deleted")?.toNumber?.() ?? 0;
|
|
10
|
-
if (deleted === 0) {
|
|
11
|
-
throw new Error("No PropertyData API key is registered for this account.");
|
|
12
|
-
}
|
|
3
|
+
const deleted = await selectKeyStore().delete(params.accountId);
|
|
4
|
+
if (!deleted) {
|
|
5
|
+
throw new Error("No PropertyData API key is registered for this account.");
|
|
13
6
|
}
|
|
14
|
-
|
|
15
|
-
await session.close();
|
|
16
|
-
}
|
|
17
|
-
console.error(`[property-data] key-op op=deregister account=${accountId}`);
|
|
7
|
+
console.error(`[property-data] key-op op=deregister account=${params.accountId}`);
|
|
18
8
|
}
|
|
19
9
|
//# sourceMappingURL=key-deregister.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-deregister.js","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"key-deregister.js","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA6B;IAC/D,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,gDAAgD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-register.d.ts","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"key-register.d.ts","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AA6CA,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB"}
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js
CHANGED
|
@@ -1,43 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { encrypt } from "../lib/crypto.js";
|
|
1
|
+
import { selectKeyStore } from "../lib/key-store.js";
|
|
3
2
|
import { PropertyDataError } from "../lib/propertydata-api.js";
|
|
4
3
|
const BASE_URL = "https://api.propertydata.co.uk";
|
|
5
4
|
const REQUEST_TIMEOUT_MS = 15_000;
|
|
6
|
-
// Validate
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// key
|
|
10
|
-
//
|
|
5
|
+
// Validate the key against PropertyData's /valuation-sale endpoint with no
|
|
6
|
+
// inputs — a valid key returns HTTP 400 + body code 701 "Missing input:
|
|
7
|
+
// property_type" (proof the key was accepted), without consuming a credit.
|
|
8
|
+
// An invalid key returns auth failure (401/403) or a different upstream code.
|
|
9
|
+
// Evidence: probing `/national-hpi` returns code X01 "Invalid API endpoint"
|
|
10
|
+
// — that path does not exist on PropertyData; `/valuation-sale` does.
|
|
11
11
|
async function validateApiKey(apiKey) {
|
|
12
|
-
|
|
12
|
+
// Probe /valuation-sale with one input. Evidence-backed envelopes:
|
|
13
|
+
// invalid key → {code:"X03", message:"Invalid input: key"}
|
|
14
|
+
// valid key → {code:"701", message:"Missing input: property_type"} (no credit)
|
|
15
|
+
// PropertyData does not charge for missing-input errors, so this is a free probe.
|
|
16
|
+
const url = `${BASE_URL}/valuation-sale?key=${encodeURIComponent(apiKey)}&postcode=SW1A1AA`;
|
|
13
17
|
const response = await fetch(url, {
|
|
14
18
|
headers: { Accept: "application/json" },
|
|
15
19
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
16
20
|
});
|
|
21
|
+
const body = await response.text().catch(() => "");
|
|
17
22
|
if (response.status === 401 || response.status === 403) {
|
|
18
23
|
throw new Error(`PropertyData rejected the API key (HTTP ${response.status}).`);
|
|
19
24
|
}
|
|
25
|
+
let parsed = {};
|
|
26
|
+
try {
|
|
27
|
+
parsed = JSON.parse(body);
|
|
28
|
+
}
|
|
29
|
+
catch { /* fall through */ }
|
|
30
|
+
if (parsed.code === "X03") {
|
|
31
|
+
throw new Error(`PropertyData rejected the API key (code=X03 ${parsed.message ?? "Invalid input: key"}).`);
|
|
32
|
+
}
|
|
33
|
+
// 701 (missing-input) or status:"success" both prove the key was authenticated.
|
|
34
|
+
// Any other envelope: surface raw so the operator sees the upstream error.
|
|
35
|
+
if (parsed.status === "success" || parsed.code === "701")
|
|
36
|
+
return;
|
|
37
|
+
if (parsed.status === "error") {
|
|
38
|
+
throw new Error(`PropertyData validate probe returned unexpected envelope (code=${parsed.code ?? "?"} message=${parsed.message ?? "?"}).`);
|
|
39
|
+
}
|
|
20
40
|
if (!response.ok) {
|
|
21
|
-
|
|
22
|
-
throw new PropertyDataError(response.status, "national-hpi", body.slice(0, 200));
|
|
41
|
+
throw new PropertyDataError(response.status, "valuation-sale", body.slice(0, 200));
|
|
23
42
|
}
|
|
24
43
|
}
|
|
25
44
|
export async function keyRegister(params) {
|
|
26
45
|
const { apiKey, accountId } = params;
|
|
27
46
|
await validateApiKey(apiKey);
|
|
28
|
-
|
|
29
|
-
const now = new Date().toISOString();
|
|
30
|
-
const session = getSession();
|
|
31
|
-
try {
|
|
32
|
-
await session.run(`CREATE INDEX property_data_key_account IF NOT EXISTS
|
|
33
|
-
FOR (k:PropertyDataKey) ON (k.accountId)`, {});
|
|
34
|
-
await session.run(`MERGE (k:PropertyDataKey {accountId: $accountId})
|
|
35
|
-
ON CREATE SET k.encryptedKey = $encryptedKey, k.createdAt = $now, k.updatedAt = $now
|
|
36
|
-
ON MATCH SET k.encryptedKey = $encryptedKey, k.updatedAt = $now`, { accountId, encryptedKey, now });
|
|
37
|
-
}
|
|
38
|
-
finally {
|
|
39
|
-
await session.close();
|
|
40
|
-
}
|
|
47
|
+
await selectKeyStore().save(accountId, apiKey);
|
|
41
48
|
console.error(`[property-data] key-op op=register account=${accountId}`);
|
|
42
49
|
}
|
|
43
50
|
//# sourceMappingURL=key-register.js.map
|
package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-register.js","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"key-register.js","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AAClD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,2EAA2E;AAC3E,wEAAwE;AACxE,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,sEAAsE;AAEtE,KAAK,UAAU,cAAc,CAAC,MAAc;IAC1C,mEAAmE;IACnE,6DAA6D;IAC7D,mFAAmF;IACnF,kFAAkF;IAClF,MAAM,GAAG,GAAG,GAAG,QAAQ,uBAAuB,kBAAkB,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAC5F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,MAAM,GAAyD,EAAE,CAAC;IACtE,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC/D,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,CAAC,OAAO,IAAI,oBAAoB,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,gFAAgF;IAChF,2EAA2E;IAC3E,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO;IACjE,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,kEAAkE,MAAM,CAAC,IAAI,IAAI,GAAG,YAAY,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI,CAC1H,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAGjC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACrC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,8CAA8C,SAAS,EAAE,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Logging-tee was a platform-wrapper concern: the platform's mcp-spawn-tee
|
|
2
|
+
// pipes our stderr where it wants. In standalone mode (Claude Code native
|
|
3
|
+
// spawn) the host owns the stderr pipe. Either way, we just write to stderr.
|
|
3
4
|
|
|
4
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -34,18 +35,22 @@ import {
|
|
|
34
35
|
PropertyDataError,
|
|
35
36
|
BadResponseError,
|
|
36
37
|
} from "./lib/propertydata-api.js";
|
|
38
|
+
import { selectKeyStore } from "./lib/key-store.js";
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// ACCOUNT_ID is the platform's tenant id; in standalone mode (Claude Code
|
|
41
|
+
// native spawn) there is no platform tenant, so "local" is the single-tenant
|
|
42
|
+
// stand-in. Same MCP body, env-selected backend.
|
|
43
|
+
const accountId = process.env.ACCOUNT_ID ?? "local";
|
|
42
44
|
|
|
43
45
|
const server = new McpServer({
|
|
44
46
|
name: "maxy-property-data",
|
|
45
47
|
version: "0.1.0",
|
|
46
48
|
});
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
const store = selectKeyStore();
|
|
51
|
+
console.error(
|
|
52
|
+
`[property-data] server started, account=${accountId} backend=${store.backendName} path=${store.backendPath}`,
|
|
53
|
+
);
|
|
49
54
|
|
|
50
55
|
function errorEnvelope(err: unknown): { content: { type: "text"; text: string }[]; isError: true } {
|
|
51
56
|
let text: string;
|
|
@@ -67,7 +72,7 @@ function endpointHandler<P extends Record<string, unknown>>(
|
|
|
67
72
|
) {
|
|
68
73
|
return async (params: P) => {
|
|
69
74
|
try {
|
|
70
|
-
const text = await fn({ ...params, accountId
|
|
75
|
+
const text = await fn({ ...params, accountId });
|
|
71
76
|
return { content: [{ type: "text" as const, text }] };
|
|
72
77
|
} catch (err) {
|
|
73
78
|
return errorEnvelope(err);
|
|
@@ -87,7 +92,7 @@ server.tool(
|
|
|
87
92
|
},
|
|
88
93
|
async ({ apiKey }) => {
|
|
89
94
|
try {
|
|
90
|
-
await keyRegister({ apiKey, accountId
|
|
95
|
+
await keyRegister({ apiKey, accountId });
|
|
91
96
|
return {
|
|
92
97
|
content: [
|
|
93
98
|
{
|
|
@@ -108,7 +113,7 @@ server.tool(
|
|
|
108
113
|
{},
|
|
109
114
|
async () => {
|
|
110
115
|
try {
|
|
111
|
-
await keyDeregister({ accountId
|
|
116
|
+
await keyDeregister({ accountId });
|
|
112
117
|
return {
|
|
113
118
|
content: [{ type: "text" as const, text: "PropertyData API key deregistered." }],
|
|
114
119
|
};
|
|
@@ -124,7 +129,7 @@ server.tool(
|
|
|
124
129
|
{},
|
|
125
130
|
async () => {
|
|
126
131
|
try {
|
|
127
|
-
const text = await keyList({ accountId
|
|
132
|
+
const text = await keyList({ accountId });
|
|
128
133
|
return { content: [{ type: "text" as const, text }] };
|
|
129
134
|
} catch (err) {
|
|
130
135
|
return errorEnvelope(err);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
3
|
+
|
|
4
|
+
// Standalone-mode crypto. Same AES-256-GCM envelope as crypto.ts, but the
|
|
5
|
+
// encryption-key file path is passed in (not derived from PLATFORM_ROOT /
|
|
6
|
+
// brand.json), so it can live under ~/.claude/ when the MCP is spawned by
|
|
7
|
+
// Claude Code natively.
|
|
8
|
+
|
|
9
|
+
const ALGORITHM = "aes-256-gcm";
|
|
10
|
+
const KEY_LENGTH = 32;
|
|
11
|
+
const IV_LENGTH = 12;
|
|
12
|
+
const AUTH_TAG_LENGTH = 16;
|
|
13
|
+
|
|
14
|
+
function loadOrGenerateKey(keyFilePath: string, label: string): Buffer {
|
|
15
|
+
if (existsSync(keyFilePath)) {
|
|
16
|
+
const hex = readFileSync(keyFilePath, "utf-8").trim();
|
|
17
|
+
const buf = Buffer.from(hex, "hex");
|
|
18
|
+
if (buf.length !== KEY_LENGTH) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`[${label}] encryption key at ${keyFilePath} is ${buf.length} bytes, expected ${KEY_LENGTH}.`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return buf;
|
|
24
|
+
}
|
|
25
|
+
const key = randomBytes(KEY_LENGTH);
|
|
26
|
+
writeFileSync(keyFilePath, key.toString("hex"), { mode: 0o600 });
|
|
27
|
+
console.error(`[${label}] encryption key generated at ${keyFilePath}`);
|
|
28
|
+
return key;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function encryptWith(plaintext: string, keyFilePath: string, label: string): string {
|
|
32
|
+
const key = loadOrGenerateKey(keyFilePath, label);
|
|
33
|
+
const iv = randomBytes(IV_LENGTH);
|
|
34
|
+
const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
35
|
+
let encrypted = cipher.update(plaintext, "utf-8", "hex");
|
|
36
|
+
encrypted += cipher.final("hex");
|
|
37
|
+
const authTag = cipher.getAuthTag().toString("hex");
|
|
38
|
+
return `${iv.toString("hex")}:${encrypted}:${authTag}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function decryptWith(encryptedValue: string, keyFilePath: string, label: string): string {
|
|
42
|
+
const parts = encryptedValue.split(":");
|
|
43
|
+
if (parts.length !== 3) {
|
|
44
|
+
throw new Error(`[${label}] bad encrypted envelope (expected iv:ct:tag)`);
|
|
45
|
+
}
|
|
46
|
+
const key = loadOrGenerateKey(keyFilePath, label);
|
|
47
|
+
const iv = Buffer.from(parts[0], "hex");
|
|
48
|
+
const ciphertext = parts[1];
|
|
49
|
+
const authTag = Buffer.from(parts[2], "hex");
|
|
50
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
51
|
+
decipher.setAuthTag(authTag);
|
|
52
|
+
let plaintext = decipher.update(ciphertext, "hex", "utf-8");
|
|
53
|
+
plaintext += decipher.final("utf-8");
|
|
54
|
+
return plaintext;
|
|
55
|
+
}
|