Google Cloud Spanner MCP server

Endpoint: https://spanner.googleapis.com/mcp · Authentication: Sign in with OAuth

Manages Spanner instances and databases, reads schema DDL, and runs SQL queries and commits. Requires Google Cloud credentials through OAuth.

How do I authenticate?

Add the endpoint in your client, start Connect or Sign in, approve the requested scopes, and return to the client. OAuth discovery finds the authorization server; client registration requirements vary by provider. Follow the provider guidance and client setup below.

Authentication and connection guide

Connection specification

Remote endpoint
https://spanner.googleapis.com/mcp
Browser access
Not yet measured
Declared MCP transport
Streamable HTTP
Live-validated MCP transport
Streamable HTTP — Observed by the latest catalog validation
Declared authentication
OAuth 2.1
Detected authentication
OAuth 2.1 detected or retained from publisher evidence
Protocol lifecycle
Stateful MCP · 2025-11-25
Authorization server
https://accounts.google.com/
Category
Databases

Product documentation · Official listing documentation

Provider guidance

  • Initialization and tool listing succeeded without credentials in the 2026-10-20 audit; tool calls require Google Cloud credentials. Google OAuth clients are pre-registered in a Google Cloud project; the server does not advertise Dynamic Client Registration.

More Databases MCP servers · Browse all MCP servers · Test this endpoint in the MCP Playground

Authorization setup

Registration requirements not verified

The OAuth authorization and app-registration requirements for this exact endpoint have not been verified. A compatible client will request authorization, but follow the publisher documentation and do not guess client credentials or callbacks.

Publisher evidence reviewed .

Publisher documentation

Connect it

Live-validated endpoint: https://spanner.googleapis.com/mcp · Streamable HTTP. Registration requirements not verified: The OAuth authorization and app-registration requirements for this exact endpoint have not been verified. A compatible client will request authorization, but follow the publisher documentation and do not guess client credentials or callbacks.

Agent prompt for Claude Code or Codex
Add the Google Cloud Spanner MCP server to my MCP client configuration and verify that it works.

What it is: Manages Spanner instances and databases, reads schema DDL, and runs SQL queries and commits. Requires Google Cloud credentials through OAuth.
Server URL: https://spanner.googleapis.com/mcp
Transport: Streamable HTTP (remote MCP server, no local install).
Authentication: OAuth 2.1. Registration requirements not verified: The OAuth authorization and app-registration requirements for this exact endpoint have not been verified. A compatible client will request authorization, but follow the publisher documentation and do not guess client credentials or callbacks.
Tools (16, as last observed by mcptest): commit, create_database, create_instance, create_session, execute_sql, execute_sql_readonly, get_config, get_database_ddl, get_instance, get_operation, get_query_plan, list_configs, list_databases, list_instances, update_database_schema, update_instance.
Reference: https://mcptest.io/servers/google-spanner/

Steps:
1. Work out which MCP client I use (Claude Code, Codex, Cursor, VS Code or another) and add the server under the name "google-spanner" in that client's MCP configuration, user scope unless I ask otherwise.
   Claude Code: claude mcp add --transport http --scope user 'google-spanner' 'https://spanner.googleapis.com/mcp'
   Other clients: use the setup for that client on the reference page.
2. Never write a credential value into a file that could be committed; reference an environment variable or the client's secret store, and ask me for any value you need.
3. Verify: connect to the server and call tools/list. Confirm the tools above are listed, and report any sign-in step I still have to complete.
MCP client

Claude Code setup

Run in a terminal. This user-scoped entry is available across projects.

claude mcp add --transport http --scope user 'google-spanner' 'https://spanner.googleapis.com/mcp'
  • After adding the server, open Claude Code, run /mcp, select the server, and follow the browser flow to authenticate.

Codex CLI setup

Run in a terminal; Codex stores the entry in ~/.codex/config.toml.

codex mcp add 'google-spanner' --url 'https://spanner.googleapis.com/mcp'
codex mcp login 'google-spanner'

Cursor setup

Add to .cursor/mcp.json for this project, or ~/.cursor/mcp.json for all projects.

{
  "mcpServers": {
    "google-spanner": {
      "url": "https://spanner.googleapis.com/mcp"
    }
  }
}

VS Code setup

Add to .vscode/mcp.json, or run “MCP: Open User Configuration” for a private user-level entry.

{
  "servers": {
    "google-spanner": {
      "type": "http",
      "url": "https://spanner.googleapis.com/mcp"
    }
  }
}

