Skip to content

feat(github): add the official GitHub MCP server, read-only - #7

Open
UnbreakableMJ wants to merge 6 commits into
mainfrom
feat/github-mcp
Open

feat(github): add the official GitHub MCP server, read-only#7
UnbreakableMJ wants to merge 6 commits into
mainfrom
feat/github-mcp

Conversation

@UnbreakableMJ

Copy link
Copy Markdown
Collaborator

Adds github-mcp-server as server #13 across all thirteen hosts. GitHub work currently goes through gh in a shell, so agents parse terminal output instead of receiving structured results.

Shape

Transport stdio — nix run nixpkgs#github-mcp-server -- stdio
Version 1.0.4 (follows the system closure)
Mode read-only (GITHUB_READ_ONLY=1)
Toolsets context,repos,issues,pull_requests,actions
Secret GITHUB_PERSONAL_ACCESS_TOKEN

nix run rather than a bare binary because there is no github-mcp-server on PATH, matching the nixos server. The nixpkgs registry entry here is pinned to a local store path, so evaluation needs no network — but the version follows the system closure rather than nixpkgs HEAD (1.0.4 vs 1.8.0 upstream). Worth revisiting when the system updates.

Read-only is a §6.4 control

Not a convenience setting. Outbound contribution is default-deny and automation never initiates one; a write-capable GitHub MCP server is precisely the tool that would let a session open an upstream PR or issue without anyone deciding to. Measured: the flag drops the surface from ~90 tools to 25, with no create_*, update_*, merge_*, or push_* among them.

Three edits, not one

  • mcp.toml[[secrets]] + [[servers]] + a [servers.overrides.VSCode] for the ${input:} form. The override repeats all three env vars because an override replaces env wholesale rather than merging (manifest.rs:231-260); omitting them would silently drop read-only mode on that host alone.
  • mcpctl/src/check.rs — an ACCEPTED row for VSCode/github. Without it the override reads as invocation drift and mcpctl check fails, which is a CI gate. This coupling was undocumented; AGENTS.md now has an "Adding a server" section recording it.
  • mcpctl render — the thirteen templates plus Gemini's enablement file.

Verification

All gates: fmt, clippy -D warnings, test (13 pass), check, render --check, reuse lint.

