Skip to content

Connect your agent

Grain speaks the Model Context Protocol, so agent clients — Claude Desktop, Claude Code, Cursor, Copilot, Windsurf, Codex — can run queries, list schemas, and describe tables against your own databases.

The one command

There is one command, and it is the same on macOS, Linux, and Windows:

npx -y grain-tools --stdio

That is the whole setup contract. Everything below is how to hand that one command to a particular client.

--stdio takes no value. -y skips npm’s install prompt — an MCP client launches the server with no terminal attached, so a prompt would have nobody to answer it. Do not drop the flag.

Before you connect

  1. Have connections. Install the extension and add a connection profile, or supply profiles through GRAIN_CONNECTIONS — see Headless connections.
  2. Turn the MCP surface on. It ships off. Set grain.mcpEnabled in the Grain settings panel, or "mcp": { "enabled": true } in ~/.grain/daemon.json. Without it the bridge refuses explicitly rather than failing quietly.
  3. Leave safe mode on unless you intend agents to run mutating SQL.

Clients that take a command

Claude Code

claude mcp add grain -- npx -y grain-tools --stdio

Cursor

Settings → MCP ServersAdd new MCP server. Type command, name grain, command npx -y grain-tools --stdio.

Windsurf

Settings → CascadeMCP ServersAdd Server, then paste the same JSON as Claude Desktop below into ~/.codeium/windsurf/mcp_config.json.

VS Code and Copilot

VS Code reads MCP servers from .vscode/mcp.json in the workspace, or from your user mcp.json via MCP: Open User Configuration in the command palette. Note the key is servers, not mcpServers:

{
  "servers": {
    "grain": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "grain-tools", "--stdio"]
    }
  }
}

Copilot Chat in agent mode picks the server up from the same file.

Codex

Add the server to ~/.codex/config.toml:

[mcp_servers.grain]
command = "npx"
args = ["-y", "grain-tools", "--stdio"]

Clients that take only a config file

Claude Desktop has no command-line registration, so it is configured by file. The JSON is a transcription of the one command above, not a second way of setting Grain up — if the two ever disagree, the command is right.

Config file location:

  • macOS~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows%APPDATA%\Claude\claude_desktop_config.json. Paste that path into Win + R; create the file if it is not there.
{
  "mcpServers": {
    "grain": {
      "command": "npx",
      "args": ["-y", "grain-tools", "--stdio"]
    }
  }
}

Restart the client fully after editing. If the file already has an mcpServers object, add only the "grain" entry inside it.

Headless connections

By default the bridge attaches to the daemon your editor is already running, so agent queries land in the same result tabs as your own. For CI, or for a client that should not share the editor’s daemon, give the server its own profiles:

{
  "mcpServers": {
    "grain": {
      "command": "npx",
      "args": ["-y", "grain-tools", "--stdio"],
      "env": {
        "GRAIN_CONNECTIONS": "[{\"id\":\"analytics\",\"name\":\"Analytics\",\"type\":\"postgres\",\"host\":\"localhost\",\"port\":5432,\"user\":\"analyst\",\"database\":\"warehouse\",\"password\":\"YOUR_PASSWORD\"}]",
        "GRAIN_EMBEDDED": "1"
      }
    }
  }
}

GRAIN_EMBEDDED=1 forces an isolated daemon rather than attaching to a shared one, which is what you want in CI.

Plaintext passwords in a config file are convenient and not secure. Prefer a driver-specific variable such as PGPASSWORD where the connector supports it, or create the profile in the editor and let the bridge read the daemon’s own credentials.

Environment variables

Variable Effect
GRAIN_CONNECTIONS JSON array of connection profiles, for headless use
GRAIN_MCP_SAFE_MODE false allows mutating SQL. Defaults to true
GRAIN_MAX_ROWS Row cap for query tools. Defaults to 10000
GRAIN_HOME Which config directory — and so which daemon — is used
GRAIN_EMBEDDED 1 forces an isolated daemon instead of attaching

Running without a registry

If npx cannot reach npm — an offline machine, or a blocked registry — run the server file directly. It is the same file the three published commands alias.

{
  "mcpServers": {
    "grain": {
      "command": "node",
      "args": ["C:\\Users\\YourName\\grain\\standalone.js", "--stdio"]
    }
  }
}

Use forward slashes or doubled backslashes in JSON paths.

The tools you get

Grain advertises 20 tools. A tool a profile does not permit is still advertised and still answers — with an explicit refusal naming the profile, so an agent can tell “not allowed here” from “does not exist”.

Group Tools
Query run_query, cancel_query
Schema list_schemas, list_tables, describe_table
Connections list_connectors, list_connections, test_connection, save_connection, delete_connection, request_connection_credentials
Result tabs get_tab_info, close_tab, list_sessions
Charts render_chart, save_chart, list_charts
Audit ledger_stats, verify_ledger
Telemetry record_ui_event

An agent attached through the packaged bridge runs under the agent profile: it may read, query, and chart, but save_connection, delete_connection, and request_connection_credentials are refused. It cannot change your saved connections or ask for your stored credentials.

Troubleshooting

Symptom Cause and fix
No tools appear in the client Node is missing, or the client was not fully restarted
npx not found on Windows Reinstall Node.js LTS with “Add to PATH” checked
The bridge starts and then stops grain.mcpEnabled is off. Turn it on, or set mcp.enabled in ~/.grain/daemon.json
Agent queries are not in the grid The bridge found no shared daemon and started its own. The initialize response reports Grain isolation mode: shared or isolated
A tool answers with a refusal The profile refuses that tool’s resource class. The message names both

Identifiers

VS Code extension id
pattrnlabs.grain
npm package name
grain-tools
stdio command
npx -y grain-tools --stdio

MCP Configuration

{
  "mcpServers": {
    "grain": {
      "command": "npx",
      "args": [
        "-y",
        "grain-tools",
        "--stdio"
      ]
    }
  }
}
Documentation