Skip to content

fix(mcp-server): pass the resolved model to run-harness like scheduled runs - #1191

Merged
aaronjmars merged 1 commit into
mainfrom
fix/mcp-server-model
Oct 7, 2026
Merged

aaronjmars merged 1 commit into
mainfrom
fix/mcp-server-model

Conversation

@aaronjmars

Copy link
Copy Markdown
Collaborator

What changed

The local MCP server (apps/mcp-server) never passed --model to run-harness, so a local run always used the CLI's own default model, even for skills pinned to a model in aeon.yml (for example sc-audit and deploy-uni-hook on claude-opus-5-5). Scheduled runs pass the model, so the two paths disagreed.

The server now picks the model the same way .github/workflows/aeon.yml does:

  1. AEON_MODEL env (the local stand-in for the workflow's model dispatch input, next to the existing AEON_HARNESS; (config default) counts as unset)
  2. the skill's own model: "..." in its aeon.yml entry
  3. the global model: in aeon.yml
  4. claude-sonnet-5-5

And it passes it per harness the way the workflow does:

  • claude: always --model <id>.
  • grok: a claude id, default or empty becomes grok-4.7, and only a grok-* id is passed.
  • codex / pi / vibe / kimi / fx / cursor / hermes: --model is the MODEL_ARG from scripts/resolve-harness.sh, the same script the workflow's "Resolve harness" step runs. It maps the pick to the harness's own id, or leaves it out so the harness's default applies, based on which auth keys are set.

The per-skill aeon.yml reader now follows block-shaped entries and strips comments, a port of scripts/skill_entry.sh (which the workflow and resolve-harness.sh already use), so a block entry's model: or harness: is not missed. The run log line now names the model, and the README documents AEON_MODEL and the order.

How it was verified

  • npm run typecheck and npm run build in apps/mcp-server.
  • No-cost argv test: fake claude, grok and codex binaries first on PATH that save their argv and print a valid result, then tools/call over stdio against the built server with a clean env:
    • aeon-sc-audit (pinned in aeon.yml): claude got --model claude-opus-5-5.
    • aeon-heartbeat (no pin): claude got --model claude-sonnet-5-5.
    • AEON_MODEL=claude-opus-5-5 on heartbeat: --model claude-opus-5-5.
    • AEON_HARNESS=grok on sc-audit: --model grok-4.7; with AEON_MODEL=grok-4.6: --model grok-4.6.
    • AEON_HARNESS=codex, no auth keys: --model openai/gpt-6-luna; with OPENAI_API_KEY: no --model; with that key and AEON_MODEL=openai/gpt-6.1-sol: --model gpt-6.1-sol. All match what resolve-harness.sh gives the workflow.
  • The per-skill model read matched the workflow's skill_entry.sh + sed pipeline for all 89 entries in aeon.yml and a fixture with block entries and trailing comments.

No real (paid) run was done.

…d runs

The local MCP server never sent --model, so every local run used the CLI's
own default model instead of the skill's pin. It now resolves the model with
the workflow's precedence (AEON_MODEL, the skill's model in aeon.yml, the
global model, claude-sonnet-5-5) and passes it per harness the way aeon.yml
does: claude gets the id, grok gets only a grok id (claude ids become
grok-4.7), and the other harnesses get MODEL_ARG from
scripts/resolve-harness.sh.

The per-skill aeon.yml reader now follows block-shaped entries and strips
comments, like scripts/skill_entry.sh, so a block entry's model or harness is
not missed.
@aaronjmars
aaronjmars merged commit b6233ee into main Oct 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant