@tryvira/mcp 0.1.14 → 0.1.15

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Vira / Esad Türkel
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vira / Esad Türkel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,79 +1,79 @@
1
- # @tryvira/mcp
2
-
3
- MIT-licensed MCP client/server package. The Vira service, application, and
4
- backend remain proprietary and are governed separately.
5
-
6
- An npx-ready MCP server for Vira's existing scoped authority boundary.
7
-
8
- ## Run it
9
-
10
- ```bash
11
- npx @tryvira/mcp
12
- ```
13
-
14
- The default transport is the official MCP transport. The legacy custom transport is an
15
- explicit migration option only: `VIRA_MCP_PROTOCOL_MODE=legacy npx @tryvira/mcp`.
16
-
17
- The launcher reads environment variables from its parent process. It does not automatically load a
18
- `.env` file. For a local shell, export the variables first; for an MCP client, put them in the
19
- client's `env` configuration:
20
-
21
- ```dotenv
22
- VIRA_API_URL=http://127.0.0.1:4185
23
- VIRA_API_KEY=vira_dev_local.local-development-only-32chars
24
- VIRA_MCP_AUTH_TOKEN=replace-with-a-long-random-mcp-token
25
- VIRA_ORGANIZATION_ID=local-org
26
- VIRA_PROJECT_ID=local-project
27
- VIRA_ENVIRONMENT_ID=local
28
- ```
29
-
30
- For example, an MCP client configuration uses the same names:
31
-
32
- ```json
33
- {"env":{"VIRA_API_URL":"https://api.example","VIRA_API_KEY":"<customer-api-key>","VIRA_MCP_AUTH_TOKEN":"<mcp-token>","VIRA_ORGANIZATION_ID":"<org>","VIRA_PROJECT_ID":"<project>","VIRA_ENVIRONMENT_ID":"<environment>"}}
34
- ```
35
-
36
- The default launcher uses MCP stdio. To run the optional HTTP transport explicitly, use
37
- `npx @tryvira/mcp --http`; it binds to `127.0.0.1` by default and requires `Authorization: Bearer
38
- <VIRA_MCP_AUTH_TOKEN>`. Effectful MCP tools are denied by default. Local-only effectful
39
- execution requires the explicit `VIRA_MCP_ALLOW_EFFECTFUL=true` opt-in; production never
40
- accepts that shortcut. Set `VIRA_MCP_BIND_PUBLIC=true` only when an authenticated reverse
41
- proxy or equivalent network boundary is present.
42
-
43
- Effectful MCP tools remain authority-gated; the launcher does not create a second execution or telemetry path.
44
-
45
- ## What a client can discover
46
-
47
- After `initialize`, call `tools/list`. Read-only tools such as `resolve_semantic` may return
48
- semantic candidates. Effectful tools such as `resolve_runtime`, pack installation/release
49
- and Strategy execution call the configured authority endpoint and can be denied by scope,
50
- role, release state or policy.
51
-
52
- ## Minimal MCP client configuration
53
-
54
- ```json
55
- {
56
- "mcpServers": {
57
- "vira": {
58
- "command": "npx",
59
- "args": ["-y", "@tryvira/mcp"],
60
- "env": {
61
- "VIRA_API_URL": "https://api.example.invalid",
62
- "VIRA_API_KEY": "<customer-api-key>",
63
- "VIRA_MCP_AUTH_TOKEN": "<mcp-auth-token>",
64
- "VIRA_MCP_AUTHORITY_URL": "https://api.example.invalid/v1/mcp/authorize",
65
- "VIRA_ORGANIZATION_ID": "<organization>",
66
- "VIRA_PROJECT_ID": "<project>",
67
- "VIRA_ENVIRONMENT_ID": "<environment>"
68
- }
69
- }
70
- }
71
- }
72
- ```
73
-
74
- Never paste real credentials into a checked-in client configuration. For local-only effectful
75
- testing, use the local stack and its documented development credentials; the production
76
- authority path does not accept the local bypass.
77
-
78
- See [`docs/MCP_GUIDE.md`](../../docs/MCP_GUIDE.md) for JSON-RPC discovery, tool examples and
79
- authority/error behavior.
1
+ # @tryvira/mcp
2
+
3
+ MIT-licensed MCP client/server package. The Vira service, application, and
4
+ backend remain proprietary and are governed separately.
5
+
6
+ An npx-ready MCP server for Vira's existing scoped authority boundary.
7
+
8
+ ## Run it
9
+
10
+ ```bash
11
+ npx @tryvira/mcp
12
+ ```
13
+
14
+ The default transport is the official MCP transport. The legacy custom transport is an
15
+ explicit migration option only: `VIRA_MCP_PROTOCOL_MODE=legacy npx @tryvira/mcp`.
16
+
17
+ The launcher reads environment variables from its parent process. It does not automatically load a
18
+ `.env` file. For a local shell, export the variables first; for an MCP client, put them in the
19
+ client's `env` configuration:
20
+
21
+ ```dotenv
22
+ VIRA_API_URL=http://127.0.0.1:4185
23
+ VIRA_API_KEY=vira_dev_local.local-development-only-32chars
24
+ VIRA_MCP_AUTH_TOKEN=replace-with-a-long-random-mcp-token
25
+ VIRA_ORGANIZATION_ID=local-org
26
+ VIRA_PROJECT_ID=local-project
27
+ VIRA_ENVIRONMENT_ID=local
28
+ ```
29
+
30
+ For example, an MCP client configuration uses the same names:
31
+
32
+ ```json
33
+ {"env":{"VIRA_API_URL":"https://api.example","VIRA_API_KEY":"<customer-api-key>","VIRA_MCP_AUTH_TOKEN":"<mcp-token>","VIRA_ORGANIZATION_ID":"<org>","VIRA_PROJECT_ID":"<project>","VIRA_ENVIRONMENT_ID":"<environment>"}}
34
+ ```
35
+
36
+ The default launcher uses MCP stdio. To run the optional HTTP transport explicitly, use
37
+ `npx @tryvira/mcp --http`; it binds to `127.0.0.1` by default and requires `Authorization: Bearer
38
+ <VIRA_MCP_AUTH_TOKEN>`. Effectful MCP tools are denied by default. Local-only effectful
39
+ execution requires the explicit `VIRA_MCP_ALLOW_EFFECTFUL=true` opt-in; production never
40
+ accepts that shortcut. Set `VIRA_MCP_BIND_PUBLIC=true` only when an authenticated reverse
41
+ proxy or equivalent network boundary is present.
42
+
43
+ Effectful MCP tools remain authority-gated; the launcher does not create a second execution or telemetry path.
44
+
45
+ ## What a client can discover
46
+
47
+ After `initialize`, call `tools/list`. Read-only tools such as `resolve_semantic` may return
48
+ semantic candidates. Effectful tools such as `resolve_runtime`, pack installation/release
49
+ and Strategy execution call the configured authority endpoint and can be denied by scope,
50
+ role, release state or policy.
51
+
52
+ ## Minimal MCP client configuration
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "vira": {
58
+ "command": "npx",
59
+ "args": ["-y", "@tryvira/mcp"],
60
+ "env": {
61
+ "VIRA_API_URL": "https://api.example.invalid",
62
+ "VIRA_API_KEY": "<customer-api-key>",
63
+ "VIRA_MCP_AUTH_TOKEN": "<mcp-auth-token>",
64
+ "VIRA_MCP_AUTHORITY_URL": "https://api.example.invalid/v1/mcp/authorize",
65
+ "VIRA_ORGANIZATION_ID": "<organization>",
66
+ "VIRA_PROJECT_ID": "<project>",
67
+ "VIRA_ENVIRONMENT_ID": "<environment>"
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ Never paste real credentials into a checked-in client configuration. For local-only effectful
75
+ testing, use the local stack and its documented development credentials; the production
76
+ authority path does not accept the local bypass.
77
+
78
+ See [`docs/MCP_GUIDE.md`](../../docs/MCP_GUIDE.md) for JSON-RPC discovery, tool examples and
79
+ authority/error behavior.
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
- // packages/domain/src/scope-composer.ts
17
+ // ../domain/src/scope-composer.ts
18
18
  import { createHash } from "node:crypto";
19
19
  function canonical(value) {
20
20
  if (value === null || typeof value !== "object") return JSON.stringify(value);
@@ -30,13 +30,13 @@ function assertComposedScopeIntegrity(composed) {
30
30
  }
31
31
  var digest;
32
32
  var init_scope_composer = __esm({
33
- "packages/domain/src/scope-composer.ts"() {
33
+ "../domain/src/scope-composer.ts"() {
34
34
  "use strict";
35
35
  digest = (value) => createHash("sha256").update(canonical(value)).digest("hex");
36
36
  }
37
37
  });
38
38
 
39
- // packages/runtime/src/mcp-gateway.ts
39
+ // ../runtime/src/mcp-gateway.ts
40
40
  import { createHash as createHash2 } from "node:crypto";
41
41
  function canonicalMcpJson(value) {
42
42
  if (value === null || typeof value !== "object") return JSON.stringify(value);
@@ -143,13 +143,13 @@ async function invokeMcpTool(input) {
143
143
  return Object.freeze({ ...body, provenanceDigest: createHash2("sha256").update(canonicalMcpJson(body)).digest("hex") });
144
144
  }
145
145
  var init_mcp_gateway = __esm({
146
- "packages/runtime/src/mcp-gateway.ts"() {
146
+ "../runtime/src/mcp-gateway.ts"() {
147
147
  "use strict";
148
148
  init_scope_composer();
149
149
  }
150
150
  });
151
151
 
152
- // packages/runtime/src/mcp-provenance.ts
152
+ // ../runtime/src/mcp-provenance.ts
153
153
  import { createHash as createHash3 } from "node:crypto";
154
154
  function verifyMcpResult2(result) {
155
155
  const { provenanceDigest: stored, ...body } = result;
@@ -163,13 +163,13 @@ function createMcpResultFromResponse(input) {
163
163
  return Object.freeze({ ...body, provenanceDigest: createHash3("sha256").update(canonicalMcpJson(body)).digest("hex") });
164
164
  }
165
165
  var init_mcp_provenance = __esm({
166
- "packages/runtime/src/mcp-provenance.ts"() {
166
+ "../runtime/src/mcp-provenance.ts"() {
167
167
  "use strict";
168
168
  init_mcp_gateway();
169
169
  }
170
170
  });
171
171
 
172
- // packages/runtime/src/mcp-session.ts
172
+ // ../runtime/src/mcp-session.ts
173
173
  import { createHash as createHash4, randomUUID } from "node:crypto";
174
174
  function assertMcpSession(session) {
175
175
  const { sessionDigest, ...base } = session;
@@ -183,14 +183,14 @@ function assertMcpSessionActive(session) {
183
183
  }
184
184
  var canonical2, digest2;
185
185
  var init_mcp_session = __esm({
186
- "packages/runtime/src/mcp-session.ts"() {
186
+ "../runtime/src/mcp-session.ts"() {
187
187
  "use strict";
188
188
  canonical2 = (value) => value === null || typeof value !== "object" ? JSON.stringify(value) : Array.isArray(value) ? `[${value.map(canonical2).join(",")}]` : `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonical2(value[key])}`).join(",")}}`;
189
189
  digest2 = (value) => createHash4("sha256").update(canonical2(value)).digest("hex");
190
190
  }
191
191
  });
192
192
 
193
- // apps/mcp-server/server.ts
193
+ // ../../apps/mcp-server/server.ts
194
194
  import {
195
195
  createServer
196
196
  } from "node:http";
@@ -555,7 +555,7 @@ function readBody(request, limit) {
555
555
  }
556
556
  var requestToken, claimInvocation;
557
557
  var init_server = __esm({
558
- "apps/mcp-server/server.ts"() {
558
+ "../../apps/mcp-server/server.ts"() {
559
559
  "use strict";
560
560
  init_mcp_gateway();
561
561
  init_mcp_provenance();
@@ -576,7 +576,7 @@ var init_server = __esm({
576
576
  }
577
577
  });
578
578
 
579
- // packages/runtime/src/mcp-invocation-service.ts
579
+ // ../runtime/src/mcp-invocation-service.ts
580
580
  import { createHash as createHash5 } from "node:crypto";
581
581
  function assertReplayIdentity(invocation, authority, result) {
582
582
  const argumentsDigest = createHash5("sha256").update(canonicalMcpJson(invocation.arguments)).digest("hex");
@@ -605,17 +605,17 @@ async function executeMcpInvocation(input) {
605
605
  }
606
606
  }
607
607
  var init_mcp_invocation_service = __esm({
608
- "packages/runtime/src/mcp-invocation-service.ts"() {
608
+ "../runtime/src/mcp-invocation-service.ts"() {
609
609
  "use strict";
610
610
  init_mcp_gateway();
611
611
  init_mcp_gateway();
612
612
  }
613
613
  });
614
614
 
615
- // packages/database/src/mcp-provenance-repository.ts
615
+ // ../database/src/mcp-provenance-repository.ts
616
616
  var assertClaimInput, McpProvenanceRepository, SqlMcpProvenanceRepository;
617
617
  var init_mcp_provenance_repository = __esm({
618
- "packages/database/src/mcp-provenance-repository.ts"() {
618
+ "../database/src/mcp-provenance-repository.ts"() {
619
619
  "use strict";
620
620
  init_mcp_provenance();
621
621
  init_scope_composer();
@@ -819,7 +819,7 @@ var init_mcp_provenance_repository = __esm({
819
819
  }
820
820
  });
821
821
 
822
- // apps/mcp-server/vira-server.ts
822
+ // ../../apps/mcp-server/vira-server.ts
823
823
  function resolveViraMcpConfig(environment = process.env) {
824
824
  const baseUrl = (environment.VIRA_API_URL ?? "http://127.0.0.1:4185").replace(/\/$/, "");
825
825
  const apiKey = environment.VIRA_API_KEY ?? (environment.NODE_ENV === "production" ? "" : "vira_dev_local.local-development-only-32chars");
@@ -928,6 +928,35 @@ function createViraMcpOptions(config) {
928
928
  const { proposalId, transition, ...body } = args;
929
929
  return api(`/v1/teach/proposals/${encodeURIComponent(String(proposalId))}/${encodeURIComponent(String(transition))}`, body, `mcp:${tool}:${String(proposalId)}`);
930
930
  }
931
+ if (tool === "create_evaluation_plan") return api("/v1/evaluation-plans", args, `mcp:${tool}:${String(args.id)}`);
932
+ if (tool === "seal_evaluation_plan") return api(`/v1/evaluation-plans/${encodeURIComponent(String(args.planId))}/seal`, {}, `mcp:${tool}:${String(args.planId)}`);
933
+ if (tool === "create_improvement_proposal") {
934
+ const { evaluationId, ...body } = args;
935
+ return api(`/v1/evaluations/${encodeURIComponent(String(evaluationId))}/improvement-proposal`, body, `mcp:${tool}:${String(evaluationId)}`);
936
+ }
937
+ if (tool === "review_improvement_proposal") {
938
+ const { proposalId, action, ...body } = args;
939
+ return api(`/v1/behavior-improvement-proposals/${encodeURIComponent(String(proposalId))}`, { action, ...body }, `mcp:${tool}:${String(proposalId)}`);
940
+ }
941
+ if (tool === "create_behavior_revision_candidate") return api("/v1/behavior-revision-candidates", args, `mcp:${tool}:${String(args.id)}`);
942
+ if (tool === "evaluate_behavior_revision_candidate") {
943
+ const { candidateId, ...body } = args;
944
+ return api(`/v1/behavior-revision-candidates/${encodeURIComponent(String(candidateId))}/evaluate`, body, `mcp:${tool}:${String(candidateId)}`);
945
+ }
946
+ if (tool === "accept_behavior_revision_candidate") {
947
+ const { candidateId, candidateEvaluationId } = args;
948
+ return api(`/v1/behavior-revision-candidates/${encodeURIComponent(String(candidateId))}/accept`, { candidateEvaluationId }, `mcp:${tool}:${String(candidateId)}`);
949
+ }
950
+ if (tool === "create_pack_revision") return api("/v1/pack-revisions", args, `mcp:${tool}:${String(args.id)}`);
951
+ if (tool === "transition_pack_revision") {
952
+ const { revisionId, transition, ...body } = args;
953
+ return api(`/v1/pack-revisions/${encodeURIComponent(String(revisionId))}/${encodeURIComponent(String(transition))}`, body, `mcp:${tool}:${String(revisionId)}`);
954
+ }
955
+ if (tool === "materialize_pack_revision") {
956
+ const { revisionId, ...body } = args;
957
+ return api(`/v1/pack-revisions/${encodeURIComponent(String(revisionId))}/materialize`, body, `mcp:${tool}:${String(revisionId)}`);
958
+ }
959
+ if (tool === "get_pack_revision_diff") return api(`/v1/pack-revisions/${encodeURIComponent(String(args.revisionId))}/diff?organizationId=${encodeURIComponent(config.scope.organizationId)}&projectId=${encodeURIComponent(config.scope.projectId)}&environmentId=${encodeURIComponent(config.scope.environmentId)}`, void 0, `mcp:${tool}:${String(args.revisionId)}`);
931
960
  if (tool === "create_release") return api("/v1/releases", args, `mcp:${tool}:${String(args.releaseId ?? args.artifactId)}`);
932
961
  return lifecycleTransport.call(input);
933
962
  } };
@@ -954,7 +983,7 @@ function createViraMcpOptions(config) {
954
983
  }
955
984
  var tools;
956
985
  var init_vira_server = __esm({
957
- "apps/mcp-server/vira-server.ts"() {
986
+ "../../apps/mcp-server/vira-server.ts"() {
958
987
  "use strict";
959
988
  init_server();
960
989
  init_mcp_invocation_service();
@@ -996,6 +1025,17 @@ var init_vira_server = __esm({
996
1025
  { name: "review_discovery_candidate", description: "Record a human review decision for a scoped discovery candidate.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, kind: { type: "string" }, key: { type: "string" }, decision: { type: "string" }, payload: { type: "object" } }, required: ["organizationId", "projectId", "environmentId", "kind", "key", "decision"] } },
997
1026
  { name: "create_observation", description: "Submit one scoped observation for discovery; it does not publish behavior.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, id: { type: "string" }, content: { type: "object" }, consent: { type: "boolean" } }, required: ["organizationId", "projectId", "environmentId", "id", "content", "consent"] } },
998
1027
  { name: "start_evaluation", description: "Start a local evaluation for an existing artifact.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, id: { type: "string" }, targetArtifact: { type: "string" }, dataset: { type: "array" }, assertions: { type: "array" } }, required: ["organizationId", "projectId", "environmentId", "id", "targetArtifact", "dataset", "assertions"] } },
1028
+ { name: "create_evaluation_plan", description: "Create an immutable OFF/current-on evaluation plan for a scoped behavior target.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, id: { type: "string" }, suiteId: { type: "string" }, suiteVersion: { type: "string" }, suiteDigest: { type: "string" }, datasetSnapshotDigest: { type: "string" }, evaluationPolicyDigest: { type: "string" }, arms: { type: "array" } }, required: ["organizationId", "projectId", "environmentId", "id", "suiteId", "suiteVersion", "suiteDigest", "datasetSnapshotDigest", "evaluationPolicyDigest", "arms"] } },
1029
+ { name: "seal_evaluation_plan", description: "Seal an evaluation plan so its suite, dataset, and execution arms cannot drift.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, planId: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "planId"] } },
1030
+ { name: "create_improvement_proposal", description: "Create a Teach improvement proposal from a completed comparative evaluation.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, evaluationId: { type: "string" }, id: { type: "string" }, basePackId: { type: "string" }, basePackDigest: { type: "string" }, behaviorSet: { type: "object" } }, required: ["organizationId", "projectId", "environmentId", "evaluationId", "id", "basePackId", "basePackDigest"] } },
1031
+ { name: "review_improvement_proposal", description: "Review a Teach improvement proposal without mutating canonical runtime state.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, proposalId: { type: "string" }, action: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "proposalId", "action"] } },
1032
+ { name: "create_behavior_revision_candidate", description: "Create an immutable behavior revision candidate from a reviewed Teach improvement proposal.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, id: { type: "string" }, sourceTeachProposalId: { type: "string" }, parentRevisionId: { type: "string" }, parentRevisionDigest: { type: "string" }, changeSet: { type: "object" } }, required: ["organizationId", "projectId", "environmentId", "id", "sourceTeachProposalId", "parentRevisionId", "parentRevisionDigest", "changeSet"] } },
1033
+ { name: "evaluate_behavior_revision_candidate", description: "Evaluate a candidate using provider-backed dataset assertions; client scores are not accepted.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, candidateId: { type: "string" }, dataset: { type: "array" }, assertions: { type: "array" } }, required: ["organizationId", "projectId", "environmentId", "candidateId", "dataset"] } },
1034
+ { name: "accept_behavior_revision_candidate", description: "Accept a candidate only when a passed evaluation is bound to its immutable digest.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, candidateId: { type: "string" }, candidateEvaluationId: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "candidateId", "candidateEvaluationId"] } },
1035
+ { name: "create_pack_revision", description: "Create a draft Pack Revision from an accepted behavior candidate.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, id: { type: "string" }, packKey: { type: "string" }, version: { type: "string" }, behaviorRevisionCandidateId: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "id", "packKey", "version", "behaviorRevisionCandidateId"] } },
1036
+ { name: "transition_pack_revision", description: "Validate, request approval, approve, or release a governed Pack Revision.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, revisionId: { type: "string" }, transition: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "revisionId", "transition"] } },
1037
+ { name: "materialize_pack_revision", description: "Materialize an approved Pack Revision into canonical runtime state.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, revisionId: { type: "string" }, packId: { type: "string" }, variables: { type: "object" } }, required: ["organizationId", "projectId", "environmentId", "revisionId", "packId"] } },
1038
+ { name: "get_pack_revision_diff", description: "Read the immutable lineage and change summary for a Pack Revision.", inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, revisionId: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "revisionId"] } },
999
1039
  { name: "compile_behavior_capsule", description: "Compile a persisted scoped Behavior VM capsule and return its receipt.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, programId: { type: "string" }, input: { type: "string" }, selection: { type: "object" }, candidates: { type: "array" } }, required: ["organizationId", "projectId", "environmentId", "programId", "input"] } },
1000
1040
  { name: "serve_behavior_projection", description: "Serve the active scoped behavior projection through the governed runtime boundary.", effectful: true, inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" }, programId: { type: "string" }, input: { type: "string" }, provider: { type: "string" }, protocol: { type: "string" } }, required: ["organizationId", "projectId", "environmentId", "input", "provider"] } },
1001
1041
  { name: "list_packs", description: "Read scoped behavior packs.", inputSchema: { type: "object", properties: { organizationId: { type: "string" }, projectId: { type: "string" }, environmentId: { type: "string" } }, required: ["organizationId", "projectId", "environmentId"] } },
@@ -1009,10 +1049,10 @@ var init_vira_server = __esm({
1009
1049
  }
1010
1050
  });
1011
1051
 
1012
- // packages/database/src/mcp-session-repository.ts
1052
+ // ../database/src/mcp-session-repository.ts
1013
1053
  var SqlMcpSessionRepository;
1014
1054
  var init_mcp_session_repository = __esm({
1015
- "packages/database/src/mcp-session-repository.ts"() {
1055
+ "../database/src/mcp-session-repository.ts"() {
1016
1056
  "use strict";
1017
1057
  init_mcp_session();
1018
1058
  SqlMcpSessionRepository = class {
@@ -1051,7 +1091,7 @@ var init_mcp_session_repository = __esm({
1051
1091
  }
1052
1092
  });
1053
1093
 
1054
- // apps/mcp-server/official-stdio.ts
1094
+ // ../../apps/mcp-server/official-stdio.ts
1055
1095
  import { McpServer } from "@modelcontextprotocol/server";
1056
1096
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
1057
1097
  import { z } from "zod";
@@ -1068,16 +1108,16 @@ function serveOfficialViraMcp(options) {
1068
1108
  });
1069
1109
  }
1070
1110
  return server;
1071
- });
1111
+ }, { legacy: "reject" });
1072
1112
  }
1073
1113
  var init_official_stdio = __esm({
1074
- "apps/mcp-server/official-stdio.ts"() {
1114
+ "../../apps/mcp-server/official-stdio.ts"() {
1075
1115
  "use strict";
1076
1116
  init_mcp_gateway();
1077
1117
  }
1078
1118
  });
1079
1119
 
1080
- // packages/database/src/postgres-adapter.ts
1120
+ // ../database/src/postgres-adapter.ts
1081
1121
  import { Pool } from "pg";
1082
1122
  function validateSql(sql) {
1083
1123
  if (!sql.trim()) throw new Error("POSTGRES_SQL_REQUIRED");
@@ -1119,12 +1159,12 @@ function createPostgresPool(input = {}) {
1119
1159
  return { pool, close: () => pool.end() };
1120
1160
  }
1121
1161
  var init_postgres_adapter = __esm({
1122
- "packages/database/src/postgres-adapter.ts"() {
1162
+ "../database/src/postgres-adapter.ts"() {
1123
1163
  "use strict";
1124
1164
  }
1125
1165
  });
1126
1166
 
1127
- // packages/database/src/postgres-migrations.ts
1167
+ // ../database/src/postgres-migrations.ts
1128
1168
  import { createHash as createHash6 } from "node:crypto";
1129
1169
  function splitSql(sql) {
1130
1170
  const statements = [];
@@ -1274,12 +1314,12 @@ async function applyPostgresMigrations(client, migrations) {
1274
1314
  }
1275
1315
  }
1276
1316
  var init_postgres_migrations = __esm({
1277
- "packages/database/src/postgres-migrations.ts"() {
1317
+ "../database/src/postgres-migrations.ts"() {
1278
1318
  "use strict";
1279
1319
  }
1280
1320
  });
1281
1321
 
1282
- // packages/database/src/postgres-runtime.ts
1322
+ // ../database/src/postgres-runtime.ts
1283
1323
  import { readFile, readdir } from "node:fs/promises";
1284
1324
  import { dirname, resolve } from "node:path";
1285
1325
  import { fileURLToPath } from "node:url";
@@ -1289,13 +1329,24 @@ async function defaultMigrationPaths() {
1289
1329
  return entries.filter((entry) => entry.isFile() && /^\d+_.+\.sql$/i.test(entry.name)).map((entry) => resolve(migrationDirectory, entry.name)).sort((left, right) => left.localeCompare(right, "en"));
1290
1330
  }
1291
1331
  async function openPostgresRuntime(options = {}) {
1292
- const { pool, close } = createPostgresPool({ databaseUrl: options.databaseUrl, max: options.maxConnections, ssl: options.ssl });
1332
+ const maxConnections = options.maxConnections ?? Number(process.env.VIRA_DB_POOL_MAX ?? 10);
1333
+ const { pool, close } = createPostgresPool({ databaseUrl: options.databaseUrl, max: maxConnections, ssl: options.ssl });
1293
1334
  const database = createPostgresDatabase({ pool, databaseUrl: options.databaseUrl });
1294
1335
  try {
1295
1336
  if (!options.skipMigrations && process.env.VIRA_WORKER_SKIP_MIGRATIONS !== "true") {
1296
1337
  const migrations = [];
1297
1338
  const migrationPaths = options.migrationPaths ?? await defaultMigrationPaths();
1298
- for (const path of migrationPaths) migrations.push({ id: path.split(/[\\/]/).pop().replace(/\.sql$/i, ""), sql: await readFile(path, "utf8") });
1339
+ for (const path of migrationPaths) {
1340
+ const id = path.split(/[\\/]/).pop().replace(/\.sql$/i, "");
1341
+ const migration = { id, sql: await readFile(path, "utf8") };
1342
+ if (id === "001_vnext_foundation") {
1343
+ migration.legacyChecksums = ["d1a175e1b8af20bcf9bc650fb299626513532e4d18da429569251eff69475427"];
1344
+ }
1345
+ if (id === "019_postgres_explicit_public_deny_policies") {
1346
+ migration.legacyChecksums = ["162658a065737b36c0cedb6f1294d497074e69b5b744bbfe10e42363427c23a9"];
1347
+ }
1348
+ migrations.push(migration);
1349
+ }
1299
1350
  const client = await pool.connect();
1300
1351
  try {
1301
1352
  await applyPostgresMigrations(client, migrations);
@@ -1311,7 +1362,7 @@ async function openPostgresRuntime(options = {}) {
1311
1362
  }
1312
1363
  var here;
1313
1364
  var init_postgres_runtime = __esm({
1314
- "packages/database/src/postgres-runtime.ts"() {
1365
+ "../database/src/postgres-runtime.ts"() {
1315
1366
  "use strict";
1316
1367
  init_postgres_adapter();
1317
1368
  init_postgres_migrations();
@@ -1319,7 +1370,7 @@ var init_postgres_runtime = __esm({
1319
1370
  }
1320
1371
  });
1321
1372
 
1322
- // packages/database/src/production-sqlite.ts
1373
+ // ../database/src/production-sqlite.ts
1323
1374
  import { access, readFile as readFile2, writeFile } from "node:fs/promises";
1324
1375
  import { existsSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
1325
1376
  import { dirname as dirname2, resolve as resolve2 } from "node:path";
@@ -1823,7 +1874,7 @@ async function openProductionSqlite({ databaseUrl = process.env.DATABASE_URL } =
1823
1874
  }
1824
1875
  var root, require2, migrationCandidates;
1825
1876
  var init_production_sqlite = __esm({
1826
- "packages/database/src/production-sqlite.ts"() {
1877
+ "../database/src/production-sqlite.ts"() {
1827
1878
  "use strict";
1828
1879
  root = dirname2(fileURLToPath2(import.meta.url));
1829
1880
  require2 = createRequire(import.meta.url);
@@ -1834,7 +1885,7 @@ var init_production_sqlite = __esm({
1834
1885
  }
1835
1886
  });
1836
1887
 
1837
- // packages/database/src/runtime-database.ts
1888
+ // ../database/src/runtime-database.ts
1838
1889
  var runtime_database_exports = {};
1839
1890
  __export(runtime_database_exports, {
1840
1891
  createProductionDatabase: () => createProductionDatabase,
@@ -1874,14 +1925,14 @@ async function openRuntimeDatabase(options = {}) {
1874
1925
  throw new Error("DATABASE_URL_UNSUPPORTED");
1875
1926
  }
1876
1927
  var init_runtime_database = __esm({
1877
- "packages/database/src/runtime-database.ts"() {
1928
+ "../database/src/runtime-database.ts"() {
1878
1929
  "use strict";
1879
1930
  init_postgres_runtime();
1880
1931
  init_production_sqlite();
1881
1932
  }
1882
1933
  });
1883
1934
 
1884
- // packages/database/src/postgres-mcp-repository.ts
1935
+ // ../database/src/postgres-mcp-repository.ts
1885
1936
  var postgres_mcp_repository_exports = {};
1886
1937
  __export(postgres_mcp_repository_exports, {
1887
1938
  PostgresMcpProvenanceRepository: () => PostgresMcpProvenanceRepository,
@@ -1889,7 +1940,7 @@ __export(postgres_mcp_repository_exports, {
1889
1940
  });
1890
1941
  var provenanceSelect, PostgresMcpProvenanceRepository, PostgresMcpSessionRepository;
1891
1942
  var init_postgres_mcp_repository = __esm({
1892
- "packages/database/src/postgres-mcp-repository.ts"() {
1943
+ "../database/src/postgres-mcp-repository.ts"() {
1893
1944
  "use strict";
1894
1945
  init_mcp_provenance();
1895
1946
  init_mcp_session();
@@ -1965,7 +2016,7 @@ var init_postgres_mcp_repository = __esm({
1965
2016
  }
1966
2017
  });
1967
2018
 
1968
- // apps/mcp-server/start.ts
2019
+ // ../../apps/mcp-server/start.ts
1969
2020
  var start_exports = {};
1970
2021
  __export(start_exports, {
1971
2022
  startMcpStdio: () => startMcpStdio
@@ -2011,7 +2062,7 @@ async function startMcpStdio() {
2011
2062
  process.once("SIGINT", close);
2012
2063
  }
2013
2064
  var init_start = __esm({
2014
- "apps/mcp-server/start.ts"() {
2065
+ "../../apps/mcp-server/start.ts"() {
2015
2066
  "use strict";
2016
2067
  init_server();
2017
2068
  init_vira_server();
@@ -2023,7 +2074,7 @@ var init_start = __esm({
2023
2074
  }
2024
2075
  });
2025
2076
 
2026
- // packages/mcp/src/cli.ts
2077
+ // src/cli.ts
2027
2078
  init_vira_server();
2028
2079
  if (process.argv.includes("--http") || process.env.VIRA_MCP_TRANSPORT === "http") {
2029
2080
  await startHttp();
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- // packages/runtime/src/mcp-gateway.ts
1
+ // ../runtime/src/mcp-gateway.ts
2
2
  import { createHash as createHash2 } from "node:crypto";
3
3
  import { isIP } from "node:net";
4
4
 
5
- // packages/domain/src/scope-composer.ts
5
+ // ../domain/src/scope-composer.ts
6
6
  import { createHash } from "node:crypto";
7
7
  function canonical(value) {
8
8
  if (value === null || typeof value !== "object") return JSON.stringify(value);
@@ -18,7 +18,7 @@ function assertComposedScopeIntegrity(composed) {
18
18
  return true;
19
19
  }
20
20
 
21
- // packages/runtime/src/mcp-gateway.ts
21
+ // ../runtime/src/mcp-gateway.ts
22
22
  var MCP_PROTOCOL_VERSIONS = ["2026-07-28", "2025-11-25", "2025-03-26"];
23
23
  function negotiateMcpProtocolVersion(offered) {
24
24
  const value = String(offered ?? "");