main
md 137 lines 6.31 KB
Rendered Raw
1 # siGit Code wave three: stdio MCP, web search, and the repo tabs
2
3 Status: draft v1 (2026-07-05). Owner: product/eng. Audience: internal (private repo).
4 Scope: the third feature wave for **siGit Code**, following
5 [sigit-code-parity-roadmap.md](sigit-code-parity-roadmap.md) (wave one, shipped
6 in v1.3.2) and [sigit-code-copilot-cli-parity.md](sigit-code-copilot-cli-parity.md)
7 (wave two, in review). One ecosystem unlock, one core capability with a product
8 hook, one differentiator. The three are independent and run in parallel; spec 3
9 stacks on the unmerged TUI tabs branch and rebases once that merges.
10
11 ---
12
13 ## 1. Spec: stdio MCP transport
14
15 **Branch:** `feature/mcp-stdio-transport` (sigit) · **Touches:** `src/mcp.rs`
16
17 ### Problem
18
19 Nearly every published MCP server (filesystem, Playwright, Postgres, GitHub's
20 own) is stdio-first. siGit Code speaks only Streamable HTTP, so users cannot
21 plug in most of the MCP ecosystem. Claude Code and Copilot CLI both support
22 stdio.
23
24 ### Design
25
26 - `mcp.toml` server entries gain the stdio shape: `command` (required),
27 `args = [...]`, `[server.env]`, all mutually exclusive with `url`. Existing
28 HTTP entries keep working unchanged.
29 - A stdio server is spawned at discovery (`mcp::init`): child process with
30 piped stdin/stdout, stderr inherited to the log. JSON-RPC frames are
31 newline-delimited per the MCP stdio transport spec. The same
32 `initialize`/`tools/list` handshake and `tools/call` forwarding as HTTP;
33 the transport is an enum behind the existing server cache.
34 - Lifecycle: the child lives for the sigit process; a dead child fails calls
35 with a clear in-band error and is not restarted mid-session (restart on
36 `/reload`). Discovery timeout applies to the handshake like HTTP. All
37 children are killed on exit.
38 - Same namespacing (`mcp__<server>__<tool>`), same output caps, same `/mcp`
39 listing (show the command instead of the URL).
40 - Cross-platform: plain std/tokio process handling, no cfg(unix).
41
42 ### Acceptance
43
44 - A `[[server]]` entry with `command = "npx"`, `args = ["-y", "@modelcontextprotocol/server-everything"]`
45 (or a local stub) discovers tools and serves calls end to end.
46 - Unit/integration tests use a tiny scripted stdio MCP server (a shell or
47 Rust stub speaking the handshake) rather than a real npm package; CI stays
48 hermetic. A dead-child call returns the in-band error.
49
50 ---
51
52 ## 2. Spec: web search through sigit.si
53
54 **Branch:** `feature/mcp-web-search` (sigit-si) · **Touches:** the MCP server, a new search proxy service
55
56 ### Problem
57
58 The agent can fetch a page (`read_website`) but cannot find one. Both
59 competitors ship search. Routing it through sigit.si instead of baking a
60 provider key into the client makes search a signed-in cloud feature, keeps one
61 place to swap providers, and adds a concrete reason to `sigit login`.
62
63 ### Design
64
65 - New MCP tool on the official server: `web_search {query, count?}` returning
66 a compact JSON list of `{title, url, snippet}` (count default 5, max 10).
67 - Behind it, a `WebSearchService` with a provider adapter. First provider:
68 Brave Search API (`SEARCH_PROVIDER=brave`, `BRAVE_SEARCH_API_KEY`), chosen
69 for its simple REST shape; the adapter boundary keeps Bing/SearXNG swappable.
70 Unconfigured provider returns an in-band ToolError telling the operator what
71 to set, never a 500.
72 - Rate limit per user (reuse the existing rate-limit pattern if one exists;
73 otherwise a simple per-user counter, e.g. 60 searches/hour) so a runaway
74 agent cannot burn the provider quota.
75 - Auth and result envelope follow the existing MCP tools exactly. Update
76 `.agents/specs/mcp-server.md`.
77 - Client side: nothing structural (MCP plumbing exists). Read-only
78 classification of official-server tools ships with spec 3.
79
80 ### Acceptance
81
82 - Request specs: happy path (provider stubbed with WebMock or the repo's
83 HTTP-stubbing convention), unconfigured provider, rate limit, param
84 validation. No live provider calls in CI.
85
86 ---
87
88 ## 3. Spec: Issues and Pull requests in the terminal
89
90 **Branch:** `feature/tui-repo-tabs` (sigit, stacked on `feature/tui-tabs`) ·
91 **Touches:** `src/chat.rs`, `src/permissions.rs`, `src/main.rs` (prompt)
92
93 ### Problem
94
95 Copilot CLI shows Issues and Pull requests tabs when run inside a GitHub repo.
96 sigit.si is our own git host, the MCP repo workflow tools exist server-side
97 (sigit-si #3), and siGit Code should be the best terminal client sigit.si has.
98
99 ### Design
100
101 - When the session cwd's `origin` remote points at the sigit.si host (parse
102 `git remote get-url origin`, compare against the `SIGIT_API_URL` host,
103 default sigit.si), the TUI adds a **Repo** tab after History: two sections,
104 Issues and Pull requests, fetched through the official MCP server
105 (`mcp__sigit__list_issues` / `mcp__sigit__list_pull_requests`, repo derived
106 from the remote's `owner/name`). Up/Down selects, Enter opens the detail
107 (`get_issue` / `get_pull_request`) in a scrollable view, `r` refreshes,
108 section toggle on `i`/`p` (or Left/Right).
109 - Fetches run as spawned tasks feeding the render loop (the Cloud tab
110 pattern); the tab degrades gracefully when signed out, MCP is off, or the
111 remote is not sigit.si (tab hidden entirely in that last case).
112 - Permission classification: the official server's read-only tools
113 (`list_*`, `get_*`, `search_code`, `get_file_contents`, `web_search`) are
114 classified read-only in `permissions.rs` so browsing never prompts;
115 everything else `mcp__sigit__*` stays mutating. Match on the official
116 server's namespace prefix plus tool-name prefix, not a hardcoded full list,
117 so new server-side read tools inherit it.
118 - Prompt guidance in `main.rs`: issue and PR workflows on sigit.si repos go
119 through the `mcp__sigit__*` tools; reference them by exact name.
120 - Stacking: branch from `feature/tui-tabs`. After sigit #25 merges, rebase
121 onto `development` before opening the PR so it shows only its own commits
122 (the repo's stacking rule).
123
124 ### Acceptance
125
126 - In a repo cloned from sigit.si while signed in, the Repo tab lists real
127 issues and PRs and opens details; signed out it shows the sign-in hint.
128 - Unit tests for the remote-URL parsing (ssh and https forms, non-sigit hosts)
129 and the read-only classification; TUI flows verified under tmux against a
130 scripted MCP server.
131
132 ---
133
134 ## 4. After this wave
135
136 Hooks, a `/context` usage display, memory recall over `remember`, then the two
137 big strategic items: sandboxing (Cloud Agent trust) and checkpointing/rewind.