@agentwares/agentguard 0.1.7 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +223 -16
  3. package/dist/audit-5LUDXZLG.js +18 -0
  4. package/dist/audit-5LUDXZLG.js.map +1 -0
  5. package/dist/chunk-2QDPPTPY.js +179 -0
  6. package/dist/chunk-2QDPPTPY.js.map +1 -0
  7. package/dist/chunk-4WTFMFRY.js +1270 -0
  8. package/dist/chunk-4WTFMFRY.js.map +1 -0
  9. package/dist/chunk-5WRI5ZAA.js +31 -0
  10. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  11. package/dist/chunk-DEVXG3IB.js +113 -0
  12. package/dist/chunk-DEVXG3IB.js.map +1 -0
  13. package/dist/chunk-F73VDY3W.js +202 -0
  14. package/dist/chunk-F73VDY3W.js.map +1 -0
  15. package/dist/chunk-IEJK7N3B.js +275 -0
  16. package/dist/chunk-IEJK7N3B.js.map +1 -0
  17. package/dist/chunk-IS3DAHZI.js +1698 -0
  18. package/dist/chunk-IS3DAHZI.js.map +1 -0
  19. package/dist/chunk-JSELR4SG.js +780 -0
  20. package/dist/chunk-JSELR4SG.js.map +1 -0
  21. package/dist/chunk-OM5L7A32.js +199 -0
  22. package/dist/chunk-OM5L7A32.js.map +1 -0
  23. package/dist/chunk-SWZQMPDG.js +206 -0
  24. package/dist/chunk-SWZQMPDG.js.map +1 -0
  25. package/dist/chunk-TJXZBOHL.js +529 -0
  26. package/dist/chunk-TJXZBOHL.js.map +1 -0
  27. package/dist/chunk-XOBFANL4.js +119 -0
  28. package/dist/chunk-XOBFANL4.js.map +1 -0
  29. package/dist/chunk-XPNBYSIN.js +23 -0
  30. package/dist/chunk-XPNBYSIN.js.map +1 -0
  31. package/dist/chunk-YBVD6HTT.js +1036 -0
  32. package/dist/chunk-YBVD6HTT.js.map +1 -0
  33. package/dist/chunk-ZG4LGUJE.js +847 -0
  34. package/dist/chunk-ZG4LGUJE.js.map +1 -0
  35. package/dist/cli.js +10 -4775
  36. package/dist/cli.js.map +1 -1
  37. package/dist/fixtures/crm-server.js +6 -1272
  38. package/dist/fixtures/crm-server.js.map +1 -1
  39. package/dist/fixtures/demo-agent.js +4 -115
  40. package/dist/fixtures/demo-agent.js.map +1 -1
  41. package/dist/index.d.ts +73 -14
  42. package/dist/index.js +247 -5138
  43. package/dist/index.js.map +1 -1
  44. package/dist/init-MKPQU2JG.js +17 -0
  45. package/dist/init-MKPQU2JG.js.map +1 -0
  46. package/dist/proxy-6GP63TLD.js +146 -0
  47. package/dist/proxy-6GP63TLD.js.map +1 -0
  48. package/dist/tools-XS7PMTLT.js +15 -0
  49. package/dist/tools-XS7PMTLT.js.map +1 -0
  50. package/llms.txt +10 -4
  51. package/package.json +16 -4
  52. package/server.json +9 -9
