@hmv-labs/agent-runner-mcp 0.0.0-stage → 0.0.1

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 (3) hide show
  1. package/README.md +107 -2
  2. package/build/index.js +89 -0
  3. package/package.json +32 -4
package/README.md CHANGED
@@ -1,3 +1,108 @@
1
- # Temporary Holding Version
1
+ # @hmv-labs/agent-runner-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An MCP server that lets Claude hand worker tasks (a codebase survey, an implementation step, a test run) to an external AI runner, agy or codex, and get back a validated result.
4
+
5
+ The server tries the provider's models strongest first and stops at the first result that passes validation. A result is valid only when:
6
+
7
+ - the runner returned `SUCCESS`, nothing timed out, and no action was denied;
8
+ - the response is not empty;
9
+ - the response starts with a complete dev-agent report envelope (`STATUS`, `SHA`, `REPORT`) whose `SHA` matches the expected commit.
10
+
11
+ - **agy:** Argon, then Claude and GPT, then the other Gemini models, one variant per family at the requested effort. agy returns `SUCCESS` with an empty response when a permission is denied or `--print-timeout` fires, so its status alone is not trusted.
12
+ - **codex:** the models `codex debug models` lists to users, in its priority order, with effort passed as `model_reasoning_effort`. The prompt goes in on stdin, so it has no length limit. The default model from your codex config is never used, because it may not be available to the signed-in account.
13
+
14
+ Validation checks the envelope, not whether the report is right: a fast model can return a valid envelope around wrong citations.
15
+
16
+ ## Requirements
17
+
18
+ - Node.js 22 or later
19
+ - git
20
+ - At least one runner, signed in:
21
+ - agy installed as a native executable on `PATH` (`agy.exe` on Windows). A `.cmd`/`.bat` shim is refused, because cmd.exe cannot pass an arbitrary prompt safely.
22
+ - codex (`npm i -g @openai/codex`, then `codex login`). On Windows npm installs only a `.cmd` shim, so the server runs the package's `codex.js` with node directly instead of going through cmd.exe.
23
+
24
+ The server looks commands up in the absolute directories of `PATH` only, never in the working directory, so a repository under review cannot ship its own `agy.exe` or `git.exe`. `PATH` comes from the MCP client that starts the server. Desktop apps often start with a shorter `PATH` than your shell; if agy is not found, set `PATH` in the server's `env`.
25
+
26
+ ## Setup
27
+
28
+ Claude Code:
29
+
30
+ ```bash
31
+ claude mcp add agent-runner -- npx -y @hmv-labs/agent-runner-mcp
32
+ ```
33
+
34
+ Or in `.mcp.json`:
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "agent-runner": {
40
+ "command": "npx",
41
+ "args": ["-y", "@hmv-labs/agent-runner-mcp"]
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ On Windows, use `"command": "cmd"` with `"args": ["/c", "npx", "-y", "@hmv-labs/agent-runner-mcp"]`, because `npx` itself is a `.cmd` shim.
48
+
49
+ The package is a single bundled file with no runtime dependencies, so `node build/index.js` also works from a copy of the file.
50
+
51
+ ## Tools
52
+
53
+ ### `list_providers`
54
+
55
+ Lists the installed runners, their versions, and each one's models in fallback order.
56
+
57
+ | Argument | Type | Default | Description |
58
+ | --------- | ------- | ------- | --------------------------------------------------- |
59
+ | `refresh` | boolean | `false` | Re-read the model lists instead of the cached ones. |
60
+
61
+ ### `run_task`
62
+
63
+ Runs one worker task, falling back through the model chain until a result is valid.
64
+
65
+ | Argument | Type | Default | Description |
66
+ | ------------- | ------------------------------- | ---------- | ------------------------------------------------------------------------ |
67
+ | `prompt` | string | required | The worker's role prompt plus the handoff. At most 30,000 characters on agy. |
68
+ | `cwd` | string | required | Absolute path inside the git repository to work in. |
69
+ | `mode` | `readonly` \| `write` | required | See below. |
70
+ | `provider` | `agy` \| `codex` | `agy` | The runner to use. |
71
+ | `model` | string | | Pin one of the provider's models from `list_providers`; no fallback. |
72
+ | `effort` | `low` \| `medium` \| `high` | `medium` | agy: each family's variant at this effort; codex: the reasoning effort. |
73
+ | `timeout_sec` | integer, 30–3600 | `900` | Per attempt. |
74
+ | `sha` | string | `HEAD` | `readonly` only: the commit to check out. |
75
+ | `report_path` | string | | Save the valid report to this file and return only the envelope. |
76
+
77
+ **`mode=readonly`** runs agy with `--mode plan --sandbox`, or codex with `--sandbox read-only`, in a throwaway detached worktree at `sha`. The worktree must stay unchanged (any change fails the attempt and is reset) and is always removed. The worker must return `REPORT: inline`. Read-only runs see committed files only.
78
+
79
+ **`mode=write`** runs in `cwd` itself: agy with all tool permissions, codex in its `workspace-write` sandbox (no network by default). Before the run the server records `HEAD` and the content of the whole working tree, untracked files included. If a failed attempt changed any file or made a commit, fallback stops and the result lists `changedFiles`, so the next model never builds on a half-done attempt. Files ignored by `.gitignore` are not tracked.
80
+
81
+ **`report_path`** is resolved against `cwd` and must be a new `.md` file inside the repository and outside `.git` (symlinks are resolved). It is checked before the run and never overwrites an existing file. If the save fails, the report comes back inline with `reportError`.
82
+
83
+ Without `report_path`, the response comes back inline, cut at 20,000 characters; `truncated` says when that happened.
84
+
85
+ ### Result
86
+
87
+ ```jsonc
88
+ {
89
+ "valid": true,
90
+ "model": "claude-opus-5-5-medium",
91
+ "envelope": { "status": "DONE", "sha": "…", "report": "inline", "summary": "…" },
92
+ "response": "…", // or "reportPath" when report_path was given
93
+ "changedFiles": [], // write mode
94
+ "attempts": [
95
+ { "model": "gemini-4-argon-medium", "problems": ["runner status ERROR: quota reached"] },
96
+ { "model": "claude-opus-5-5-medium", "problems": [] }
97
+ ]
98
+ }
99
+ ```
100
+
101
+ An invalid result has `valid: false`, the problems of every attempt, and `stoppedFallback` when write mode stopped early.
102
+
103
+ ## Adding a runner
104
+
105
+ Each CLI is a `Runner` strategy (`src/runner.ts`): it detects the CLI, lists its models, orders them strongest first, and runs one attempt. Worktrees, envelope validation, change detection, and `report_path` stay in `runTask` and apply to every runner.
106
+
107
+ 1. Write `src/<cli>.ts` exporting a `Runner`. Resolve the executable with `command()` or `which()` from `util.ts`, never by bare name, and pass the prompt on stdin when the CLI allows it; otherwise set `maxPrompt`.
108
+ 2. Add it to `RUNNERS` in `src/runners.ts`. The `provider` argument and `list_providers` pick it up from there.