Claude setup

Add the endpoint above in Claude:

  • Customize > Connectors > Add custom connector
  • Team/Enterprise: Organization settings > Connectors > Add > Custom > Web

Claude Desktop setup

Add the endpoint above in Claude Desktop:

  • Remote: Customize > Connectors (same as claude.ai)
  • Local: Settings > Developer > Edit Config, or Settings > Extensions for .mcpb files
  • ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows), local servers only

ChatGPT setup

Add the endpoint above in ChatGPT:

  • ChatGPT web: Plugins > Add custom MCP server, then configure authentication and accept the risk warning

Windsurf setup

Add the endpoint above in Windsurf:

  • ~/.config/devin/mcp_config.json (%APPDATA%\devin\mcp_config.json on Windows), serverUrl or url
  • Cascade panel > ... > MCPs > Open MCP config file

Gemini CLI setup

Add the endpoint above in Gemini CLI:

  • gemini mcp add --transport http <name> <url>
  • ~/.gemini/settings.json (user) or .gemini/settings.json (project), mcpServers

MCP SDK setup

Add the endpoint above in MCP SDK:

  • Programmatic: new Client(...).connect(new StreamableHTTPClientTransport(url))

Notes for every client

  • Publisher evidence (reviewed 2026-10-20): https://docs.cloud.google.com/spanner/docs/use-spanner-mcp
  • Provider guidance: Initialization and tool listing succeeded without credentials in the 2026-10-20 audit; tool calls require Google Cloud credentials. Google OAuth clients are pre-registered in a Google Cloud project; the server does not advertise Dynamic Client Registration.

Client compatibility

ClientStatusWhy
Claude CodeSupportedClaude Code supports Streamable HTTP servers and OAuth sign-in.
CodexSupportedCodex supports Streamable HTTP servers and OAuth sign-in.
CursorSupportedCursor supports Streamable HTTP servers and OAuth sign-in.
VS CodeSupportedVS Code supports Streamable HTTP servers and OAuth sign-in.
ClaudeSupportedClaude supports Streamable HTTP servers and OAuth sign-in.
Claude DesktopSupportedClaude Desktop supports Streamable HTTP servers and OAuth sign-in.
ChatGPTPartialStateful routing needs operational care: ChatGPT can preserve MCP sessions, but the deployment must route a session consistently and retain its state.
WindsurfPartialWindsurf's documentation does not state support for OAuth sign-in.
Gemini CLISupportedGemini CLI supports Streamable HTTP servers and OAuth sign-in.
MCP SDKSupportedMCP SDK supports Streamable HTTP servers and OAuth sign-in.

Computed from this server's validated transport, protocol and authentication against documented client support. Checks the catalog has not observed are not counted.

Similar servers

  • Supabase — Remote MCP server for Supabase projects, Postgres databases, backend tooling, and documentation. OAuth 2.1
  • Neon — Remote MCP server for Neon Postgres projects, branches, SQL, and documentation. OAuth 2.1
  • Prisma — Creates and manages Prisma Postgres databases, connection strings, backups, Prisma Compute apps, and Object Storage buckets in a Prisma workspace. Requires Prisma OAuth. OAuth 2.1
  • PlanetScale — Lists PlanetScale organizations, databases, and branches, reads Insights and schema recommendations, and runs read or write queries with short-lived credentials. Requires PlanetScale OAuth. OAuth 2.1
  • Google BigQuery — Lists BigQuery datasets and tables, reads table schemas, and runs SQL queries in a Google Cloud project. Requires Google Cloud credentials through OAuth. OAuth 2.1
  • InstantDB — Creates and manages Instant apps, including their schema and permission rules. Requires Instant account OAuth. OAuth 2.1

Guides for this server

Watch this server for breaking changes

Share and embed

Maintain Google Cloud Spanner? Embed this badge in your README. It follows the latest catalog validation result and links to this server profile.

mcptest.io: ready

Latest validation evidence

Validation status
Online when last tested
Validation checked at
Oct 26, 2026 at 11:06 AM
Validation detail
Negotiated stateful MCP 2025-11-25 at https://spanner.googleapis.com/mcp; detected transport streamable-http; authentication oauth

Tool inventory

What the catalog validator observed on at https://spanner.googleapis.com/mcp without credentials. The live server may have changed since; connect in the Playground for the current list.

Tools provided by Google Cloud Spanner 16

