Prerequisites
Toolbox version
Built from main (module github.com/googleapis/mcp-toolbox); the affected code is unchanged on the latest release.
Environment
- OS type and version: macOS (Darwin); reproducible on any platform — the bug is in argument normalization, not OS-specific.
- How are you running Toolbox: Compiled from source (
go build).
Client
- Client: MCP client driving the Looker tools (e.g. an LLM-backed MCP host).
- Version: n/a — any client that sends a
filters value wrapped in quotes triggers it.
- Example filter payload that triggers the bug:
{"view.attribution_model": "\"first_touch\""}
Expected Behavior
When a looker-query (or any tool that goes through the shared lookercommon.ProcessQueryArgs helper) targets an explore whose filter is backed by a LookML parameter field declared type: unquoted, the parameter value should reach Looker bare so it is substituted into SQL exactly as written (e.g. first_touch).
Current Behavior
Filter values frequently arrive with a literal layer of wrapping quote characters (e.g. "first_touch" or 'first_touch') — LLM clients tend to add them. ProcessQueryArgs only strips wrapping quotes from filter keys, not from values, so the quoted value is sent to Looker as-is. For type: unquoted parameters Looker substitutes the value bare into SQL via {% parameter %}, producing invalid SQL like ... = "first_touch" (or a stray-quote literal) and the query fails.
This affects every tool built on the shared helper: looker-query, looker-query-sql, looker-query-url, looker-make-look, and looker-add-dashboard-element.
Steps to reproduce?
- Define a LookML
parameter field with type: unquoted and reference it in SQL via {% parameter view.attribution_model %}.
- Run a
looker-query against that explore with a filter value the client has wrapped in quotes, e.g. {"view.attribution_model": "\"first_touch\""}.
- The generated SQL contains the wrapping quotes around the parameter value and the query errors out, instead of substituting
first_touch bare.
Additional Details
Proposed fix: in internal/tools/looker/lookercommon/lookercommon.go, extend the existing key-quote-stripping in ProcessQueryArgs to also strip a single layer of wrapping "/' from string values (only when the first and last characters match). Bare values are correct for all parameter types over the WriteQuery wire format, so this is safe to apply unconditionally. Additionally, tighten the filters parameter description so the model is told not to wrap values in extra quotes, addressing the upstream cause while the normalization stays a backstop. Unit tests for the new behavior are ready and I'm happy to send a PR.
Prerequisites
Toolbox version
Built from
main(modulegithub.com/googleapis/mcp-toolbox); the affected code is unchanged on the latest release.Environment
go build).Client
filtersvalue wrapped in quotes triggers it.{"view.attribution_model": "\"first_touch\""}Expected Behavior
When a
looker-query(or any tool that goes through the sharedlookercommon.ProcessQueryArgshelper) targets an explore whose filter is backed by a LookMLparameterfield declaredtype: unquoted, the parameter value should reach Looker bare so it is substituted into SQL exactly as written (e.g.first_touch).Current Behavior
Filter values frequently arrive with a literal layer of wrapping quote characters (e.g.
"first_touch"or'first_touch') — LLM clients tend to add them.ProcessQueryArgsonly strips wrapping quotes from filter keys, not from values, so the quoted value is sent to Looker as-is. Fortype: unquotedparameters Looker substitutes the value bare into SQL via{% parameter %}, producing invalid SQL like... = "first_touch"(or a stray-quote literal) and the query fails.This affects every tool built on the shared helper:
looker-query,looker-query-sql,looker-query-url,looker-make-look, andlooker-add-dashboard-element.Steps to reproduce?
parameterfield withtype: unquotedand reference it in SQL via{% parameter view.attribution_model %}.looker-queryagainst that explore with a filter value the client has wrapped in quotes, e.g.{"view.attribution_model": "\"first_touch\""}.first_touchbare.Additional Details
Proposed fix: in
internal/tools/looker/lookercommon/lookercommon.go, extend the existing key-quote-stripping inProcessQueryArgsto also strip a single layer of wrapping"/'from string values (only when the first and last characters match). Bare values are correct for all parameter types over theWriteQuerywire format, so this is safe to apply unconditionally. Additionally, tighten thefiltersparameter description so the model is told not to wrap values in extra quotes, addressing the upstream cause while the normalization stays a backstop. Unit tests for the new behavior are ready and I'm happy to send a PR.