Skip to content

Expose yul as an MCP server for cross-agent support (Gemini CLI, Codex, etc.) #8

Description

@algomaster99

Problem

Today yul only integrates with Claude Code via a PreToolUse hook (runHook() in main.go, wired through .claude/settings.json). That hook shape is Claude Code-specific and doesn't carry over to other coding agents:

  • Codex's PreToolUse equivalent only fires on Bash, not on Write/Edit — so the same hook-adapter approach doesn't work there at all.
  • Gemini CLI has no equivalent hook mechanism yul could plug into today.

The actual checking logic (newCheckers/checkerFor in main.go, and each ecosystem's checker.Check) is agent-agnostic — it just takes manifest content and returns mismatches. Only the hook plumbing is Claude Code-specific.

Proposal

Add an MCP server mode to yul, built on github.com/modelcontextprotocol/go-sdk, exposing two tools:

  1. check_dependencies(file_path, content) — thin wrapper around the existing dispatch: resolve the checker via checkerFor(newCheckers(res), file_path) and call checker.Check(before, content), reading before from disk the same way runHook does today. Returns the same mismatch list the hook already produces.
  2. scan_dependencies() — wraps the repo-wide scan added in yul init: scan repo for outdated pinned dependencies across all manifests #7 (yul init's walk + Check("", fileContent) logic), so an agent can proactively audit a repo instead of only reacting to a single file.

This lets Claude Code, Gemini CLI, and Codex all call yul as a normal MCP tool instead of needing a bespoke hook adapter per agent — sidestepping the Codex Bash-only hook limitation entirely, since MCP tool calls aren't gated by which built-in tool triggered them.

The existing Claude Code PreToolUse hook stays exactly as-is (runHook(), .claude/settings.json wiring); the MCP server is a new, additive entry point, not a replacement.

Acceptance criteria

  • New subcommand/mode (e.g. yul mcp) starts an MCP server over stdio using github.com/modelcontextprotocol/go-sdk.
  • check_dependencies(file_path, content) tool implemented, delegating to the existing checkerFor + checker.Check path with no duplicated logic; returns mismatches (name/namespace, current, latest) as structured tool output.
  • scan_dependencies() tool implemented, delegating to the repo-scan logic from yul init: scan repo for outdated pinned dependencies across all manifests #7 rather than reimplementing the walk.
  • Unknown/unsupported file paths return an empty result (or a clear "not a supported manifest" response), not an error — consistent with the hook's checkerFor == nil → no-op behavior.
  • Resolver/network failures are surfaced as tool errors rather than crashing the server (mirrors the hook's fail-open comments, adapted to MCP's error-reporting shape).
  • go.mod updated with the modelcontextprotocol/go-sdk dependency.
  • README documents how to register yul as an MCP server in Claude Code, Gemini CLI, and Codex config, alongside the existing hook instructions.
  • Existing .claude/settings.json PreToolUse hook and runHook() are unmodified and continue to work exactly as before.
  • Test/example confirming both tools return correct results for at least one manifest kind (e.g. package.json with an outdated pin).

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions