gcp-mcp-server
README.md
# gcp-mcp-server
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
[](LICENSE)
Model Context Protocol server for Google Cloud Platform. Built on the MCP
Python SDK (`mcp>=1.27`) using FastMCP, with tools that touch Resource
Manager, 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
```bash
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:
1. If `GCP_CREDENTIALS_PATH` points to a service-account JSON file, that file
is used.
2. Otherwise, Application Default Credentials (ADC) are loaded via
`google.auth.default()`.
For ADC, the simplest path is:
```bash
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:
```json
{
"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 ensure
`gcloud auth application-default login` was run as the same user that
launches Claude Desktop.
## Tools
### Resource Manager / IAM
- `list_projects()` - list visible GCP projects
- `get_project(project_id)` - fetch project metadata
- `list_service_accounts(project_id)` - list IAM service accounts via the IAM REST API
### Compute Engine
- `list_instances(project_id?, zone?)` - zonal or aggregated instance list
- `get_instance(project_id, zone, name)` - single instance details
- `start_instance(project_id, zone, name)` - start a VM
- `stop_instance(project_id, zone, name)` - stop a VM
### Cloud Storage
- `list_buckets(project_id?)` - list buckets in a project
- `list_objects(bucket, prefix?, max_results=100)` - list blobs
- `get_object_metadata(bucket, name)` - fetch blob metadata
### BigQuery
- `list_datasets(project_id?)` - list datasets
- `list_tables(project_id, dataset)` - list tables
- `query_bigquery(project_id, sql, dry_run=False)` - run a query; dry-run returns schema and estimated bytes
### Pub/Sub
- `list_topics(project_id?)` - list topics
- `list_subscriptions(project_id?)` - list subscriptions
- `publish_message(project_id, topic, data, attributes?)` - publish a message. `data` is UTF-8; prefix with `base64:` 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. Minimal
recommended 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:
```bash
source .venv/bin/activate
pytest -x --tb=short
```
Lint:
```bash
ruff check src/ tests/
```
Tests mock each Google Cloud client with `unittest.mock`, so no real
GCP 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.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues