@revfleet/hscli 0.9.8 → 0.11.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +142 -13
  3. package/SECURITY.md +14 -3
  4. package/dist/cli.js +3 -3
  5. package/dist/cli.js.map +1 -1
  6. package/dist/cloud/cloud-run-caller-contract.d.ts +28 -0
  7. package/dist/cloud/cloud-run-caller-contract.js +35 -0
  8. package/dist/cloud/cloud-run-caller-contract.js.map +1 -0
  9. package/dist/cloud/main.d.ts +1 -0
  10. package/dist/cloud/main.js +15 -0
  11. package/dist/cloud/main.js.map +1 -0
  12. package/dist/cloud/server.d.ts +5 -0
  13. package/dist/cloud/server.js +133 -0
  14. package/dist/cloud/server.js.map +1 -0
  15. package/dist/commands/agent/access-baseline.d.ts +47 -0
  16. package/dist/commands/agent/access-baseline.js +238 -0
  17. package/dist/commands/agent/access-baseline.js.map +1 -0
  18. package/dist/commands/agent/index.js +99 -11
  19. package/dist/commands/agent/index.js.map +1 -1
  20. package/dist/commands/agent/recipes.d.ts +7 -1
  21. package/dist/commands/agent/recipes.js +57 -1
  22. package/dist/commands/agent/recipes.js.map +1 -1
  23. package/dist/commands/agent/reporting-joinability.d.ts +129 -0
  24. package/dist/commands/agent/reporting-joinability.js +412 -0
  25. package/dist/commands/agent/reporting-joinability.js.map +1 -0
  26. package/dist/commands/agent/runner.d.ts +1 -0
  27. package/dist/commands/agent/runner.js +181 -27
  28. package/dist/commands/agent/runner.js.map +1 -1
  29. package/dist/commands/audit/index.js +2 -1
  30. package/dist/commands/audit/index.js.map +1 -1
  31. package/dist/commands/auth/index.d.ts +6 -2
  32. package/dist/commands/auth/index.js +172 -57
  33. package/dist/commands/auth/index.js.map +1 -1
  34. package/dist/commands/backup/index.js +6 -8
  35. package/dist/commands/backup/index.js.map +1 -1
  36. package/dist/commands/crm/describe.js +3 -3
  37. package/dist/commands/crm/describe.js.map +1 -1
  38. package/dist/commands/crm/index.js +2 -0
  39. package/dist/commands/crm/index.js.map +1 -1
  40. package/dist/commands/crm/record-layouts.d.ts +3 -0
  41. package/dist/commands/crm/record-layouts.js +246 -0
  42. package/dist/commands/crm/record-layouts.js.map +1 -0
  43. package/dist/commands/crm/shared.d.ts +1 -0
  44. package/dist/commands/crm/shared.js +7 -3
  45. package/dist/commands/crm/shared.js.map +1 -1
  46. package/dist/commands/crm/sync.js +170 -27
  47. package/dist/commands/crm/sync.js.map +1 -1
  48. package/dist/commands/doctor/index.js +5 -5
  49. package/dist/commands/doctor/index.js.map +1 -1
  50. package/dist/commands/internal/index.js +20 -6
  51. package/dist/commands/internal/index.js.map +1 -1
  52. package/dist/commands/internal-session.d.ts +4 -0
  53. package/dist/commands/internal-session.js +27 -0
  54. package/dist/commands/internal-session.js.map +1 -1
  55. package/dist/commands/lists/index.js +18 -0
  56. package/dist/commands/lists/index.js.map +1 -1
  57. package/dist/commands/marketing/index.js +5 -5
  58. package/dist/commands/marketing/index.js.map +1 -1
  59. package/dist/commands/mcp.d.ts +2 -1
  60. package/dist/commands/mcp.js +49 -5
  61. package/dist/commands/mcp.js.map +1 -1
  62. package/dist/commands/sales/index.js +2 -0
  63. package/dist/commands/sales/index.js.map +1 -1
  64. package/dist/commands/sales/views.d.ts +3 -0
  65. package/dist/commands/sales/views.js +263 -0
  66. package/dist/commands/sales/views.js.map +1 -0
  67. package/dist/commands/settings/index.js +20 -0
  68. package/dist/commands/settings/index.js.map +1 -1
  69. package/dist/commands/trace/index.js +11 -4
  70. package/dist/commands/trace/index.js.map +1 -1
  71. package/dist/commands/workflows/index.js +2 -0
  72. package/dist/commands/workflows/index.js.map +1 -1
  73. package/dist/commands/workflows/internal.d.ts +3 -0
  74. package/dist/commands/workflows/internal.js +332 -0
  75. package/dist/commands/workflows/internal.js.map +1 -0
  76. package/dist/core/auth.d.ts +18 -2
  77. package/dist/core/auth.js +96 -3
  78. package/dist/core/auth.js.map +1 -1
  79. package/dist/core/bounded-response.d.ts +2 -0
  80. package/dist/core/bounded-response.js +37 -0
  81. package/dist/core/bounded-response.js.map +1 -0
  82. package/dist/core/capabilities.d.ts +8 -0
  83. package/dist/core/capabilities.js +31 -3
  84. package/dist/core/capabilities.js.map +1 -1
  85. package/dist/core/http.d.ts +16 -0
  86. package/dist/core/http.js +151 -35
  87. package/dist/core/http.js.map +1 -1
  88. package/dist/core/output.js +20 -4
  89. package/dist/core/output.js.map +1 -1
  90. package/dist/core/permissions.js +15 -1
  91. package/dist/core/permissions.js.map +1 -1
  92. package/dist/core/policy.js +8 -0
  93. package/dist/core/policy.js.map +1 -1
  94. package/dist/core/request-path.d.ts +13 -0
  95. package/dist/core/request-path.js +90 -0
  96. package/dist/core/request-path.js.map +1 -0
  97. package/dist/core/schema-cache.js +6 -2
  98. package/dist/core/schema-cache.js.map +1 -1
  99. package/dist/core/vault.js +10 -5
  100. package/dist/core/vault.js.map +1 -1
  101. package/dist/core/version.d.ts +1 -0
  102. package/dist/core/version.js +3 -0
  103. package/dist/core/version.js.map +1 -0
  104. package/dist/mcp/compat-hubspot.d.ts +5 -14
  105. package/dist/mcp/compat-hubspot.js +19 -16
  106. package/dist/mcp/compat-hubspot.js.map +1 -1
  107. package/dist/mcp/diagnostics.d.ts +157 -0
  108. package/dist/mcp/diagnostics.js +200 -0
  109. package/dist/mcp/diagnostics.js.map +1 -0
  110. package/dist/mcp/ecosystem.d.ts +107 -0
  111. package/dist/mcp/ecosystem.js +127 -0
  112. package/dist/mcp/ecosystem.js.map +1 -0
  113. package/dist/mcp/ext-tools.d.ts +4 -3
  114. package/dist/mcp/ext-tools.js +20 -8
  115. package/dist/mcp/ext-tools.js.map +1 -1
  116. package/dist/mcp/profiles.d.ts +9 -0
  117. package/dist/mcp/profiles.js +38 -4
  118. package/dist/mcp/profiles.js.map +1 -1
  119. package/dist/mcp/server.d.ts +118 -1
  120. package/dist/mcp/server.js +67 -10
  121. package/dist/mcp/server.js.map +1 -1
  122. package/docs/CAPABILITY_LIBRARY.md +7 -1
  123. package/docs/CLOUD_RUN.md +188 -0
  124. package/docs/COMMAND_TREE.md +20 -6
  125. package/docs/COMPARISON.md +14 -6
  126. package/docs/COOKBOOK.md +46 -2
  127. package/docs/INTERNAL-ENDPOINTS-DISCOVERY.md +59 -0
  128. package/docs/INTERNAL-ENDPOINTS.md +13 -0
  129. package/docs/INTERNAL_ENDPOINTS.md +23 -5
  130. package/docs/MCP.md +48 -6
  131. package/docs/MCP_TOOL_CATALOG.md +188 -186
  132. package/docs/OPERATIONAL_PLAYBOOKS.md +9 -8
  133. package/docs/PORTAL_BACKUP.md +26 -2
  134. package/docs/RELEASE_GOVERNANCE.md +7 -0
  135. package/docs/SAFETY_MODEL.md +23 -4
  136. package/docs/TUTORIALS/secure-agent-writes.md +3 -2
  137. package/docs/VALIDATION_BOUNDARIES.md +101 -0
  138. package/docs/policy-templates/compliance-strict.json +7 -0
  139. package/examples/cloud-run-mcp-caller.mjs +71 -0
  140. package/package.json +11 -8
