1. Conduid
  2. Data
  3. Spanner Readonly
MCP server · Data

Spanner Readonly

Read-only MCP server for Google Cloud Spanner

37Low

Scored 5 months ago · breakdown

About Spanner Readonly

Spanner Readonly is an MCP server in the Data category: read-only MCP server for Google Cloud Spanner.

Install

Claude Code
claude mcp add spanner-readonly -- npx -y spanner-readonly-mcp
npx
npx -y spanner-readonly-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Tools (4)

describe_tableGet column definitions (type, nullability, ordinal position) for a table

Parameters not published.

execute_queryExecute an arbitrary SELECT query

Parameters not published.

list_indexesList indexes, optionally filtered by table

Parameters not published.

list_tablesList all user tables in the database

Parameters not published.

Ask AI

✦

Ask AI about Spanner Readonly

Powered by Claude · Grounded in docs

I know everything about Spanner Readonly. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

spanner-readonly-mcp

English | 日本語

A read-only MCP server for Google Cloud Spanner. Lets LLMs safely inspect schemas and run SELECT queries against a Spanner database.

Prerequisites

gcloud auth application-default login

Environment Variables

The server reads these at runtime (the Claude Code plugin prompts for them on install and persists to settings.json; for other clients, set them in the MCP config's env block).

Variable Required Description
SPANNER_PROJECT Yes GCP project ID
SPANNER_INSTANCE Yes Spanner instance ID
SPANNER_DATABASE Yes Spanner database ID
SPANNER_EMULATOR_HOST No host:port to point at a local Spanner (127.0.0.1:15000 for Spanner Omni single-server, 127.0.0.1:9010 for the legacy emulator). Leave unset for production.

Usage

Claude Code Plugin

This repo doubles as a Claude Code plugin marketplace. Register it and install the plugin:

/plugin marketplace add nu0ma/spanner-readonly-mcp
/plugin install spanner-readonly-mcp@spanner-readonly-mcp

The plugin launches the server via npx -y spanner-readonly-mcp@latest. Claude Code will prompt for SPANNER_PROJECT, SPANNER_INSTANCE, and SPANNER_DATABASE on install and persist them to settings.json.

Claude Code (without the plugin)

Create .mcp.json at your project root:

{
  "mcpServers": {
    "spanner-readonly-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "spanner-readonly-mcp@latest"],
      "env": {
        "SPANNER_PROJECT": "my-project",
        "SPANNER_INSTANCE": "my-instance",
        "SPANNER_DATABASE": "my-database"
      }
    }
  }
}

Claude Code picks this up on session start and prompts to approve the server on first launch.

Tools

Tool Description
list_tables List all user tables in the database
describe_table Get column definitions (type, nullability, ordinal position) for a table
list_indexes List indexes, optionally filtered by table
execute_query Execute an arbitrary SELECT query

Read-Only Guarantee

Writes are blocked even if your IAM credentials have write permissions. Two layers enforce this:

  1. Application layer (UX, best-effort): A regex rejects common mutation keywords (INSERT, UPDATE, UPSERT, DELETE, MERGE, and DDL/DCL) before they reach Spanner. Its purpose is to give the agent a clear, fast error when it accidentally writes a mutation — not to act as a security boundary. Payloads can trivially be rewritten (comments, CTE wrapping, parenthesization) to slip past it.
  2. Transaction layer (authoritative): Every query runs inside a Spanner read-only snapshot transaction (database.getSnapshot()). The Snapshot class does not expose DML methods, and the Spanner backend rejects any mutation attempt within a read-only transaction. This is the real guarantee.

All snapshot queries (including the metadata tools) run with a 30-second gaxOptions.timeout to bound worst-case latency.

Error messages returned to clients are sanitized (first line only, prefixed REGEX_BLOCKED: or SPANNER_ERROR:) to avoid leaking stack traces or internal paths.

IAM least privilege

execute_query accepts arbitrary SELECT statements, including queries against information_schema and spanner_sys. To bound the read surface, grant only roles/spanner.databaseReader to the service account — do not rely on application-level filtering alone.

Development

pnpm install
pnpm build           # compile to dist/
pnpm dev             # run from source without building
pnpm test            # vitest, starts Spanner Omni via docker compose

Direct execution against a real Spanner instance (build first, then run):

pnpm build
SPANNER_PROJECT=my-project \
SPANNER_INSTANCE=my-instance \
SPANNER_DATABASE=my-database \
pnpm start

License

MIT

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Spanner Readonly

How do I install Spanner Readonly?

Run claude mcp add spanner-readonly -- npx -y spanner-readonly-mcp, then add the server to your MCP client's configuration.

Is Spanner Readonly safe to use with an AI agent?

Its trust score is 37 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Spanner Readonly still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.