metals-mcp
by eloquentix
README.md
# metals-mcp
MCP wrapper for [Metals](https://scalameta.org/metals/) (Scala language server) that adds file editing and refactoring tools.
## Prerequisites
- Node.js 22+
- `metals-mcp` binary on PATH (or set `METALS_MCP_PATH`)
## Install
```bash
npm install
```
## Usage
### Claude Code
Add to your project's `.mcp.json`:
```json
{
"mcpServers": {
"metals": {
"command": "npx",
"args": ["tsx", "src/index.ts", "--workspace", "/path/to/scala/project"]
}
}
}
```
Or globally in `~/.claude.json`:
```json
{
"mcpServers": {
"metals": {
"command": "npx",
"args": ["--prefix", "/path/to/metals-mcp", "tsx", "src/index.ts", "--workspace", "/path/to/scala/project"]
}
}
}
```
### Manual
```bash
npx tsx src/index.ts --workspace /path/to/scala/project
```
## Tools
**File operations:** `read-file`, `write-file`, `edit-file`, `list-files`
**Refactoring:** `rename-symbol`, `add-import`, `remove-unused-imports`
All Metals tools are also proxied transparently when Metals connects.
## Configuration
| Option | Description |
|--------|-------------|
| `--workspace <path>` | Scala project root (required) |
| `METALS_MCP_PATH` | Custom path to metals-mcp binary |
### `ERR_MODULE_NOT_FOUND` or "Failed to reconnect to metals"
If the MCP server is configured in `.mcp.json` with a relative path for the entry point:
```json
{
"mcpServers": {
"metals": {
"command": "npx",
"args": ["--prefix", "/path/to/metals-lsp", "tsx", "src/index.ts"]
}
}
}
```
The `npx --prefix` flag sets the package lookup directory, but the **working directory** remains the project being edited. The relative `src/index.ts` resolves against the workspace, not the plugin directory, causing the module-not-found error.
**Fix:** Use an absolute path for the entry point:
```json
{
"mcpServers": {
"metals": {
"command": "npx",
"args": ["--prefix", "/path/to/metals-lsp", "tsx", "/path/to/metals-lsp/src/index.ts"]
}
}
}
```This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues