@tryvira/mcp 0.1.14 → 0.1.16
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 +21 -21
- package/README.md +79 -79
- package/dist/cli.js +89 -38
- package/dist/index.js +3 -3
- package/dist/migrations/001_vnext_foundation.sql +628 -628
- package/package.json +52 -52
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
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
146
|
+
"../runtime/src/mcp-gateway.ts"() {
|
|
147
147
|
"use strict";
|
|
148
148
|
init_scope_composer();
|
|
149
149
|
}
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
-
//
|
|
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
|
-
"
|
|
166
|
+
"../runtime/src/mcp-provenance.ts"() {
|
|
167
167
|
"use strict";
|
|
168
168
|
init_mcp_gateway();
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
615
|
+
// ../database/src/mcp-provenance-repository.ts
|
|
616
616
|
var assertClaimInput, McpProvenanceRepository, SqlMcpProvenanceRepository;
|
|
617
617
|
var init_mcp_provenance_repository = __esm({
|
|
618
|
-
"
|
|
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
|
-
//
|
|
1052
|
+
// ../database/src/mcp-session-repository.ts
|
|
1013
1053
|
var SqlMcpSessionRepository;
|
|
1014
1054
|
var init_mcp_session_repository = __esm({
|
|
1015
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
1162
|
+
"../database/src/postgres-adapter.ts"() {
|
|
1123
1163
|
"use strict";
|
|
1124
1164
|
}
|
|
1125
1165
|
});
|
|
1126
1166
|
|
|
1127
|
-
//
|
|
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
|
-
"
|
|
1317
|
+
"../database/src/postgres-migrations.ts"() {
|
|
1278
1318
|
"use strict";
|
|
1279
1319
|
}
|
|
1280
1320
|
});
|
|
1281
1321
|
|
|
1282
|
-
//
|
|
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
|
|
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)
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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 ?? "");
|