Skip to content

Launcher: Claude Code on Linux and WSL - #143

Merged
pmoses-s1 merged 2 commits into
Sentinel-One:mainfrom
pmoses-s1:fix/launcher-claude-code-wsl
Oct 30, 2026
Merged

pmoses-s1 merged 2 commits into
Sentinel-One:mainfrom
pmoses-s1:fix/launcher-claude-code-wsl

Conversation

@pmoses-s1

@pmoses-s1 pmoses-s1 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Mac/Linux launcher now works with Claude Code on Linux and WSL:

  • Servers started by Claude Code no longer time out on connect.
  • One command registers the servers with Claude Code.
  • WSL keeps credentials in Windows Credential Manager.

The image, MCP and plugin are unchanged at 1.5.7.

Changes

mcp/docker/s1-secops-mcp-launch.sh

  • Connect fix:
    • The launcher forwards the client's stdin to the container with dd instead of cat.
    • Claude Code connects stdio servers over a Unix socket. The uutils cat shipped by recent Ubuntu releases does not forward socket input, so the server never received initialize.
    • dd handles pipes and sockets alike, and works with both GNU and BSD dd.
  • install --claude-code:
    • Registers s1-secops-mcp, purple-mcp and virustotal with claude mcp add-json --scope user, carrying the read-only or read-write setting.
    • Removes the older entry names virustotal-mcp and sentinelone-mcp only when claude mcp get shows they run this launcher.
    • Sets MCP_TIMEOUT to at least 120 s in ~/.claude/settings.json:
      • A larger existing value is kept.
      • The file is updated through its resolved path, so a symlinked settings file stays a symlink.
      • The install message notes that the setting applies to all MCP servers.
    • Selected automatically when install runs inside Claude Code. The launcher says so and states that the Claude Desktop config is unchanged.
    • If the claude CLI is not on PATH, the launcher prints the registration commands instead.
  • WSL credentials:
    • When no Linux Secret Service is available, credentials are read from and written to Windows Credential Manager through powershell.exe. These are the same items that s1-secops-mcp-launch.ps1 and Cowork on Windows use.
    • Secret values travel on stdin and stdout only, never on the command line.
    • Each read has a wall-clock deadline (S1_KEYCHAIN_TIMEOUT), so an unresponsive powershell.exe cannot hang the start.
  • Prompts and guidance:
    • install and setup prompt through the terminal when stdin is a pipe.
    • Inside Claude Code, or with no terminal, they print a single setup command instead of prompting.
    • Missing Docker WSL integration is reported with the setting to change.
  • Diagnostics: S1_LAUNCH_TRACE=<file> logs launcher stages with timestamps. Only stage names and durations are logged, never values.

Tests and CI

mcp/docker/launcher-test.sh now covers:

  • the initialize handshake over a Unix socketpair (the way Claude Code connects), alongside the pipe check;
  • --claude-code against a stub claude:
    • the entries and the write opt-out;
    • conditional removal of older entries;
    • the settings merge, keeping a larger value and preserving a symlink;
    • automatic selection inside Claude Code;
  • on Linux, the WSL credential path against a stand-in powershell.exe: the timeout on a hung call, concurrent reads, and the setup write and read-back.

The new workflow .github/workflows/launcher-tests.yml runs shellcheck on the launcher and then launcher-test.sh, with the image pulled.

Docs

  • docs/upgrading.md: re-run install to pick up the new launcher, with the Claude Code and WSL notes.
  • docs/docker.md:
    • --claude-code and Windows Credential Manager added to the commands and options.
    • Troubleshooting rows for the Claude Code connect timeout, Docker WSL integration, docker.sock permission and powershell.exe interop.
  • docs/installation.md: a Claude Code (CLI) section for macOS, Linux and WSL.
  • README.md, docs/credentials.md and docs/testing.md updated to match.
  • Changelog entries in CHANGELOG.md and mcp/s1-secops-mcp/CHANGELOG.md.

Verification

  • WSL2, end to end:
    • Test setup: Ubuntu with uutils coreutils on Windows 11, Docker Desktop with WSL integration, Claude Code 2.1.312.
    • install --claude-code registered the servers and read the existing credentials from Windows Credential Manager.
    • /mcp connected s1-secops-mcp, purple-mcp and virustotal.
  • launcher-test.sh:
    • macOS: 65 passed, 0 failed, including the pipe and Unix socket handshakes.
    • Linux container with pwsh: 91 passed, 0 failed, including the WSL credential cases.
    • Run from this branch's mcp/docker/ layout: 65 passed, 0 failed.
    • CI, launcher-tests on ubuntu-latest: 93 passed, 0 failed.
  • Repo checks:
    • shellcheck is clean on the launcher.
    • The scrub guard passes.
    • 0 broken links across 273 markdown files.

@pmoses-s1
pmoses-s1 requested a review from a team as a code owner October 29, 2026 23:53