@@ -9,6 +9,12 @@
9
9
  4. **Policy-first execution**: optional policy file can deny writes/deletes or require change-ticket context.
10
10
  5. **Graceful API resilience**: timeout + retry skeleton handles transient failures and rate limits.
11
11
 
12
+ `policy validate` and `policy show-matching` are diagnostics, not execution
13
+ authorization. A matching allow rule still has to pass every active runtime
14
+ gate. Rules with `rateLimit.maxPerHour` fail closed with
15
+ `POLICY_RATE_LIMIT_UNSUPPORTED` until a durable counter is available; they do
16
+ not simulate hourly enforcement.
17
+
12
18
  ## Dry-run Contract
13
19
  - Applies to all mutating commands routed through `maybeWrite`.
14
20
  - In dry-run mode, command returns:
@@ -19,14 +25,24 @@
19
25
  - No network mutation request is sent.
20
26
 
21
27
  ## Rate Limit & Retry Baseline
22
- - Retry on: `429`, `5xx`, and network errors.
23
- - Honor `Retry-After` header when present.
24
- - Use capped exponential backoff.
28
+ - Retry-eligible reads (`GET`, plus a `POST` explicitly marked as a read) retry
29
+ on `429`, `5xx`, and network errors.
30
+ - Mutations (`POST`/`PATCH`/`PUT`/`DELETE` unless explicitly classified as a
31
+ read) do not retry by default, including on `429`. A non-retried mutation
32
+ `429` returns `HTTP_RETRY_DISABLED`; ambiguous mutation timeout, network, or
33
+ `5xx` outcomes return `HTTP_OUTCOME_UNKNOWN` for fresh server-state
34
+ reconciliation.
35
+ - A retry-eligible read forced to `retryMode: never` returns
36
+ `HTTP_RETRY_DISABLED` for a `429` or `5xx` response.
37
+ - An internal `retryMode: idempotent` opt-in is valid only with a verified
38
+ server-side idempotency contract. An `Idempotency-Key` header alone is not
39
+ that proof.
40
+ - Retry-eligible requests honor `Retry-After`, use capped exponential backoff,
41
+ and can return `HTTP_RETRY_EXHAUSTED` after their retry budget.
25
42
  - Share observed HubSpot rate-limit state across clients in the same process by profile + API base URL.
