Files
isphere-ai-bridge/docs/go-mcp-minimal-plan.md

981 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Go MCP Minimal Plan Nodes
> **Process rule:** This is the single active plan for the next phase. The final MCP direction is Go. Python MCP, Python tests, offline-lab/native-lab Python layers are not part of the active path.
**Goal:** Build a minimal Go MCP server that exposes the existing C# `ISphereWinHelper.exe` read-only operations as MCP tools.
**Architecture:** Go is the MCP/service layer. C# is the Windows/UI Automation execution layer. Go calls C# through one-shot stdin/stdout JSON using `isphere.helper.v1`.
**Tech Stack:** Go, MCP stdio, C# .NET Framework WinHelper, PowerShell verification scripts.
---
## 1. Node Tree
```text
N0 Baseline cleanup and direction lock
-> N1 C# WinHelper baseline verification
-> N2 Go module skeleton
-> N3 Go helper protocol contract
-> N4 Go helper process client
-> N5 Helper client live verification
-> N6 MCP library decision
-> N7 Go MCP server skeleton
-> N8 Four read-only MCP tool handlers
-> N9 MCP stdio smoke verification
-> N10 Operator runbook and process scripts
-> N11 Commit/review checkpoint
-> N12-pre Offline evidence intake
-> N12R Internal-sandbox live UIA capture route
-> N12R-review Selector design review gate
Blocked/non-active:
-> N12-current Current-environment real logged-in UIA capture gate
```
**Reality update 2026-07-08:** iSphere is internal-network only. The current repository environment is an outer-network coordination/analysis environment. Therefore `N12-current` is not the active route unless network placement changes. Live login and live UIA capture must happen in an internal-network test sandbox through `N12R`.
Hard rule: **no node may start until the previous node's acceptance conditions are met.**
---
## 2. Node Details and Acceptance Conditions
## N0: Baseline cleanup and direction lock
**Purpose:** Ensure the project is no longer split between Python MCP and Go MCP.
**Preconditions:**
- Current branch is `codex/isphere-win-helper-first-phase` unless explicitly changed by the user.
- Python MCP temporary layer has been removed.
**Actions:**
- Confirm tracked files only include current docs/prompts/C# helper/scripts/evidence placeholders.
- Confirm no active `src/isphere_ai_bridge`, Python MCP package, or Python test suite is tracked.
- Confirm `docs/go-csharp-helper-boundary.md` remains the source boundary document.
**Expected outputs:**
- Clean project direction: C# helper now, Go MCP next.
- No Python MCP fallback path.
**Acceptance conditions:**
```powershell
git status --short
```
Pass if:
- No unexpected modified or untracked files exist except the active plan file while editing.
- `git ls-files` includes `native/ISphereWinHelper/*`.
- `git ls-files` does not include `src/isphere_ai_bridge/*`.
- `git ls-files` does not include `tests/test_*.py`.
**Stop conditions:**
- Python MCP files reappear.
- C# helper files are missing.
- Worktree has unrelated dirty files.
**Next node:** N1.
---
## N1: C# WinHelper baseline verification
**Purpose:** Prove the existing C# helper still works before writing Go code.
**Preconditions:**
- N0 accepted.
- `scripts/build-win-helper.ps1` exists.
- `scripts/verify-win-helper.ps1` exists.
**Actions:**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
```
**Expected outputs:**
- `runs/win-helper/ISphereWinHelper.exe` is built locally.
- `version`, `self_check`, `scan_windows`, and `dump_uia` all run through JSON.
**Acceptance conditions:**
Pass if output contains:
```json
{"ok":true}
```
And confirms:
- `helper` path points to `runs\win-helper\ISphereWinHelper.exe`.
- `version` is `0.1.0`.
- `scan_window_count` is a number.
- `uia_available` is `true` or a valid boolean field.
- Temporary WinForms `dump_uia` succeeds.
**Stop conditions:**
- Build fails.
- Helper stdout is not JSON.
- `dump_uia` cannot capture the temporary WinForms window.
- Helper requires admin rights.
**Next node:** N2.
---
## N2: Go module skeleton
**Purpose:** Create the smallest Go project shell.
**Preconditions:**
- N1 accepted.
- Go toolchain is available on this machine.
**Actions:**
Create:
```text
go.mod
```
Initial module name:
```text
isphere-ai-bridge
```
Do not create server code yet.
**Expected outputs:**
- A Go module exists.
- No dependencies are added unless required by standard Go tooling.
**Acceptance conditions:**
Run:
```powershell
go version
go list ./...
```
Pass if:
- `go version` exits 0.
- `go list ./...` exits 0 or reports only the root module with no packages before packages are created.
- No Python files are added.
**Stop conditions:**
- Go is not installed.
- Module name conflicts with repository layout.
- Toolchain tries to create unrelated files outside the repo.
**Commit boundary:** optional; can be combined with N3.
**Next node:** N3.
---
## N3: Go helper protocol contract
**Purpose:** Model `isphere.helper.v1` in Go before process execution.
**Preconditions:**
- N2 accepted.
- `docs/go-csharp-helper-boundary.md` is available.
**Actions:**
Create:
```text
internal/helperclient/contract.go
internal/helperclient/client_test.go
```
Define minimal structs:
```text
HelperRequest
HelperResponse
HelperError
```
Required fields:
```text
protocol
request_id
op
timeout_ms
args
ok
data
error
warnings
```
**Expected outputs:**
- JSON marshaling generates `isphere.helper.v1` requests.
- JSON unmarshaling accepts C# helper success and error responses.
**Acceptance conditions:**
Run:
```powershell
go test ./internal/helperclient -run Contract -v
```
Pass if tests prove:
- `version` request marshals with `protocol="isphere.helper.v1"`.
- success response unmarshals with `ok=true` and `data.helper_name="ISphereWinHelper"`.
- error response unmarshals with `ok=false` and `error.code="WINDOW_NOT_FOUND"`.
- unknown data fields are preserved as JSON maps or raw JSON.
**Stop conditions:**
- Contract field names differ from C# helper output.
- Tests require a real helper process; N3 must be pure JSON only.
**Commit boundary:**
```powershell
git add go.mod internal/helperclient/contract.go internal/helperclient/client_test.go
git commit -m "feat: add go helper contract"
```
**Next node:** N4.
---
## N4: Go helper process client
**Purpose:** Let Go call `ISphereWinHelper.exe --json` with one request and one response.
**Preconditions:**
- N3 accepted.
- C# helper verification from N1 passes.
**Actions:**
Create:
```text
internal/helperclient/client.go
```
Implement:
```text
Client
Client.Call(ctx, op, args)
```
Client responsibilities:
- Resolve helper exe path.
- Start helper with `--json`.
- Write request JSON to stdin.
- Read stdout.
- Capture stderr.
- Enforce context timeout.
- Return structured Go error for missing helper, timeout, bad JSON, non-zero exit.
**Expected outputs:**
- Go can call C# helper without MCP.
- Process execution logic lives only in `internal/helperclient`.
**Acceptance conditions:**
Run:
```powershell
go test ./internal/helperclient -run Client -v
```
Pass if tests prove:
- Missing helper path returns a structured error.
- Bad helper output returns a structured error using a test stub.
- Timeout returns a structured error using a test stub.
- Real `version` call returns `ok=true` when helper is built.
**Stop conditions:**
- Client leaks helper processes after timeout.
- Client requires admin rights.
- Client writes logs/files by default.
- Client duplicates C# UIA logic.
**Commit boundary:**
```powershell
git add internal/helperclient/client.go internal/helperclient/client_test.go
git commit -m "feat: add win helper process client"
```
**Next node:** N5.
---
## N5: Helper client live verification
**Purpose:** Verify Go-to-C# works against the real helper on this machine.
**Preconditions:**
- N4 accepted.
- `scripts/verify-win-helper.ps1` passes.
**Actions:**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
go test ./internal/helperclient -v
```
**Expected outputs:**
- C# helper works alone.
- Go helper client works against C# helper.
**Acceptance conditions:**
Pass if:
- PowerShell verification exits 0.
- Go tests exit 0.
- Test output includes a real `version` call.
- No tests click/type/send/upload/download.
**Stop conditions:**
- Tests only pass with mocked helper and never call the real C# helper.
- C# helper passes alone but Go client cannot call it.
**Commit boundary:** no separate commit unless tests/scripts changed.
**Next node:** N6.
---
## N6: MCP library decision
**Purpose:** Choose the Go MCP server library before writing server code.
**Preconditions:**
- N5 accepted.
- Network/package access is available or a local dependency strategy is chosen.
**Actions:**
Evaluate one current Go MCP library or official SDK option.
Record the decision inside the implementation commit or a short docs section. Do not create a large architecture document.
Decision must answer:
```text
package/module name
stdio support yes/no
tool registration style
JSON schema support
maintenance risk
why this is enough for four tools
```
**Expected outputs:**
- One MCP server package is selected.
- No competing MCP framework remains in the codebase.
**Acceptance conditions:**
Pass if:
```powershell
go list -m all
```
shows exactly one MCP-related Go dependency, or no external MCP dependency if a minimal stdio implementation is deliberately chosen.
Also pass if:
- The decision does not add HTTP server dependencies.
- The decision does not require Python or Node runtime.
- The decision supports stdio.
**Stop conditions:**
- MCP package cannot build on Windows.
- Package requires a background daemon.
- Package forces HTTP-only transport.
- Multiple MCP packages are added without a reason.
**Commit boundary:** can be combined with N7.
**Next node:** N7.
---
## N7: Go MCP server skeleton
**Purpose:** Create a Go binary that can start as an MCP stdio server.
**Preconditions:**
- N6 accepted.
**Actions:**
Create:
```text
cmd/isphere-mcp/main.go
```
Optional only if it keeps `main.go` small:
```text
internal/mcpserver/server.go
```
Do not register real tools yet if the library supports a clean empty server test. If the library requires tools immediately, register only placeholder-free real tool definitions from N8.
**Expected outputs:**
- `go build ./cmd/isphere-mcp` creates a binary.
- Server starts in stdio mode.
**Acceptance conditions:**
Run:
```powershell
go test ./...
go build ./cmd/isphere-mcp
```
Pass if:
- Build exits 0.
- No Python runtime is required.
- No C# helper is launched during simple server construction tests.
**Stop conditions:**
- Server starts an HTTP listener.
- Server invokes C# helper during initialization.
- Build requires unrelated services.
**Commit boundary:** can be combined with N8.
**Next node:** N8.
---
## N8: Four read-only MCP tool handlers
**Purpose:** Expose the first four read-only WinHelper operations through Go MCP.
**Preconditions:**
- N7 accepted.
- `internal/helperclient` accepted.
**Actions:**
Create:
```text
internal/tools/winhelper.go
internal/tools/winhelper_test.go
```
Register exactly these tools:
```text
win_helper_version
win_helper_self_check
win_helper_scan_windows
win_helper_dump_uia
```
Tool behavior:
```text
win_helper_version -> helper op version
win_helper_self_check -> helper op self_check
win_helper_scan_windows -> helper op scan_windows
win_helper_dump_uia -> helper op dump_uia
```
**Expected outputs:**
- Four tool definitions exist.
- Tool handlers call `internal/helperclient`.
- No handler performs UI logic directly.
**Acceptance conditions:**
Run:
```powershell
go test ./internal/tools -v
go test ./...
```
Pass if tests prove:
- Exactly four WinHelper tools are registered for this phase.
- Tool names match the list above.
- Tool schemas include only needed parameters:
- `include_all_visible` for scan.
- `hwnd`, `max_depth`, `include_text`, `max_children` for dump.
- No send/search/file tools exist.
**Stop conditions:**
- A fifth real action tool is added.
- A handler clicks, types, sends, uploads, downloads, or edits files.
- Tool code bypasses `internal/helperclient`.
**Commit boundary:**
```powershell
git add cmd/isphere-mcp internal/mcpserver internal/tools go.mod go.sum
git commit -m "feat: add minimal go mcp server"
```
**Next node:** N9.
---
## N9: MCP stdio smoke verification
**Purpose:** Verify the Go MCP binary can run over stdio and expose the four tools.
**Preconditions:**
- N8 accepted.
**Actions:**
Create if useful:
```text
scripts/verify-go-mcp.ps1
```
The script should:
- Build C# helper.
- Build Go MCP binary.
- Start Go MCP over stdio or use the MCP library test harness.
- List tools.
- Confirm the four expected tools exist.
- Call at least `win_helper_version`.
**Expected outputs:**
- A repeatable local verification command.
**Acceptance conditions:**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
```
Pass if output includes:
```json
{"ok":true}
```
And confirms:
- Four tool names are present.
- `win_helper_version` returns `ISphereWinHelper`.
- No real iSphere login is required.
- No message/file/search action is present.
**Stop conditions:**
- Verification needs manual interaction.
- Verification needs Python.
- Tool listing cannot be automated.
**Commit boundary:**
```powershell
git add scripts/verify-go-mcp.ps1
git commit -m "test: add go mcp verification script"
```
**Next node:** N10.
---
## N10: Operator runbook and process scripts
**Purpose:** Make the current tool usable by a human operator without reading code.
**Preconditions:**
- N9 accepted.
**Actions:**
Create:
```text
docs/go-mcp-runbook.md
```
Update only if needed:
```text
README.md
```
Runbook must include:
- Build C# helper.
- Verify C# helper.
- Build Go MCP.
- Verify Go MCP.
- Configure MCP client command.
- Allowed tools.
- Explicit non-goals.
- Real-login UIA capture procedure.
**Expected outputs:**
- A user can run the first phase without asking for hidden context.
**Acceptance conditions:**
Pass if runbook includes exact commands for:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
```
And includes these boundaries:
```text
no login automation
no send message
no send file
no receive/download file
no process injection
no hook
no memory reading
```
**Stop conditions:**
- Runbook says Python MCP is required.
- Runbook implies sending is implemented.
- Runbook omits approval boundaries for future sends.
**Commit boundary:**
```powershell
git add docs/go-mcp-runbook.md README.md
git commit -m "docs: add go mcp runbook"
```
**Next node:** N11.
---
## N11: Commit and review checkpoint
**Purpose:** Freeze the first Go MCP phase before real iSphere data is introduced.
**Preconditions:**
- N10 accepted.
**Actions:**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
go test ./...
go build ./cmd/isphere-mcp
git status --short
```
**Expected outputs:**
- All local verification passes.
- Worktree is clean after commits.
**Acceptance conditions:**
Pass if:
- `git status --short` has no output.
- Latest commits are small and tied to N3/N4/N8/N9/N10.
- No Python MCP files exist.
- No search/send/file tools exist.
**Stop conditions:**
- Any verification fails.
- Unrelated generated files are staged.
- Worktree contains ignored build outputs outside `runs/`.
**Next node:** N12-pre for offline evidence intake, followed by N12R for live capture in an internal-network test sandbox. `N12-current` remains blocked because the current outer-network environment cannot log in to internal iSphere.
---
## N12-pre: Offline evidence intake
**Purpose:** Define and validate offline evidence copied from a separate logged-in test sandbox when the current repository environment cannot log in to iSphere.
**Preconditions:**
- N11 accepted.
- Current environment cannot manually log in to iSphere / IMPlatformClient.
- Business manager approves offline evidence intake as a pre-gate only.
**Actions:**
- Follow `docs/offline-evidence-intake-plan.md`.
- Prefer mode A, **Full sandbox artifact bundle**. The user does not need to understand or generate JSON; they only copy folders from the logged-in test sandbox.
- Recommended full-bundle shape:
```text
runs/offline-evidence-intake/<evidence-id>/
copy-notes.txt
raw/
install/
user-profile/
programdata/
shortcuts/
temp-importal-localcache/
other-candidates/
metadata/
notes/
```
- Common candidate source paths include install directories, `%APPDATA%`, `%LOCALAPPDATA%`, `%PROGRAMDATA%`, `Documents`, Desktop/Start Menu shortcuts, and `%TEMP%\importal` or `localcache` folders.
- Pay attention to historical iSphere anchors such as `importal\localcache`, `LoginLog`, `IMPP.Util.dll`, `IMPlatformClient`, and `iSphere`.
- Optional mode B, **Minimal redacted UIA package**, is only for advanced operators who already know how to produce JSON:
```text
runs/offline-evidence-intake/<evidence-id>/
manifest.json
scan_windows-redacted.json
dump_uia-main-redacted.json
```
- For optional mode B, confirm the package states `n12_status = offline_pre_only_not_n12_pass` and uses only:
```text
version
self_check
scan_windows
dump_uia
```
**Expected outputs:**
- Full sandbox artifact bundle for read-only offline inventory, or optional minimal UIA JSON package for advanced users.
- No claim that the current environment has a logged-in iSphere window.
- No claim that N12 passed.
**Acceptance conditions:**
Pass if:
- In mode A, the copied bundle preserves directory structure and includes at least one useful `raw/` source area plus `copy-notes.txt` when available.
- In mode A, repository-side handling is read-only inventory: do not directly run unknown binaries and do not modify original copied files.
- In mode B, required JSON files exist and parse as JSON, and the manifest records offline pre-evidence only, not N12 pass.
- For both modes, the route does not design or perform automatic login, send message, send file, receive file, injection, hook, memory reading, or endpoint-security bypass.
**Stop conditions:**
- Any step requires the user to understand JSON before they can provide the recommended full bundle.
- Any step directly runs unknown binaries from the copied bundle.
- Any step modifies original copied files.
- Package is used to design automatic login, sending, file transfer, injection, hook, memory reading, or endpoint-security bypass.
- Any reader treats the offline package as a replacement for true N12.
**Next node:** N12R internal-sandbox live capture route if live UI evidence is needed. `N12-current` remains blocked in the outer-network environment.
---
## N12R: Internal-sandbox live capture route
**Purpose:** Capture live iSphere UIA evidence from a separate internal-network test sandbox where iSphere can be manually opened and logged in.
**Preconditions:**
- N11 accepted.
- Optional N12-pre offline evidence, if used, has been validated only as pre-gate context and not as live capture evidence.
- An internal-network test sandbox can manually open and log in to iSphere / IMPlatformClient using the normal approved process.
- The internal sandbox has this repository or a trusted copy of the built helper/MCP artifacts.
- The operator follows `docs/internal-sandbox-operator-runbook.md`.
**Actions:**
- In the internal sandbox, run only the first-phase read-only operations:
```text
win_helper_version
win_helper_self_check
win_helper_scan_windows
win_helper_dump_uia
```
or the equivalent helper ops:
```text
version
self_check
scan_windows
dump_uia
```
- Save the returned package under:
```text
runs/internal-sandbox-live-capture/<capture-id>/
```
- Follow the package contract in `docs/internal-sandbox-live-capture-plan.md`.
**Expected outputs:**
- `metadata/source-notes.txt` stating internal-network test sandbox, manual login, main window visible, and forbidden actions not performed.
- `helper/version.json`.
- `helper/self-check.json`.
- `windows/scan-windows.json`.
- `windows/selected-window.json`.
- `uia/dump-uia-main.json`.
- `uia/dump-uia-main-redacted.json`.
- `notes/operator-notes.txt`.
**Acceptance conditions:**
Pass if:
- The package satisfies `docs/n12r-return-package-validation-checklist.md`.
- `scan-windows.json` includes an iSphere / IMPlatformClient candidate window.
- `dump-uia-main.json` contains a UI Automation root tree for the selected window.
- The capture notes state the user manually logged in and no forbidden action was performed.
- The redacted dump exists before broad sharing.
**Stop conditions:**
- Internal sandbox cannot manually log in.
- No candidate window appears.
- UIA tree is empty or inaccessible.
- Package contains secrets or message contents that require redaction before review.
- Any step requires automatic login, clicking into conversations, sending, uploading, downloading, injection, hook, memory reading, or endpoint-security bypass.
**Next node:** N12R-review selector design review gate. Do not implement selectors until N12R evidence is accepted and a separate selector design plan is approved.
---
## N12-current: Current-environment real logged-in UIA capture gate (blocked)
This is the original N12 definition. It is retained as a blocked/non-active gate for historical clarity. It is not the active route while the repository environment is outside the internal network.
**Blocked reason:** iSphere is internal-network only, and the current repository environment cannot manually log in.
**Original purpose:** Capture real iSphere UIA evidence from a manually logged-in iSphere window in the same environment where this repository is running.
**Original preconditions, if network placement changes later:**
- N11 accepted.
- Optional N12-pre offline evidence, if used, has been validated only as pre-gate context and not as N12 pass evidence.
- The repository environment can manually open and log in to iSphere / IMPlatformClient using the normal approved process.
- iSphere main window is visible in that same environment.
**Original allowed actions:**
Use only these Go MCP tools:
```text
win_helper_scan_windows
win_helper_dump_uia
```
Save output under:
```text
runs/real-loggedin-lab/uia-dumps/
```
**Current decision:** Do not wait on this gate as the active route. Use N12R internal-sandbox live capture instead.
**Next node:** Future selector design may be considered only after N12R evidence is accepted, or after N12-current becomes possible and passes. Do not implement selectors before a separate selector design plan is approved.
---
## 3. Global Acceptance Rules
Every node must satisfy these rules:
1. No Python MCP code.
2. No real send/search/file action before an explicitly approved post-N12R selector/action plan.
3. No process injection, hook, credential extraction, token extraction, or memory reading.
4. No broad `git add -A`; stage exact paths.
5. Every code node uses tests first.
6. Every completion claim needs a fresh verification command.
7. Every failed gate stops the plan and requires a short report before continuing.
---
## 4. Current Next Node
Current guidance after N0-N15 remote updates is:
```text
当前下一步MCP 核心工具合同冻结 + 只读消息源 discovery + N12-pre 证据包整理。
```
Immediate next action:
```text
Use `docs/mcp-core-tools-contract.md` and `docs/mcp-core-business-plan.md` as the active business route. Prioritize `isphere_search_contacts`, `isphere_search_groups`, `isphere_receive_messages`, and `isphere_receive_files` before any write-capable tool. Keep `isphere_send_message` and `isphere_send_file` behind `dry_run=true`, `approval_id`, and audit requirements.
```
Do not treat N12-pre offline evidence as N12 pass. Do not start N16/N17 selector/report hardening as the mainline. Existing UIA selector/report work is auxiliary evidence and fallback support only; the project core is MCP communication capability for contacts, groups, messages, and files.