Wire steam-mcp across Web API, storefront, and authenticated client data planes #8

Closed
opened 2026-07-23 05:38:08 +00:00 by coilyco-ops · 3 comments
Owner

Problem

The deployed steam-mcp currently exposes only get_owned_games and get_recently_played. Both use one Steam access plane: IPlayerService with STEAM_WEB_API_KEY plus STEAM_STEAMID64.

The original roadmap in #1 describes broader coverage, but it was never implemented. This is a fresh execution issue rather than reopening or repurposing older work.

There are three data-access planes, not three equivalent auth credentials:

  1. Official Steam Web API, authenticated by Web API key. This exists today.
  2. Storefront/community HTTP endpoints, intentionally unauthenticated. This is absent.
  3. Steam client protocol/PICS, authenticated as the account. Account credentials bootstrap a session; a persisted refresh token should be the steady-state credential. This is absent.

The caller-facing Authelia/OAuth proxy is transport access control and must not be counted as a Steam data source.

Scope

Build a read-only multi-source layer in steam-mcp and wire its runtime configuration in coilyco-bridge/deploy.

  • Preserve the existing Web API tools and their response compatibility.
  • Add a storefront adapter and representative read-only tools for app metadata, reviews, news, search, or sale/category discovery. Choose a cohesive initial set rather than exposing raw arbitrary URLs.
  • Add a maintained Steam client-protocol library and an authenticated session adapter for PICS/product info plus account-readable surfaces such as licenses, wishlist, family sharing, or rich presence. Choose the smallest useful coherent tool set.
  • Resolve existing account credentials without exposing their values. Use them only to bootstrap login when no valid refresh token exists.
  • Persist and reuse the refresh token through the established SSM/ExternalSecret boundary. Do not perform password plus Steam Guard login on every process start or request.
  • Add explicit per-result source/provenance so callers can distinguish Web API, storefront, and client/PICS data.
  • Keep every MCP tool read-only. Do not add purchasing, trading, market mutation, refund, social mutation, or arbitrary-request tools.
  • Keep secret-bearing URLs, tokens, account credentials, and Steam Guard material out of logs, exceptions, tool results, tests, and tracked files.
  • Update README.md and docs/FEATURES.md with the exact access and credential model.

Acceptance

  • The MCP has useful tools backed by all three access planes.
  • Tests independently exercise each adapter, credential precedence, refresh-token reuse/rotation behavior, failure modes, provenance, and the no-write-tool invariant without making live Steam calls.
  • The deploy manifests inject only the required secret references and preserve the existing Authelia caller-auth overlay.
  • Existing Web API tools remain compatible.
  • Source and deploy validation pass.
  • The issue records any Steam Guard/manual bootstrap step that cannot be automated safely, without recording secret values.

Coordination

coilyco-bridge/deploy#183 is an active Eco-only repair. Keep deploy edits confined to the steam-mcp service so the workstreams do not overlap.

## Problem The deployed `steam-mcp` currently exposes only `get_owned_games` and `get_recently_played`. Both use one Steam access plane: `IPlayerService` with `STEAM_WEB_API_KEY` plus `STEAM_STEAMID64`. The original roadmap in #1 describes broader coverage, but it was never implemented. This is a fresh execution issue rather than reopening or repurposing older work. There are three **data-access planes**, not three equivalent auth credentials: 1. Official Steam Web API, authenticated by Web API key. This exists today. 2. Storefront/community HTTP endpoints, intentionally unauthenticated. This is absent. 3. Steam client protocol/PICS, authenticated as the account. Account credentials bootstrap a session; a persisted refresh token should be the steady-state credential. This is absent. The caller-facing Authelia/OAuth proxy is transport access control and must not be counted as a Steam data source. ## Scope Build a read-only multi-source layer in `steam-mcp` and wire its runtime configuration in `coilyco-bridge/deploy`. - Preserve the existing Web API tools and their response compatibility. - Add a storefront adapter and representative read-only tools for app metadata, reviews, news, search, or sale/category discovery. Choose a cohesive initial set rather than exposing raw arbitrary URLs. - Add a maintained Steam client-protocol library and an authenticated session adapter for PICS/product info plus account-readable surfaces such as licenses, wishlist, family sharing, or rich presence. Choose the smallest useful coherent tool set. - Resolve existing account credentials without exposing their values. Use them only to bootstrap login when no valid refresh token exists. - Persist and reuse the refresh token through the established SSM/ExternalSecret boundary. Do not perform password plus Steam Guard login on every process start or request. - Add explicit per-result source/provenance so callers can distinguish Web API, storefront, and client/PICS data. - Keep every MCP tool read-only. Do not add purchasing, trading, market mutation, refund, social mutation, or arbitrary-request tools. - Keep secret-bearing URLs, tokens, account credentials, and Steam Guard material out of logs, exceptions, tool results, tests, and tracked files. - Update README.md and docs/FEATURES.md with the exact access and credential model. ## Acceptance - The MCP has useful tools backed by all three access planes. - Tests independently exercise each adapter, credential precedence, refresh-token reuse/rotation behavior, failure modes, provenance, and the no-write-tool invariant without making live Steam calls. - The deploy manifests inject only the required secret references and preserve the existing Authelia caller-auth overlay. - Existing Web API tools remain compatible. - Source and deploy validation pass. - The issue records any Steam Guard/manual bootstrap step that cannot be automated safely, without recording secret values. ## Coordination `coilyco-bridge/deploy#183` is an active Eco-only repair. Keep deploy edits confined to the `steam-mcp` service so the workstreams do not overlap.
Author
Owner

WARDED_WORKFLOW: done \n

details\n\nReview: skipped — the in-container review gate was intentionally skipped because ward's temporary default awaits brokered QA.\nworkflow: merge-remote-main; review summary: skipped (brokered QA pending)\nLanded: steam-ops 7605d49; deploy bcbf7b4, both freshly verified on remote main.\nFelt: compact, well-bounded adapter work.\nConfidence: high.\nFollow-up: Kai seeds the client refresh-token SSM parameter through the documented controlled Steam Guard bootstrap.\n\n

WARDED_WORKFLOW: done ✅\n<details><summary>details</summary>\n\nReview: skipped — the in-container review gate was intentionally skipped because ward's temporary default awaits brokered QA.\nworkflow: merge-remote-main; review summary: skipped (brokered QA pending)\nLanded: steam-ops 7605d49; deploy bcbf7b4, both freshly verified on remote main.\nFelt: compact, well-bounded adapter work.\nConfidence: high.\nFollow-up: Kai seeds the client refresh-token SSM parameter through the documented controlled Steam Guard bootstrap.\n\n</details>
Author
Owner

WARDED_WORKFLOW: blocked 🛑

salvage details

An ephemeral ward container (codex mode) dispatched for this issue finished but its work was not merged to main, so cleanup preserved it on a branch before teardown and reopened the issue (a closing reference for #8 never reached main). Recover from the salvage branch below.

  • Repo: coilyco-gaming/steam-ops
  • Salvage branch: ward-salvage/steam-ops-22ae5513
  • Pull request: not opened - PR creation failed: forgejo: parse created pull request: unexpected end of JSON input
  • Reason: merge conflict integrating onto main
  • Container uptime at reap: 12m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token)

Cleanup diagnostics

--- reap diagnostics ---
ward version:      v0.792.0
version source:    pinned via WARD_VERSION/--ward-version (v0.792.0)
HEAD:              7605d499781b
origin/main:       7605d499781b
ancestry:          HEAD is ALREADY on origin/main - a salvage here is a FALSE salvage (ward#504 signature)
decision gate:     provenance missing or unreadable on already-landed merge-remote-main run
reason:            merge conflict integrating onto main
provenance:        missing or unreadable
run-owned landed:  no
working tree:      clean
container uptime:  12m (baked Forgejo PAT age proxy)
--- end reap diagnostics ---

Recover

git fetch https://forgejo.coilysiren.me/coilyco-gaming/steam-ops.git ward-salvage/steam-ops-22ae5513
git checkout -b ward-salvage/steam-ops-22ae5513 FETCH_HEAD

— Codex, via ward agent

WARDED_WORKFLOW: blocked 🛑 <details><summary>salvage details</summary> An ephemeral `ward container` (codex mode) dispatched for this issue finished but its work was **not merged to `main`**, so cleanup preserved it on a branch before teardown and reopened the issue (a closing reference for #8 never reached `main`). Recover from the salvage branch below. - **Repo:** `coilyco-gaming/steam-ops` - **Salvage branch:** `ward-salvage/steam-ops-22ae5513` - **Pull request:** not opened - PR creation failed: forgejo: parse created pull request: unexpected end of JSON input - **Reason:** merge conflict integrating onto main - **Container uptime at reap:** 12m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token) ## Cleanup diagnostics ``` --- reap diagnostics --- ward version: v0.792.0 version source: pinned via WARD_VERSION/--ward-version (v0.792.0) HEAD: 7605d499781b origin/main: 7605d499781b ancestry: HEAD is ALREADY on origin/main - a salvage here is a FALSE salvage (ward#504 signature) decision gate: provenance missing or unreadable on already-landed merge-remote-main run reason: merge conflict integrating onto main provenance: missing or unreadable run-owned landed: no working tree: clean container uptime: 12m (baked Forgejo PAT age proxy) --- end reap diagnostics --- ``` ## Recover ```bash git fetch https://forgejo.coilysiren.me/coilyco-gaming/steam-ops.git ward-salvage/steam-ops-22ae5513 git checkout -b ward-salvage/steam-ops-22ae5513 FETCH_HEAD ``` </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Owner

WARDED_WORKFLOW: reservation-released

release details

Run finished with WARDED_WORKFLOW: blocked 🛑.

ward container reap released container engineer-codex-steam-ops-8 (--harness codex): the terminal outcome supersedes the reservation, so a later redispatch no longer needs --override-reservation.

— Codex, via ward agent

<!-- ward-agent-reservation-released --> WARDED_WORKFLOW: reservation-released <details><summary>release details</summary> Run finished with `WARDED_WORKFLOW: blocked 🛑`. `ward container reap` released container `engineer-codex-steam-ops-8` (`--harness codex`): the terminal outcome supersedes the reservation, so a later redispatch no longer needs `--override-reservation`. </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/steam-ops#8
No description provided.