Probed for the crates-mcp failure mode — a server logging to stdout poisons the JSON-RPC stream and the diff never shows it. This one logs to stderr: the first bytes on stdout are {", and a tools/list returns 25 tools. No STDOUT_LOGGERS row needed.

Deployed to 14 of 15 live configs. ClaudeCode is blocked by guard_process while Claude Code runs and needs a follow-up deploy --yes --host ClaudeCode. Backup at ~/.mcp-backup/20260808T114831Z/.

Three hosts (VS Code, Qwen, Goose) already had hand-made github entries pointing at the hosted api.githubcopilot.com/mcp/ endpoint — inconsistently, with Goose's enabled: false behind a dangling Bearer YOUR_GITHUB_PAT placeholder. Those are now managed. Note that VS Code's and Qwen's remote entries authenticated through the host's own GitHub sign-in and so worked without a token; Qwen's github stays broken until fill-keys runs. VS Code prompts via inputs. Stray servers were preserved — pruning is interactive-only, and --yes skips it.

Drive-by: corrects engram's store path in the README table, stale since 5c76d14.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K1mcRXXDw9jxWMxBS3ccRS

UnbreakableMJ and others added 2 commits August 8, 2026 13:10
AGENTS.md becomes the single authoritative, harness-neutral agent context
file; CLAUDE.md is reduced to an @AGENTS.md import plus Claude-Code-only
content. Both leave .gitignore and become tracked — Claude Code reads
CLAUDE.md and never AGENTS.md, so an ignored pair breaks the import on a
fresh clone and hides project knowledge from every other contributor.

Any "keep these two files in sync" instruction is removed: it was the
symptom, not the fix.

Both files were read end to end and reviewed for sensitive content before
being un-ignored. No credentials, tokens, private hostnames, or personal
filesystem paths remain; tilde-relative paths were kept, absolute ones
genericised.

Steelbore Standard v1.46 §5.7.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds github-mcp-server as server #13, reached through `nix run
nixpkgs#github-mcp-server -- stdio` like `nixos` — there is no
github-mcp-server on PATH here, and the `nixpkgs` registry entry is pinned to
a local store path, so evaluation needs no network. The version therefore
follows the system closure (1.0.4 today), not nixpkgs HEAD.

Ships read-only. GITHUB_READ_ONLY=1 drops the surface from ~90 tools to 25
with no create_*, update_*, merge_*, or push_* among them. That is a §6.4
control rather than a convenience: outbound contribution is default-deny and
automation never initiates one, so the tools that would let a session open an
upstream PR or issue are simply absent. GITHUB_TOOLSETS narrows it further to
context,repos,issues,pull_requests,actions.

The VSCode override repeats all three variables because an override replaces
`env` wholesale rather than merging, and carries a matching ACCEPTED row in
check.rs — without it the ${input:} form reads as drift and fails that gate.

Verified the server writes its logs to stderr, not stdout: the first bytes on
stdout are `{"` and a tools/list returns 25 read-only tools. No STDOUT_LOGGERS
row needed, unlike crates and terminal.

AGENTS.md gains an "Adding a server" section recording the check.rs coupling,
which was undocumented, and the stdout probe. Also corrects engram's store path
in the README table, stale since 5c76d14.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1mcRXXDw9jxWMxBS3ccRS
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

UnbreakableMJ and others added 4 commits August 9, 2026 01:55
Gives every host browser automation on a real V8 isolate -- navigate,
click, fill forms, tabs, cookies, extraction -- with no Chromium and no
Node anywhere in the chain.

One manifest edit, since it needs no credential: no [[secrets]], no
VSCode override, and therefore no ACCEPTED row in check.rs. `render`
propagated it to all 14 host templates, including Gemini's companion
enablement file, which Gemini requires before it will start a server.

`command = "obscura"` is a bare name, like engram, crates and
bravais-cli. Bravais installs Obscura into the SYSTEM profile rather
than the user one specifically so it resolves for a host launched from
a desktop entry with a pruned environment.

No RUST_LOG/NO_COLOR/TERM block, and that is measured rather than
assumed -- the trap `crates` and `terminal` document. `obscura mcp`
writes nothing to stdout but JSON-RPC and nothing at all to stderr,
even with RUST_LOG=debug set, so there is no log output to silence.

Two of its tools, browser_screenshot and browser_pdf, exist only
because Bravais builds Obscura with the `render` feature; a
default-feature build drops them from tools/list without erroring. The
manifest comment says so, because that failure is silent.

Gates: check (14 servers, no drift, no missing), render --check (no
differing), cargo test, reuse lint.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCm5Hn7HbspET32Ez7nuxN
The server table has claimed `cargo install` since before Bravais
packaged it. It is Nix-provided now -- pkgs/crates-mcp/, pinned by
version + hash, installed into the user profile -- and mcp.toml resolves
`crates-mcp` by bare name on PATH, so the entry a host spawns is
whichever copy is in that profile.

That makes the stale line more than cosmetic: it is the drift Bravais
constraint #23 exists to prevent, describing the exact imperative
install that was removed. Reading it as instructions would reintroduce a
~/.cargo/bin build shadowed only by PATH ordering.

The `cargo install` mention left in mcp.toml is engram's, and it is
history rather than a claim -- it records what the flake input replaced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCm5Hn7HbspET32Ez7nuxN
`github:utensils/mcp-nixos` is a bare branch ref, which nix re-resolves once its
flake-tarball TTL expires. On 2026-08-09 that landed on mcp-nixos 3.0.0, whose
closure is not in the binary cache. Every cold start then tried to fetch
144.9 MiB and build two derivations, so the server never answered inside the
30 s MCP init timeout — it failed in both Codex and Claude Code.

The collateral is the worse half. That build saturated the machine while the
other servers were starting from the same launch, so `perplexity` and
`sequential-thinking` timed out as well; measured on their own they start in
14.2 s and 0.85 s. One unpinned ref took down three servers.

Pinning to b94d837 makes the ref immutable: fetched once, cached permanently, no
TTL re-resolution. Warm start measured at 1.47 s against the pinned rev, versus
the 30 s timeout before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1mcRXXDw9jxWMxBS3ccRS
`~/.kimi-code/config.toml` carried a `[mcp.client]` + `[mcp.client.servers.*]`
block listing twelve servers, last touched 2026-08-03 and drifting ever since —
it still named the unpinned mcp-nixos ref after every managed config had moved
on. It looks exactly like the third Antigravity path this manifest already
documents: a live config outside `live`, quietly keeping stale servers.

It is not one. The installed Kimi binary contains zero occurrences of
`mcp.client.servers`, `mcp.client`, or `tool_call_timeout_ms`, against 84 for
`mcpServers` and 20 for `mcp.json` — Kimi moved MCP configuration to
`~/.kimi-code/mcp.json`, which is already managed here. The block was dead.

Removed from the live file (backed up first; the `api_key` and `reasoning_key`
entries that share that file were left untouched and the file still parses), and
the reasoning is recorded here so the next reader does not adopt it as a host or
build a dialect for its nested wrapper.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1mcRXXDw9jxWMxBS3ccRS
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.

1 participant