witnora 0.19.0 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/cli.js +8 -0
- package/dist/command-help.js +15 -0
- package/dist/gateway.js +15 -0
- package/dist/index.js +1 -0
- package/dist/mcp.js +91 -0
- package/dist/onboard.js +1 -1
- package/dist/real-path-activation.js +11 -4
- package/mcp.d.ts +42 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -90,6 +90,20 @@ For a cloud Agent, the customer exposes only this path through its HTTPS ingress
|
|
|
90
90
|
or private network. This generated endpoint is limited to the current sandbox
|
|
91
91
|
Task/action path; it does not create a production Provider or broader authority.
|
|
92
92
|
|
|
93
|
+
An MCP client can use the same exact path without receiving either local
|
|
94
|
+
credential. Launch the stdio server from the onboarded repository:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx witnora@latest mcp
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
It exposes one generated Action tool, for example `witnora_cancel-order`, plus
|
|
101
|
+
`witnora_get_action`. The Agent can propose an Action and inspect its state, but
|
|
102
|
+
there is no MCP approval, direct-execution, or self-verification tool. Human
|
|
103
|
+
approval, customer-owned execution, the separate Probe, Receipt, and
|
|
104
|
+
idempotency contract remain unchanged. See the public [MCP Action integration](https://witnora.com/docs/mcp-actions)
|
|
105
|
+
and [HTTP Actions](https://witnora.com/docs/http-actions) guides.
|
|
106
|
+
|
|
93
107
|
Initialization writes a reusable `.witnora/gateway/client.mjs`. Import its
|
|
94
108
|
`witnoraGateway.start`, `event`, and `complete` methods at one existing sandbox
|
|
95
109
|
workflow boundary. The generated README contains the exact code and privacy
|
package/dist/cli.js
CHANGED
|
@@ -161,6 +161,13 @@ else if (command === "onboard") {
|
|
|
161
161
|
openBrowser: readBoolFlag("--no-browser") ? async () => { } : undefined,
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
|
+
else if (command === "mcp") {
|
|
165
|
+
const { runWitnoraMcpStdioServer } = await import("./mcp.js");
|
|
166
|
+
await runWitnoraMcpStdioServer({
|
|
167
|
+
repository: readFlag("--repo") ?? process.cwd(),
|
|
168
|
+
dir: readFlag("--dir"),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
164
171
|
else if (command === "release") {
|
|
165
172
|
const action = process.argv[3] ?? "help";
|
|
166
173
|
if (action !== "evaluate")
|
|
@@ -862,6 +869,7 @@ else if (command === "conformance") {
|
|
|
862
869
|
else {
|
|
863
870
|
process.stdout.write(`Usage:
|
|
864
871
|
witnora onboard --project <project-id>
|
|
872
|
+
witnora mcp
|
|
865
873
|
witnora try --template workflow [--push]
|
|
866
874
|
witnora init --subject my-browser-agent
|
|
867
875
|
witnora connect --server https://witnora.com --project <project-id>
|
package/dist/command-help.js
CHANGED
|
@@ -54,6 +54,21 @@ Options:
|
|
|
54
54
|
--repo <directory> Repository to configure (default: current directory)
|
|
55
55
|
--template <type> Override automatic repository detection
|
|
56
56
|
--no-browser Print the approval URL without opening it
|
|
57
|
+
`;
|
|
58
|
+
if (command === "mcp")
|
|
59
|
+
return `Usage:
|
|
60
|
+
witnora mcp [--repo <agent-repository>] [--dir <gateway-directory>]
|
|
61
|
+
|
|
62
|
+
Starts a local stdio MCP server for the one exact sandbox HTTP Action generated
|
|
63
|
+
by onboarding. The MCP process reads ignored Gateway credentials locally; they
|
|
64
|
+
are never exposed as tool inputs. The Agent can propose and inspect an Action,
|
|
65
|
+
but cannot approve it, execute outside the customer Gateway, or self-assert an
|
|
66
|
+
independently verified result.
|
|
67
|
+
|
|
68
|
+
Options:
|
|
69
|
+
--repo <directory> Onboarded Agent repository (default: current directory)
|
|
70
|
+
--dir <directory> Gateway directory relative to the repo (default: .witnora/gateway)
|
|
71
|
+
--help, -h Show this help without starting the MCP server
|
|
57
72
|
`;
|
|
58
73
|
if (command === "gateway")
|
|
59
74
|
return `Usage:
|
package/dist/gateway.js
CHANGED
|
@@ -1463,6 +1463,21 @@ async function loadConfiguredCustomerHttpAction(directory, gateway) {
|
|
|
1463
1463
|
throw new Error("Customer HTTP Action token is missing or invalid.");
|
|
1464
1464
|
return { action, token };
|
|
1465
1465
|
}
|
|
1466
|
+
export async function loadCustomerMcpActionBinding(options = {}) {
|
|
1467
|
+
const directory = resolve(options.repository ?? process.cwd(), options.dir ?? ".witnora/gateway");
|
|
1468
|
+
const gateway = parseConfig(await readFile(join(directory, "gateway.json"), "utf8"));
|
|
1469
|
+
const configured = await loadConfiguredCustomerHttpAction(directory, gateway);
|
|
1470
|
+
if (!configured) {
|
|
1471
|
+
throw new Error("Witnora MCP requires one configured sandbox HTTP Action. Run onboarding for one exact Task/action path first.");
|
|
1472
|
+
}
|
|
1473
|
+
const secrets = parseSecrets(await readFile(join(directory, "secrets.json"), "utf8"));
|
|
1474
|
+
return {
|
|
1475
|
+
baseUrl: `http://${gateway.host}:${gateway.port}`,
|
|
1476
|
+
action: configured.action,
|
|
1477
|
+
actionToken: configured.token,
|
|
1478
|
+
gatewayToken: secrets.gatewayToken,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1466
1481
|
export function createCustomerHttpActionConfig(activations) {
|
|
1467
1482
|
if (activations.length !== 1)
|
|
1468
1483
|
return undefined;
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./failure-review.js";
|
|
|
9
9
|
export * from "./evidence-signing.js";
|
|
10
10
|
export * from "./local-server.js";
|
|
11
11
|
export * from "./monitor.js";
|
|
12
|
+
export * from "./mcp.js";
|
|
12
13
|
export * from "./onboard.js";
|
|
13
14
|
export * from "./normalizers.js";
|
|
14
15
|
export * from "./report.js";
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { loadCustomerMcpActionBinding, } from "./gateway.js";
|
|
6
|
+
const IDENTIFIER = /^[A-Za-z0-9._:-]{1,160}$/;
|
|
7
|
+
const STATUS = /^[A-Za-z0-9._:-]{1,100}$/;
|
|
8
|
+
export function createWitnoraMcpServer(options) {
|
|
9
|
+
if (options.action.environment !== "sandbox" || options.action.actionPathId !== options.action.id) {
|
|
10
|
+
throw new Error("Witnora MCP accepts one exact sandbox Task/action binding only.");
|
|
11
|
+
}
|
|
12
|
+
const actionTool = witnoraMcpActionToolName(options.action.id);
|
|
13
|
+
const server = new McpServer({ name: "witnora", version: "0.1.0" });
|
|
14
|
+
const issuedActionIds = new Set();
|
|
15
|
+
server.registerTool(actionTool, {
|
|
16
|
+
description: `Propose the exact ${options.action.actionPathId} sandbox action through the customer-owned Witnora Gateway. This tool cannot approve its own action. A result is proved only after the independent Probe and signed Receipt are present.`,
|
|
17
|
+
inputSchema: {
|
|
18
|
+
idempotencyKey: z.string().regex(IDENTIFIER).describe("Stable external request ID. Reuse it only for an exact retry."),
|
|
19
|
+
resourceId: z.string().regex(IDENTIFIER).describe("The exact sandbox resource covered by this action path."),
|
|
20
|
+
status: z.string().regex(STATUS).optional().describe(`Requested state. Defaults to ${options.action.defaultStatus}.`),
|
|
21
|
+
},
|
|
22
|
+
}, async (input) => {
|
|
23
|
+
const action = await options.transport.propose(input);
|
|
24
|
+
const actionId = typeof action.id === "string" && IDENTIFIER.test(action.id) ? action.id : undefined;
|
|
25
|
+
if (!actionId)
|
|
26
|
+
throw new Error("Witnora Gateway returned an Action without a valid Action ID.");
|
|
27
|
+
issuedActionIds.add(actionId);
|
|
28
|
+
return toolResult(action);
|
|
29
|
+
});
|
|
30
|
+
server.registerTool("witnora_get_action", {
|
|
31
|
+
description: "Read the current Action, approval, execution, Probe, and Receipt state. Reported success is not an independently verified outcome.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
actionId: z.string().regex(IDENTIFIER),
|
|
34
|
+
},
|
|
35
|
+
}, async ({ actionId }) => {
|
|
36
|
+
if (!issuedActionIds.has(actionId)) {
|
|
37
|
+
throw new Error("This MCP session can inspect only Actions returned by its exact sandbox Action tool. Retry the exact proposal first after a restart.");
|
|
38
|
+
}
|
|
39
|
+
return toolResult(await options.transport.getAction(actionId));
|
|
40
|
+
});
|
|
41
|
+
return server;
|
|
42
|
+
}
|
|
43
|
+
export async function createWitnoraMcpServerFromRepository(options = {}) {
|
|
44
|
+
const binding = await loadCustomerMcpActionBinding(options);
|
|
45
|
+
return {
|
|
46
|
+
server: createWitnoraMcpServer({ action: binding.action, transport: gatewayTransport(binding, options.fetch ?? fetch) }),
|
|
47
|
+
actionTool: witnoraMcpActionToolName(binding.action.id),
|
|
48
|
+
action: binding.action,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export async function runWitnoraMcpStdioServer(options = {}) {
|
|
52
|
+
const { server } = await createWitnoraMcpServerFromRepository(options);
|
|
53
|
+
await server.connect(new StdioServerTransport());
|
|
54
|
+
}
|
|
55
|
+
export function witnoraMcpActionToolName(actionId) {
|
|
56
|
+
const normalized = actionId.toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "action";
|
|
57
|
+
const candidate = `witnora_${normalized}`;
|
|
58
|
+
if (candidate.length <= 96)
|
|
59
|
+
return candidate;
|
|
60
|
+
const suffix = createHash("sha256").update(actionId).digest("hex").slice(0, 10);
|
|
61
|
+
return `${candidate.slice(0, 85)}_${suffix}`;
|
|
62
|
+
}
|
|
63
|
+
function gatewayTransport(binding, requestFetch) {
|
|
64
|
+
return {
|
|
65
|
+
propose: ({ idempotencyKey, resourceId, status }) => requestJson(requestFetch, `${binding.baseUrl}${binding.action.path}`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
authorization: `Bearer ${binding.actionToken}`,
|
|
69
|
+
"content-type": "application/json",
|
|
70
|
+
"idempotency-key": idempotencyKey,
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({ resourceId, ...(status === undefined ? {} : { status }) }),
|
|
73
|
+
}),
|
|
74
|
+
getAction: (actionId) => requestJson(requestFetch, `${binding.baseUrl}/v1/actions/${encodeURIComponent(actionId)}`, { headers: { authorization: `Bearer ${binding.gatewayToken}` } }),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function requestJson(requestFetch, url, init) {
|
|
78
|
+
const response = await requestFetch(url, { ...init, signal: init.signal ?? AbortSignal.timeout(10_000) });
|
|
79
|
+
const body = await response.json().catch(() => ({}));
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
const message = typeof body.error === "string" ? body.error : `Witnora Gateway returned HTTP ${response.status}.`;
|
|
82
|
+
throw new Error(message.slice(0, 500));
|
|
83
|
+
}
|
|
84
|
+
return body;
|
|
85
|
+
}
|
|
86
|
+
function toolResult(value) {
|
|
87
|
+
return {
|
|
88
|
+
content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
|
|
89
|
+
structuredContent: value,
|
|
90
|
+
};
|
|
91
|
+
}
|
package/dist/onboard.js
CHANGED
|
@@ -311,7 +311,7 @@ export async function runOnboard(options) {
|
|
|
311
311
|
? "Runtime: LOCAL_SANDBOX_READY. This proves only the generated localhost sandbox loop is ready; it does not establish coverage, CURRENT, or a verified customer outcome.\n"
|
|
312
312
|
: `Runtime: RECORDED_ONLY. ${runtimeReadiness.limitations[0]}\n`);
|
|
313
313
|
output(assuranceHarnessReadiness.state === "ACTIVE"
|
|
314
|
-
? `Assurance Harness: ACTIVE. Nora can dispatch authority-ready Replay and no-write Shadow evaluations without manual Workflow IDs, evaluator origins, credentials, or contract digests.${realPathActivation.activations.length ? ` ${realPathActivation.activations.length} exact
|
|
314
|
+
? `Assurance Harness: ACTIVE. Nora can dispatch authority-ready Replay and no-write Shadow evaluations without manual Workflow IDs, evaluator origins, credentials, or contract digests.${realPathActivation.activations.length ? ` ${realPathActivation.activations.length} exact sandbox real-path binding(s) passed read-only preflight.` : ""}\n`
|
|
315
315
|
: `Assurance Harness: WAITING_FOR_CUSTOMER_HARNESS. ${assuranceHarnessReadiness.limitation}\n`);
|
|
316
316
|
if (httpActionSetup?.state === "READY" && httpActionSetup.action) {
|
|
317
317
|
output(`HTTP Action: READY. POST ${managedGateway.baseUrl}${httpActionSetup.action.path}; copy the action-scoped token and request example from .witnora/gateway/HTTP_ACTION.md.\n`);
|
|
@@ -12,7 +12,7 @@ export async function activateRealPathIntegrations(options) {
|
|
|
12
12
|
throw new Error(`Could not load approved real-path integrations (${response.status}).`);
|
|
13
13
|
const body = await boundedJson(response);
|
|
14
14
|
const approved = Array.isArray(body.integrations) ? body.integrations.map(parsePlan).filter((plan) => plan.status === "READY_TO_ACTIVATE" || plan.status === "HARNESS_ACTIVE") : [];
|
|
15
|
-
const plans = approved.filter((plan) => ["STRIPE_REFUND", "SHOPIFY_DISPUTE", "ZENDESK_TICKET", "SALESFORCE_RECORD", "HUBSPOT_CRM_RECORD", "POSTGRES_RECORD"].includes(plan.generated.providerPackId) && plan.environment === "sandbox" && plan.customerSummary.evaluationMode === "SHADOW");
|
|
15
|
+
const plans = approved.filter((plan) => ["STRIPE_REFUND", "SHOPIFY_DISPUTE", "ZENDESK_TICKET", "SALESFORCE_RECORD", "HUBSPOT_CRM_RECORD", "POSTGRES_RECORD", "QUEUE_JOB"].includes(plan.generated.providerPackId) && plan.environment === "sandbox" && plan.customerSummary.evaluationMode === "SHADOW");
|
|
16
16
|
if (!plans.length)
|
|
17
17
|
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [], rollback: async () => undefined };
|
|
18
18
|
const environment = options.env ?? process.env;
|
|
@@ -91,6 +91,8 @@ async function providerPreflight(request, env, plan, now, postgresClientFactory)
|
|
|
91
91
|
}
|
|
92
92
|
if (plan.generated.providerPackId === "SHOPIFY_DISPUTE")
|
|
93
93
|
return shopifyDisputePreflight(request, env, plan, now);
|
|
94
|
+
if (plan.generated.providerPackId === "QUEUE_JOB" && plan.environment === "sandbox")
|
|
95
|
+
return localSandboxFixturePreflight(plan, now, "queue-job", "queue-job-sandbox");
|
|
94
96
|
if (plan.generated.providerPackId === "ZENDESK_TICKET")
|
|
95
97
|
return zendeskPreflight(request, env, plan, now);
|
|
96
98
|
if (plan.generated.providerPackId === "SALESFORCE_RECORD")
|
|
@@ -124,10 +126,13 @@ async function shopifyDisputePreflight(request, env, plan, now) {
|
|
|
124
126
|
return preflightResult(plan, now, "shopify", id, observation);
|
|
125
127
|
}
|
|
126
128
|
function shopifySandboxFixturePreflight(plan, now) {
|
|
127
|
-
|
|
129
|
+
return localSandboxFixturePreflight(plan, now, "sellershield-dispute", "shopify-sandbox");
|
|
130
|
+
}
|
|
131
|
+
function localSandboxFixturePreflight(plan, now, resourcePrefix, scenarioPrefix) {
|
|
132
|
+
const resourceId = `${resourcePrefix}-${sha(plan.taskContractDigestSha256).slice(0, 16)}`;
|
|
128
133
|
const observation = { status: plan.generated.criterion.expected };
|
|
129
134
|
const resultDigest = sha(canonical(observation));
|
|
130
|
-
return { acceptance: { kind: "READ_ONLY_PROVIDER_PREFLIGHT", passedAt: now.toISOString(), productionWrites: 0, observationDigestSha256: resultDigest }, scenario: { id:
|
|
135
|
+
return { acceptance: { kind: "READ_ONLY_PROVIDER_PREFLIGHT", passedAt: now.toISOString(), productionWrites: 0, observationDigestSha256: resultDigest }, scenario: { id: `${scenarioPrefix}:${sha(resourceId).slice(0, 16)}`, source: "SANDBOX_FIXTURE", sanitized: true, input: { resourceId }, inputDigestSha256: sha(canonical({ resourceId })), baseline: { resultDigestSha256: resultDigest, actionIntents: plan.generated.actionPathBindings.map((item) => ({ pathId: item.actionPathId, parametersDigestSha256: sha(resourceId) })) } } };
|
|
131
136
|
}
|
|
132
137
|
async function stripePreflight(request, secret, plan, now) {
|
|
133
138
|
const response = await request("https://api.stripe.com/v1/refunds?limit=1", { headers: { authorization: `Bearer ${secret}` }, redirect: "error", signal: AbortSignal.timeout(5_000) });
|
|
@@ -240,7 +245,7 @@ async function postgresPreflight(env, plan, now, clientFactory) {
|
|
|
240
245
|
}
|
|
241
246
|
async function defaultPostgresClient(connectionString) { const imported = await import("pg"); return new imported.Client({ connectionString, application_name: "witnora-read-only-preflight" }); }
|
|
242
247
|
function generatedProviderHarness(plans) {
|
|
243
|
-
const contracts = plans.map((plan) => ({ taskContractId: plan.taskContractId, providerPackId: plan.generated.providerPackId, providerConfiguration: plan.generated.providerConfiguration ?? {}, credentialHandle: `.witnora/provider-credentials/${plan.id}.secret`, criterion: plan.generated.criterion, actionPathIds: plan.generated.actionPathBindings.map((item) => item.actionPathId), ...(plan.generated.providerPackId === "SHOPIFY_DISPUTE" && plan.environment === "sandbox" && plan.generated.providerConfiguration === undefined ? { sandboxObservation: { [plan.generated.criterion.field]: plan.generated.criterion.expected } } : {}) }));
|
|
248
|
+
const contracts = plans.map((plan) => ({ taskContractId: plan.taskContractId, providerPackId: plan.generated.providerPackId, providerConfiguration: plan.generated.providerConfiguration ?? {}, credentialHandle: `.witnora/provider-credentials/${plan.id}.secret`, criterion: plan.generated.criterion, actionPathIds: plan.generated.actionPathBindings.map((item) => item.actionPathId), ...((plan.generated.providerPackId === "SHOPIFY_DISPUTE" && plan.environment === "sandbox" && plan.generated.providerConfiguration === undefined) || (plan.generated.providerPackId === "QUEUE_JOB" && plan.environment === "sandbox") ? { sandboxObservation: { [plan.generated.criterion.field]: plan.generated.criterion.expected } } : {}) }));
|
|
244
249
|
return `import {createHash} from "node:crypto";
|
|
245
250
|
import {readFile} from "node:fs/promises";
|
|
246
251
|
import {join} from "node:path";
|
|
@@ -258,6 +263,8 @@ export async function checkWitnoraProviderHealth(context){for(const contract of
|
|
|
258
263
|
async function persistProviderCredential(repository, plan, environment) {
|
|
259
264
|
if (plan.generated.providerPackId === "SHOPIFY_DISPUTE" && plan.environment === "sandbox" && plan.generated.providerConfiguration === undefined)
|
|
260
265
|
return;
|
|
266
|
+
if (plan.generated.providerPackId === "QUEUE_JOB" && plan.environment === "sandbox")
|
|
267
|
+
return;
|
|
261
268
|
const name = providerCredentialEnvironmentName(plan.generated.providerPackId);
|
|
262
269
|
const value = environment[name];
|
|
263
270
|
const directory = join(repository, ".witnora", "provider-credentials");
|
package/mcp.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
|
|
3
|
+
export interface WitnoraMcpActionConfig {
|
|
4
|
+
id: string;
|
|
5
|
+
actionPathId: string;
|
|
6
|
+
defaultStatus: string;
|
|
7
|
+
environment: "sandbox";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface WitnoraMcpActionTransport {
|
|
11
|
+
propose(input: {
|
|
12
|
+
idempotencyKey: string;
|
|
13
|
+
resourceId: string;
|
|
14
|
+
status?: string;
|
|
15
|
+
}): Promise<Record<string, unknown>>;
|
|
16
|
+
getAction(actionId: string): Promise<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface WitnoraMcpServerOptions {
|
|
20
|
+
action: WitnoraMcpActionConfig;
|
|
21
|
+
transport: WitnoraMcpActionTransport;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createWitnoraMcpServer(options: WitnoraMcpServerOptions): McpServer;
|
|
25
|
+
|
|
26
|
+
export function createWitnoraMcpServerFromRepository(options?: {
|
|
27
|
+
repository?: string;
|
|
28
|
+
dir?: string;
|
|
29
|
+
fetch?: typeof fetch;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
server: McpServer;
|
|
32
|
+
actionTool: string;
|
|
33
|
+
action: WitnoraMcpActionConfig;
|
|
34
|
+
}>;
|
|
35
|
+
|
|
36
|
+
export function runWitnoraMcpStdioServer(options?: {
|
|
37
|
+
repository?: string;
|
|
38
|
+
dir?: string;
|
|
39
|
+
fetch?: typeof fetch;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
|
|
42
|
+
export function witnoraMcpActionToolName(actionId: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "witnora",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.2",
|
|
4
4
|
"description": "Independent assurance for covered agent action paths across models and frameworks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
},
|
|
37
37
|
"exports": {
|
|
38
38
|
"./cli": "./dist/cli.js",
|
|
39
|
+
"./mcp": {
|
|
40
|
+
"types": "./mcp.d.ts",
|
|
41
|
+
"import": "./dist/mcp.js"
|
|
42
|
+
},
|
|
39
43
|
"./browser-adapter-kit": {
|
|
40
44
|
"types": "./dist/vendor/onegent-runtime/browser-adapter-kit.d.ts",
|
|
41
45
|
"import": "./dist/vendor/onegent-runtime/browser-adapter-kit.js"
|
|
@@ -63,6 +67,7 @@
|
|
|
63
67
|
},
|
|
64
68
|
"files": [
|
|
65
69
|
"dist",
|
|
70
|
+
"mcp.d.ts",
|
|
66
71
|
"README.md",
|
|
67
72
|
"LICENSE",
|
|
68
73
|
"package.json"
|
|
@@ -82,6 +87,8 @@
|
|
|
82
87
|
"vitest": "^4.0.13"
|
|
83
88
|
},
|
|
84
89
|
"optionalDependencies": {
|
|
90
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
91
|
+
"zod": "^4.3.6",
|
|
85
92
|
"pg": "^8.16.3"
|
|
86
93
|
}
|
|
87
94
|
}
|