Problem
The cloud-context MCP needs its contract and safety model before any provider or launcher wiring can be written: the provider-agnostic tool surface, the bypass-resistant command harness, and the shared identity probe. Building this first lets the GCP provider, AWS provider, and launcher integration proceed in parallel against a frozen contract.
This sub-issue ships the package with a fake provider behind it — no real cloud calls yet.
Approach
Add pkg/mcp/cloud/ with the established MCP shape (New(Options) + Run(ctx) + specs.go::ToolSpecs()), registered with one case "cloud" in cmd/triagent-mcp/serve.go (ADR-0001) and parameterized by --provider=<gcp|aws>. The package's server name is triagent-mcp-cloud; the triagent-cloud-<alias> naming is applied at the wiring layer. Options.Provider is an injectable Provider interface value (the teleport pattern); concrete providers are constructed in serve.go.
Deliverables:
- The
Provider interface and projection structs (Inventory, IdentityStatus, CLIResult), plus a RunFunc exec seam so providers never exec directly.
LoadCommandAllowlist(path, extra) mirroring pkg/mcp/k8s's LoadAllowlist: embedded default, profile-override path, and a hardcoded deny floor (subcommands, flags, argument prefixes file:///@/http(s)://) the override can never re-enable.
- The harness: argv-only input, direct
execve (no sh -c anywhere), validateArgv (allowlist + deny floor + scope), output truncation, pinned absolute binary, minimal cmd.Env, closed stdin.
- Thin typed tools
list_inventory and session_status, plus run_cli and list_allowed_commands reading the same allowlist (single source of truth).
- The shared
Probe(ctx, Provider) (IdentityStatus, error) consumed later by preflight and the connections panel.
The long-tail axes (reachability, permissions, cluster, logs, audit) are reached through run_cli against the allowlist; any can be promoted to a typed tool later.
Verification
make test passes, including the package's tools_*_test.go (fake provider), the wire test, and harness_security_test.go (no sh -c; metacharacter argv never spawns a second process; deny floor and scope enforced; output truncates).
make lint clean.
triagent-mcp dump-meta lists the triagent-cloud tools, matching ToolSpecs().
triagent-mcp serve --kind=cloud --provider=<x> rejects an unknown provider with a clear error.
Out of scope
- Real GCP/AWS calls (the provider sub-issues) and launcher wiring (the launcher sub-issue). This issue ships the contract, harness, and a test fake.
Context
Sub-issue of #44.
Problem
The cloud-context MCP needs its contract and safety model before any provider or launcher wiring can be written: the provider-agnostic tool surface, the bypass-resistant command harness, and the shared identity probe. Building this first lets the GCP provider, AWS provider, and launcher integration proceed in parallel against a frozen contract.
This sub-issue ships the package with a fake provider behind it — no real cloud calls yet.
Approach
Add
pkg/mcp/cloud/with the established MCP shape (New(Options)+Run(ctx)+specs.go::ToolSpecs()), registered with onecase "cloud"incmd/triagent-mcp/serve.go(ADR-0001) and parameterized by--provider=<gcp|aws>. The package's server name istriagent-mcp-cloud; thetriagent-cloud-<alias>naming is applied at the wiring layer.Options.Provideris an injectableProviderinterface value (the teleport pattern); concrete providers are constructed inserve.go.Deliverables:
Providerinterface and projection structs (Inventory,IdentityStatus,CLIResult), plus aRunFuncexec seam so providers never exec directly.LoadCommandAllowlist(path, extra)mirroringpkg/mcp/k8s'sLoadAllowlist: embedded default, profile-override path, and a hardcoded deny floor (subcommands, flags, argument prefixesfile:///@/http(s)://) the override can never re-enable.execve(nosh -canywhere),validateArgv(allowlist + deny floor + scope), output truncation, pinned absolute binary, minimalcmd.Env, closed stdin.list_inventoryandsession_status, plusrun_cliandlist_allowed_commandsreading the same allowlist (single source of truth).Probe(ctx, Provider) (IdentityStatus, error)consumed later by preflight and the connections panel.The long-tail axes (reachability, permissions, cluster, logs, audit) are reached through
run_cliagainst the allowlist; any can be promoted to a typed tool later.Verification
make testpasses, including the package'stools_*_test.go(fake provider), the wire test, andharness_security_test.go(nosh -c; metacharacter argv never spawns a second process; deny floor and scope enforced; output truncates).make lintclean.triagent-mcp dump-metalists thetriagent-cloudtools, matchingToolSpecs().triagent-mcp serve --kind=cloud --provider=<x>rejects an unknown provider with a clear error.Out of scope
Context
Sub-issue of #44.