Phosphor

io.github.Kirusshenkin由 GitHub 账号 Kirusshenkin 发布v0.3.0更新于 Oct 24, 2026

Hosts, metrics, Docker and authorized_keys over a macOS terminal's live SSH connections

概览

AI 生成的概览

Phosphor 的 MCP 组件让助手通过 macOS 应用已有的 SSH 连接列出主机、读取服务器指标、查看 Docker 容器与日志,并在授权范围内执行命令。

可以做什么
  • 主机管理:列出已配置的 SSH 主机,并在人工确认后新增、修改或删除主机条目。
  • 读取服务器状态:基于 /proc 快照获取每核负载、内存、磁盘、网络以及各容器的 CPU 与内存。
  • 检查 Docker:列出容器,查看统计、挂载、环境变量,并按 tail 与过滤条件跟踪日志。
  • 执行操作:在用户已授权的模式下运行命令、重启容器。
  • 管理 authorized_keys:读取和编辑密钥条目,指纹在本地计算,写入为原子操作。
适用场景
适合已在 Mac 上运行 Phosphor、希望让助手检查服务器健康状况、查看容器日志或在自有主机上做有限操作的场景,无需把 SSH 密钥或原始 shell 交给模型。以只读监控为主,写权限需按主机单独开启。
运行要求
仅限 macOS。需安装并运行 Phosphor 应用,并在应用内按会话用 Touch ID 授予 MCP 访问权限。客户端注册随应用附带的 phosphor-mcp stdio 组件,它通过用户主目录下的 Unix socket 与应��通信,自身不携带凭据。每台主机默认禁用,需设为只读、确认或完全模式。
安装前请注意
当主机设为确认或完全模式时,可执行命令、重启容器并编辑 authorized_keys;所有主机默认禁用,应授予最小权限,生产服务器建议保持只读。主机列表的修改始终需要人工确认。被入侵的服务器可在模型读取的日志行中注入内容。应用为临时签名,安装时会出现 macOS 隔离警告,请校验发布校验和。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Phosphor,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Phosphor

A macOS terminal that also runs your servers.

Shell, Docker, metrics, keys and files — over one SSH connection per host. Unlocked with your fingerprint. Green on black, because that is how it should look.

SSH client · Docker manager · server monitor · SFTP · authorized_keys editor · MCP server for Claude Code and Claude Desktop · macOS 26 · Swift 6 · MIT

[Terminal]


The problem

You keep four windows open to do one job. A terminal for the shell. A second terminal for docker logs -f. A third for htop. A browser tab for whatever dashboard someone installed on the box. Each of them logs in separately, each one asks for the key passphrase again, and none of them knows what the others are looking at.

Phosphor opens one SSH connection per host and multiplexes everything through it — the interactive shell, container logs, docker commands, /proc snapshots, SFTP transfers, port forwards. One login. One tunnel through your proxy. One place where the state lives.

And because that state is already in the app, it also exposes an MCP server: Claude Code and Claude Desktop can use your servers through your connections, your keys and your access policy — with every call written to an audit log.


What it does

Docker, without leaving the terminal

[Docker]

The container list is a sidebar, not a separate app. Inspect, stats, mounts, environment and live logs with --tail and a filter, streamed over the SSH connection you already have. Environment values whose name looks like a secret (PASS, KEY, TOKEN, SECRET) are masked in the UI and never copied into the audit log.

No Docker Engine API to expose, no socket to tunnel: it shells out to docker with JSON output, which works on every box where Docker already runs.

Metrics that cost one channel

[Metrics]

Per-core load, memory with the cache broken out, disks, network, and per container CPU and memory — from /proc snapshots taken over a single long-lived channel. No agent to install on the server, no swarm of exec channels. Polling stops when the window is hidden, and every buffer has a ceiling.

Hosts, groups and tags

[Hosts]

One group per host, as many tags as you like. The group carries the settings — how to reach it, which key, which theme, what MCP is allowed to do — and tags are just for finding things. Import ~/.ssh/config and keep going.

Unlock with a fingerprint

[Touch ID]

Phosphor has no account and no password of its own. There is a profile on this Mac, and your fingerprint opens it. Passwords, passphrases and TOTP seeds live in the Keychain behind biometrics; keys can live in the Secure Enclave, where they cannot be copied off the machine at all. Risky actions ask again.

A new server, set up by a recipe

[Provisioning]