Some details were sanitized for public display.

  • commitoutputSchema declared

    Commit a transaction in a given session. * If commit is finalizing the result of a DML statement then commit request should include latest precommit_token returned by execute_sql tool. * If response to commit includes another precommit_token then issue another commit call to finalize the transaction with the latest precommit_token.

    Input precommitToken: any, session: string, transactionId: string
    • precommitToken: anyrequired

      Required. You must include the precommit token with the highest sequence number received in this transaction attempt. Failing to do so results in a `FailedPrecondition` error.

    • session: stringrequired

      Required. The session in which the transaction to be committed is running.

    • transactionId: stringrequired

      Required. The transaction in which to commit. Commit a previously-started transaction.

  • create_databaseoutputSchema declared

    Create a Spanner database in a given instance.

    Input createStatement: string, databaseDialect?: string, encryptionConfig?: any, extraStatements?: array, parent: string, protoDescriptors?: string
    • createStatement: stringrequired

      Required. A `CREATE DATABASE` statement, which specifies the ID of the new database. The database ID must conform to the regular expression `a-z*[a-z0-9]` and be between 2 and 30 characters in length. If the database ID is a reserved word or if it contains a hyphen, the database ID must be enclosed in backticks (`` ` ``).

    • databaseDialect?: stringoptional

      Optional. The dialect of the Cloud Spanner Database.

    • encryptionConfig?: anyoptional

      Optional. The encryption configuration for the database. If this field is not specified, Cloud Spanner will encrypt/decrypt all data at rest using Google default encryption.

    • extraStatements?: arrayoptional

      Optional. A list of DDL statements to run inside the newly created database. Statements can create tables, indexes, etc. These statements execute atomically with the creation of the database: if there is an error in any statement, the database is not created.

    • parent: stringrequired

      Required. The name of the instance that will serve the new database. Values are of the form `projects//instances/`.

    • protoDescriptors?: stringoptional

      Optional. Proto descriptors used by `CREATE/ALTER PROTO BUNDLE` statements in 'extra_statements'. Contains a protobuf-serialized [`google.protobuf.FileDescriptorSet`]([REDACTED URI] descriptor set. To generate it, [install]([REDACTED URI] and run `protoc` with --include_imports and --descriptor_set_out. For example, to generate for moon/shot/app.proto, run ``` $protoc --proto_path=/app_path --proto_path=/lib_path \ --include_imports \ --descriptor_set_out=descriptors.data \ moon/shot/app.pr

  • create_instanceoutputSchema declared

    Create a Spanner instance in a given project.

    Input instance: any, instanceId: string, parent: string
    • instance: anyrequired

      Required. The instance to create. The name may be omitted, but if specified must be `/instances/`.

    • instanceId: stringrequired

      Required. The ID of the instance to create. Valid identifiers are of the form `a-z*[a-z0-9]` and must be between 2 and 64 characters in length.

    • parent: stringrequired

      Required. The name of the project in which to create the instance. Values are of the form `projects/`.

  • create_sessionoutputSchema declared

    Create a session in a given database for query executions using execute_sql tool. * A session provides transactional context and should be reused across operations if possible. * If a session expires (e.g., returning NOT_FOUND), call create_session tool to get a new one. * Treat the create_session tool call that results as part of running execute_sql_readonly tool as a read-only operation.

    Input database: string, fineGrainedAccessRole?: string
    • database: stringrequired

      Required. The database in which the new session is created. Format: `projects/{project}/instances/{instance}/databases/{database}`

    • fineGrainedAccessRole?: stringoptional

      Optional. The fine grained access role of the session. All operations performed using the session will be performed with the fine grained access role.

  • execute_sqloutputSchema declared

    Execute SQL statement using a given session. * Requires an active session. Reuse existing sessions if possible. If a session expires, call create_session to get a new one. * **CRITICAL:** To prevent SQL injection vulnerabilities and improve performance, ALWAYS use the `parameters` argument to pass any dynamic values into your SQL query. Do NOT embed variables directly into the `sql` string. * Use placeholders in the `sql` string and provide values in the `parameters` list: * For GoogleSQL: Use named placeholders (e.g., `@my_param`). * For PostgreSQL: Use positional placeholders (e.g., `$1`, `$

    Input existingTransactionId?: string, parameters?: array, readOnlyTransaction?: boolean, readWriteTransaction?: boolean, seqno?: string, session: string, singleUseTransaction?: boolean, sql: string
    • existingTransactionId?: stringoptional

      Use an existing transaction.

    • parameters?: arrayoptional

      Optional. The SQL query parameters.

    • readOnlyTransaction?: booleanoptional

      Begin a new read-only transaction.

    • readWriteTransaction?: booleanoptional

      Begin a new read-write transaction.

    • seqno?: stringoptional

      Optional. Sequence number of the request within a transaction. The sequence number must be monotonically increasing within the transaction. If a request arrives for the first time with an out-of-order sequence number, the transaction can be aborted.

    • session: stringrequired

      Required. The session in which the SQL query is executed. Format: `projects/{project}/instances/{instance}/databases/{database}/sessions/{session}`

    • singleUseTransaction?: booleanoptional

      Use a single use transaction for query execution.

    • sql: stringrequired

      Required. The SQL query to execute.

  • execute_sql_readonlyoutputSchema declared

    Execute SQL query statement using a given session in a read-only transaction. * Requires an active session. Reuse existing sessions if possible. If a session expires, call create_session tool to get a new one. Treat create_session tool invocation made as part of execute_sql_readonly as a read-only operation. * **CRITICAL:** To prevent SQL injection vulnerabilities and improve performance, ALWAYS use the `parameters` argument to pass any dynamic values into your SQL query. Do NOT embed variables directly into the `sql` string. * Use placeholders in the `sql` string and provide values in the `pa

    Input existingTransactionId?: string, parameters?: array, readOnlyTransaction?: boolean, readWriteTransaction?: boolean, seqno?: string, session: string, singleUseTransaction?: boolean, sql: string
    • existingTransactionId?: stringoptional

      Use an existing transaction.

    • parameters?: arrayoptional

      Optional. The SQL query parameters.

    • readOnlyTransaction?: booleanoptional

      Begin a new read-only transaction.

    • readWriteTransaction?: booleanoptional

      Begin a new read-write transaction.

    • seqno?: stringoptional

      Optional. Sequence number of the request within a transaction. The sequence number must be monotonically increasing within the transaction. If a request arrives for the first time with an out-of-order sequence number, the transaction can be aborted.

    • session: stringrequired

      Required. The session in which the SQL query is executed. Format: `projects/{project}/instances/{instance}/databases/{database}/sessions/{session}`

    • singleUseTransaction?: booleanoptional

      Use a single use transaction for query execution.

    • sql: stringrequired

      Required. The SQL query to execute.

  • get_configoutputSchema declared

    Get information about a specific Spanner instance configuration.

    Input name: string
    • name: stringrequired

      Required. The name of the requested instance configuration. Values are of the form `projects//instanceConfigs/`.

  • get_database_ddloutputSchema declared

    Get database schema for a given database.

    Input database: string
    • database: stringrequired

      Required. The database whose schema we wish to get. Values are of the form `projects//instances//databases/`

  • get_instanceoutputSchema declared

    Get information about a Spanner instance

    Input fieldMask?: string, name: string
    • fieldMask?: stringoptional

      If field_mask is present, specifies the subset of Instance fields that should be returned. If absent, all Instance fields are returned.

    • name: stringrequired

      Required. The name of the requested instance. Values are of the form `projects//instances/`.

  • get_operationoutputSchema declared

    Get status of a long-running operation. * Long running operation may take several minutes to complete. get_operation tool can be used to poll the status of a long running operation.

    Input name?: string
    • name?: stringoptional

      The name of the operation resource.

  • get_query_planoutputSchema declared

    Retrieves the execution plan (query plan) for a Spanner SQL query. This tool does NOT execute the query itself, making it safe and efficient to run even on large datasets or write operations. Use this tool to understand index usage, join algorithms, and execution cost before executing the query. Queries may include parameter placeholders (e.g., `@param_name` for GoogleSQL or `$1` for PostgreSQL), but there is no need to provide or bind parameter values when requesting the query plan. * **Example (GoogleSQL):** ``` sql: "SELECT * FROM Users WHERE UserId = @user_id" ``` * **Example (PostgreSQL):

    Input session: string, sql: string
    • session: stringrequired

      Required. The session in which the SQL query is executed. Format: `projects/{project}/instances/{instance}/databases/{database}/sessions/{session}`

    • sql: stringrequired

      Required. The SQL query to get the plan for.

  • list_configsoutputSchema declared

    List instance configs in a given project. * `page_size` defaults to 10 if not specified. * Response may include next_page_token to fetch additional configs using list_configs tool with page_token set.

    Input pageSize?: integer, pageToken?: string, parent: string
    • pageSize?: integeroptional

      Number of instance configurations to be returned in the response. If 0 or less, defaults to the server's maximum allowed page size.

    • pageToken?: stringoptional

      If non-empty, `page_token` should contain a next_page_token from a previous ListInstanceConfigsResponse.

    • parent: stringrequired

      Required. The name of the project for which a list of supported instance configurations is requested. Values are of the form `projects/`.

  • list_databasesoutputSchema declared

    List Spanner databases in a given spanner instance. * Response may include next_page_token to fetch additional databases using list_databases tool with page_token set.

    Input pageSize?: integer, pageToken?: string, parent: string
    • pageSize?: integeroptional

      Number of databases to be returned in the response. If 0 or less, defaults to the server's maximum allowed page size.

    • pageToken?: stringoptional

      If non-empty, `page_token` should contain a next_page_token from a previous ListDatabasesResponse.

    • parent: stringrequired

      Required. The instance whose databases should be listed. Values are of the form `projects//instances/`.

  • list_instancesoutputSchema declared

    List Spanner instances in a given project. * `page_size` defaults to 10 if not specified. * Response may include next_page_token to fetch additional instances using list_instances tool with page_token set.

    Input filter?: string, instanceDeadline?: string, pageSize?: integer, pageToken?: string, parent: string
    • filter?: stringoptional

      An expression for filtering the results of the request. Filter rules are case insensitive. The fields eligible for filtering are: * `name` * `display_name` * `labels.key` where key is the name of a label Some examples of using filters are: * `name:*` --> The instance has a name. * `name:Howl` --> The instance's name contains the string "howl". * `name:HOWL` --> Equivalent to above. * `NAME:howl` --> Equivalent to above. * `labels.env:*` --> The instance has the label "env". * `labels.env:dev` --> The instance has the label "env" and the value of the label contains the string "dev". * `name:how

    • instanceDeadline?: stringoptional

      Deadline used while retrieving metadata for instances. Instances whose metadata cannot be retrieved within this deadline will be added to unreachable in ListInstancesResponse.

    • pageSize?: integeroptional

      Number of instances to be returned in the response. If 0 or less, defaults to the server's maximum allowed page size.

    • pageToken?: stringoptional

      If non-empty, `page_token` should contain a next_page_token from a previous ListInstancesResponse.

    • parent: stringrequired

      Required. The name of the project for which a list of instances is requested. Values are of the form `projects/`.

  • update_database_schemaoutputSchema declared

    Update schema for a given database.

    Input database: string, operationId?: string, protoDescriptors?: string, statements: array
    • database: stringrequired

      Required. The database to update.

    • operationId?: stringoptional

      If empty, the new update request is assigned an automatically-generated operation ID. Otherwise, `operation_id` is used to construct the name of the resulting Operation. Specifying an explicit operation ID simplifies determining whether the statements were executed in the event that the UpdateDatabaseDdl call is replayed, or the return value is otherwise lost: the database and `operation_id` fields can be combined to form the `name` of the resulting longrunning.Operation: `/operations/`. `operation_id` should be unique within the database, and must be a valid identifier: `a-z*`. Note that auto

    • protoDescriptors?: stringoptional

      Optional. Proto descriptors used by CREATE/ALTER PROTO BUNDLE statements. Contains a protobuf-serialized [google.protobuf.FileDescriptorSet]([REDACTED URI] To generate it, [install]([REDACTED URI] and run `protoc` with --include_imports and --descriptor_set_out. For example, to generate for moon/shot/app.proto, run ``` $protoc --proto_path=/app_path --proto_path=/lib_path \ --include_imports \ --descriptor_set_out=descriptors.data \ moon/shot/app.proto ``` For more details, see protobuffer

    • statements: arrayrequired

      Required. DDL statements to be applied to the database.

  • update_instanceoutputSchema declared

    Update a Spanner instance. * While updating an instance always include instance name and config.

    Input fieldMask: string, instance: any
    • fieldMask: stringrequired

      Required. A mask specifying which fields in Instance should be updated. The field mask must always be specified; this prevents any future fields in Instance from being erased accidentally by clients that do not know about them.

    • instance: anyrequired

      Required. The instance to update, which must always include the instance name. Otherwise, only fields mentioned in field_mask need be included.