Skip to main content
Glama

solhint-mcp

Lint and autofix Solidity smart contracts with Solhint, from any MCP client — Claude Code, OpenAI Codex, Cursor, Windsurf, Claude Desktop, and anything else that speaks the protocol. Nothing in it is specific to one vendor.

Your agent gets seven tools: lint_solidity, lint_file, lint_project, fix_solidity, fix_file, explain_rule and get_config.

Solhint's CLI points users at this package — protofire/solhint#801, shipped in Solhint 6.2.5.

Installation

Add this to your MCP client's configuration, with the Solidity project as the working directory:

{
  "mcpServers": {
    "solhint": {
      "command": "npx",
      "args": ["-y", "solhint-mcp"]
    }
  }
}

Requires Node.js 20 or newer. On native Windows, clients that launch servers through npx generally need "command": "cmd" with "args": ["/c", "npx", "-y", "solhint-mcp"].

One server process lints one project: its working directory is the project root, so start another process for a different project. A Solhint installed in that project takes precedence over the copy bundled here.

The server calls Solhint through its JavaScript API. It does not start a shell, invoke npx solhint, make update checks, or parse CLI output.

Client-specific shortcuts

Claude Code — from the Solidity project directory:

claude mcp add solhint -- npx -y solhint-mcp

The default local scope associates the server with the current project. Use --scope project before -- if the configuration should be committed in .mcp.json. On native Windows, Claude Code requires cmd /c:

claude mcp add solhint -- cmd /c npx -y solhint-mcp

OpenAI Codex — Codex uses TOML, not the JSON block above, and shares one configuration across the Codex CLI, the ChatGPT desktop app and the IDE extension. From the Solidity project directory:

codex mcp add solhint -- npx -y solhint-mcp

Or add it by hand to ~/.codex/config.toml, or to .codex/config.toml to scope it to one project:

[mcp_servers.solhint]
command = "npx"
args = ["-y", "solhint-mcp"]

Cursor / Windsurf — add the JSON block above to the editor's MCP settings.

Claude Desktop — installation is separate from Claude Code. This package is a stdio npm server, not a packaged Desktop Extension (.mcpb). Configure it as a local development MCP server only if the client launches it with the Solidity project as its working directory. See Anthropic's current local-server instructions.

Related MCP server: glintefy

Tools

Tool

Input

Description

lint_solidity

{ code, config? }

Lint a Solidity source string

lint_file

{ filePath }

Lint one .sol file inside the project

lint_project

{ pattern? }

Lint a project-relative glob

fix_solidity

{ code, config? }

Autofix a Solidity source string

fix_file

{ filePath, write? }

Autofix one .sol file

explain_rule

{ ruleId }

Explain any rule the linter ships

get_config

{}

Show the project's Solhint config

lint_project autodetects contracts/**/*.sol, then src/**/*.sol, and finally **/*.sol. Paths and patterns outside the project root are rejected.

The fix_* tools apply Solhint's own autofixes and then re-lint, so what they report as remaining is what is genuinely left rather than the pre-fix report. fix_solidity returns the corrected source and touches nothing on disk. fix_file previews by default and only writes when called with write: true — Solhint's CLI asks for a backup before --fix, and an MCP client should not rewrite someone's contracts without being asked either.

explain_rule reads the documentation Solhint ships with each rule, so it covers the whole registry and always describes the version this project runs: description, category, default severity, configurable options, notes and the good/bad examples when the rule defines them.

If your repository already documents a lint command

An agent follows an explicit instruction in your repository over a tool description. If AGENTS.md, CLAUDE.md, .cursorrules or a similar agent playbook says how to lint, for example:

- Solidity lint: `npm run lint:sol`

the agent will run that command and never reach for these tools. That is reasonable behaviour, not a misconfiguration, but it means the server goes unused until you say it is there. Mention it alongside the command:

- Solidity lint: prefer the `solhint` MCP tools (`lint_file`, `lint_project`,
  `fix_file`, `explain_rule`, `get_config`) when that server is configured; they run this project's
  own Solhint with its config. Fall back to `npm run lint:sol` when the server is
  unavailable.

The two are complementary. The command is what a person and CI run. The tools are what an agent runs, and their advantage is that the invocation cannot drift: no unquoted ** collapsing to a single level, no forgotten config, no stray flag. A shell glob written by hand can silently cover a fraction of a project; lint_project cannot.

Configuration

lint_solidity uses configuration in this order:

  1. The complete config object supplied to the tool.

  2. The configuration found in the project root.

  3. { "extends": "solhint:recommended" }.

An explicit config replaces the project config; it is not merged. File and project linting use Solhint's per-file configuration hierarchy and the same recommended fallback when no configuration exists.

The server prefers a compatible solhint (>=6.1.0 <7.0.0) installed by the project. If none exists, it uses its bundled, tested version. An installed but incompatible project version produces an explicit error. Pass --bundled-solhint only when you intentionally want the bundled version.

Solhint 6.0.x is excluded because its plugin loader can terminate the host process when a configured plugin cannot be loaded, which is unsafe for an in-process MCP server.

Protocol and current limitations

The server uses @modelcontextprotocol/server 2.x over stdio. It supports the current 2026-07-28 lifecycle and the SDK's legacy compatibility path.

Solhint currently resolves shareable configs and plugins relative to process.cwd(). That is why this release supports one project per process. A third-party plugin that writes to stdout synchronously is redirected to stderr while linting so it cannot corrupt the MCP channel. Full plugin isolation, cancellation, and lint timeouts are deferred to a worker-based release.

Docker

docker build -t solhint-mcp .
docker run -i --rm -v "$PWD":/project solhint-mcp

The server lints whatever directory it starts in, so the Solidity project is mounted at /project, which is the image's working directory. -i is required because the server speaks MCP over stdio; no port is exposed. A Solhint installed in the mounted project takes precedence over the image's own copy.

MCP Registry

Listed as io.github.vschernoff/solhint-mcp. server.json in this repository is the registry manifest; its name must stay identical to mcpName in package.json, and both version fields must match the published npm version, or a registry publish is rejected.

Credits and licence

MIT. The linting runner, tool surface and test suite were originally written by Diego Bale (@dbale-arg) for protofire/solhint and moved here with his agreement, so the MCP server can be maintained and released independently of Solhint's release cycle. See NOTICE for the file-level breakdown.

Solhint is maintained by Protofire. This package depends on it; it is not part of it.

Related MCP Connectors

Related MCP Servers