@haven_ai/mcp 0.2.1-alpha.0 → 0.3.0-alpha.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 +6 -3
- package/dist/cli.cjs +29 -20
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +29 -20
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +29 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -20
- package/dist/index.d.ts +8 -20
- package/dist/index.js +29 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -44,9 +44,12 @@ Create a private JSON file from the values in the Haven agent handoff:
|
|
|
44
44
|
`delegate_key` is required. Without it the MCP server cannot sign locally.
|
|
45
45
|
`account_address` is the name the connector writes since #2908; a file that
|
|
46
46
|
still says `safe_address` (or `safeAddress`) is read the same way, permanently.
|
|
47
|
-
The
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
The environment is **not** the same: only `HAVEN_ACCOUNT_ADDRESS` is read.
|
|
48
|
+
`HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` were accepted for one release
|
|
49
|
+
and #2914 removed them, so a machine still configured through either resolves
|
|
50
|
+
no account address at all. The credential-FILE fallback above is permanent —
|
|
51
|
+
a file on disk never rewrites itself — and the environment is not, which is
|
|
52
|
+
the whole difference between the two paragraphs.
|
|
50
53
|
|
|
51
54
|
The Haven connector may also write split credentials:
|
|
52
55
|
|
package/dist/cli.cjs
CHANGED
|
@@ -56,7 +56,6 @@ async function loadCredentialsFromFile(path) {
|
|
|
56
56
|
delegateKey,
|
|
57
57
|
agentId: stringField(raw.agent_id ?? raw.agentId),
|
|
58
58
|
accountAddress,
|
|
59
|
-
safeAddress: accountAddress,
|
|
60
59
|
delegateAddress: stringField(raw.delegate_address ?? raw.delegateAddress),
|
|
61
60
|
chainId: numberField(raw.chain_id ?? raw.chainId),
|
|
62
61
|
network: stringField(raw.network),
|
|
@@ -86,13 +85,11 @@ async function loadCredentialsFromSplitFiles(identityPath, signerPath) {
|
|
|
86
85
|
identity.agent_id ?? identity.agentId,
|
|
87
86
|
signer.agent_id ?? signer.agentId
|
|
88
87
|
),
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{ caseInsensitive: true }
|
|
95
|
-
)
|
|
88
|
+
accountAddress: matchingStringField(
|
|
89
|
+
"account_address",
|
|
90
|
+
readAccountAddressField(identity),
|
|
91
|
+
readAccountAddressField(signer),
|
|
92
|
+
{ caseInsensitive: true }
|
|
96
93
|
),
|
|
97
94
|
delegateAddress: matchingStringField(
|
|
98
95
|
"delegate_address",
|
|
@@ -147,7 +144,7 @@ function loadCredentialsFromEnv() {
|
|
|
147
144
|
apiKey,
|
|
148
145
|
delegateKey,
|
|
149
146
|
agentId: stringField(process.env.HAVEN_AGENT_ID),
|
|
150
|
-
|
|
147
|
+
accountAddress: readAccountAddressEnv(process.env),
|
|
151
148
|
chainId: numberField(process.env.HAVEN_CHAIN_ID),
|
|
152
149
|
network: stringField(process.env.HAVEN_NETWORK),
|
|
153
150
|
apiUrl: stringField(process.env.HAVEN_API_URL)
|
|
@@ -157,10 +154,22 @@ function readAccountAddressField(raw) {
|
|
|
157
154
|
return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress);
|
|
158
155
|
}
|
|
159
156
|
function readAccountAddressEnv(env) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
const current = stringField(env.HAVEN_ACCOUNT_ADDRESS);
|
|
158
|
+
for (const name of ["HAVEN_WALLET_ADDRESS", "HAVEN_SAFE_ADDRESS"]) {
|
|
159
|
+
const retired = stringField(env[name]);
|
|
160
|
+
if (!retired) continue;
|
|
161
|
+
if (!current) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`${name} is retired (#2906) \u2014 Haven accounts are addressed as accounts, not Safes. Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, because an unset account address silently skips the sweep-destination check.`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (retired.toLowerCase() !== current.toLowerCase()) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. Remove the retired name, or make them match \u2014 picking one silently would hide the mismatch.`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return current;
|
|
164
173
|
}
|
|
165
174
|
function stringField(value) {
|
|
166
175
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
@@ -723,7 +732,7 @@ function computeConsentHash(input) {
|
|
|
723
732
|
input.apiKeyPrefix,
|
|
724
733
|
input.apiUrl ?? "",
|
|
725
734
|
input.agentId ?? "",
|
|
726
|
-
(input.
|
|
735
|
+
(input.accountAddress ?? "").toLowerCase(),
|
|
727
736
|
(input.delegateAddress ?? "").toLowerCase(),
|
|
728
737
|
input.chainId ?? ""
|
|
729
738
|
].join("|");
|
|
@@ -742,7 +751,7 @@ function renderConsentBlock(input, hash) {
|
|
|
742
751
|
];
|
|
743
752
|
if (input.apiUrl) lines.push(`Haven API: ${input.apiUrl}`);
|
|
744
753
|
if (input.agentId) lines.push(`Agent ID: ${input.agentId}`);
|
|
745
|
-
if (input.
|
|
754
|
+
if (input.accountAddress) lines.push(`Haven wallet (Safe): ${input.accountAddress}`);
|
|
746
755
|
if (input.delegateAddress) lines.push(`Delegate (local signer): ${input.delegateAddress}`);
|
|
747
756
|
if (typeof input.chainId === "number") lines.push(`Chain ID: ${input.chainId}`);
|
|
748
757
|
lines.push("");
|
|
@@ -849,14 +858,14 @@ async function writeAckFile(path$1, hash) {
|
|
|
849
858
|
}
|
|
850
859
|
async function consentInputFromClient(haven, seed, toolNames) {
|
|
851
860
|
let allowanceSummary = seed.allowanceSummary ?? [];
|
|
852
|
-
let
|
|
861
|
+
let accountAddress = seed.accountAddress;
|
|
853
862
|
let delegateAddress = seed.delegateAddress;
|
|
854
863
|
let chainId = seed.chainId;
|
|
855
864
|
try {
|
|
856
865
|
const summary = await haven.getAllowances();
|
|
857
866
|
const list = isAllowanceSummary(summary) ? summary.allowances : Array.isArray(summary) ? summary : [];
|
|
858
867
|
if (isAllowanceSummary(summary)) {
|
|
859
|
-
|
|
868
|
+
accountAddress = summary.accountAddress ?? accountAddress;
|
|
860
869
|
delegateAddress = summary.delegateAddress;
|
|
861
870
|
chainId = typeof summary.chainId === "number" ? summary.chainId : chainId;
|
|
862
871
|
}
|
|
@@ -872,7 +881,7 @@ async function consentInputFromClient(haven, seed, toolNames) {
|
|
|
872
881
|
apiKeyPrefix: derivePrefix(seed.apiKey),
|
|
873
882
|
apiUrl: seed.apiUrl,
|
|
874
883
|
agentId: seed.agentId,
|
|
875
|
-
|
|
884
|
+
accountAddress,
|
|
876
885
|
delegateAddress,
|
|
877
886
|
chainId,
|
|
878
887
|
toolNames,
|
|
@@ -906,7 +915,7 @@ async function resolveHavenClient(options = {}) {
|
|
|
906
915
|
return { client, credentials };
|
|
907
916
|
}
|
|
908
917
|
var MCP_NAME = "@haven_ai/mcp";
|
|
909
|
-
var MCP_VERSION = "0.
|
|
918
|
+
var MCP_VERSION = "0.3.0-alpha.0";
|
|
910
919
|
var MCP_INSTRUCTIONS = [
|
|
911
920
|
"Haven local MCP server: signs in-process with the delegate key it holds on",
|
|
912
921
|
"this machine \u2014 the key never leaves this process. Call haven_get_agent",
|
|
@@ -979,7 +988,7 @@ async function runConsentGate(haven, credentials, options) {
|
|
|
979
988
|
apiKey: credentials.apiKey,
|
|
980
989
|
apiUrl: credentials.apiUrl,
|
|
981
990
|
agentId: credentials.agentId,
|
|
982
|
-
|
|
991
|
+
accountAddress: credentials.accountAddress,
|
|
983
992
|
delegateAddress: credentials.delegateAddress,
|
|
984
993
|
chainId: credentials.chainId,
|
|
985
994
|
allowanceSummary: credentials.allowanceSummary
|