Connect to a fresh box and Phosphor probes it: what is installed, what is listening, whether anyone has been here before. If it is empty, it offers a recipe — packages and unattended upgrades, Docker with log size caps, nginx, certbot, a firewall that only opens 22/80/443, and finally disabling password login. Every step is idempotent, every step shows the exact commands, and the lockout guard means password login is closed only after a second key-based connection has proved it works.

Keys you can actually see

[Keys]

authorized_keys as a table instead of a text file: fingerprints computed locally, weak RSA flagged, options shown, disabled entries kept as comments. The key you are currently connected with cannot be removed without an explicit confirmation, writes are atomic, and a backup stays on the server.

Files on both sides

[SFTP]

Two panes, drag between them or in from Finder. Same SSH connection, same proxy. A dropped transfer resumes where it stopped.

Make it yours

[Theme]

Themes are plain JSON in themes/ — keep them in git, trade them with people, import .itermcolors, alacritty and base16. Palette, font, ligatures, line height, background image, scanlines, glow, vignette, window opacity. Bind a theme to a group so production is unmistakably red.

And there is a cat in the corner. Or a sugar glider. It sleeps while the app is locked, it never covers your output, and one switch turns it off forever.


Give an agent your servers without giving it your keys

Phosphor is also a Model Context Protocol server. Register one command and Claude Code, Claude Desktop, Cursor or any other MCP client can list your hosts, read metrics, inspect containers, follow logs and — when you allow it — run commands, restart containers, manage authorized_keys, and add, change or remove hosts in your own list. Anything that edits the list asks you first, in every mode.

The difference from handing a model a shell: the app holds the connection, the agent holds nothing.

Shell tool with raw sshCredentials in an MCP configPhosphor
Where the key liveson disk, agent-readableon disk, agent-readableKeychain / Secure Enclave, behind Touch ID
What is reachableeverythingeverythingonly hosts you enabled, in the mode you set
rm -rf /runsrunsrefused by a deny-list that overrides every mode
Human in the loopnonenoneper-write confirmation, grants expire in 15 min
Trail afterwardsshell history, maybenonean audit log with no writing tool
Secrets in outputwhatever is on screenwhatever is on screenmasked before the model sees them
Runaway loopunboundedunboundedrate-limited writes
sh
claude mcp add phosphor /Applications/Phosphor.app/Contents/MacOS/phosphor-mcp

In the MCP registry it is io.github.Kirusshenkin/phosphor; every release also ships a .mcpb bundle with a published SHA-256 for clients that install that way.

Thirteen tools, seven of them read-only. Every host starts disabled — nothing is reachable until you choose read-only, confirm or full for it, and production servers are meant to stay read-only. A compromised server can put anything it likes into a log line the model reads; it still cannot grant itself a mode, get past the deny-list, or erase the record of trying.

Full details: docs/MCP.md — tool catalogue, policy, audit, and the exact error the agent gets when the app is closed, locked or refusing.

Principles

No integrations. The only network traffic the app makes is SSH to your own servers and the update feed. No telemetry, no accounts, no third-party services, nothing phoning home.

Secrets stay secret. Never in a log line, a crash report, an MCP audit entry or an error message. Terminal scrollback is not written to disk by default.

Errors tell you what to do. "Could not connect" is a bug. "The proxy at 127.0.0.1:10808 is not answering — is V2Box running?" is an error message. The app distinguishes a dead proxy from an unreachable server from a refused credential, because otherwise diagnosis is guesswork.

It stays fast because it is open all day. Bytes from the network are batched into ~16 ms windows before they reach the emulator, the draw path allocates nothing, every buffer is bounded, polling stops when the window is not visible, and animations only ever touch transform and opacity.

Strict Swift 6 concurrency, in every target, with no escape hatches. Network, parsing and disk work live in actors; only view models are on the main actor.

Two languages. English and Russian, both through a String Catalog. Not one hardcoded interface string — a linter checks.


Status

Builds, runs, 179 tests green. Eleven screens: lock, hosts, terminal with persistent sessions, files, Docker, monitor, keys, provisioning, AI activity and settings. Interface in Russian and English.

What works against a real server: SSH over one multiplexed connection per host, container listing with actions and streaming logs, /proc metrics, reading and editing authorized_keys, provisioning recipes, both file panes, and an interactive shell that rides the same socket.

MCP works end to end: an phosphor-mcp shim ships inside the bundle, speaks JSON-RPC over stdio and proxies to a local socket the app owns. Every host starts disabled, writes need a decision from a person, a deny-list overrides every mode, and the audit log has no writing tool — the model can act but cannot erase its trail.

