Skip to content

feat(desktop): Config tab to pin oab-mcp target + reload core - #10

Open
brettchien wants to merge 1 commit into
feat/desktop-mcp-sidecarfrom
feat/oab-mcp-config-tab
Open

feat(desktop): Config tab to pin oab-mcp target + reload core#10
brettchien wants to merge 1 commit into
feat/desktop-mcp-sidecarfrom
feat/oab-mcp-config-tab

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

Why

The deploy_list AccessDeniedException Brett hit wasn't a missing IAM policy — it was credential/region drift. The desktop spawned the oab-mcp sidecar with only OAB_CLUSTER, so it inherited the host's ambient AWS default chain and pointed at the wrong account/region (916371022086 / ap-southeast-1), where the oab cluster doesn't exist. The cluster actually lives in 504190915686 / ap-east-2.

Fix: make each oab-mcp's target explicit and persisted, and let the user change it from the UI without restarting the app.

What

  • src-tauri/src/config.rs (new) — McpConfig { cluster, profile?, region? }, persisted to the app config dir as mcp-config.json. First-run defaults seed from the process env so behaviour is unchanged until the user saves.
  • src-tauri/src/mcp.rsspawn() takes the config and builds a curated child env: inherit the parent env minus every AWS_*, then re-inject the configured AWS_PROFILE / AWS_REGION (+AWS_DEFAULT_REGION). This is deliberate: a stale ambient AWS_ACCESS_KEY_ID would otherwise outrank AWS_PROFILE in the SDK chain and re-introduce the drift. The child is now held in an Option and killable via shutdown() for reload.
  • src-tauri/src/lib.rsget_config / set_config commands. set_config persists, then kills + respawns the core with the new env. deploy_list now defaults to the configured cluster. Config is loaded into managed state at startup.
  • console/ — third Config tab (index.html, config.ts, styles.css): a profile / region / cluster form. Save calls set_config, then refreshes the roster against the new target. Browser build disables the form.

v1 is a single target, shaped to grow into a multi-fleet registry (provider-tagged connections) — the direction discussed in the thread.

Verification

  • console: npm run typecheck, npm test (8/8), npm run build — all green.
  • ⚠️ Rust: not compiled in my env — the ECS container lacks the GTK/WebKit system libs Tauri needs (glib-sys build fails on missing glib-2.0.pc). I verified every external API against the pinned crate sources instead:
    • Command::env_clear() / envs<I,K,V> / sidecar() -> Command — tauri-plugin-shell 2.3.5
    • CommandChild::kill(self) — same
    • PathResolver::app_config_dir() -> Result<PathBuf>, Manager::path() — tauri 2.11.5
    • command-arg default is camelCase (new_confignewConfig) — tauri-macros 2.6.3
    • Please run cargo build/cargo check in src-tauri/ on the host to confirm the compile.

How to test on the host

  1. Build & run the desktop app (cargo tauri dev or the bundled build).
  2. Open the Config tab → set profile brettchien, region ap-east-2, cluster oabSave & reload core.
  3. Activity pane should log config saved — reloading core… then a fresh spawn; roster should list the oab services (oab-prod-mira, oab-prod-orca) instead of the AccessDenied error.
  4. Config persists across restarts (mcp-config.json in the app config dir).

Base is feat/desktop-mcp-sidecar (not main) because this builds directly on the sidecar work that isn't merged yet.

🤖 Generated with Claude Code

The desktop spawned oab-mcp with only OAB_CLUSTER, so the sidecar
inherited the host's ambient AWS credential chain — silently pointing
Studio at the wrong account/region (deploy_list AccessDenied on a
cluster that doesn't exist in that account). This adds an explicit,
persisted connection target and a way to change it without restarting
the app.

- config.rs: McpConfig { cluster, profile?, region? }, persisted to the
  app config dir (mcp-config.json); env-seeded defaults on first run.
- mcp.rs: spawn() takes the config and builds a *curated* child env —
  inherit parent env minus all AWS_*, then re-inject the configured
  AWS_PROFILE / AWS_REGION so a stale ambient AWS_ACCESS_KEY_ID can't
  outrank the profile. Child is now killable for reload (shutdown()).
- lib.rs: get_config / set_config commands; set_config persists then
  kills+respawns the core; deploy_list defaults to the configured cluster.
- console: third "Config" tab with a profile/region/cluster form; save
  invokes set_config and refreshes the roster against the new target.

v1 is a single target; shaped to grow into a multi-fleet registry.

Verified: console typecheck + tests + build green. Rust API checked
against pinned crate sources; not compiled here (ECS container lacks the
GTK/WebKit system libs Tauri needs) — needs a host cargo build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant