siGit Code wave three: stdio MCP, web search, and the repo tabs
Status: draft v1 (2026-07-05). Owner: product/eng. Audience: internal (private repo). Scope: the third feature wave for siGit Code, following sigit-code-parity-roadmap.md (wave one, shipped in v1.3.2) and sigit-code-copilot-cli-parity.md (wave two, in review). One ecosystem unlock, one core capability with a product hook, one differentiator. The three are independent and run in parallel; spec 3 stacks on the unmerged TUI tabs branch and rebases once that merges.
1. Spec: stdio MCP transport
Branch: feature/mcp-stdio-transport (sigit) · Touches: src/mcp.rs
Problem
Nearly every published MCP server (filesystem, Playwright, Postgres, GitHub's own) is stdio-first. siGit Code speaks only Streamable HTTP, so users cannot plug in most of the MCP ecosystem. Claude Code and Copilot CLI both support stdio.
Design
mcp.tomlserver entries gain the stdio shape:command(required),args = [...],[server.env], all mutually exclusive withurl. Existing HTTP entries keep working unchanged.- A stdio server is spawned at discovery (
mcp::init): child process with piped stdin/stdout, stderr inherited to the log. JSON-RPC frames are newline-delimited per the MCP stdio transport spec. The sameinitialize/tools/listhandshake andtools/callforwarding as HTTP; the transport is an enum behind the existing server cache. - Lifecycle: the child lives for the sigit process; a dead child fails calls
with a clear in-band error and is not restarted mid-session (restart on
/reload). Discovery timeout applies to the handshake like HTTP. All children are killed on exit. - Same namespacing (
mcp__<server>__<tool>), same output caps, same/mcplisting (show the command instead of the URL). - Cross-platform: plain std/tokio process handling, no cfg(unix).
Acceptance
- A
[[server]]entry withcommand = "npx",args = ["-y", "@modelcontextprotocol/server-everything"](or a local stub) discovers tools and serves calls end to end. - Unit/integration tests use a tiny scripted stdio MCP server (a shell or Rust stub speaking the handshake) rather than a real npm package; CI stays hermetic. A dead-child call returns the in-band error.
2. Spec: web search through sigit.si
Branch: feature/mcp-web-search (sigit-si) · Touches: the MCP server, a new search proxy service
Problem
The agent can fetch a page (read_website) but cannot find one. Both
competitors ship search. Routing it through sigit.si instead of baking a
provider key into the client makes search a signed-in cloud feature, keeps one
place to swap providers, and adds a concrete reason to sigit login.
Design
- New MCP tool on the official server:
web_search {query, count?}returning a compact JSON list of{title, url, snippet}(count default 5, max 10). - Behind it, a
WebSearchServicewith a provider adapter. First provider: Brave Search API (SEARCH_PROVIDER=brave,BRAVE_SEARCH_API_KEY), chosen for its simple REST shape; the adapter boundary keeps Bing/SearXNG swappable. Unconfigured provider returns an in-band ToolError telling the operator what to set, never a 500. - Rate limit per user (reuse the existing rate-limit pattern if one exists; otherwise a simple per-user counter, e.g. 60 searches/hour) so a runaway agent cannot burn the provider quota.
- Auth and result envelope follow the existing MCP tools exactly. Update
.agents/specs/mcp-server.md. - Client side: nothing structural (MCP plumbing exists). Read-only classification of official-server tools ships with spec 3.
Acceptance
- Request specs: happy path (provider stubbed with WebMock or the repo's HTTP-stubbing convention), unconfigured provider, rate limit, param validation. No live provider calls in CI.
3. Spec: Issues and Pull requests in the terminal
Branch: feature/tui-repo-tabs (sigit, stacked on feature/tui-tabs) ·
Touches: src/chat.rs, src/permissions.rs, src/main.rs (prompt)
Problem
Copilot CLI shows Issues and Pull requests tabs when run inside a GitHub repo. sigit.si is our own git host, the MCP repo workflow tools exist server-side (sigit-si #3), and siGit Code should be the best terminal client sigit.si has.
Design
- When the session cwd's
originremote points at the sigit.si host (parsegit remote get-url origin, compare against theSIGIT_API_URLhost, default sigit.si), the TUI adds a Repo tab after History: two sections, Issues and Pull requests, fetched through the official MCP server (mcp__sigit__list_issues/mcp__sigit__list_pull_requests, repo derived from the remote'sowner/name). Up/Down selects, Enter opens the detail (get_issue/get_pull_request) in a scrollable view,rrefreshes, section toggle oni/p(or Left/Right). - Fetches run as spawned tasks feeding the render loop (the Cloud tab pattern); the tab degrades gracefully when signed out, MCP is off, or the remote is not sigit.si (tab hidden entirely in that last case).
- Permission classification: the official server's read-only tools
(
list_*,get_*,search_code,get_file_contents,web_search) are classified read-only inpermissions.rsso browsing never prompts; everything elsemcp__sigit__*stays mutating. Match on the official server's namespace prefix plus tool-name prefix, not a hardcoded full list, so new server-side read tools inherit it. - Prompt guidance in
main.rs: issue and PR workflows on sigit.si repos go through themcp__sigit__*tools; reference them by exact name. - Stacking: branch from
feature/tui-tabs. After sigit #25 merges, rebase ontodevelopmentbefore opening the PR so it shows only its own commits (the repo's stacking rule).
Acceptance
- In a repo cloned from sigit.si while signed in, the Repo tab lists real issues and PRs and opens details; signed out it shows the sign-in hint.
- Unit tests for the remote-URL parsing (ssh and https forms, non-sigit hosts) and the read-only classification; TUI flows verified under tmux against a scripted MCP server.
4. After this wave
Hooks, a /context usage display, memory recall over remember, then the two
big strategic items: sandboxing (Cloud Agent trust) and checkpointing/rewind.