@@ -0,0 +1,17 @@
1
+ import {
2
+ initCommand,
3
+ renderStarterPolicy
4
+ } from "./chunk-IEJK7N3B.js";
5
+ import "./chunk-OM5L7A32.js";
6
+ import "./chunk-DEVXG3IB.js";
7
+ import "./chunk-TJXZBOHL.js";
8
+ import "./chunk-IS3DAHZI.js";
9
+ import "./chunk-2QDPPTPY.js";
10
+ import "./chunk-XPNBYSIN.js";
11
+ import "./chunk-4WTFMFRY.js";
12
+ import "./chunk-5WRI5ZAA.js";
13
+ export {
14
+ initCommand,
15
+ renderStarterPolicy
16
+ };
17
+ //# sourceMappingURL=init-MKPQU2JG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,146 @@
1
+ import {
2
+ INIT_COMMAND,
3
+ createDownstreamServer,
4
+ startHttpProxy
5
+ } from "./chunk-JSELR4SG.js";
6
+ import {
7
+ ProxyRuntime
8
+ } from "./chunk-TJXZBOHL.js";
9
+ import {
10
+ serveStdio
11
+ } from "./chunk-IS3DAHZI.js";
12
+ import "./chunk-XPNBYSIN.js";
13
+ import {
14
+ createFileGuard,
15
+ flagBool,
16
+ flagNumber,
17
+ flagString,
18
+ loadPolicyFor,
19
+ policyPathFrom
20
+ } from "./chunk-4WTFMFRY.js";
21
+ import "./chunk-5WRI5ZAA.js";
22
+
23
+ // src/commands/proxy.ts
24
+ import { existsSync } from "fs";
25
+ import { Guard, defaultPolicy, envTwin, resolveAgent } from "@agentwares/agentguard-core";
26
+ import {
27
+ killSwitchFor,
28
+ resolveLoadedPolicy
29
+ } from "@agentwares/agentguard-core/node";
30
+ function newRunId(now = /* @__PURE__ */ new Date()) {
31
+ return `run_${now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}_${Math.random().toString(36).slice(2, 6)}`;
32
+ }
33
+ function unconfiguredPolicy(args, io) {
34
+ if (flagString(args, "config") !== void 0 || envTwin(io.env, "CONFIG")) return void 0;
35
+ const path = policyPathFrom(args, io);
36
+ if (existsSync(path)) return void 0;
37
+ return resolveLoadedPolicy(defaultPolicy(), path, {});
38
+ }
39
+ async function serveOverStdio(runtime) {
40
+ const server = createDownstreamServer(runtime);
41
+ const stop = async () => {
42
+ await runtime.close();
43
+ };
44
+ process.once("SIGINT", () => void stop().then(() => process.exit(0)));
45
+ process.once("SIGTERM", () => void stop().then(() => process.exit(0)));
46
+ await serveStdio(server);
47
+ await stop();
48
+ return 0;
49
+ }
50
+ async function proxyCommand(args, io) {
51
+ const log = (line) => io.err(`[okgate] ${line}`);
52
+ const modeOverride = flagString(args, "mode");
53
+ const http = flagBool(args, "http") === true;
54
+ const unconfigured = http ? void 0 : unconfiguredPolicy(args, io);
55
+ if (unconfigured) {
56
+ if (modeOverride === "dry-run" || modeOverride === "enforce")
57
+ unconfigured.policy.mode = modeOverride;
58
+ const runtime2 = new ProxyRuntime({
59
+ loaded: unconfigured,
60
+ guard: new Guard({
61
+ policy: unconfigured.policy,
62
+ env: io.env,
63
+ kill: killSwitchFor(unconfigured)
64
+ }),
65
+ configured: false,
66
+ defaultRunId: flagString(args, "run-id") ?? newRunId(),
67
+ log
68
+ });
69
+ await runtime2.start();
70
+ log(
71
+ `no policy file at ${unconfigured.path}: serving okgate's own read-only tools only. To guard your MCP servers, run \`${INIT_COMMAND}\` in the project directory.`
72
+ );
73
+ return serveOverStdio(runtime2);
74
+ }
75
+ const loaded = loadPolicyFor(args, io);
76
+ if (modeOverride === "dry-run" || modeOverride === "enforce") loaded.policy.mode = modeOverride;
77
+ const agentName = flagString(args, "agent");
78
+ let agent = void 0;
79
+ if (agentName) {
80
+ const resolved = await resolveAgent(loaded.policy, { name: agentName });
81
+ if (resolved.error) {
82
+ io.err(
83
+ `unknown agent "${agentName}" \u2014 agents in okgate.yaml: ${loaded.policy.agents.map((a) => a.name).join(", ") || "none"}`
84
+ );
85
+ return 1;
86
+ }
87
+ agent = resolved.agent;
88
+ }
89
+ let approvalBase;
90
+ const fileGuard = createFileGuard(loaded, {
91
+ log,
92
+ env: io.env,
93
+ approvalUrl: (r) => approvalBase ? `${approvalBase.baseUrl}/approve/${r.id}?token=${approvalBase.token}` : void 0,
94
+ onEvent: (e) => {
95
+ if (e.type === "APPROVAL_DECIDED") return;
96
+ log(`${e.type} ${e.tool} (run ${e.runId})${e.error ? `: ${e.error.cause}` : ""}`);
97
+ if (e.type === "APPROVAL_REQUIRED" && e.approval)
98
+ log(`approve with: okgate approve ${e.approval.id}`);
99
+ }
100
+ });
101
+ const runtime = new ProxyRuntime({
102
+ loaded,
103
+ guard: fileGuard.guard,
104
+ agent,
105
+ defaultRunId: flagString(args, "run-id") ?? newRunId(),
106
+ log
107
+ });
108
+ await runtime.start();
109
+ const killed = await fileGuard.kill.check();
110
+ if (killed.killed)
111
+ log(`kill switch is ON (${killed.reason}); every call returns KILLED until \`okgate resume\``);
112
+ if (runtime.upstreamStatus().length === 0)
113
+ log(
114
+ `${loaded.path} lists no upstreams: serving okgate's own read-only tools only. Add servers under \`upstreams:\` to guard them.`
115
+ );
116
+ if (http) {
117
+ const server = await startHttpProxy({
118
+ runtime,
119
+ port: flagNumber(args, "port") ?? 8788,
120
+ host: flagString(args, "host") ?? "127.0.0.1",
121
+ token: envTwin(io.env, "HTTP_TOKEN")
122
+ });
123
+ approvalBase = { baseUrl: server.url.replace(/\/mcp$/, ""), token: server.token };
124
+ log(
125
+ `Streamable HTTP at ${server.url} \xB7 GET ${approvalBase.baseUrl}/health \xB7 control token in ${loaded.stateDir}/http.json`
126
+ );
127
+ log(
128
+ `point your agent at ${server.url} (send X-Run-Id per run; Authorization: Bearer <agent key> for scoped agents)`
129
+ );
130
+ const stop = async () => {
131
+ await server.close();
132
+ await runtime.close();
133
+ process.exit(0);
134
+ };
135
+ process.once("SIGINT", () => void stop());
136
+ process.once("SIGTERM", () => void stop());
137
+ await new Promise(() => void 0);
138
+ }
139
+ return serveOverStdio(runtime);
140
+ }
141
+ export {
142
+ newRunId,
143
+ proxyCommand,
144
+ unconfiguredPolicy
145
+ };
146
+ //# sourceMappingURL=proxy-6GP63TLD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/proxy.ts"],"sourcesContent":["/**\n * `okgate proxy` — stdio by default (what MCP clients spawn), `--http` for Streamable HTTP\n * with the control endpoints. Logs go to stderr only; stdout is the MCP channel.\n */\nimport { existsSync } from \"node:fs\";\nimport { serveStdio } from \"@agentwares/mcp-kit\";\nimport { Guard, defaultPolicy, envTwin, resolveAgent } from \"@agentwares/agentguard-core\";\nimport {\n killSwitchFor,\n resolveLoadedPolicy,\n type LoadedPolicy,\n} from \"@agentwares/agentguard-core/node\";\nimport { flagBool, flagNumber, flagString, type ParsedArgs } from \"../args.js\";\nimport { createFileGuard, loadPolicyFor, policyPathFrom, type Io } from \"../context.js\";\nimport { startHttpProxy } from \"../proxy/http.js\";\nimport { INIT_COMMAND } from \"../proxy/own-tools.js\";\nimport { ProxyRuntime } from \"../proxy/runtime.js\";\nimport { createDownstreamServer } from \"../proxy/server.js\";\n\nexport function newRunId(now: Date = new Date()): string {\n return `run_${now\n .toISOString()\n .replace(/[-:.TZ]/g, \"\")\n .slice(0, 14)}_${Math.random().toString(36).slice(2, 6)}`;\n}\n\n/**\n * The policy okgate runs on when no `okgate.yaml` exists and none was named: the\n * defaults, no upstreams, paths resolved where the file would be. It is what an install button\n * or a registry install starts before `init` has run. Nothing is written for it: the guard built\n * on it keeps counters, audit and approvals in memory, so the proxy leaves no `.okgate/` in\n * whatever directory the client spawned it in.\n *\n * `undefined` when a policy file exists, or when one was named with `--config` or\n * `OKGATE_CONFIG` / `AGENTGUARD_CONFIG` — a named file that is missing is still an error.\n */\nexport function unconfiguredPolicy(args: ParsedArgs, io: Io): LoadedPolicy | undefined {\n if (flagString(args, \"config\") !== undefined || envTwin(io.env, \"CONFIG\")) return undefined;\n const path = policyPathFrom(args, io);\n if (existsSync(path)) return undefined;\n return resolveLoadedPolicy(defaultPolicy(), path, {});\n}\n\nasync function serveOverStdio(runtime: ProxyRuntime): Promise<number> {\n const server = createDownstreamServer(runtime);\n const stop = async (): Promise<void> => {\n await runtime.close();\n };\n process.once(\"SIGINT\", () => void stop().then(() => process.exit(0)));\n process.once(\"SIGTERM\", () => void stop().then(() => process.exit(0)));\n await serveStdio(server);\n await stop();\n return 0;\n}\n\nexport async function proxyCommand(args: ParsedArgs, io: Io): Promise<number> {\n const log = (line: string): void => io.err(`[okgate] ${line}`);\n const modeOverride = flagString(args, \"mode\");\n const http = flagBool(args, \"http\") === true;\n\n // No policy file and none named: serve okgate's own read-only tools over stdio rather than\n // exit, so a client that installed it from a button or a registry gets a working server that\n // says how to set it up. `--http` still needs a policy (it writes its control token beside it).\n const unconfigured = http ? undefined : unconfiguredPolicy(args, io);\n if (unconfigured) {\n if (modeOverride === \"dry-run\" || modeOverride === \"enforce\")\n unconfigured.policy.mode = modeOverride;\n const runtime = new ProxyRuntime({\n loaded: unconfigured,\n guard: new Guard({\n policy: unconfigured.policy,\n env: io.env,\n kill: killSwitchFor(unconfigured),\n }),\n configured: false,\n defaultRunId: flagString(args, \"run-id\") ?? newRunId(),\n log,\n });\n await runtime.start();\n log(\n `no policy file at ${unconfigured.path}: serving okgate's own read-only tools only. To guard your MCP servers, run \\`${INIT_COMMAND}\\` in the project directory.`,\n );\n return serveOverStdio(runtime);\n }\n\n const loaded = loadPolicyFor(args, io);\n if (modeOverride === \"dry-run\" || modeOverride === \"enforce\") loaded.policy.mode = modeOverride;\n\n const agentName = flagString(args, \"agent\");\n let agent = undefined;\n if (agentName) {\n const resolved = await resolveAgent(loaded.policy, { name: agentName });\n if (resolved.error) {\n io.err(\n `unknown agent \"${agentName}\" — agents in okgate.yaml: ${loaded.policy.agents.map((a) => a.name).join(\", \") || \"none\"}`,\n );\n return 1;\n }\n agent = resolved.agent;\n }\n\n let approvalBase: { baseUrl: string; token: string } | undefined;\n const fileGuard = createFileGuard(loaded, {\n log,\n env: io.env,\n approvalUrl: (r) =>\n approvalBase\n ? `${approvalBase.baseUrl}/approve/${r.id}?token=${approvalBase.token}`\n : undefined,\n onEvent: (e) => {\n if (e.type === \"APPROVAL_DECIDED\") return;\n log(`${e.type} ${e.tool} (run ${e.runId})${e.error ? `: ${e.error.cause}` : \"\"}`);\n if (e.type === \"APPROVAL_REQUIRED\" && e.approval)\n log(`approve with: okgate approve ${e.approval.id}`);\n },\n });\n const runtime = new ProxyRuntime({\n loaded,\n guard: fileGuard.guard,\n agent,\n defaultRunId: flagString(args, \"run-id\") ?? newRunId(),\n log,\n });\n await runtime.start();\n const killed = await fileGuard.kill.check();\n if (killed.killed)\n log(`kill switch is ON (${killed.reason}); every call returns KILLED until \\`okgate resume\\``);\n if (runtime.upstreamStatus().length === 0)\n log(\n `${loaded.path} lists no upstreams: serving okgate's own read-only tools only. Add servers under \\`upstreams:\\` to guard them.`,\n );\n\n if (http) {\n const server = await startHttpProxy({\n runtime,\n port: flagNumber(args, \"port\") ?? 8788,\n host: flagString(args, \"host\") ?? \"127.0.0.1\",\n token: envTwin(io.env, \"HTTP_TOKEN\"),\n });\n approvalBase = { baseUrl: server.url.replace(/\\/mcp$/, \"\"), token: server.token };\n log(\n `Streamable HTTP at ${server.url} · GET ${approvalBase.baseUrl}/health · control token in ${loaded.stateDir}/http.json`,\n );\n log(\n `point your agent at ${server.url} (send X-Run-Id per run; Authorization: Bearer <agent key> for scoped agents)`,\n );\n const stop = async (): Promise<void> => {\n await server.close();\n await runtime.close();\n process.exit(0);\n };\n process.once(\"SIGINT\", () => void stop());\n process.once(\"SIGTERM\", () => void stop());\n await new Promise<never>(() => undefined);\n }\n\n return serveOverStdio(runtime);\n}\n"],"mappings":"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","names":["runtime"]}
@@ -0,0 +1,15 @@
1
+ import {
2
+ formatToolTable,
3
+ probeUpstreams,
4
+ toolsCommand
5
+ } from "./chunk-DEVXG3IB.js";
6
+ import "./chunk-TJXZBOHL.js";
7
+ import "./chunk-IS3DAHZI.js";
8
+ import "./chunk-4WTFMFRY.js";
9
+ import "./chunk-5WRI5ZAA.js";
10
+ export {
11
+ formatToolTable,
12
+ probeUpstreams,
13
+ toolsCommand
14
+ };
15
+ //# sourceMappingURL=tools-XS7PMTLT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/llms.txt CHANGED
@@ -1,10 +1,16 @@
1
- # agentguard
1
+ # okgate
2
2
 