Hosts import from ~/.ssh/config, from known_hosts and from a Termius vault, whose plaintext dump is deleted once the hosts are inside the encrypted profile.

What is not built yet: the native Citadel transport (the process-based one is tested and works), the pet in the corner, and in-app updates through Sparkle.

Idle CPU is zero — no timers, polling pauses when the window is in the background.

Install

sh
curl -fsSL https://github.com/Kirusshenkin/terminalOs/releases/latest/download/Phosphor.zip -o Phosphor.zipunzip -q Phosphor.zip -d /Applicationsxattr -dr com.apple.quarantine /Applications/Phosphor.app

Or download Phosphor.zip from the release page and drag the app into Applications.

macOS will warn you the first time. The app is ad-hoc signed — there is no Apple Developer certificate behind it — so everything downloaded from the internet lands in quarantine. This is not damage:

  1. Double-click the app, dismiss the warning.
  2. System Settings → Privacy & Security → scroll down → Open Anyway.
  3. Confirm. It never asks again.

The xattr command above does the same thing in one step.

Every release ships SHA256SUMS.txt; verify with shasum -a 256 -c SHA256SUMS.txt.

There is no in-app updater yet — check the releases page. The version you are running is in the About panel.

Getting started

A guided walkthrough of the first run: docs/GUIDE.ru.md (Russian), docs/GUIDE.en.md (English).

For AI agents

Each release carries latest.json, so nothing has to be scraped:

sh
curl -fsSL https://github.com/Kirusshenkin/terminalOs/releases/latest/download/latest.json
json
{  "version": "0.1.0",  "url": "https://github.com/.../Phosphor-0.1.0.zip",  "sha256": "…",  "mcp": { "command": "/Applications/Phosphor.app/Contents/MacOS/phosphor-mcp",           "transport": "stdio" }}

The bundle contains an MCP stdio shim. Register it and Phosphor exposes its tools:

json
{  "mcpServers": {    "phosphor": {      "command": "/Applications/Phosphor.app/Contents/MacOS/phosphor-mcp"    }  }}

The shim talks to the running app over a Unix socket in the user's home directory; it carries no credentials of its own. If the app is closed or locked it says so and every tool call fails closed — MCP access is off by default and has to be granted in the app, per session, with a fingerprint.

Releasing

Tag and push:

sh
git tag v0.1.0 && git push origin v0.1.0

.github/workflows/release.yml runs the tests, then .github/scripts/package.sh — which is the same script used locally, so a release can always be reproduced on your own machine:

sh
MARKETING_VERSION=0.1.0 BUILD_NUMBER=1 ./.github/scripts/package.sh

It produces dist/Phosphor-<version>.zip, a copy named Phosphor.zip (only an exact filename works behind /releases/latest/download/), SHA256SUMS.txt and latest.json. The workflow unzips the archive again and runs codesign --verify on it before publishing: a bundle whose signature does not survive the round trip will not open on anyone's machine.

Build

Requires macOS 26+ and a Swift 6.3 toolchain.

sh
git clone https://github.com/Kirusshenkin/terminalOs.gitcd terminalOsswift buildswift test./.github/scripts/check.sh     # format, lint, build, tests — before every commitgit config core.hooksPath .github/hooks   # once: blocks commits with real addresses or keys

Layout

Sources/          PhosphorCore, VaultKit, HostsKit, SSHKit, DockerKit,                  MetricsKit, KeysKit, ThemeKit, ProvisionKit, PhosphorUIdesign/           UI artboards (.dc.html), one per screendocs/PLAN.md      The full architecture plan, in Russiandocs/images/      Screenshots rendered from the artboards

Contributing

The plan comes first — requirements land in docs/PLAN.md before any code. Conventions worth knowing before a pull request: code, names and commit messages in English; user-visible strings in both English and Russian through Strings, never hardcoded; strict Swift 6 concurrency in every target; no swallowed errors, and every message says what happened and what to do; no secrets in logs, errors or the audit; bounded buffers and nothing allocated in the draw path.

Security

Please report vulnerabilities privately — see SECURITY.md. The threat model is docs/PLAN.md §15.

License

MIT

来源:README.md,提交 4595d30

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

4
  1. v0.3.0最新Oct 8, 2026
  2. v0.2.3Oct 5, 2026
  3. v0.2.2Oct 4, 2026
  4. v0.1.1Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分