Skip to content

fix(install): write opencode MCP config in official schema#530

Open
fdcp wants to merge 5 commits into
tirth8205:mainfrom
fdcp:fix/opencode-mcp-schema
Open

fix(install): write opencode MCP config in official schema#530
fdcp wants to merge 5 commits into
tirth8205:mainfrom
fdcp:fix/opencode-mcp-schema

Conversation

@fdcp

@fdcp fdcp commented Jun 4, 2026

Copy link
Copy Markdown

code-review-graph install --platform opencode was writing {repo_root}/.opencode.json with a Cursor-shaped mcpServers payload (command + args + type: stdio). OpenCode's documented schema is different: project config lives in opencode.json / opencode.jsonc, MCP servers go under the mcp key, local servers use type: local with a single array-form command. The previous file was never loaded by OpenCode, so install --platform opencode was effectively a no-op. Issue #388 (closed as fixed by PR #198 in 2026-05, but that PR only added a hook plugin — not the MCP config fix) was reopened in practice.

Changes:

  • PLATFORMS["opencode"]: config_path now resolves opencode.jsonc if it already exists, otherwise opencode.json, otherwise creates opencode.jsonc (matches OpenCode's documented convention); key: mcp; needs_type: false
  • _build_server_entry emits a single dict for OpenCode with array-form command ([command, *args]) and type: local; no separate args / env array. All other platforms unchanged
  • _warn_legacy_opencode_config prints a one-line hint when an old .opencode.json with a code-review-graph entry is still present (no auto-delete — safer than clobbering). The hint now derives the "new config is at …" path from the same _opencode_config_path helper used by config_path, so the message stays consistent with the actual write path
  • _strip_jsonc_comments helper — replaces the previous regex call in install_platform_configs and _warn_legacy_opencode_config. The earlier r'(^|\s)//.*$' regex still ate // sequences inside quoted strings when preceded by whitespace (e.g. "text": "\thello // world"). The new helper is a small stateful scanner that tracks string boundaries, stops at either \r or \n (so CRLF and old-Mac CR-only files are handled), and only strips // outside quoted regions. Found and fixed while adding .jsonc support
  • Tests: existing test_install_opencode_config rewritten for the new schema; new tests cover the legacy-file warning (presence + absence), merge-into-existing behavior for both opencode.json and opencode.jsonc, JSONC comment stripping (string preservation, full-line and inline stripping, CRLF/CR line endings), and _opencode_config_path precedence
  • docs/USAGE.md updated to show opencode.json / opencode.jsonc

Review status (Copilot, 3 rounds): 8 of 10 threads resolved. The 2 remaining are intentionally left open:

  • docs row wording (L33 uses a arrow that could be misread as a migration; the code only does path selection, not migration) — left as-is to keep the diff minimal; happy to refine if the maintainer prefers.
  • Trailing-comma stripping regex at skills.py:416 (re.sub(r',(\s*[}\])])', …)) is pre-existing on main and is string-unaware in the same class as the JSONC-comment bug. Out of scope for this PR; worth a follow-up issue if the maintainer agrees.

Fixes #388.

Copilot AI review requested due to automatic review settings June 4, 2026 09:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates OpenCode platform support to use the newer mcp schema and prefer opencode.jsonc/opencode.json, including merge behavior and a warning for legacy .opencode.json files.

Changes:

  • Switch OpenCode config target from .opencode.json + mcpServers to opencode.jsonc/opencode.json + mcp.
  • Update OpenCode server entry format to type: local and a list-based command.
  • Add a warning when a legacy .opencode.json containing code-review-graph is detected; expand tests/docs accordingly.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
tests/test_skills.py Updates/extends tests to validate new OpenCode config paths, schema, merge behavior, and legacy warning output.
docs/USAGE.md Documents OpenCode config file locations as opencode.json / opencode.jsonc.
code_review_graph/skills.py Implements OpenCode config path selection, new entry format, legacy warning, and adjusts JSONC comment stripping.

Comment thread code_review_graph/skills.py
Comment thread code_review_graph/skills.py Outdated
Comment thread code_review_graph/skills.py Outdated
Comment thread code_review_graph/skills.py
@fdcp fdcp requested a review from Copilot June 4, 2026 10:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread code_review_graph/skills.py
Comment thread code_review_graph/skills.py
Comment thread docs/USAGE.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread docs/USAGE.md
| **Zed** | `.zed/settings.json` |
| **Continue** | `.continue/config.json` |
| **OpenCode** | `.opencode.json` |
| **OpenCode** | `opencode.jsonc` (existing) → `opencode.json` (else create `opencode.jsonc`) |
Comment thread code_review_graph/skills.py
# for editors like Zed that allow non-standard JSON).
stripped = re.sub(r'//.*?$', '', raw, flags=re.MULTILINE)
stripped = _strip_jsonc_comments(raw)
stripped = re.sub(r',(\s*[}\]])', r'\1', stripped)
@fdcp

fdcp commented Jun 4, 2026

Copy link
Copy Markdown
Author

Friendly ping, @tirth8205 👋

Just flagging this is still on the table — issue #388 has 3+ users (PhilYang09, dragonabyss, Dhruv-Garg79) confirming install --platform opencode is broken on v2.3.2 / v2.3.3 / v2.3.5. This PR addresses it directly.

Summary:

  • 3 commits, 1275 tests pass, ruff clean
  • Copilot 3 rounds of review: 8/10 threads resolved, 2 intentionally left open with rationale in the PR body
  • No new external dependencies
  • Backwards-compatible: existing .opencode.json users get a deprecation hint, not a silent overwrite

Happy to iterate on review feedback or split into smaller PRs if that helps. If you're not actively maintaining right now, no worries — at minimum the diff here gives anyone hitting #388 a known-good reference. Just let me know either way so I can stop pinging 🙂

@tirth8205

Copy link
Copy Markdown
Owner

Thanks @fdcp — and apologies for the slow response on this and #388. I applied the branch and verified it end to end: the schema target is right (confirmed against opencode.ai/docs/mcp-servers and the published config.json — opencode.json/.jsonc, top-level "mcp", type "local", array command), the legacy-hint-without-delete call is the right one, and _strip_jsonc_comments is a genuine fix over the old regex. Full suite: 1282 passed; mypy clean.

Two changes to get this merged:

  1. Drop "cwd" from the OpenCode entry. McpLocalConfig in the official schema is additionalProperties: false (only type/command/environment/enabled/timeout), so we'd be writing an out-of-spec key in a spec-compliance PR. Append "--repo", str(repo_root) to the command array instead — serve --repo already feeds _default_repo_root — and assert "cwd" not in entry in test_install_opencode_config.
  2. Fix the new E501 at tests/test_skills.py:913 (103 > 100 chars).

Agreed the trailing-comma regex is out of scope — please file that follow-up issue. Happy to merge once those land.

fdcp and others added 4 commits June 12, 2026 02:50
code-review-graph install --platform opencode wrote
{repo_root}/.opencode.json with a Cursor-shaped mcpServers payload
(command + args + type stdio). OpenCode's documented schema is
different: project config lives in opencode.json, MCP servers go
under the mcp key, local servers use type local and a single
array-form command. The previous file was never loaded by OpenCode.

- config_path -> opencode.json, key -> mcp, needs_type -> False
- _build_server_entry emits McpLocalConfig (array command, type local)
  for opencode and nothing else
- _warn_legacy_opencode_config prints a one-line hint when an old
  .opencode.json with a code-review-graph entry is still present
  (no auto-delete, safer than clobbering)
- test_install_opencode_config asserts the new schema; two new tests
  cover the legacy-file warning (presence + absence)
- docs/USAGE.md updated to reflect the new path

Closes tirth8205#388.
…nt stripping

- _opencode_config_path helper: PLATFORMS["opencode"].config_path and
  _warn_legacy_opencode_config now share one source of truth, so the
  warning's "new config is at ..." no longer disagrees with the actual
  write path (previously the warning said opencode.json while the lambda
  defaulted to opencode.jsonc).

- _strip_jsonc_comments helper: stateful scanner that respects quoted
  strings. The earlier regex r'(^|\s)//.*$' still ate "//" inside
  string values when preceded by whitespace (e.g. "text": "\thello
  // world"), so it is replaced in install_platform_configs and
  _warn_legacy_opencode_config.

- Tests: 3 new in TestJsoncHelpers (string preservation, full-line and
  inline stripping, _opencode_config_path precedence). 1274 passed.
…ync opencode docs

- _strip_jsonc_comments now stops at either "\r" or "\n". The
  previous check (text[i] != "\n") silently consumed the "\r"
  in Windows CRLF line endings and would consume the entire file on
  old-Mac CR-only line endings. Found by Copilot re-review (thread
  on skills.py L286).
- docs/USAGE.md: clarify the opencode config precedence
  (opencode.jsonc existing -> opencode.json existing -> else create
  opencode.jsonc) so the table matches _opencode_config_path.
- Tests: 1 new in TestJsoncHelpers covering both \r\n and \r-only
  line endings. 1275 passed.
McpLocalConfig in opencode's schema is additionalProperties: false
(only type/command/environment/enabled/timeout). Pass --repo to
serve via the command array instead, which feeds _default_repo_root
in main.py. Also fix E501 in test_skills.py:913 (103 > 100 chars).
@fdcp

fdcp commented Jun 12, 2026

Copy link
Copy Markdown
Author

Both changes are pushed (commits rebased onto current main, head b7ec0ef):

  1. cwd removed from the OpenCode entry. --repo <path> is now appended to the command array — serve consumes it via _default_repo_root (cli.py:652 → main.py:1038). Schema-compliant: entry now contains only type and command.
    • Assertion added: assert "cwd" not in entry in test_install_opencode_config.
  2. E501 fixed at tests/test_skills.py:913 by splitting the long line into named locals.

Verification:

  • pytest tests/test_skills.py → 150 passed (was 149)
  • ruff check code_review_graph/skills.py tests/test_skills.py → 3 errors, all pre-existing on main (I001 import sort at L3 + L18, docstring >100 chars at L1472). No new errors introduced by this commit.

Follow-up issue filed per your request: #553 (trailing-comma regex at skills.py:417 doesn't track string boundaries — same bug class as the _strip_jsonc_comments one fixed here).

One thing I can't do from a fork: the CI and PR Review checks are showing as action_required (0 jobs) on head b7ec0ef. That's the fork-PR workflow-approval gate. Could you approve them in the Checks tab? Once they go green, this should be ready to merge.

@fdcp

fdcp commented Jun 12, 2026

Copy link
Copy Markdown
Author

Follow-up: I re-ran the full verification on the rebased head after pushing b7ec0ef (not just the touched file). Results:

  • python -m pytest -q1385 passed, 8 skipped, 2 xpassed (23 warnings)
  • ruff check .49 errors, which matches origin/main exactly (same pre-existing baseline; no new lint introduced by this branch)

So the branch now has:

  • the two requested fixes (drop cwd / add --repo, plus the E501 cleanup)
  • full-suite green on the rebased branch
  • no new repo-wide ruff regressions

Still waiting on the fork-PR workflow approval gate in Checks (CI / PR Review showing action_required). Once those are approved and rerun, this should be merge-ready from my side.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@fdcp

fdcp commented Jun 12, 2026

Copy link
Copy Markdown
Author

Small follow-up pushed on top: 55db06e (fix(tests): clean up pre-existing lint in test_skills). I cleaned the 3 pre-existing ruff findings in the touched file (tests/test_skills.py): 2x I001 import ordering + 1x stale long docstring.

Updated verification:

  • ruff check tests/test_skills.py → clean
  • python -m pytest tests/test_skills.py -q → 150 passed
  • python -m pytest -q → 1385 passed, 8 skipped, 2 xpassed
  • ruff check . baseline is now 46 on this branch vs 49 on origin/main (i.e. this branch removes 3 pre-existing lint issues rather than introducing any)

So the branch now has the requested install/schema fixes plus a small lint cleanup in the touched test file.

@fdcp

fdcp commented Jun 12, 2026

Copy link
Copy Markdown
Author

Quick nudge, @tirth8205: the code side is done on head 55db06e, but the PR is still blocked on the fork-PR workflow gate. Could you hit Approve and run for the CI / PR Review checks in the Checks tab when you get a moment? Once those run, this should be ready to merge from my side.

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.

OpenCode MCP install: use official opencode.json + mcp schema (not .opencode.json / mcpServers)

3 participants