Files
isphere-ai-bridge/docs/go-mcp-minimal-plan.md
2026-07-05 19:18:56 +08:00

17 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 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.


N12: Real logged-in UIA capture gate

Purpose: Capture real iSphere UIA evidence after the user provides/login context.

Preconditions:

  • N11 accepted.
  • User has copied real install/user files if needed.
  • 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.

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 next node is:

N0 -> N1 -> N2

Immediate next action:

Run N1 C# baseline verification, then start N2 Go module skeleton.

Do not start N8 or N12 early.