{"id":48822823,"url":"https://github.com/yotsuda/splash","last_synced_at":"2026-04-17T07:01:16.949Z","repository":{"id":350278420,"uuid":"1206131104","full_name":"yotsuda/splash","owner":"yotsuda","description":"Shared console MCP server for any shell (bash, pwsh, cmd) — AI and user work in the same terminal. Real-time command visibility, interactive prompt support, session persistence, multi-shell management with automatic cwd handoff.","archived":false,"fork":false,"pushed_at":"2026-04-13T21:36:10.000Z","size":689,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-13T23:29:05.996Z","etag":null,"topics":["ai","bash","claude","cmd","conpty","devops","mcp","mcp-server","model-context-protocol","powershell","pwsh","shared-console","shell","terminal"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/splashshell","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yotsuda.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T15:54:36.000Z","updated_at":"2026-04-13T21:36:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"470e810f-27f1-45d7-b3fe-145a57876724","html_url":"https://github.com/yotsuda/splash","commit_stats":null,"previous_names":["yotsuda/splashshell","yotsuda/splash"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/yotsuda/splash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yotsuda%2Fsplash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yotsuda%2Fsplash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yotsuda%2Fsplash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yotsuda%2Fsplash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yotsuda","download_url":"https://codeload.github.com/yotsuda/splash/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yotsuda%2Fsplash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31803790,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","bash","claude","cmd","conpty","devops","mcp","mcp-server","model-context-protocol","powershell","pwsh","shared-console","shell","terminal"],"created_at":"2026-04-14T16:00:21.192Z","updated_at":"2026-04-14T16:00:29.794Z","avatar_url":"https://github.com/yotsuda.png","language":"C#","readme":"# splash\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/1343f694-1c05-4899-9faa-d2b1138aa3ba\" alt=\"social-image\" width=\"640\" /\u003e\n\u003c/div\u003e\n\n**A shell MCP server for AI that actually holds a session.** Load `Import-Module Az` once and let AI run 50 follow-up cmdlets in milliseconds each. Watch every command happen in a real terminal window — the same one you can type into yourself.\n\n## Install\n\nPrerequisite: [.NET 9 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/9.0). No global install needed — `npx` fetches a ~5 MB native binary on first run.\n\n```bash\nclaude mcp add-json splash -s user '{\"command\":\"npx\",\"args\":[\"-y\",\"splashshell@latest\"]}'\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eClaude Desktop\u003c/summary\u003e\n\nAdd to `%APPDATA%\\Claude\\claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"splash\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"splashshell@latest\"]\n    }\n  }\n}\n```\n\nThe `@latest` tag is important: without it, npx will happily keep reusing a stale cached copy even after a new version ships.\n\n\u003c/details\u003e\n\n## Why SplashShell?\n\nOther shell MCP servers are either **stateless** (fresh subshell per command, nothing persists) or **headless** (persistent PTY, but invisible to you). SplashShell is neither — and that unlocks things the others can't do.\n\n### PowerShell becomes a first-class AI environment\n\nSession persistence helps every shell, but for **PowerShell it's transformative**. Most MCP shell servers spin up a fresh subshell per command — which makes real PowerShell workflows impractical:\n\n- **10,000+ modules on [PowerShell Gallery](https://www.powershellgallery.com/).** Az (Azure), AWS.Tools, Microsoft.Graph (Entra ID / M365), ExchangeOnlineManagement, PnP.PowerShell, SqlServer, ActiveDirectory — plus every CLI in PATH (git, docker, kubectl, terraform, gh, az, aws, gcloud) and full access to .NET types.\n- **30–70 second cold imports, paid once.** `Import-Module Az.Compute, Az.Storage, Az.Network` can take over a minute on the first call. A subshell-per-command MCP server pays that cost on *every* command and the AI gives up on Azure workflows entirely. With SplashShell, the AI imports once and every subsequent cmdlet runs in milliseconds.\n- **Live .NET object graphs.** PowerShell pipes rich objects, not text. After `$vms = Get-AzVM -Status`, the AI can chain arbitrary follow-ups against the live object — filter, group, drill into nested properties — without re-hitting Azure. In a one-shot MCP server, that object vanishes the moment the command returns.\n- **Interactive build-up of complex work.** Set a variable, inspect it, reshape it, feed it back into the next cmdlet. Build a multi-step workflow one command at a time with every previous step's result still in scope.\n\n```powershell\n# Command 1 — cold import, paid once for the whole session\nImport-Module Az.Compute, Az.Storage, Az.Network\n\n# Command 2 — instant; capture the result into a variable\n$vms = Get-AzVM -Status\n\n# Command 3 — instant; same session, $vms still in scope\n$vms | Where-Object PowerState -eq \"VM running\" |\n    Group-Object Location | Sort-Object Count -Descending\n\n# Command 4 — instant; reach into a new service, same session\nGet-AzStorageAccount | Where-Object { -not $_.EnableHttpsTrafficOnly }\n```\n\nPowerShell on SplashShell is the difference between **\"AI can answer one-off questions\"** and **\"AI can do real infrastructure work.\"** bash and cmd are fully supported too, but pwsh is where SplashShell shines.\n\n### Full transparency, in both directions\n\nSplashShell opens a **real, visible terminal window**. You see every AI command as it runs — same characters, same output, same prompt — and you can type into the same window yourself at any time. When a command hangs on an interactive prompt, stalls in watch mode, or just needs a Ctrl+C, the AI can read what's currently on the screen and send keystrokes (Enter, y/n, arrow keys, Ctrl+C) back to the running command — diagnosing and responding without human intervention.\n\n## Tools\n\n### Shell tools\n\n| Tool | Description |\n|------|-------------|\n| `start_console` | Open a visible terminal window. Pick a shell (bash, pwsh, powershell, cmd, or a full path). Optional `cwd`, `banner`, and `reason` parameters. Reuses an existing standby of the same shell unless `reason` is provided. |\n| `execute_command` | Run a pipeline. Optionally specify `shell` to target a specific shell type — finds an existing console of that shell, or auto-starts one. Times out cleanly with output cached for `wait_for_completion`. On timeout, includes a `partialOutput` snapshot so the AI can diagnose stuck commands immediately. |\n| `wait_for_completion` | Block until busy consoles finish and retrieve cached output (use after a command times out). |\n| `peek_console` | Read-only snapshot of what a console is currently displaying. On Windows, reads the console screen buffer directly (exact match with the visible terminal). On Linux/macOS, uses a built-in VT terminal interpreter as fallback. Specify a console by display name or PID, or omit to peek at the active console. Reports busy/idle state, running command, and elapsed time. |\n| `send_input` | Send raw keystrokes to a **busy** console's PTY input. Use `\\r` for Enter, `\\x03` for Ctrl+C, `\\x1b[A` for arrow up, etc. Rejected when the console is idle (use `execute_command` instead). Console must be specified explicitly — no implicit routing, for safety. Max 256 chars per call. |\n\nStatus lines include the console name, shell family, exit code, duration, and current directory:\n\n```\n✓ #12345 Sapphire (bash) | Status: Completed | Pipeline: ls /tmp | Duration: 0.6s | Location: /tmp\n```\n\n### File tools\n\nClaude Code–compatible file primitives (`read_file`, `write_file`, `edit_file`, `search_files`, `find_files`), useful when the MCP client doesn't already provide them.\n\n## Multi-shell behavior\n\nEach console tracks its own cwd. When the active console is busy, the AI is auto-routed to a sibling console of the same shell family — started at the source console's cwd — and its next command runs immediately. Manual `cd` in the terminal is detected and the AI is warned before it runs the wrong command in the wrong place.\n\nOther niceties: **console re-claim** — consoles outlive their parent MCP process, so AI client restarts don't kill your loaded modules and variables. **Multi-line PowerShell** — heredocs, foreach, try/catch, and nested scriptblocks all work. **Sub-agent isolation** — parallel AI agents each get their own consoles so they don't clobber each other's shells.\n\n\u003cdetails\u003e\n\u003csummary\u003eFull routing matrix\u003c/summary\u003e\n\n| Scenario | Behavior |\n|---|---|\n| First execute on a new shell | Auto-starts a console; warns so you can verify cwd before re-executing |\n| Active console matches requested shell | Runs immediately |\n| Active console busy, same shell requested | Auto-starts a sibling console **at the source console's cwd** and runs immediately |\n| Switch to a same-shell standby | Prepends `cd` preamble so the command runs in the source cwd, then executes |\n| Switch to a different shell | Warns to confirm cwd (cross-shell path translation is not implemented) |\n| User manually `cd`'d in the active console | Warns so the AI can verify the new cwd before running its next command |\n\n\u003c/details\u003e\n\n## How it works\n\nSplashShell runs as a stdio MCP server. When the AI calls `start_console`, SplashShell spawns itself in `--console` mode as a ConPTY worker, which hosts the actual shell (cmd.exe, pwsh.exe, bash.exe) inside a real Windows console window. The parent process streams stdin/stdout over a named pipe, injects [OSC 633 shell integration](https://code.visualstudio.com/docs/terminal/shell-integration) scripts (the same protocol VS Code uses) to emit explicit command-lifecycle markers, and parses those markers to delimit command output, track cwd, and capture exit codes — no output-silence heuristics, no prompt-string detection.\n\n\u003cdetails\u003e\n\u003csummary\u003eArchitecture diagram\u003c/summary\u003e\n\n```mermaid\ngraph TB\n    Client[\"MCP Client\u003cbr/\u003e(Claude Code, etc.)\"]\n\n    subgraph Proxy[\"SplashShell proxy (stdio MCP server)\"]\n        CM[\"Console Manager\u003cbr/\u003e(cwd tracking, re-claim,\u003cbr/\u003ecache drain, switching)\"]\n        Tools[\"start_console\u003cbr/\u003eexecute_command\u003cbr/\u003ewait_for_completion\u003cbr/\u003epeek_console / send_input\u003cbr/\u003eread_file / write_file / edit_file\u003cbr/\u003esearch_files / find_files\"]\n    end\n\n    subgraph Consoles[\"Visible Console Windows (each runs splash --console)\"]\n        subgraph C1[\"#9876 Sapphire (bash)\"]\n            PTY1[\"ConPTY + bash\u003cbr/\u003e(+ OSC 633)\"]\n        end\n        subgraph C2[\"#5432 Cobalt (pwsh)\"]\n            PTY2[\"ConPTY + pwsh\u003cbr/\u003e(+ OSC 633)\"]\n        end\n        subgraph C3[\"#1234 Topaz (cmd)\"]\n            PTY3[\"ConPTY + cmd.exe\u003cbr/\u003e(+ OSC 633 via PROMPT)\"]\n        end\n    end\n\n    User[\"User\"] -- \"keyboard\" --\u003e C1\n    User -- \"keyboard\" --\u003e C2\n    User -- \"keyboard\" --\u003e C3\n    Client -- \"stdio\" --\u003e Proxy\n    CM -- \"Named Pipe\" --\u003e C1\n    CM -- \"Named Pipe\" --\u003e C2\n    CM -- \"Named Pipe\" --\u003e C3\n    CM -. \"auto-switch\u003cbr/\u003eif busy\" .-\u003e C1\n    CM -. \"shell routing\" .-\u003e C2\n```\n\n\u003c/details\u003e\n\n### Build from source\n\n```bash\ngit clone https://github.com/yotsuda/SplashShell.git\ncd SplashShell\ndotnet publish -c Release -r win-x64 --no-self-contained -o ./dist\n```\n\nThe binary is `./dist/splash.exe`. Use the absolute path instead of the `npx` command in your MCP config.\n\n## Platform support\n\n**Windows** is the primary target (ConPTY + Named Pipe, fully tested). Unix PTY fallback for Linux/macOS is experimental.\n\n## Known limitations\n\n- **cmd.exe exit codes always read as 0** — cmd's `PROMPT` can't expand `%ERRORLEVEL%` at display time, so AI commands show as `Finished (exit code unavailable)`. Use `pwsh` or `bash` for exit-code-aware work.\n- **Don't `Remove-Module PSReadLine -Force` inside a pwsh session** — PSReadLine's background reader threads survive module unload and steal console input, hanging the next AI command. Not recoverable.\n\n## License\n\nMIT. Release notes in [CHANGELOG.md](CHANGELOG.md).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyotsuda%2Fsplash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyotsuda%2Fsplash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyotsuda%2Fsplash/lists"}