Add Goose agent support via Databricks AI Gateway#61
Open
bkvarda wants to merge 4 commits into
Open
Conversation
Goose (https://github.com/aaif-goose/goose) is a native Rust binary with a built-in Databricks provider. This wires it into ucode alongside codex, claude, gemini, opencode, copilot, and pi. Key design decisions: - Config is merged (not overwritten) into ~/.config/goose/config.yaml so that user-defined extensions and preferences survive reconfiguration. - Only DATABRICKS_HOST, GOOSE_PROVIDER, and GOOSE_MODEL are managed; the token is injected as DATABRICKS_TOKEN at launch and refreshed every 30 minutes. - Goose ships as a native binary (not an npm package), so install_tool_binary now short-circuits with a helpful message for tools with an empty `package`. - Adds pyyaml as a runtime dependency for YAML config read/write. - Adds read_yaml_safe and write_yaml_file helpers to config_io.py. - 34 focused unit tests cover the full agent surface (spec, model selection, overlay rendering, runtime env, config write/merge, validate_cmd, validate_env). MCP support (config.yaml extensions block) is a follow-up, consistent with Pi. Co-authored-by: Isaac
- MCP: wire goose into MCP_CLIENTS; add write_mcp_server_config and remove_mcp_server_config using goose's streamable_http extension format; OAUTH_TOKEN is forwarded via env_keys and injected at runtime - Skills: enable the goose skills platform extension in the managed overlay so .goose/skills and .claude/skills directories are loaded by default - Gemini model support: default_model now falls back to gemini_models from the Databricks gateway; check_gateway_endpoint and _TOOL_DISCOVERY_SOURCES updated accordingly; cli discovery consumers include goose in both claude and gemini lookups - build_runtime_env now sets OAUTH_TOKEN alongside DATABRICKS_TOKEN - 52 goose unit tests (up from 34); updated test_mcp.py and test_agents_init.py Co-authored-by: Isaac
added 2 commits
May 21, 2026 15:44
Goose resolves ${OAUTH_TOKEN} in streamable_http extension headers from
its config file, not the process environment. Without OAUTH_TOKEN as a
top-level key in config.yaml, goose fails to start any MCP extension
with: "Failed to fetch secret 'OAUTH_TOKEN' from config: Configuration
value not found: OAUTH_TOKEN".
write_tool_config now writes OAUTH_TOKEN alongside DATABRICKS_HOST so
goose can substitute it into the Authorization header of each registered
MCP extension. It is refreshed every 30 minutes by the background token
refresh thread alongside the rest of the managed config.
Co-authored-by: Isaac
Goose resolves env_keys from the system keyring (service="goose",
username="secrets"), not from config.yaml top-level keys. The token
written to OAUTH_TOKEN: in config.yaml was never found during
extension startup, causing "Configuration value not found: OAUTH_TOKEN".
The fix: store the token in the extension's envs dict instead.
Goose merges envs with env_keys before header substitution, so
${OAUTH_TOKEN} in the Authorization header resolves from envs.
write_tool_config now also refreshes envs.OAUTH_TOKEN for all
streamable_http extensions on every token refresh (every 30 min),
keeping long-running sessions authenticated. configure_client_mcp_server
fetches a fresh token when writing a new goose MCP extension.
Co-authored-by: Isaac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DATABRICKS_HOST,GOOSE_PROVIDER,GOOSE_MODEL) into~/.config/goose/config.yamlwhile preserving user-defined extensions and preferencesdefault_modelprefers Claude (sonnet → opus → haiku) and falls back to Databricks-hosted Gemini models;check_gateway_endpointand CLI discovery consumers updated accordinglywrite_mcp_server_config/remove_mcp_server_configuse goose'sstreamable_httpextension format;OAUTH_TOKENis injected at runtime and referenced viaenv_keysfor extension header authtype: platform) is enabled in the managed overlay so.goose/skillsand.claude/skillstool directories are active by defaultDATABRICKS_TOKENis injected as an env variable at launch and refreshed every 30 minutes via a background thread — never written to the config file;OAUTH_TOKENis set alongside it for MCP authinstall_tool_binarynow short-circuits with an actionable install message for tools with an emptypackageread_yaml_safeandwrite_yaml_filehelpers toconfig_io.py, withpyyaml>=6.0as a new runtime dependencytest_mcp.pyandtest_agents_init.pyTest plan
uv run pytest— all 566 tests passuv run ruff check .— no lint errorsucode configure --agent goosemerges config without overwriting user extensions; skills extension is enableducode gooselaunches a Goose session with auto-refreshed tokenucode configure mcpdiscovers and saves external MCP connections to~/.config/goose/config.yamlasstreamable_httpextensionsThis pull request and its description were written by Isaac.