@auctra/mcp-gateway 0.1.11 → 0.1.13

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 CHANGED
@@ -4,6 +4,8 @@ Stage 0 MCP gateway adapter. Wrap MCP tool calls **and installs** with Auctra **
4
4
 
5
5
  **REQUIRE_MCP_GATEWAY:** Production orgs (Startup+) default `require_mcp_gateway=true`. MCP-shaped `action.execute` without this package’s stamp (`auctra_mcp_gateway`) is blocked. Set `AUCTRA_REQUIRE_MCP_GATEWAY=1` for a global fail-closed override.
6
6
 
7
+ **Before the gateway:** register the agent with a sponsor, issue authority for the tool's action type, and `createIntent`. Pass `claimedIntentId` and `intentAnchorToken`. A payment-shaped tool also needs provenance on the execute metadata. The full field list is `docs/onboarding/quick-start.md`. ALLOW still does not run the tool until the lease is consumed.
8
+
7
9
  ```ts
8
10
  import { Auctra } from "@auctra/sdk";
9
11
  import {
@@ -21,6 +23,8 @@ await gateMcpToolCall({
21
23
  agentId: "agent-uuid",
22
24
  toolName: "send_email",
23
25
  args: { to: "vendor@example.com" },
26
+ claimedIntentId: "intent-uuid",
27
+ intentAnchorToken: "anchor-token-from-createIntent",
24
28
  });
25
29
 
26
30
  const sendEmail = withAuctraGate({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auctra/mcp-gateway",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "MCP gateway — gate tool calls and MCP/skill installs through Auctra action.execute",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -29,6 +29,55 @@ function resolveActionType(input) {
29
29
  return input.actionType ?? input.actionTypeMap?.[input.toolName] ?? "execute_tool";
30
30
  }
31
31
 
32
+ function isSupportedProductionConfig() {
33
+ if (process.env.NODE_ENV === "production") return true;
34
+ return Boolean(process.env.AUCTRA_EXECUTION_LEASE_SECRET?.trim());
35
+ }
36
+
37
+ /**
38
+ * Lab/dev escape only. Ignored when NODE_ENV=production or
39
+ * AUCTRA_EXECUTION_LEASE_SECRET is set — those are supported production signals.
40
+ */
41
+ export function allowMcpWithoutLease() {
42
+ if (isSupportedProductionConfig()) return false;
43
+ const v = process.env.AUCTRA_ALLOW_MCP_WITHOUT_LEASE?.trim().toLowerCase();
44
+ return v === "1" || v === "true" || v === "yes";
45
+ }
46
+
47
+ async function assertConsumedExecutionLease(input, result) {
48
+ if (allowMcpWithoutLease()) return;
49
+ const leaseToken = result.execution_lease?.token;
50
+ if (!leaseToken) {
51
+ throw new McpToolBlockedError(
52
+ "execution lease required but action.execute returned none — configure AUCTRA_EXECUTION_LEASE_SECRET",
53
+ "blocked",
54
+ result.evidence,
55
+ result.action_decision ?? null,
56
+ );
57
+ }
58
+ if (!input.client.executionLease?.consume) {
59
+ throw new McpToolBlockedError(
60
+ "executionLease.consume client method required after ALLOW",
61
+ "blocked",
62
+ result.evidence,
63
+ result.action_decision ?? null,
64
+ );
65
+ }
66
+ const consumed = await input.client.executionLease.consume({
67
+ lease: leaseToken,
68
+ expectedActionType: resolveActionType(input),
69
+ expectedRequestFingerprint: result.execution_lease?.request_fingerprint,
70
+ });
71
+ if (!consumed.ok) {
72
+ throw new McpToolBlockedError(
73
+ consumed.error ?? "execution lease consume failed",
74
+ "blocked",
75
+ result.evidence,
76
+ result.action_decision ?? null,
77
+ );
78
+ }
79
+ }
80
+
32
81
  function evidenceIdFromResult(result) {
33
82
  return result.evidence_payload?.evidence_id ?? result.action_request_id ?? null;
34
83
  }
@@ -199,45 +248,9 @@ export async function gateMcpToolCall(input) {
199
248
  throw new McpToolBlockedError(message, result.decision, result.evidence, result.action_decision ?? null);
200
249
  }
201
250
 
202
- const requireLease =
203
- process.env.AUCTRA_REQUIRE_EXECUTION_LEASE === "1" ||
204
- (process.env.NODE_ENV === "production" &&
205
- Boolean(process.env.AUCTRA_EXECUTION_LEASE_SECRET?.trim()));
206
- const leaseToken = result.execution_lease?.token;
207
- if (requireLease || leaseToken) {
208
- if (!leaseToken) {
209
- throw new McpToolBlockedError(
210
- "execution lease required but action.execute returned none — configure AUCTRA_EXECUTION_LEASE_SECRET",
211
- "blocked",
212
- result.evidence,
213
- result.action_decision ?? null,
214
- );
215
- }
216
- if (!input.client.executionLease?.consume) {
217
- if (requireLease) {
218
- throw new McpToolBlockedError(
219
- "executionLease.consume client method required when AUCTRA_REQUIRE_EXECUTION_LEASE=1",
220
- "blocked",
221
- result.evidence,
222
- result.action_decision ?? null,
223
- );
224
- }
225
- } else {
226
- const consumed = await input.client.executionLease.consume({
227
- lease: leaseToken,
228
- expectedActionType: resolveActionType(input),
229
- expectedRequestFingerprint: result.execution_lease?.request_fingerprint,
230
- });
231
- if (!consumed.ok) {
232
- throw new McpToolBlockedError(
233
- consumed.error ?? "execution lease consume failed",
234
- "blocked",
235
- result.evidence,
236
- result.action_decision ?? null,
237
- );
238
- }
239
- }
240
- }
251
+ // Default fail-closed (P5-F-007). AUCTRA_REQUIRE_EXECUTION_LEASE remains a
252
+ // recognized alias; AUCTRA_ALLOW_MCP_WITHOUT_LEASE=1 is the only opt-out.
253
+ await assertConsumedExecutionLease(input, result);
241
254
 
242
255
  return result;
243
256
  }
package/src/index.ts CHANGED
@@ -52,7 +52,7 @@ export type ExecuteActionClient = {
52
52
  evidence_payload?: { evidence_id?: string };
53
53
  }>;
54
54
  };
55
- /** Optional — required when AUCTRA_REQUIRE_EXECUTION_LEASE=1 */
55
+ /** Required after ALLOW. Lab opt-out is ignored in supported production configs. */
56
56
  executionLease?: {
57
57
  consume(input: {
58
58
  lease: string;
@@ -123,6 +123,55 @@ function resolveActionType(input: McpToolGateInput) {
123
123
  return input.actionType ?? input.actionTypeMap?.[input.toolName] ?? "execute_tool";
124
124
  }
125
125
 
126
+ function isSupportedProductionConfig(): boolean {
127
+ if (process.env.NODE_ENV === "production") return true;
128
+ return Boolean(process.env.AUCTRA_EXECUTION_LEASE_SECRET?.trim());
129
+ }
130
+
131
+ /**
132
+ * Lab/dev escape only. Ignored when NODE_ENV=production or
133
+ * AUCTRA_EXECUTION_LEASE_SECRET is set — those are supported production signals.
134
+ */
135
+ export function allowMcpWithoutLease(): boolean {
136
+ if (isSupportedProductionConfig()) return false;
137
+ const v = process.env.AUCTRA_ALLOW_MCP_WITHOUT_LEASE?.trim().toLowerCase();
138
+ return v === "1" || v === "true" || v === "yes";
139
+ }
140
+
141
+ async function assertConsumedExecutionLease(
142
+ input: McpToolGateInput,
143
+ result: Awaited<ReturnType<ExecuteActionClient["action"]["execute"]>>,
144
+ ) {
145
+ if (allowMcpWithoutLease()) return;
146
+ const leaseToken = result.execution_lease?.token;
147
+ if (!leaseToken) {
148
+ throw new McpToolBlockedError(
149
+ "execution lease required but action.execute returned none — configure AUCTRA_EXECUTION_LEASE_SECRET",
150
+ "blocked",
151
+ result.evidence,
152
+ );
153
+ }
154
+ if (!input.client.executionLease?.consume) {
155
+ throw new McpToolBlockedError(
156
+ "executionLease.consume client method required after ALLOW",
157
+ "blocked",
158
+ result.evidence,
159
+ );
160
+ }
161
+ const consumed = await input.client.executionLease.consume({
162
+ lease: leaseToken,
163
+ expectedActionType: resolveActionType(input),
164
+ expectedRequestFingerprint: result.execution_lease?.request_fingerprint,
165
+ });
166
+ if (!consumed.ok) {
167
+ throw new McpToolBlockedError(
168
+ consumed.error ?? "execution lease consume failed",
169
+ "blocked",
170
+ result.evidence,
171
+ );
172
+ }
173
+ }
174
+
126
175
  function evidenceIdFromResult(
127
176
  result: Awaited<ReturnType<ExecuteActionClient["action"]["execute"]>>,
128
177
  ) {
@@ -353,42 +402,9 @@ export async function gateMcpToolCall(input: McpToolGateInput) {
353
402
  throw new McpToolBlockedError(message, result.decision, result.evidence);
354
403
  }
355
404
 
356
- const requireLease =
357
- process.env.AUCTRA_REQUIRE_EXECUTION_LEASE === "1" ||
358
- (process.env.NODE_ENV === "production" &&
359
- Boolean(process.env.AUCTRA_EXECUTION_LEASE_SECRET?.trim()));
360
- const leaseToken = result.execution_lease?.token;
361
- if (requireLease || leaseToken) {
362
- if (!leaseToken) {
363
- throw new McpToolBlockedError(
364
- "execution lease required but action.execute returned none — configure AUCTRA_EXECUTION_LEASE_SECRET",
365
- "blocked",
366
- result.evidence,
367
- );
368
- }
369
- if (!input.client.executionLease?.consume) {
370
- if (requireLease) {
371
- throw new McpToolBlockedError(
372
- "executionLease.consume client method required when AUCTRA_REQUIRE_EXECUTION_LEASE=1",
373
- "blocked",
374
- result.evidence,
375
- );
376
- }
377
- } else {
378
- const consumed = await input.client.executionLease.consume({
379
- lease: leaseToken,
380
- expectedActionType: resolveActionType(input),
381
- expectedRequestFingerprint: result.execution_lease?.request_fingerprint,
382
- });
383
- if (!consumed.ok) {
384
- throw new McpToolBlockedError(
385
- consumed.error ?? "execution lease consume failed",
386
- "blocked",
387
- result.evidence,
388
- );
389
- }
390
- }
391
- }
405
+ // Default fail-closed (P5-F-007). AUCTRA_REQUIRE_EXECUTION_LEASE remains a
406
+ // recognized alias; AUCTRA_ALLOW_MCP_WITHOUT_LEASE=1 is the only opt-out.
407
+ await assertConsumedExecutionLease(input, result);
392
408
 
393
409
  return result;
394
410
  }