Files
isphere-ai-bridge/docs/go-mcp-minimal-plan.md
2026-07-06 20:46:49 +08:00

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-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:

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 -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:

{"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:

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 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:

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.v1 requests.
  • JSON unmarshaling accepts C# helper success and error responses.

Acceptance conditions:

Run:

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:

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 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:

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 -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:

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-mcp creates 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/helperclient accepted.

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_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:

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_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:

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 --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 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%\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:
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:
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: 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:
    • name
    • control_type
    • automation_id
    • class_name
    • children
  • 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:

  1. No Python MCP code.
  2. No real send/search/file action before N12.
  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-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.