21 KiB
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
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
-> N12 Real logged-in UIA capture gate
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-phaseunless 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.mdremains the source boundary document.
Expected outputs:
- Clean project direction: C# helper now, Go MCP next.
- No Python MCP fallback path.
Acceptance conditions:
git status --short
Pass if:
- No unexpected modified or untracked files exist except the active plan file while editing.
git ls-filesincludesnative/ISphereWinHelper/*.git ls-filesdoes not includesrc/isphere_ai_bridge/*.git ls-filesdoes not includetests/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.ps1exists.scripts/verify-win-helper.ps1exists.
Actions:
Run:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
Expected outputs:
runs/win-helper/ISphereWinHelper.exeis built locally.version,self_check,scan_windows, anddump_uiaall run through JSON.
Acceptance conditions:
Pass if output contains:
{"ok":true}
And confirms:
helperpath points toruns\win-helper\ISphereWinHelper.exe.versionis0.1.0.scan_window_countis a number.uia_availableistrueor a valid boolean field.- Temporary WinForms
dump_uiasucceeds.
Stop conditions:
- Build fails.
- Helper stdout is not JSON.
dump_uiacannot 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:
go.mod
Initial module name:
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:
go version
go list ./...
Pass if:
go versionexits 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.mdis available.
Actions:
Create:
internal/helperclient/contract.go
internal/helperclient/client_test.go
Define minimal structs:
HelperRequest
HelperResponse
HelperError
Required fields:
protocol
request_id
op
timeout_ms
args
ok
data
error
warnings
Expected outputs:
- JSON marshaling generates
isphere.helper.v1requests. - JSON unmarshaling accepts C# helper success and error responses.
Acceptance conditions:
Run:
go test ./internal/helperclient -run Contract -v
Pass if tests prove:
versionrequest marshals withprotocol="isphere.helper.v1".- success response unmarshals with
ok=trueanddata.helper_name="ISphereWinHelper". - error response unmarshals with
ok=falseanderror.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:
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:
internal/helperclient/client.go
Implement:
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:
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
versioncall returnsok=truewhen 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:
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.ps1passes.
Actions:
Run:
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
versioncall. - 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:
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:
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:
cmd/isphere-mcp/main.go
Optional only if it keeps main.go small:
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-mcpcreates a binary.- Server starts in stdio mode.
Acceptance conditions:
Run:
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/helperclientaccepted.
Actions:
Create:
internal/tools/winhelper.go
internal/tools/winhelper_test.go
Register exactly these tools:
win_helper_version
win_helper_self_check
win_helper_scan_windows
win_helper_dump_uia
Tool behavior:
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:
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_visiblefor scan.hwnd,max_depth,include_text,max_childrenfor 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:
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:
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 -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
Pass if output includes:
{"ok":true}
And confirms:
- Four tool names are present.
win_helper_versionreturnsISphereWinHelper.- 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:
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:
docs/go-mcp-runbook.md
Update only if needed:
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 -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:
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:
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 -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 --shorthas 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 if the current environment cannot log in; otherwise N12 may start only when the real logged-in current-environment preconditions below are met.
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:
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%\importalorlocalcachefolders. - Pay attention to historical iSphere anchors such as
importal\localcache,LoginLog,IMPP.Util.dll,IMPlatformClient, andiSphere. - Optional mode B, Minimal redacted UIA package, is only for advanced operators who already know how to produce JSON:
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_passand uses only:
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 pluscopy-notes.txtwhen 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: N12 remains blocked until the current environment can manually log in and perform a live current-environment UIA capture.
N12: Real logged-in UIA capture gate
Purpose: Capture real iSphere UIA evidence after the user provides/login context.
Preconditions:
- N11 accepted.
- Optional N12-pre offline evidence, if used, has been validated only as pre-gate context and not as N12 pass evidence.
- User manually opens and logs in to iSphere.
- iSphere main window is visible.
Actions:
Use Go MCP tools:
win_helper_scan_windows
win_helper_dump_uia
Save output under:
runs/real-loggedin-lab/uia-dumps/
Expected outputs:
- One or more real iSphere UIA dump JSON files.
- Window metadata showing process name/title/handle.
Acceptance conditions:
Pass if:
- Candidate iSphere/IMPlatform window is found.
- UIA root node is a window/control tree.
- Dump includes enough fields to identify controls:
namecontrol_typeautomation_idclass_namechildren
- No clicking, typing, sending, uploading, receiving, or downloading occurs.
- No passwords/tokens are captured.
Stop conditions:
- User is not logged in.
- No candidate window appears.
- UIA tree is empty or inaccessible.
- Captured data contains sensitive secrets that need redaction before reporting.
- Current environment cannot log in; in that case, use only N12-pre offline analysis and do not mark N12 passed.
Next node: Future selector design. Do not implement selectors until N12 passes.
3. Global Acceptance Rules
Every node must satisfy these rules:
- No Python MCP code.
- No real send/search/file action before N12.
- No process injection, hook, credential extraction, token extraction, or memory reading.
- No broad
git add -A; stage exact paths. - Every code node uses tests first.
- Every completion claim needs a fresh verification command.
- Every failed gate stops the plan and requires a short report before continuing.
4. Current Next Node
Current guidance after N0-N11 completion is:
N12-pre if the current environment cannot log in; N12 only after current-environment manual login is possible.
Immediate next action:
If login is unavailable here, collect/validate the full sandbox artifact bundle described in docs/offline-evidence-intake-plan.md. Minimal manifest/scan/dump JSON is optional and only for advanced operators.
Do not treat offline evidence as N12 pass. Do not start selector/action design until true N12 passes in the current environment.