26
43
  - Enforce HubSpot `X-HubSpot-RateLimit-Secondly`, rolling interval, and daily remaining headers before the next request.
27
44
  - Stop before daily quota exhaustion with `RATE_LIMIT_DAILY_EXHAUSTED`.
28
45
  - Enforce request timeout (`30s`) to prevent hung command invocations.
29
- - Surface retry exhaustion as `HTTP_RETRY_EXHAUSTED`.
30
46
 
31
47
  ## Profiles & Access
32
48
  - Profiles isolate tokens per environment/workspace.
@@ -38,3 +54,6 @@
38
54
  - Explicit JSON payload required for create/update.
39
55
  - Unknown command errors are structured and non-destructive.
40
56
  - API paths are constrained to approved HubSpot scopes.
57
+ - A configured profile or stored portal ID is local metadata, not proof of the
58
+ live target. Confirm the target in the approved operation before sensitive
59
+ work.
@@ -89,7 +89,7 @@ Rules are evaluated **first-match-wins**, so order matters. `defaultAction: "den
89
89
  hscli policy validate ./policy.json
90
90
  ```
91
91
 
92
- This parses the file and flags structural issues (invalid actions, malformed `window.hours`, rules with no `match` block that would match everything). If `valid: true`, you're good.
92
+ This parses the file and flags structural issues (invalid actions, malformed `window.hours`, rules with no `match` block that would match everything). `valid: true` means the static check passed; it does not authorize a future request or prove its target portal.
93
93
 
94
94
  ## Step 4 — dry-run rule matching
95
95
 
@@ -99,6 +99,7 @@ Before enforcing, confirm the right rule fires for the requests you expect:
99
99
  hscli --policy-file ./policy.json \
100
100
  policy show-matching POST /crm/v3/objects/contacts
101
101
  # → matched: allow-crm-writes-with-ticket, effectiveAction: allow
102
+ # Diagnostic only: the real command still needs every runtime gate.
102
103
 
103
104
  hscli --policy-file ./policy.json \
104
105
  policy show-matching DELETE /crm/v3/objects/contacts/123
@@ -117,7 +118,7 @@ Either pass `--policy-file` on every invocation, or set it globally:
117
118
  export HSCLI_POLICY_FILE=$PWD/policy.json