@nate-smalls-s1 nate-smalls-s1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. The dd relay fix is correct for pipes and sockets, secrets only travel on stdin/stdout, the Credential Manager read is bounded, and CI is green. Please add the doc updates below before merging.

Docs to update before merge

  1. plugins/s1-secops-skills/docs/upgrading.md: add a note that existing users must re-run install to refresh the installed launcher copy. Without it the dd fix never reaches ~/.local/bin.
  2. plugins/s1-secops-skills/docs/docker.md: line 52 still says setup uses security or secret-tool, and the option list on line 59 omits --claude-code. The troubleshooting rows don't cover WSL / Docker Desktop integration.
  3. plugins/s1-secops-skills/README.md line 515: the install/config options paragraph omits --claude-code (line 140 mentions it).
  4. plugins/s1-secops-skills/docs/credentials.md: the platform table has no WSL row for Windows Credential Manager via powershell.exe.
  5. plugins/s1-secops-skills/docs/testing.md line 218: the launcher-test coverage list doesn't mention the new socket check.

Non-blocking, fine as follow-ups

  • install --claude-code runs claude mcp remove --scope user for virustotal-mcp and sentinelone-mcp. That deletes a user's own entry if they use either name.
  • Inside Claude Code with no --config-path, install silently skips the Claude Desktop config. A --desktop opt-out would help.
  • The ~/.claude/settings.json write uses temp file + os.replace, which replaces a symlinked settings file with a plain one.
  • python3 is now required on the --claude-code path with no fallback.
  • If sleep 0.1 is unsupported, the fallback sleep 1 makes the credential timeout about 10x longer than set.
  • CI doesn't run launcher-test.sh or shellcheck, and there is no committed test for --claude-code (stub claude) or the WSL credential path.

- Remove older Claude Code entry names only when they run this launcher
- State when install selects --claude-code inside Claude Code; Desktop config unchanged
- Update ~/.claude/settings.json through its resolved path; document MCP_TIMEOUT scope
- Wall-clock timeout on Windows Credential Manager reads
- Tests for --claude-code and the WSL credential path; new launcher-tests workflow
- Docs: upgrading, docker, README, credentials, installation, testing
@pmoses-s1

pmoses-s1 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the review. All items are addressed in the latest push.

Docs

  1. docs/upgrading.md: new "Launcher update for Claude Code, Linux and WSL" section, linked from the index. It covers re-running install to refresh the copy in ~/.local/bin, --claude-code for Claude Code users, and the WSL prerequisites.
  2. docs/docker.md: the setup line now includes Windows Credential Manager (WSL), and --claude-code is in the install description and the options list. Four new troubleshooting rows: Claude Code connect timeout, Docker WSL integration, docker.sock permission, and powershell.exe interop.
  3. README.md: the options paragraph lists --config-path and --claude-code.
  4. docs/credentials.md: WSL rows in the backend and the inspect/delete tables.
  5. docs/testing.md: the coverage list includes the new cases (below).

Code

  • Older entry names (virustotal-mcp, sentinelone-mcp) are removed only when claude mcp get shows they run this launcher. Our own names are replaced, as the Claude Desktop merge does.
  • When install selects --claude-code automatically inside Claude Code, it says so and states that the Claude Desktop config was left unchanged, with the command to configure it.
  • ~/.claude/settings.json is updated through its resolved path, so a symlinked settings file stays a symlink. The install message and docs state that MCP_TIMEOUT applies to every MCP server in Claude Code.
  • The Windows Credential Manager read uses a wall-clock deadline, so S1_KEYCHAIN_TIMEOUT holds whether or not sleep accepts fractions.
  • python3 stays required on the --claude-code path, consistent with the Linux Claude Desktop path; the launcher exits with a clear message when it is missing.

Tests and CI

  • launcher-test.sh adds the following cases, under sh, dash and bash:
    • --claude-code against a stub claude: entries and the write opt-out, conditional removal of old entries, the settings merge with a larger value and a symlink preserved, and automatic selection inside Claude Code.
    • On Linux, the WSL credential path against a stand-in powershell.exe: the timeout on a hung call, three concurrent reads, and the setup write and read-back, with pwsh.
  • New workflow .github/workflows/launcher-tests.yml runs shellcheck on the launcher and launcher-test.sh with the image pulled, so the pipe and Unix socket handshakes run in CI.
  • Results:
    • macOS: launcher-test passes, including both live handshakes.
    • Linux container with pwsh: all hermetic and WSL cases pass.
    • shellcheck is clean on the launcher.
    • CI, launcher-tests on ubuntu-latest: 93 passed, 0 failed, including the WSL credential cases and the Unix socket handshake.

@pmoses-s1
pmoses-s1 merged commit 903e46a into Sentinel-One:main Oct 30, 2026
6 checks passed

@marcorottigni-s1 marcorottigni-s1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved

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.

3 participants