Skip to content

Explore steam:// IPC pipe as an experimental launch/stop primitive #31

Description

@KevinTCoughlin

Background

launch_game/stop_game currently always return 501 unsupported (see internal/server/handlers.go's handleLaunch/handleStop, and /v1/capabilities). This is by design: Valve's vendored devkit_client (python/vendor/devkit_client/__init__.py) has no remote launch/stop primitive at all — there's nothing in the current supported devkit protocol to wire up.

What I found

While validating PR #29/#30 against real hardware, I noticed devkit_utils.execute_steam_client_command (part of Valve's own on-device devkit-utils, e.g. ~/.local/share/steamos-devkit/client/devkit-utils/devkit_utils/__init__.py) writes raw steam://... commands to a local IPC pipe (~/.steam/steam.pipe) using a session token from ~/.steam/steam.token:

def execute_steam_client_command(cmd):
    """Send a command to the steam client over the IPC pipe"""
    ...
    #pipe_cmd = 'steam://{0}'.format(cmd)
    # ^ hack to execute a normal command over the IPC directly - sometimes useful
    pipe_cmd = 'devkit-1 steam://devkit-1/{0}/{1}'.format(session_token, cmd)
    ...
    pipe.write('{0}\n'.format(pipe_cmd).encode('utf-8'))

The tool this project already uses (steam-client-create-shortcut) sends create-shortcut?response=...&gameid=... over exactly this channel. In principle, the same pipe could send other steam:// commands — e.g. steam://rungameid/<appid> to launch, or some stop-equivalent — which would give launch_game/stop_game a real implementation instead of a permanent stub.

Why this is a follow-up, not immediate work

  • The comment in Valve's own source literally calls this "a hack."
  • It's undocumented and closed-source on Steam's end — no guarantee rungameid (or any other verb) is accepted over this specific devkit-1 session-token-scoped pipe protocol, vs. the normal steam:// URI handler.
  • Real risk of destabilizing the Steam client / gamescope session on real hardware if the command is malformed or unsupported.
  • Needs careful, deliberate prototyping directly against real hardware (a Steam Deck/Machine) before any code ships, with a clear rollback story if it misbehaves.

Proposed next steps

  1. Prototype sending steam://rungameid/<appid> (and look for a plausible stop/quit verb) over the pipe against a real device, observing behavior/logs, ideally in a way that's easy to abort if the Steam client misbehaves.
  2. If it works reliably, wire it into internal/client, /v1's handleLaunch/handleStop, and the launch_game/stop_game MCP tools, updating /v1/capabilities and docs/DEVICE_LAUNCH.md accordingly.
  3. If unreliable/risky, document the finding and close this out as "investigated, not viable" so future contributors don't have to rediscover it.

Related: #29, #30.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions