overseer-mcp 0.1.1 → 0.2.0

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/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { consultExpertInputSchema, handleConsultExpert } from "./tools/consultEx
10
10
  import { getPlanInputSchema, handleGetPlan } from "./tools/getPlan.js";
11
11
  import { handleRequestReview, requestReviewInputSchema } from "./tools/requestReview.js";
12
12
  export function createServer(config) {
13
- const server = new McpServer({ name: "overseer-mcp", version: "0.1.1" });
13
+ const server = new McpServer({ name: "overseer-mcp", version: "0.2.0" });
14
14
  server.registerTool("get_plan", {
15
15
  title: "Get implementation plan",
16
16
  description: "Call before writing any code. Forward the user's request so the expert can produce a surgical plan from real git and disk context.",
@@ -34,16 +34,35 @@ async function interactiveArgs(io, scriptPath) {
34
34
  "",
35
35
  ].join("\n"));
36
36
  const expert = parseExpertAnswer(await ask(rl, "Choose expert", "1"));
37
- const args = ["--print", "--expert", expert, "--name", await ask(rl, "MCP server name", "overseer")];
37
+ const targetAnswer = await ask(rl, "Output format: 1=json (most agents) or 2=codex (TOML)", "1");
38
+ const target = targetAnswer === "2" || targetAnswer === "codex" ? "codex" : "json";
39
+ const args = ["--print", "--expert", expert, "--target", target, "--name", await ask(rl, "MCP server name", "overseer")];
38
40
  args.push("--repo-root", await ask(rl, "Repo root", process.cwd()));
39
41
  const testCommand = await ask(rl, "Validation command, empty to skip");
40
42
  if (testCommand)
41
43
  args.push("--test-command", testCommand);
42
44
  if (expert === "cli") {
43
- args.push("--cli-command", await ask(rl, "CLI command", "codex"));
44
- const cliArgs = await ask(rl, "CLI args as JSON array", '["exec"]');
45
- if (cliArgs)
46
- args.push("--cli-args", cliArgs);
45
+ const cliCommand = await ask(rl, "CLI command", "codex");
46
+ args.push("--cli-command", cliCommand);
47
+ write(io.stdout, [
48
+ "",
49
+ "CLI expert configuration:",
50
+ " The expert will be invoked as: <command> <args...> <prompt-via-stdin-or-arg>",
51
+ " Include any flags like --model, --reasoning-effort, etc. in the args.",
52
+ "",
53
+ " Examples:",
54
+ ' codex: exec --model o3 --reasoning-effort high',
55
+ ' claude: -p (with --cli-prompt-via arg)',
56
+ "",
57
+ ].join("\n"));
58
+ const rawArgs = await ask(rl, "CLI args (space-separated)", cliCommand === "codex" ? "exec --model o3 --reasoning-effort high" : "exec");
59
+ if (rawArgs)
60
+ args.push("--cli-args", rawArgs);
61
+ if (cliCommand === "claude") {
62
+ const promptVia = await ask(rl, "How does the prompt reach the CLI? stdin or arg", "arg");
63
+ if (promptVia === "arg")
64
+ args.push("--cli-prompt-via", "arg");
65
+ }
47
66
  const login = await ask(rl, "Run CLI login now? yes/no", "no");
48
67
  if (login.toLowerCase().startsWith("y"))
49
68
  args.push("--run-login");
@@ -91,7 +110,37 @@ async function runLogin(parsed, io) {
91
110
  });
92
111
  }
93
112
  export async function runInit(argv, io = process, scriptPath) {
94
- const parsed = argv.length > 0 ? parseInitArgs(argv, scriptPath) : await interactiveArgs(io, scriptPath);
113
+ if (argv.length > 0) {
114
+ const parsed = parseInitArgs(argv, scriptPath);
115
+ await runLogin(parsed, io);
116
+ const text = parsed.target === "json" ? buildGenericMcpJson([parsed.profile]) : `${buildCodexToml([parsed.profile])}\n`;
117
+ write(io.stdout, text);
118
+ return;
119
+ }
120
+ // Interactive mode: check if stdin can actually handle interactive input
121
+ const stdin = io.stdin;
122
+ if (!stdin.isTTY) {
123
+ write(io.stderr, [
124
+ "overseer-mcp init: interactive mode requires a terminal (TTY).",
125
+ "",
126
+ "Use flags instead. Add --use-npx to generate portable configs.",
127
+ "",
128
+ " # CLI expert — Codex with o3 + high reasoning:",
129
+ ' npx -y overseer-mcp init --expert cli --cli-command codex --cli-args "exec --model o3 --reasoning-effort high" --target json --print',
130
+ "",
131
+ " # OpenAI expert (GPT-4o):",
132
+ ' npx -y overseer-mcp init --expert openai --model gpt-4o --api-key-env OPENAI_API_KEY --target json --print',
133
+ "",
134
+ " # Anthropic expert (Claude):",
135
+ ' npx -y overseer-mcp init --expert anthropic --model claude-sonnet-4-20250514 --api-key-env ANTHROPIC_API_KEY --target json --print',
136
+ "",
137
+ " # CLI expert — Claude Code:",
138
+ ' npx -y overseer-mcp init --expert cli --cli-command claude --cli-args "-p" --cli-prompt-via arg --target json --print',
139
+ "",
140
+ ].join("\n") + "\n");
141
+ return;
142
+ }
143
+ const parsed = await interactiveArgs(io, scriptPath);
95
144
  await runLogin(parsed, io);
96
145
  const text = parsed.target === "json" ? buildGenericMcpJson([parsed.profile]) : `${buildCodexToml([parsed.profile])}\n`;
97
146
  write(io.stdout, text);
@@ -145,6 +145,12 @@ export function buildGenericMcpJson(profiles) {
145
145
  return `${JSON.stringify({ mcpServers }, null, 2)}\n`;
146
146
  }
147
147
  export function defaultServerCommand(scriptPath = process.argv[1] ?? "dist/index.js") {
148
+ // When installed via npm/npx, prefer `npx -y overseer-mcp` so the config
149
+ // is portable and doesn't hard-code a cache path.
150
+ const isNpx = scriptPath.includes("_npx") || scriptPath.includes("node_modules") || scriptPath.includes(".npm");
151
+ if (isNpx) {
152
+ return { command: "npx", args: ["-y", "overseer-mcp"] };
153
+ }
148
154
  return {
149
155
  command: "node",
150
156
  args: [configPath(path.resolve(scriptPath))],
@@ -160,12 +166,16 @@ export function parseInitArgs(argv, scriptPath) {
160
166
  const flags = readFlagMap(argv);
161
167
  const target = parseTarget(getOne(flags, "target"));
162
168
  const expert = parseExpert(getOne(flags, "expert"));
169
+ const useNpx = flags.has("use-npx");
170
+ const defaultCmd = useNpx
171
+ ? { command: "npx", args: ["-y", "overseer-mcp"] }
172
+ : defaultServerCommand(scriptPath);
163
173
  const server = {
164
- command: getOne(flags, "server-command") ?? defaultServerCommand(scriptPath).command,
174
+ command: getOne(flags, "server-command") ?? defaultCmd.command,
165
175
  args: getMany(flags, "server-arg"),
166
176
  };
167
177
  if (server.args.length === 0) {
168
- server.args = defaultServerCommand(scriptPath).args;
178
+ server.args = defaultCmd.args;
169
179
  }
170
180
  const repoRoot = getOne(flags, "repo-root") ?? process.cwd();
171
181
  const cliArgs = parseList(getOne(flags, "cli-args"));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "overseer-mcp",
3
- "version": "0.1.1",
4
- "description": "An MCP server that lets a cheaper executor agent consult a more capable expert model at the three moments it tends to derail: planning, mid-implementation decisions, and final review. The expert reads ground truth (git + disk), never the executor's summary.",
3
+ "version": "0.2.0",
4
+ "description": "MCP server that lets a cheap executor agent consult a capable expert at three gates: planning, mid-implementation decisions, and final review. Expert receives executor summaries and real evidence, never reads the repo directly.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "overseer-mcp": "dist/index.js"