gcp-mcp-server
Model Context Protocol server for Google Cloud Platform. Built on the MCPPython SDK (mcp>=1.27) using FastMCP, with tools that touch ResourceManager, Compute Engine, Cloud Storage, BigQuery, Pub/Sub, and Cloud Logging.
Features
- Application Default Credentials (ADC) or explicit service-account JSON auth
- Lazy-constructed Google Cloud SDK clients bound to resolved credentials
- Blocking SDK calls executed in worker threads via
anyio.to_thread.run_sync - Typed tools covering the most common GCP day-to-day operations
- Unit tests that mock the SDK clients end-to-end (no real API calls)
Install
git clone https://github.com/asklokesh/gcp-mcp-server.git
cd gcp-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Requires Python 3.10 or newer.
Authentication
The server resolves credentials in the following order:
- If
GCP_CREDENTIALS_PATHpoints to a service-account JSON file, that fileis used. - Otherwise, Application Default Credentials (ADC) are loaded via
google.auth.default().
For ADC, the simplest path is:
gcloud auth application-default login
Or point GOOGLE_APPLICATION_CREDENTIALS at a service-account JSON file.
Environment variables
All settings are optional and use the GCP_ prefix:
| Variable | Description | Default |
|---|---|---|
GCP_DEFAULT_PROJECT_ID |
Project id used when a tool doesn't receive one | unset |
GCP_CREDENTIALS_PATH |
Path to a service-account JSON file | unset (ADC) |
GCP_TIMEOUT |
Default per-request timeout in seconds | 60 |
Claude Desktop configuration
Add an entry like this to your Claude Desktop mcpServers config:
{
"mcpServers": {
"gcp": {
"command": "gcp-mcp",
"env": {
"GCP_DEFAULT_PROJECT_ID": "my-gcp-project",
"GCP_CREDENTIALS_PATH": "/absolute/path/to/service-account.json"
}
}
}
}
If you prefer ADC, omit GCP_CREDENTIALS_PATH and ensuregcloud auth application-default login was run as the same user thatlaunches Claude Desktop.
Tools
Resource Manager / IAM
list_projects()- list visible GCP projectsget_project(project_id)- fetch project metadatalist_service_accounts(project_id)- list IAM service accounts via the IAM REST API
Compute Engine
list_instances(project_id?, zone?)- zonal or aggregated instance listget_instance(project_id, zone, name)- single instance detailsstart_instance(project_id, zone, name)- start a VMstop_instance(project_id, zone, name)- stop a VM
Cloud Storage
list_buckets(project_id?)- list buckets in a projectlist_objects(bucket, prefix?, max_results=100)- list blobsget_object_metadata(bucket, name)- fetch blob metadata
BigQuery
list_datasets(project_id?)- list datasetslist_tables(project_id, dataset)- list tablesquery_bigquery(project_id, sql, dry_run=False)- run a query; dry-run returns schema and estimated bytes
Pub/Sub
list_topics(project_id?)- list topicslist_subscriptions(project_id?)- list subscriptionspublish_message(project_id, topic, data, attributes?)- publish a message.datais UTF-8; prefix withbase64:for binary payloads.
Cloud Logging
read_logs(project_id, filter, max_entries=50)- advanced log filter, e.g.resource.type="gce_instance"
Required IAM roles
The caller's principal needs appropriate roles per surface. Minimalrecommended roles:
| Surface | Role(s) |
|---|---|
| Resource Manager | roles/resourcemanager.projectViewer, roles/browser |
| IAM | roles/iam.serviceAccountViewer |
| Compute | roles/compute.viewer, roles/compute.instanceAdmin.v1 (for start/stop) |
| Cloud Storage | roles/storage.objectViewer, roles/storage.bucketViewer |
| BigQuery | roles/bigquery.dataViewer, roles/bigquery.jobUser |
| Pub/Sub | roles/pubsub.viewer, roles/pubsub.publisher |
| Cloud Logging | roles/logging.viewer (or roles/logging.privateLogViewer) |
Grant only what the caller actually needs.
Development
Run the test suite:
source .venv/bin/activate
pytest -x --tb=short
Lint:
ruff check src/ tests/
Tests mock each Google Cloud client with unittest.mock, so no realGCP APIs are called.
Project layout
src/gcp_mcp/
__init__.py # main entry point
auth.py # ADC / service-account credential resolution
clients.py # lazy SDK client construction
config.py # pydantic-settings config (GCP_ env prefix)
exceptions.py # GCPError, AuthenticationError, APIError, NotFoundError
server.py # FastMCP server + @mcp.tool() definitions
tests/ # unit tests with mocked SDK clients
pyproject.toml
requirements.txt
License
MIT.