Set up the Looker Toolbox MCP server
Looker Toolbox is a hosted MintMCP connector, built on Google's MCP Toolbox, that gives agents a curated set of Looker tools against one Looker instance: querying explores, running Looks and dashboards, editing LookML, and checking instance health. You pick exactly which tools the connector exposes by declaring them in a configuration value, so a read-only analytics connector and a LookML developer connector can run side by side from the same image.
Prerequisites
- A MintMCP admin account
- A Looker instance (Looker Original or Looker Google Cloud Core) reachable from MintMCP's runtime
- Admin access to that Looker instance, to create a service account and API credentials
Create a service account and API credentials
Every user of this connector acts in Looker as one shared identity, so create a dedicated user with only the permissions your tools need rather than reusing an admin account. Looker permissions are the real boundary here: a user that can only access_data and see_looks cannot edit LookML or create dashboards, whatever tools you declare.
For Looker Original
- Go to Admin → Users and create a user for the connector (for example
mintmcp-toolbox), then assign it a role with only the model sets and permissions the tools need. - Open the user, scroll to API 4.0 Keys and click Edit Keys → New API 4.0 Key.
- Copy the Client ID and Client Secret, because the secret is shown only once.
For Looker Google Cloud Core
- Have a Looker admin enable API credential management on the Users page.
- Sign in as the service account user, open the Account page → API 4.0 Keys → Generate New Key.
- Copy the Client ID and Client Secret.
| Credential | Where to find it | Environment variable |
|---|---|---|
| Looker instance URL | Your browser's address bar (no trailing slash) | LOOKER_BASE_URL |
| Client ID | Admin → Users → Edit → API 4.0 Keys | LOOKER_CLIENT_ID |
| Client Secret | Shown once at key creation | LOOKER_CLIENT_SECRET |
Looker instances that serve the API on port 19999 need the port in the URL, e.g. https://looker.example.com:19999.
Allow MintMCP to reach Looker
Most Looker instances are reachable from the public internet, so this step usually needs nothing. If yours sits behind an IP allowlist (Looker Original with an allowlist, or a private network in front of Looker Core), allow the connector's dedicated egress IP: open the Looker Toolbox connector page under MCP store > Manage store in MintMCP and copy the Egress IP shown there.
Define the tools
The connector exposes only the tools you declare in the TOOLBOX_TOOLS environment variable. You define tools, not data sources, because every tool runs against the Looker instance you configure at install time and the connector wires that connection in for you, so you never set a source. Each tool has a kind and an optional description, and you can group tools into named toolsets.
Every Looker tool is ready-made: declare the kind and a description, and the tool exposes its own input parameters automatically (e.g. looker-query accepts a model, explore, fields, filters and limit). There is no custom-statement tool for Looker; looker-query is the general query entry point.
{
"tools": {
"get_models": { "kind": "looker-get-models", "description": "List LookML models." },
"get_explores": { "kind": "looker-get-explores", "description": "List explores in a model." },
"get_dimensions": { "kind": "looker-get-dimensions", "description": "List dimensions in an explore." },
"get_measures": { "kind": "looker-get-measures", "description": "List measures in an explore." },
"query": { "kind": "looker-query", "description": "Run a query against an explore and return rows." },
"query_url": { "kind": "looker-query-url", "description": "Build a shareable explore URL for a query." },
"get_dashboards": { "kind": "looker-get-dashboards", "description": "Search saved dashboards." },
"run_dashboard": { "kind": "looker-run-dashboard", "description": "Run every tile in a dashboard." }
},
"toolsets": {
"explore": ["get_models", "get_explores", "get_dimensions", "get_measures", "query", "query_url"],
"dashboards": ["get_dashboards", "run_dashboard"]
}
}
Available tools
Pick a category to see what each tool does, then expand Copy as JSON for a ready-to-paste config. The first two categories cover what most teams want, while the LookML, git and health categories change or audit the instance and need a service account with developer or admin permissions.
- Explore & query
- Looks & dashboards
- LookML & projects
- Git & connections
- Health & analytics
| Kind | Purpose |
|---|---|
looker-get-models | List LookML models |
looker-get-explores | List explores in a model |
looker-get-dimensions | List dimensions in an explore |
looker-get-measures | List measures in an explore |
looker-get-filters | List filter-only fields in an explore |
looker-get-parameters | List parameters in an explore |
looker-query | Run an inline query against an explore and return the rows |
looker-query-sql | Return the SQL Looker would run for a query, without running it |
looker-query-url | Build a shareable explore URL for a query |
Copy as JSON
{
"tools": {
"get_models": { "kind": "looker-get-models", "description": "List LookML models." },
"get_explores": { "kind": "looker-get-explores", "description": "List explores in a model." },
"get_dimensions": { "kind": "looker-get-dimensions", "description": "List dimensions in an explore." },
"get_measures": { "kind": "looker-get-measures", "description": "List measures in an explore." },
"get_filters": { "kind": "looker-get-filters", "description": "List filter-only fields in an explore." },
"get_parameters": { "kind": "looker-get-parameters", "description": "List parameters in an explore." },
"query": { "kind": "looker-query", "description": "Run a query against an explore and return rows." },
"query_sql": { "kind": "looker-query-sql", "description": "Show the SQL Looker would run for a query." },
"query_url": { "kind": "looker-query-url", "description": "Build a shareable explore URL for a query." }
},
"toolsets": { "explore": ["get_models", "get_explores", "get_dimensions", "get_measures", "get_filters", "get_parameters", "query", "query_sql", "query_url"] }
}
| Kind | Purpose |
|---|---|
looker-get-looks | Search saved Looks by name or description |
looker-run-look | Run the query behind a saved Look |
looker-make-look | Create a Look in the service account's personal folder |
looker-get-dashboards | Search saved dashboards by name or description |
looker-run-dashboard | Run the queries behind every tile in a dashboard |
looker-make-dashboard | Create an empty dashboard in the service account's personal folder |
looker-add-dashboard-element | Add a tile to an existing dashboard |
looker-add-dashboard-filter | Add a filter to an existing dashboard |
looker-generate-embed-url | Generate a signed private embed URL for a Look, dashboard or explore |
Copy as JSON
{
"tools": {
"get_looks": { "kind": "looker-get-looks", "description": "Search saved Looks." },
"run_look": { "kind": "looker-run-look", "description": "Run a saved Look." },
"make_look": { "kind": "looker-make-look", "description": "Create a Look." },
"get_dashboards": { "kind": "looker-get-dashboards", "description": "Search saved dashboards." },
"run_dashboard": { "kind": "looker-run-dashboard", "description": "Run every tile in a dashboard." },
"make_dashboard": { "kind": "looker-make-dashboard", "description": "Create an empty dashboard." },
"add_dashboard_element": { "kind": "looker-add-dashboard-element", "description": "Add a tile to a dashboard." },
"add_dashboard_filter": { "kind": "looker-add-dashboard-filter", "description": "Add a filter to a dashboard." },
"generate_embed_url": { "kind": "looker-generate-embed-url", "description": "Generate a private embed URL." }
},
"toolsets": {
"content_read": ["get_looks", "run_look", "get_dashboards", "run_dashboard", "generate_embed_url"],
"content_write": ["make_look", "make_dashboard", "add_dashboard_element", "add_dashboard_filter"]
}
}
These tools read and edit LookML through the Looker IDE API. Writes only apply in dev mode, so pair them with looker-dev-mode and the git tools and give the service account the develop permission.
| Kind | Purpose |
|---|---|
looker-dev-mode | Switch the session into or out of dev mode |
looker-get-projects | List LookML projects |
looker-get-project-files | List files in a project |
looker-get-project-file | Read a LookML file |
looker-create-project-file | Create a LookML file |
looker-update-project-file | Replace the contents of a LookML file |
looker-delete-project-file | Delete a LookML file |
looker-get-project-directories | List directories in a project |
looker-create-project-directory | Create a directory in a project |
looker-delete-project-directory | Delete a directory from a project |
looker-validate-project | Validate a project's LookML and report errors |
looker-get-lookml-tests | List LookML data tests in a project |
looker-run-lookml-tests | Run LookML data tests |
looker-create-view-from-table | Generate a LookML view from a database table |
Copy as JSON
{
"tools": {
"dev_mode": { "kind": "looker-dev-mode", "description": "Switch the session into or out of dev mode." },
"get_projects": { "kind": "looker-get-projects", "description": "List LookML projects." },
"get_project_files": { "kind": "looker-get-project-files", "description": "List files in a project." },
"get_project_file": { "kind": "looker-get-project-file", "description": "Read a LookML file." },
"create_project_file": { "kind": "looker-create-project-file", "description": "Create a LookML file." },
"update_project_file": { "kind": "looker-update-project-file", "description": "Replace a LookML file's contents." },
"delete_project_file": { "kind": "looker-delete-project-file", "description": "Delete a LookML file." },
"get_project_directories": { "kind": "looker-get-project-directories", "description": "List directories in a project." },
"create_project_directory": { "kind": "looker-create-project-directory", "description": "Create a project directory." },
"delete_project_directory": { "kind": "looker-delete-project-directory", "description": "Delete a project directory." },
"validate_project": { "kind": "looker-validate-project", "description": "Validate a project's LookML." },
"get_lookml_tests": { "kind": "looker-get-lookml-tests", "description": "List LookML data tests." },
"run_lookml_tests": { "kind": "looker-run-lookml-tests", "description": "Run LookML data tests." },
"create_view_from_table": { "kind": "looker-create-view-from-table", "description": "Generate a view from a database table." }
},
"toolsets": {
"lookml_read": ["get_projects", "get_project_files", "get_project_file", "get_project_directories", "validate_project", "get_lookml_tests", "run_lookml_tests"],
"lookml_write": ["dev_mode", "create_project_file", "update_project_file", "delete_project_file", "create_project_directory", "delete_project_directory", "create_view_from_table"]
}
}
| Kind | Purpose |
|---|---|
looker-list-git-branches | List git branches of a project |
looker-get-git-branch | Show the project's current git branch |
looker-create-git-branch | Create a git branch |
looker-switch-git-branch | Switch the project to another branch |
looker-delete-git-branch | Delete a git branch |
looker-get-connections | List database connections |
looker-get-connection-databases | List databases in a connection |
looker-get-connection-schemas | List schemas in a connection |
looker-get-connection-tables | List tables in a connection schema |
looker-get-connection-table-columns | List columns of the given tables |
Copy as JSON
{
"tools": {
"list_git_branches": { "kind": "looker-list-git-branches", "description": "List git branches of a project." },
"get_git_branch": { "kind": "looker-get-git-branch", "description": "Show the current git branch." },
"create_git_branch": { "kind": "looker-create-git-branch", "description": "Create a git branch." },
"switch_git_branch": { "kind": "looker-switch-git-branch", "description": "Switch git branch." },
"delete_git_branch": { "kind": "looker-delete-git-branch", "description": "Delete a git branch." },
"get_connections": { "kind": "looker-get-connections", "description": "List database connections." },
"get_connection_databases": { "kind": "looker-get-connection-databases", "description": "List databases in a connection." },
"get_connection_schemas": { "kind": "looker-get-connection-schemas", "description": "List schemas in a connection." },
"get_connection_tables": { "kind": "looker-get-connection-tables", "description": "List tables in a schema." },
"get_connection_table_columns": { "kind": "looker-get-connection-table-columns", "description": "List columns of tables." }
},
"toolsets": {
"git": ["list_git_branches", "get_git_branch", "create_git_branch", "switch_git_branch", "delete_git_branch"],
"connections": ["get_connections", "get_connection_databases", "get_connection_schemas", "get_connection_tables", "get_connection_table_columns"]
}
}
The health tools need a service account with admin permissions. The Conversational Analytics tools also need LOOKER_PROJECT and LOOKER_LOCATION set, on a Google Cloud project with the Gemini Data Analytics API enabled.
| Kind | Purpose |
|---|---|
looker-health-pulse | Health checks: database connections, dashboard performance, errors |
looker-health-analyze | Analyze projects, models and explores for usage |
looker-health-vacuum | Find unused LookML objects |
looker-conversational-analytics | Ask questions about your data in natural language via Conversational Analytics |
looker-list-agents | List Conversational Analytics agents |
looker-get-agent | Retrieve a Conversational Analytics agent |
looker-create-agent | Create a Conversational Analytics agent |
looker-update-agent | Update a Conversational Analytics agent |
looker-delete-agent | Delete a Conversational Analytics agent |
Copy as JSON
{
"tools": {
"health_pulse": { "kind": "looker-health-pulse", "description": "Run instance health checks." },
"health_analyze": { "kind": "looker-health-analyze", "description": "Analyze projects, models and explores." },
"health_vacuum": { "kind": "looker-health-vacuum", "description": "Find unused LookML objects." },
"ask_data_insights": { "kind": "looker-conversational-analytics", "description": "Ask questions about your data in natural language." }
},
"toolsets": {
"health": ["health_pulse", "health_analyze", "health_vacuum"],
"conversational": ["ask_data_insights"]
}
}
Add Looker Toolbox to MintMCP
- In MintMCP, go to MCP store and open the Recommended servers tab.
- Select Looker Toolbox to open its configuration panel.
- Fill in the connection fields with the values from Create a service account and API credentials:
| Field | Value | Required |
|---|---|---|
| Looker URL | Instance URL, no trailing slash | Yes |
| Client ID | API 4.0 client ID of the service account | Yes |
| Client secret | API 4.0 client secret, stored as a secret | Yes |
| Verify TLS certificate | true (default), or false for a self-signed certificate | No |
| Google Cloud project | Only for the Conversational Analytics tools | No |
| Google Cloud location | Only for the Conversational Analytics tools (default: us) | No |
- Paste your tool definitions from Define the tools into Tool Definitions.
- Click Install.
The connector authenticates to Looker and loads your tools on startup, and shows as active once Looker accepts the credentials. If Looker is unreachable, the credentials are rejected, or the tool definitions are invalid, the connector fails to start and its logs say why.
All fields are global: every user shares the service account, and MintMCP's audit log records which user issued each call. A few tuning variables exist for the rare cases that need them and can be added as extra environment variables: LOOKER_TIMEOUT (API timeout, default 600s) and LOOKER_SHOW_HIDDEN_MODELS, LOOKER_SHOW_HIDDEN_EXPLORES and LOOKER_SHOW_HIDDEN_FIELDS (default true; set to false to keep LookML objects marked hidden out of the listing tools).
Security considerations
- Every user acts in Looker as the single configured service account, so its Looker role and model set are the real guardrail. Grant only what the declared tools need, and keep it read-only unless writes are explicitly intended.
- The connector only ever talks to the Looker instance you configure and only accepts
looker-*tool kinds, but it does not restrict what those tools do in Looker. Tools that create content, edit LookML or switch git branches change the instance for everyone, so omit them or leave the service account without thedeveloppermission to prevent writes. - Looker's own audit log attributes every action to the service account; use MintMCP's audit log to see which user was behind each call.
- Keep Verify TLS certificate at
trueunless the instance uses a self-signed certificate. - If your instance supports an IP allowlist, combine it with the dedicated egress IP so only MintMCP can use these credentials from outside your network.
Next steps
- Tool customization to control which tools reach which users
- MCP gateway administration to manage access and permissions