@minhpnq1807/contextos 0.1.8 → 0.1.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.9
4
+
5
+ - Proxies all configured MCP servers except ContextOS' own `ctx-mcp` server.
6
+ - Preserves each original MCP command after the proxy separator and forwards it unchanged, including RTK-managed commands.
7
+
3
8
  ## 0.1.8
4
9
 
5
10
  - Limits automatic MCP telemetry wrapping to `code-review-graph` only.
package/README.md CHANGED
@@ -105,7 +105,7 @@ node bin/ctx.js install
105
105
  3. Downloads and caches the required local MiniLM embedding model under `~/.ctx/contextos/models`.
106
106
  4. Warms `~/.ctx/contextos/embeddings.db` for AGENTS rules and project file paths.
107
107
  5. Registers the `ctx-mcp` MCP server and merges ContextOS global hooks into `$CODEX_HOME/hooks.json`.
108
- 6. Wraps supported local MCP servers, currently `code-review-graph` and `agentmemory`, with a transparent telemetry proxy so `tools/call` events can be measured.
108
+ 6. Wraps configured local MCP servers, except ContextOS' own `ctx-mcp`, with a transparent telemetry proxy so `tools/call` events can be measured. The original MCP command is preserved after the proxy separator and executed unchanged.
109
109
 
110
110
  Restart Codex after installing.
111
111
 
@@ -290,7 +290,7 @@ unknown = the rule was relevant, but the diff does not prove either way
290
290
 
291
291
  For runtime-only rules, ContextOS also checks `telemetry.jsonl` for hook-visible tool names, MCP server names, and command metadata. A rule like "use code-review-graph before reading files" can be marked `followed` when telemetry contains a matching `code-review-graph` signal.
292
292
 
293
- `ctx install` wraps supported stdio MCP servers with a transparent proxy. The proxy forwards MCP JSON-RPC unchanged, but records `tools/call` requests such as `code-review-graph.detect_changes_tool` to workspace telemetry. This is what lets ContextOS prove runtime rules that cannot be seen in git diff.
293
+ `ctx install` wraps configured stdio MCP servers with a transparent proxy. Codex will show `node .../proxy.js` as the launched command because that is how stdio can be intercepted, but the original MCP command is kept after `--` and executed unchanged, including RTK-managed commands. The proxy forwards MCP JSON-RPC unchanged and records `tools/call` requests such as `code-review-graph.detect_changes_tool` to workspace telemetry.
294
294
 
295
295
  Host/session setup rules such as "run shell commands as user X", `sudo su - user`, `sudo -i -u user`, and `sudo -u user` are filtered before scoring. They are not injected and do not count toward `unknown` outcomes because they describe the agent runtime environment rather than project behavior.
296
296
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhpnq1807/contextos",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Task-aware AGENTS.md context injection and compliance reporting for Codex.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,22 +1,22 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
 
4
- const DEFAULT_TARGETS = new Set(["code-review-graph"]);
4
+ const DEFAULT_EXCLUDES = new Set(["ctx-mcp"]);
5
5
 
6
- export function installMcpTelemetryProxies({ codexHome, marketplaceRoot, targets = DEFAULT_TARGETS } = {}) {
6
+ export function installMcpTelemetryProxies({ codexHome, marketplaceRoot, targets = null, excludes = DEFAULT_EXCLUDES } = {}) {
7
7
  const configPath = path.join(codexHome, "config.toml");
8
8
  if (!fs.existsSync(configPath)) return { wrapped: [], skipped: [], configPath };
9
9
 
10
10
  const original = fs.readFileSync(configPath, "utf8");
11
11
  const proxyPath = path.join(marketplaceRoot, "plugins", "ctx", "mcp", "proxy.js");
12
- const result = rewriteMcpTelemetryProxies(original, { proxyPath, targets });
12
+ const result = rewriteMcpTelemetryProxies(original, { proxyPath, targets, excludes });
13
13
  if (result.content !== original) {
14
14
  fs.writeFileSync(configPath, result.content, "utf8");
15
15
  }
16
16
  return { ...result, configPath };
17
17
  }
18
18
 
19
- export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = DEFAULT_TARGETS } = {}) {
19
+ export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = null, excludes = DEFAULT_EXCLUDES } = {}) {
20
20
  const lines = String(toml || "").split(/\r?\n/);
21
21
  const sections = findMcpServerSections(lines);
22
22
  const wrapped = [];
@@ -26,8 +26,9 @@ export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = DEFAULT_
26
26
  const body = lines.slice(section.start + 1, section.end);
27
27
  const command = findStringValue(body, "command");
28
28
  const args = findArrayValue(body, "args") || [];
29
+ const shouldProxy = shouldProxyServer(section.name, { targets, excludes });
29
30
 
30
- if (command === "node" && args[0] === proxyPath && !targets.has(section.name)) {
31
+ if (command === "node" && args[0] === proxyPath && !shouldProxy) {
31
32
  const original = unwrapProxyArgs(args);
32
33
  if (original) {
33
34
  const nextBody = replaceOrInsertServerField(
@@ -41,7 +42,7 @@ export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = DEFAULT_
41
42
  }
42
43
  }
43
44
 
44
- if (!targets.has(section.name)) {
45
+ if (!shouldProxy) {
45
46
  skipped.push({ name: section.name, reason: "not-targeted" });
46
47
  continue;
47
48
  }
@@ -54,10 +55,6 @@ export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = DEFAULT_
54
55
  skipped.push({ name: section.name, reason: "already-wrapped" });
55
56
  continue;
56
57
  }
57
- if (command === "rtk") {
58
- skipped.push({ name: section.name, reason: "rtk-managed" });
59
- continue;
60
- }
61
58
 
62
59
  const nextBody = replaceOrInsertServerField(
63
60
  replaceOrInsertServerField(body, "command", tomlString("node")),
@@ -71,6 +68,12 @@ export function rewriteMcpTelemetryProxies(toml, { proxyPath, targets = DEFAULT_
71
68
  return { content: lines.join("\n"), wrapped: wrapped.reverse(), skipped: skipped.reverse() };
72
69
  }
73
70
 
71
+ function shouldProxyServer(name, { targets, excludes }) {
72
+ if (targets instanceof Set) return targets.has(name);
73
+ if (Array.isArray(targets)) return targets.includes(name);
74
+ return !(excludes || DEFAULT_EXCLUDES).has(name);
75
+ }
76
+
74
77
  function unwrapProxyArgs(args) {
75
78
  const separator = args.indexOf("--");
76
79
  if (separator < 0 || separator >= args.length - 1) return null;