3
- > MCP policy proxy for AI agents: hard spend limits, destructive-action gating with approvals, kill switch, scoped agent keys, dry-run writes with mutation diffs, semantic loop breaker, blast-radius caps, hash-chained audit log. CLI `npx @agentwares/agentguard`; SDK `@agentwares/agentguard-sdk`. No LLM calls, no phone-home, no account.
3
+ > Nothing irreversible without an OK. okgate (formerly agentguard) is an MCP policy proxy and coding-agent hook: hard spend limits, destructive-action gating with approvals, kill switch, scoped agent keys, dry-run writes with mutation diffs, semantic loop breaker, blast-radius caps, hash-chained audit log. CLI `npx -p @agentwares/agentguard okgate`; SDK `@agentwares/agentguard-sdk`. No LLM calls, no phone-home, no account.
4
4
 
5
- Set up: `npx -y @agentwares/agentguard init` in the project directory writes agentguard.yaml (dry-run) and routes the project's MCP servers through the proxy. The same command ships as a Claude Code plugin (`/plugin marketplace add agentwares/agentguard`, then `/plugin install agentguard@agentwares`) and a Gemini CLI extension (`gemini extensions install https://github.com/agentwares/agentguard`).
5
+ Set up: `npx -y -p @agentwares/agentguard okgate init` in the project directory writes okgate.yaml (dry-run) and routes the project's MCP servers through the proxy. The same command ships as a Claude Code plugin (`/plugin marketplace add agentwares/agentguard`, then `/plugin install agentguard@agentwares`) and a Gemini CLI extension (`gemini extensions install https://github.com/agentwares/agentguard`).
6
6
 
7
- Started with no agentguard.yaml (an editor install button, a registry install, the repo's Dockerfile), the proxy fronts no servers and serves three read-only tools of its own: `agentguard_get_status` (what it guards, caps used and remaining, kill switch, pending approvals), `agentguard_get_report` (what a run did, or would have done in dry-run) and `agentguard_verify_audit_log` (the hash chain). With upstreams configured, the agent sees only the upstreams' tools.
7
+ Started with no okgate.yaml (an editor install button, a registry install, the repo's Dockerfile), the proxy fronts no servers and serves three read-only tools of its own: `okgate_get_status` (what it guards, caps used and remaining, kill switch, pending approvals), `okgate_get_report` (what a run did, or would have done in dry-run) and `okgate_verify_audit_log` (the hash chain). The agentguard_* names they had before the rename still work until 2027-01-15. With upstreams configured, the agent sees only the upstreams' tools.
8
+
9
+ Renamed from agentguard on 8 Oct 2026: agentguard.yaml, an existing .agentguard/ directory, AGENTGUARD_* variables, the `agentguard` bin and the agentguard_* tool names keep working; npm serves the `okgate` bin from @agentwares/agentguard until @agentwares/okgate is published.
10
+
11
+ Hook mode: `npx -y -p @agentwares/agentguard okgate hooks install` (add `--client codex`, `--client gemini` or `--client all`) writes a pre-execution hook (Claude Code PreToolUse, Codex PreToolUse, Gemini CLI BeforeTool) that checks the coding agent's own shell commands, file edits and MCP calls against the same okgate.yaml. Irreversible commands (git push, merges, tag deletion, rm outside the workspace, package publish, sending mail or messages, edits to the guard itself) run only on a recent turn a person typed that names the action; in Claude Code that is read from the session transcript, and text the model writes never counts. Otherwise the agent gets APPROVAL_REQUIRED with an id, and `npx -p @agentwares/agentguard okgate approve <id>` lets the identical command run once. Dry-run (log only) until `hooks.mode: enforce`.
12
+
13
+ Audit: `npx -y -p @agentwares/agentguard okgate audit [--since 7d|30d|all] [--json]` reads the repository's CLAUDE.md, AGENTS.md, GEMINI.md and .cursor/rules (and `audit.rules` in okgate.yaml) and this machine's Claude Code and Codex sessions in it, and reports per rule how many sessions broke it and when. Rules are recognised by a pattern library with no LLM (never push to main, never force-push, never --no-verify, run X before pushing, use pnpm not npm, do not edit or commit a path, no new dependencies without asking, never rm outside the repo, never publish, never deploy, never run a named command), or stated with an inline `<!-- okgate: <check> -->` (`<!-- agentguard: … -->` still works). It runs locally and sends nothing; `--json` carries counts, rule ids and dates only. `--enforce` writes the checkable rules into okgate.yaml as hook-mode rules in dry-run and installs the hook. The plugin's `/agentguard:audit` has your own agent judge the rules no script can check.
8
14
 
9
15
  ## Links
10
16
 
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@agentwares/agentguard",
3
- "version": "0.1.7",
4
- "description": "MCP policy proxy for AI agents: hard spend limits, destructive-action gating with approvals, a kill switch, scoped credentials, dry-run writes with mutation diffs, loop breaker, blast-radius caps and a hash-chained audit log. No LLM calls, no phone-home, no account.",
3
+ "version": "0.1.10",
4
+ "description": "okgate (formerly agentguard): nothing irreversible without an OK. MCP policy proxy for AI agents: hard spend limits, destructive-action gating with approvals, a kill switch, scoped credentials, dry-run writes with mutation diffs, loop breaker, blast-radius caps and a hash-chained audit log. Hook mode applies the same policy to Claude Code, Codex and Gemini CLI shell commands and file edits, and runs irreversible commands only on a turn a person typed. Audit mode reports which CLAUDE.md / AGENTS.md rules your coding agents broke, from your own sessions, locally. No LLM calls, no phone-home, no account. Runs as `okgate`; the `agentguard` bin, agentguard.yaml, .agentguard/ and AGENTGUARD_* keep working.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
+ "okgate": "./dist/cli.js",
8
9
  "agentguard": "./dist/cli.js"
9
10
  },
10
11
  "main": "./dist/index.js",
@@ -13,6 +14,9 @@
13
14
  ".": {
14
15
  "types": "./dist/index.d.ts",
15
16
  "import": "./dist/index.js"
17
+ },
18
+ "./cli": {
19
+ "import": "./dist/cli.js"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -25,7 +29,7 @@
25
29
  "publishConfig": {
26
30
  "access": "public"
27
31
  },
28
- "mcpName": "io.github.agentwares/agentguard",
32
+ "mcpName": "io.github.agentwares/okgate",
29
33
  "repository": {
30
34
  "type": "git",
31
35
  "url": "git+https://github.com/agentwares/agentguard.git",
@@ -33,6 +37,8 @@
33
37
  },
34
38
  "homepage": "https://github.com/agentwares/agentguard#readme",
35
39
  "keywords": [
40
+ "okgate",
41
+ "agentguard",
36
42
  "mcp",
37
43
  "mcp-proxy",
38
44
  "model-context-protocol",
@@ -43,6 +49,12 @@
43
49
  "dry-run",
44
50
  "audit-log",
45
51
  "claude-code",
52
+ "claude-code-hooks",
53
+ "claude-md",
54
+ "agents-md",
55
+ "codex",
56
+ "gemini-cli",
57
+ "coding-agents",
46
58
  "cursor",
47
59
  "guardrails",
48
60
  "mcp-server",
@@ -62,7 +74,7 @@
62
74
  "conformance": "node scripts/conformance.mjs"
63
75
  },
64
76
  "dependencies": {
65
- "@agentwares/agentguard-core": "^0.1.3",
77
+ "@agentwares/agentguard-core": "^0.1.6",
66
78
  "@modelcontextprotocol/sdk": "^1.30.0",
67
79
  "yaml": "^2.9.0",
68
80
  "zod": "^4.5.4"
package/server.json CHANGED
@@ -1,35 +1,35 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
- "name": "io.github.agentwares/agentguard",
4
- "description": "MCP policy proxy: spend caps, approvals for destructive tools, kill switch, dry-run, audit log.",
5
- "version": "0.1.7",
3
+ "name": "io.github.agentwares/okgate",
4
+ "description": "Nothing irreversible without an OK: MCP policy proxy with spend caps, approvals, kill switch.",
5
+ "version": "0.1.10",
6
6
  "repository": {
7
7
  "url": "https://github.com/agentwares/agentguard",
8
8
  "source": "github",
9
9
  "subfolder": "apps/agentguard-cli"
10
10
  },
11
- "title": "agentguard",
11
+ "title": "okgate",
12
12
  "websiteUrl": "https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli",
13
13
  "packages": [
14
14
  {
15
15
  "registryType": "npm",
16
16
  "registryBaseUrl": "https://registry.npmjs.org",
17
17
  "identifier": "@agentwares/agentguard",
18
- "version": "0.1.7",
18
+ "version": "0.1.10",
19
19
  "runtimeHint": "npx",
20
20
  "transport": {
21
21
  "type": "stdio"
22
22
  },
23
23
  "environmentVariables": [
24
24
  {
25
- "name": "AGENTGUARD_CONFIG",
26
- "description": "Path to agentguard.yaml (default ./agentguard.yaml). If unset and that file does not exist, agentguard serves only its own read-only tools: agentguard_get_status, agentguard_get_report, agentguard_verify_audit_log",
25
+ "name": "OKGATE_CONFIG",
26
+ "description": "Path to okgate.yaml (default ./okgate.yaml, else ./agentguard.yaml; AGENTGUARD_CONFIG also works). With neither file, okgate serves only its own read-only tools: okgate_get_status, okgate_get_report, okgate_verify_audit_log",
27
27
  "isRequired": false,
28
28
  "format": "filepath"
29
29
  },
30
30
  {
31
- "name": "AGENTGUARD_KILL",
32
- "description": "Set to 1 to halt every tool call (kill switch)",
31
+ "name": "OKGATE_KILL",
32
+ "description": "Set to 1 to halt every tool call (kill switch); AGENTGUARD_KILL=1 does the same",
33
33
  "isRequired": false
34
34
  }
35
35
  ]