118
119
  ```
119
120
 
120
- From now on, every `hscli` command (and every MCP tool call) runs through the policy. A denied write fails *before* the HTTP request is issued.
121
+ From now on, hscli write paths wired to the policy control evaluate the active policy before their HTTP request. A denied guarded write fails *before* that request is issued. This is not a claim that every read, local command, or MCP tool is policy-enforced. An allowed diagnostic match remains subject to `--force`, tickets, approvals, time windows, and all other runtime controls.
121
122
 
122
123
  Try a denied operation:
123
124
 
@@ -0,0 +1,101 @@
1
+ # Validation Boundaries and Operational Limits
2
+
3
+ hscli is designed to make evidence visible, not to turn a local configuration
4
+ or a green test suite into proof about a HubSpot portal. This page records the
5
+ boundary between local checks, CI, and a separately approved live rehearsal.
6
+
7
+ | Evidence layer | Can establish | Does not establish |
8
+ | --- | --- | --- |
9
+ | Source and local gates | Command parsing, deterministic behavior under synthetic fixtures, type safety, lint, build output, and locked dependency resolution | HubSpot endpoint availability, portal state, scopes, subscriptions, or browser-session access |
10
+ | CI from a clean checkout | That the declared automated gates reproduce from the committed inputs | That an operator's local profile, policy file, cookies, or target portal are current |
11
+ | Approved live rehearsal | The specific read or write path, credential, portal, and time-window actually exercised | A blanket guarantee for other portals, identities, plans, feature flags, or later HubSpot changes |
12
+
13
+ Keep these layers separate in release notes and handoffs. A successful local or
14
+ CI check is never a substitute for an approved live rehearsal, and a live
15
+ rehearsal must be reported with its scope rather than generalized to all
16
+ portals.
17
+
18
+ ## Profile and portal identity
19
+
20
+ `--profile` selects a local credential configuration. A stored or displayed
21
+ `portalId` is local metadata and must not be treated as attestation of the
22
+ currently authenticated target. `auth whoami` reads that saved local profile,
23
+ including its historical `identityVerified` value; it does not call HubSpot and
24
+ is not live identity proof. Before a sensitive live operation, use only a
25
+ remote target check explicitly supported and authorized by that operation,
26
+ compare it with the approved target, and keep source, sandbox, and production
27
+ profiles distinct.
28
+
29
+ This applies equally to agent-run evidence: a profile name and declared policy
30
+ path describe local execution context. They do not prove a live target, and
31
+ they do not cryptographically authenticate older local artifacts.
32
+
33
+ ## Agent resume migration
34
+
35
+ Resumable agent runs require a manifest and checkpoint carrying the same run
36
+ ID, plus the retained stdout/stderr files and matching completion events for
37
+ every step that would be skipped. Historical checkpoints without that run-ID
38
+ binding are intentionally not resumable. Preserve them as legacy evidence if
39
+ needed, then start a new output directory without `--resume`; do not add a run
40
+ ID by hand or relabel the old steps as fresh evidence.
41
+
42
+ ## Policy diagnostics and enforcement
43
+
44
+ `hscli policy validate` parses and statically checks a policy file. `hscli
45
+ policy show-matching` evaluates a hypothetical method/path against that file.
46
+ They are useful diagnostics, but neither command executes the request or grants
47
+ permission. In particular, an `effectiveAction: allow` result still needs the
48
+ actual command to pass all execution-time controls: canonical path handling,
49
+ the active policy, `--force` for writes, tickets, approvals, windows, and any
50
+ other applicable gates.
51
+
52
+ Policy rules that declare `rateLimit.maxPerHour` are not backed by a durable
53
+ hourly counter. The reviewed implementation fails closed with
54
+ `POLICY_RATE_LIMIT_UNSUPPORTED` rather than pretending that the limit was
55
+ enforced. Operators must remove that rule only after choosing and reviewing an
56
+ appropriate external or durable rate-control mechanism.
57
+
58
+ Built-in policy templates are starting points. Extracting a template creates a
59
+ separate local policy file; later changes to a template, including a newly
60
+ covered HTTP method such as `PUT`, do not retrofit an already extracted or
61
+ active policy. Re-extract or edit the intended policy, then validate and review
62
+ it before use.
63
+
64
+ ## Backup completeness
65
+
66
+ `hscli backup plan` is plan-only: it makes no HubSpot request and creates no
67
+ archive. Its coverage model is a checklist, not proof that every asset was
68
+ captured. Capture execution still has known limitations: some reads materialize
69
+ pages in memory, and a complete durable pagination/resume reconciliation is not
70
+ yet guaranteed across every backup surface.
71
+
72
+ Treat a backup as partial until the operator reconciles object counts and
73
+ cursors, records unavailable or permission-blocked surfaces, and verifies the
74
+ resulting capture manifest. Do not call a plan, a successful command, or an
75
+ archive complete merely because no local error was emitted.
76
+
77
+ The record `crm sync pull` fields have deliberately narrower meanings:
78
+
79
+ - `complete` and `captureScope.paginationExhausted` mean this traversal reached
80
+ the end of its pagination cursor; they do not prove a complete portal archive.
81
+ - `captureScope.objectSnapshotComplete` means a fresh, unfiltered list
82
+ traversal started at the initial cursor and exhausted pagination for that
83
+ object. It does not prove every property, association, file, report, or other
84
+ portal surface was captured.
85
+ - The backup plan's `--full-snapshot --max-pages all` record commands retain all
86
+ fetched pages in memory. A full snapshot refuses an existing state file or
87
+ output file rather than silently mixing old and new results.
88
+
89
+ Sync checkpoint reuse is separate from agent resume. A reusable sync state is
90
+ bound to the configured `portalId`, local profile name, object type, mode,
91
+ `since` value, limit, and query fingerprint. Legacy states without that binding
92
+ are refused; this prevents cursor reuse across a different declared scope but
93
+ does not attest a live target.
94
+
95
+ ## Release language
96
+
97
+ Use precise, time-bounded claims. For example, “`npm audit` reported zero
98
+ advisories at verification time” describes an observed result; it does not mean
99
+ that future advisory databases will remain empty. Likewise, a reviewed source
100
+ diff is not merged, deployed, published, or live-tested until those separate
101
+ actions have been explicitly authorized and evidenced.
@@ -29,6 +29,13 @@
29
29
  "action": "allow",
30
30
  "requireChangeTicket": true,
31
31
  "window": { "tz": "US/Eastern", "hours": "09-17", "days": "mon-fri" }
32
+ },
33
+ {
34
+ "name": "puts-require-change-ticket-and-hours",
35
+ "match": { "method": "PUT", "path": "**" },
36
+ "action": "allow",
37
+ "requireChangeTicket": true,
38
+ "window": { "tz": "US/Eastern", "hours": "09-17", "days": "mon-fri" }
32
39
  }
33
40
  ]
34
41
  }
@@ -0,0 +1,71 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
+
4
+ const READ_ONLY_TOOLS = new Set([
5
+ "hscli_service_info",
6
+ "crm_properties_list",
7
+ "crm_pipelines_list",
8
+ ]);
9
+
10
+ function serviceEndpoint(cloudRunServiceUrl, label) {
11
+ const service = new URL(cloudRunServiceUrl);
12
+ if (service.protocol !== "https:" || service.pathname !== "/" || service.search || service.hash || service.username || service.password || service.port) {
13
+ throw new Error(`${label} must be an HTTPS base URL without a path`);
14
+ }
15
+ return service.origin;
16
+ }
17
+
18
+ /**
19
+ * Server-only example: its authenticatedSubject and portalId must come from the
20
+ * web service's own authenticated request context, not from browser headers,
21
+ * query parameters or tool arguments. resolveAuthorizedPortal is responsible
22
+ * for authorizing that pair and obtaining short-lived server-held HubSpot data.
23
+ */
24
+ export async function callAuthorizedHostedMcp({
25
+ cloudRunServiceUrl,
26
+ mcpTargetUrl,
27
+ authenticatedSubject,
28
+ portalId,
29
+ toolName,
30
+ toolArguments,
31
+ resolveAuthorizedPortal,
32
+ getGoogleIdToken,
33
+ fetch,
34
+ }) {
35
+ // `cloudRunServiceUrl` is the canonical service URL for the Google ID-token
36
+ // audience. `mcpTargetUrl` is the freshly checked tagged candidate URL; do
37
+ // not infer it from a shared tag without checking it still names this revision.
38
+ const audience = serviceEndpoint(cloudRunServiceUrl, "Cloud Run service URL");
39
+ const mcpUrl = new URL("/mcp", serviceEndpoint(mcpTargetUrl, "MCP target URL"));
40
+ if (!READ_ONLY_TOOLS.has(toolName)) throw new Error("HOSTED_TOOL_NOT_ALLOWED");
41
+
42
+ // Do this before requesting a Google token or constructing an HTTP transport.
43
+ const hubSpotContext = await resolveAuthorizedPortal({ authenticatedSubject, portalId });
44
+ if (!hubSpotContext || hubSpotContext.portalId !== portalId) throw new Error("PORTAL_NOT_AUTHORIZED");
45
+ if (!/^[0-9]+$/.test(hubSpotContext.portalId) || !["eu1", "na1"].includes(hubSpotContext.hublet) || !hubSpotContext.accessToken) {
46
+ throw new Error("INVALID_AUTHORIZED_PORTAL_CONTEXT");
47
+ }
48
+
49
+ // An attached Cloud Run identity normally implements this with ADC's
50
+ // google-auth-library.getIdTokenClient(audience). The ID token is not a
51
+ // HubSpot credential and is sent in a distinct Cloud Run IAM header.
52
+ const googleIdToken = await getGoogleIdToken(audience);
53
+ if (!googleIdToken) throw new Error("GOOGLE_ID_TOKEN_REQUIRED");
54
+ const client = new Client({ name: "authorized-web-backend", version: "example" });
55
+ try {
56
+ await client.connect(new StreamableHTTPClientTransport(mcpUrl, {
57
+ fetch,
58
+ requestInit: {
59
+ headers: {
60
+ "X-Serverless-Authorization": `Bearer ${googleIdToken}`,
61
+ "X-HubSpot-Access-Token": hubSpotContext.accessToken,
62
+ "X-HubSpot-Portal-Id": hubSpotContext.portalId,
63
+ "X-HubSpot-Hublet": hubSpotContext.hublet,
64
+ },
65
+ },
66
+ }));
67
+ return await client.callTool({ name: toolName, arguments: toolArguments });
68
+ } finally {
69
+ await client.close();
70
+ }
71
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revfleet/hscli",
3
- "version": "0.9.8",
3
+ "version": "0.11.0",
4
4
  "description": "HubSpot operations and migration control plane for humans and agents, with deterministic runbooks, policy guardrails, and auditable evidence.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,9 +18,9 @@
18
18
  "docs:mcp": "npm run build && node scripts/generate-mcp-catalog.mjs",
19
19
  "docs:mcp:check": "npm run build && node scripts/generate-mcp-catalog.mjs --check",
20
20
  "release:checksums": "node scripts/release-checksums.mjs",
21
- "audit": "npm audit --audit-level=high",
21
+ "audit": "npm audit --audit-level=low",
22
22
  "release:verify": "npm run typecheck && npm run lint && npm test && npm run audit && npm run build && npm run release:checksums && shasum -a 256 -c release/checksums.sha256",
23
- "prepublishOnly": "npm run typecheck && npm test && npm run build",
23
+ "prepublishOnly": "npm run release:verify",
24
24
  "clean": "rm -rf dist"
25
25
  },
26
26
  "keywords": [
@@ -62,6 +62,7 @@
62
62
  "docs/TUTORIALS/*.md",
63
63
  "docs/POLICY_EXAMPLE.json",
64
64
  "docs/policy-templates",
65
+ "examples/cloud-run-mcp-caller.mjs",
65
66
  "brand/readme-hero.svg",
66
67
  "README.md",
67
68
  "CONTRIBUTING.md",
@@ -73,20 +74,22 @@
73
74
  "access": "public"
74
75
  },
75
76
  "dependencies": {
76
- "@modelcontextprotocol/sdk": "^1.29.0",
77
+ "@modelcontextprotocol/sdk": "1.30.0",
77
78
  "commander": "^14.0.3",
78
79
  "zod": "^4.3.6"
79
80
  },
80
81
  "devDependencies": {
81
82
  "@eslint/js": "^10.0.1",
82
- "@types/node": "^25.5.0",
83
- "eslint": "^10.0.3",
84
- "tsx": "^4.19.2",
83
+ "@types/node": "^26.1.1",
84
+ "eslint": "^10.7.0",
85
+ "tsx": "^4.23.1",
85
86
  "typescript": "^6.0.3",
86
- "typescript-eslint": "^8.57.0",
87
+ "typescript-eslint": "^8.64.0",
87
88
  "vitest": "^4.1.0"
88
89
  },
89
90
  "overrides": {
91
+ "hono": "^4.13.0",
92
+ "ip-address": "^10.4.0",
90
93
  "path-to-regexp": "^8.4.2"
91
94
  }
92
95
  }