A Model Context Protocol (MCP) server for the Looker API with full tool coverage, OAuth pass-through, and user impersonation support.
Project description
looker-mcp-server
A full-featured Model Context Protocol (MCP) server for the Looker API. Gives AI assistants direct access to your Looker instance — querying the semantic model, managing content, editing LookML, and administering users — all through a standard MCP interface.
Features
- 160 tools across 15 groups covering the full Looker API surface
- Semantic layer queries — query through LookML models, not raw SQL
- OAuth pass-through — forward user tokens from an upstream gateway or MCP OAuth flow
- User impersonation — admin sudo on self-hosted Looker, OAuth on Google Cloud core
- Dual transport — stdio for local/CLI use, streamable-http for production deployment
- Selective tool loading — enable only the tool groups you need via
--groups - Pluggable identity — swap in custom authentication via the
IdentityProviderprotocol - Health endpoints —
/healthzand/readyzfor container orchestration
Quick Start
Installation
pip install looker-mcp-server
# or
uv add looker-mcp-server
Environment Variables
At minimum, set your Looker instance URL and API3 credentials:
export LOOKER_BASE_URL="https://mycompany.looker.com"
export LOOKER_CLIENT_ID="your-api3-client-id"
export LOOKER_CLIENT_SECRET="your-api3-client-secret"
Run with stdio (for Claude Code, Claude Desktop, etc.)
looker-mcp-server --groups explore,query,schema
Run with HTTP (for production deployment)
LOOKER_TRANSPORT=streamable-http looker-mcp-server --groups all --port 8080
MCP Client Configuration
Claude Code
Add to your Claude Code MCP settings:
{
"mcpServers": {
"looker": {
"command": "looker-mcp-server",
"args": ["--groups", "explore,query,schema,content"],
"env": {
"LOOKER_BASE_URL": "https://mycompany.looker.com",
"LOOKER_CLIENT_ID": "your-client-id",
"LOOKER_CLIENT_SECRET": "your-client-secret"
}
}
}
}
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"looker": {
"command": "looker-mcp-server",
"args": ["--groups", "explore,query,schema,content"],
"env": {
"LOOKER_BASE_URL": "https://mycompany.looker.com",
"LOOKER_CLIENT_ID": "your-client-id",
"LOOKER_CLIENT_SECRET": "your-client-secret"
}
}
}
}
Tool Groups
Tools are organized into groups that can be selectively enabled. Default groups are marked with *.
| Group | Tools | Description |
|---|---|---|
| explore* | list_models, get_model, get_explore, list_dimensions, list_measures, list_connections |
Browse LookML models, explores, and fields |
| query* | query, query_sql, run_look, run_dashboard, query_url, search_content |
Run queries through the semantic layer |
| schema* | list_databases, list_schemas, list_tables, list_columns |
Inspect underlying database schema |
| content* | list_looks, create_look, update_look, delete_look, list_dashboards, create_dashboard, update_dashboard, delete_dashboard, add_dashboard_element, add_dashboard_filter, generate_embed_url, validate_content |
Manage Looks and dashboards |
| board | list_boards, get_board, create_board, update_board, delete_board, get_board_section, create_board_section, update_board_section, delete_board_section, get_board_item, create_board_item, update_board_item, delete_board_item |
Curate content with boards, sections, and items |
| folder | list_folders, get_folder, create_folder, update_folder, delete_folder, get_folder_children, get_folder_ancestors, get_folder_looks, get_folder_dashboards |
Navigate and manage the folder hierarchy |
| health* | health_pulse, health_analyze, health_vacuum |
Instance health checks and usage analysis |
| modeling | list_projects, get_project, create_project, update_project, delete_project, get_project_manifest, get_project_deploy_key, create_project_deploy_key, list_project_files, get_file, create_file, update_file, delete_file, validate_project, list_datagroups, reset_datagroup |
LookML project lifecycle, file edits, syntax validation, and datagroup cache management |
| git | get_git_branch, list_git_branches, create_git_branch, switch_git_branch, deploy_to_production, reset_to_production |
Git operations and production deployment |
| admin | list_users, get_user, create_user, update_user, delete_user, create_credentials_email, send_password_reset, list_roles, get_role, create_role, update_role, delete_role, get_role_groups, get_role_users, list_permissions, list_permission_sets, create_permission_set, update_permission_set, delete_permission_set, list_model_sets, create_model_set, update_model_set, delete_model_set, list_groups, create_group, delete_group, add_group_user, remove_group_user, set_role_groups, set_role_users, set_user_roles, get_user_roles, list_schedules, create_schedule, update_schedule, delete_schedule, run_schedule_once |
User, role, RBAC, group, and schedule management |
| connection | get_connection, list_connection_dialects, create_connection, update_connection, delete_connection, test_connection |
Database connection CRUD and health checks |
| user_attributes | list_user_attributes, get_user_attribute, create_user_attribute, update_user_attribute, delete_user_attribute, list_user_attribute_group_values, set_user_attribute_group_values, delete_user_attribute_group_value, list_user_attribute_values_for_user, set_user_attribute_user_value, delete_user_attribute_user_value |
User attribute definitions plus per-group and per-user value overrides (row-level security, per-developer credentials, filter defaults) |
| credentials | list_credentials_api3, create_credentials_api3, get_credentials_api3, delete_credentials_api3, get_credentials_ldap, delete_credentials_ldap, get_credentials_saml, delete_credentials_saml, get_credentials_oidc, delete_credentials_oidc, get_credentials_google, delete_credentials_google |
Non-email credentials — API3 key-pair rotation plus get/delete for LDAP, SAML, OIDC, and Google SSO links |
| audit | get_query_history, get_content_usage, get_pdt_build_log, get_schedule_history, get_user_activity_log, list_running_queries, kill_query, list_active_sessions, get_session, terminate_session, list_project_ci_runs, get_project_ci_run, trigger_project_ci_run |
Query history, content usage, PDT build + schedule + event logs via system__activity, plus live-ops (running queries, sessions, CI runs) |
| workflows | provision_connection, bootstrap_lookml_project, deploy_lookml_changes, rollback_to_production, provision_user, grant_access, offboard_user, rotate_api_credentials, audit_query_activity, audit_instance_health, investigate_runaway_queries, find_stale_content, disable_stale_sessions |
Task-oriented Layer 2 compositions — provisioning workflows (bootstrap, deploy, provision users) plus ops/audit workflows (offboard, rotate credentials, audit, cleanup) |
Selecting Groups
# Default groups only (explore, query, schema, content, health)
looker-mcp-server
# Specific groups
looker-mcp-server --groups explore,query
# All groups (including board, folder, modeling, git, admin, connection, user_attributes, credentials, audit, workflows)
looker-mcp-server --groups all
Configuration Reference
All settings are configured via environment variables with the LOOKER_ prefix, or via a .env file.
| Variable | Default | Description |
|---|---|---|
LOOKER_BASE_URL |
(required) | Base URL of the Looker instance |
LOOKER_CLIENT_ID |
API3 client ID for service account | |
LOOKER_CLIENT_SECRET |
API3 client secret for service account | |
LOOKER_API_VERSION |
4.0 |
Looker API version |
LOOKER_DEPLOYMENT_TYPE |
self_hosted |
self_hosted or google_cloud_core |
LOOKER_TRANSPORT |
stdio |
stdio or streamable-http |
LOOKER_HOST |
0.0.0.0 |
HTTP bind address |
LOOKER_PORT |
8080 |
HTTP port |
LOOKER_SUDO_AS_USER |
true |
Enable user impersonation when identity headers are present |
LOOKER_SUDO_ASSOCIATIVE |
false |
Attribute sudo activity to admin (true) or impersonated user (false) |
LOOKER_USER_EMAIL_HEADER |
X-User-Email |
HTTP header carrying user email for sudo impersonation |
LOOKER_USER_TOKEN_HEADER |
X-User-Token |
HTTP header carrying pre-exchanged OAuth token |
LOOKER_TIMEOUT |
60.0 |
HTTP request timeout in seconds |
LOOKER_MAX_ROWS |
5000 |
Default maximum rows for query tools |
LOOKER_VERIFY_SSL |
true |
Verify TLS certificates |
LOOKER_LOG_LEVEL |
INFO |
Logging level |
LOOKER_MCP_AUTH_TOKEN |
Static bearer token for MCP-level authentication |
Authentication & Impersonation
The server supports three authentication modes, selected automatically based on configuration and request headers.
Mode 1: Service Account (API Key)
The simplest mode — all API calls use the configured service-account credentials.
export LOOKER_CLIENT_ID="your-api3-client-id"
export LOOKER_CLIENT_SECRET="your-api3-client-secret"
export LOOKER_SUDO_AS_USER=false
Mode 2: Admin Sudo (Self-Hosted Looker)
An admin service account impersonates individual users via Looker's login_user API. The user is identified by an email address in the request headers (typically set by an upstream gateway).
export LOOKER_CLIENT_ID="admin-api3-client-id"
export LOOKER_CLIENT_SECRET="admin-api3-client-secret"
export LOOKER_DEPLOYMENT_TYPE=self_hosted
export LOOKER_SUDO_AS_USER=true
When a request arrives with X-User-Email: alice@company.com, the server:
- Logs in with admin credentials
- Looks up Alice's Looker user ID by email
- Creates a sudo session as Alice via
login_user - Executes the tool call as Alice
- Logs out both sessions
Note: On Looker (Google Cloud core),
login_useronly works for Embed-type users. Regular users require OAuth mode.
Mode 3: OAuth Pass-Through (Google Cloud Core)
For Looker (Google Cloud core) deployments where regular users cannot be impersonated via sudo. An upstream gateway performs OAuth token exchange and passes the user's token in a header.
export LOOKER_CLIENT_ID="fallback-api3-client-id"
export LOOKER_CLIENT_SECRET="fallback-api3-client-secret"
export LOOKER_DEPLOYMENT_TYPE=google_cloud_core
export LOOKER_SUDO_AS_USER=true
When a request arrives with X-User-Token: <oauth-access-token>, the server uses that token directly — no login/logout cycle needed.
If no token header is present, the server falls back to service-account mode.
Automatic Mode Selection
When LOOKER_SUDO_AS_USER=true (the default), the server uses a DualModeIdentityProvider that automatically routes:
- Self-hosted → sudo (via
X-User-Emailheader) - Google Cloud core → OAuth (via
X-User-Tokenheader) - No identity headers → service account fallback
Extending with Custom Identity Providers
The IdentityProvider protocol is the primary extension point for integrating with custom authentication systems.
from looker_mcp_server.identity import IdentityProvider, LookerIdentity, RequestContext
from looker_mcp_server.server import create_server
from looker_mcp_server.config import LookerConfig
class MyIdentityProvider:
"""Custom identity provider that integrates with your auth system."""
async def resolve(self, context: RequestContext) -> LookerIdentity:
# Extract identity from headers, tokens, etc.
token = context.headers.get("authorization", "").removeprefix("Bearer ")
if token:
# Exchange for a Looker-scoped token via your auth system
looker_token = await my_token_exchange(token)
return LookerIdentity(mode="oauth", access_token=looker_token)
# Fall back to service account
return LookerIdentity(
mode="api_key",
client_id="your-client-id",
client_secret="your-client-secret",
)
# Wire it up
config = LookerConfig()
mcp, client = create_server(config, identity_provider=MyIdentityProvider())
The RequestContext provides:
headers— HTTP request headers (empty in stdio mode)tool_name— name of the MCP tool being invokedtool_group— which group the tool belongs toarguments— arguments passed to the tool
MCP-Level Authentication
To protect the MCP server itself (who can connect to it), set a static bearer token:
export LOOKER_MCP_AUTH_TOKEN="your-secret-mcp-token"
MCP clients must then include this token in their connection. This is separate from Looker API authentication.
Health Endpoints
When running in HTTP mode, the server exposes:
GET /healthz— liveness probe (always returns 200 if server is running)GET /readyz— readiness probe (verifies Looker connectivity with a login/logout cycle)
Development
# Clone
git clone https://github.com/ultrathink-solutions/looker-mcp-server.git
cd looker-mcp-server
# Install dependencies
uv sync --locked --dev
# Run quality checks
uv run ruff check . # lint
uv run ruff format . # format
uv run pyright # type check
uv run pytest tests/ -v # tests
See CONTRIBUTING.md for contribution guidelines.
License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file looker_mcp_server-0.12.0.tar.gz.
File metadata
- Download URL: looker_mcp_server-0.12.0.tar.gz
- Upload date:
- Size: 160.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0cd0bb3820e8c9e6596db930b4bab2b302cacc60bc4e25064b900948000c793a
|
|
| MD5 |
79b96f14ac4b3db279a5e569318ecd1c
|
|
| BLAKE2b-256 |
f3aa07c33537a060d2545aece0e50e1a874abf8a14e0f3eb4690a615fcc7ac99
|
File details
Details for the file looker_mcp_server-0.12.0-py3-none-any.whl.
File metadata
- Download URL: looker_mcp_server-0.12.0-py3-none-any.whl
- Upload date:
- Size: 74.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dcb7d575492e212dd2b9aa32ccb83c67bbddbbb3bec7f8e86b94aa6aa64a7a75
|
|
| MD5 |
21391a4f882824a331058483d819d83d
|
|
| BLAKE2b-256 |
d1255ead80372ccd27ba7842add4d1e5ac888839e4500b45913e2410eb51086e
|