verify

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package verify implements behavior probes for MCP servers introduced in SDK v1.4.0–v1.6.0. Each probe is a self-contained check that drives a target server with a single malformed/edge-case request and reports pass/fail plus a fix suggestion.

Probes are designed for reuse by the conformance suite (Tier-3 follow-up) and for unit-testing in isolation: each probe takes a Target value and produces a ProbeResult — no global state, no shared transport, no hidden CLI coupling.

Index

Constants

This section is empty.

Variables

View Source
var AllProbes = []string{
	"cross-origin",
	"dns-rebind",
	"content-type",
	"origin-header",
	"mcp-method-headers",
	"seterror-content",
}

AllProbes is the canonical list of probe names in display order. Drives the --probe flag's allowed values, the --json output ordering, and the conformance suite's iteration plan.

Functions

func AllPassed

func AllPassed(results []ProbeResult) bool

AllPassed returns true when every probe in results passed. An empty slice counts as failure — callers that pass an empty list want exit 1.

func IsHTTPProbe

func IsHTTPProbe(name string) bool

IsHTTPProbe reports whether a probe needs a URL target rather than a stdio command. The CLI dispatcher uses this to validate the supplied target shape before invoking probes.

Types

type ProbeResult

type ProbeResult struct {
	Name  string `json:"name"`
	Pass  bool   `json:"pass"`
	Error string `json:"error,omitempty"`
	Fix   string `json:"fix,omitempty"`
}

ProbeResult is the typed outcome of a single behavior probe. The shape is fixed by the task spec — Tier-3 conformance suite re-uses these fields verbatim.

Name  — probe identifier matching the --probe flag value
Pass  — true when the server's behavior matches the expected contract
Error — concrete failure detail when Pass=false (empty on pass)
Fix   — human-readable suggestion the user can apply (empty on pass)

func ProbeContentType

func ProbeContentType(ctx context.Context, t Target) ProbeResult

ProbeContentType sends a POST with text/plain to confirm the server rejects non-JSON payloads. The streamable-HTTP spec (§2.1) requires Content-Type application/json; SDK servers respond with 415 Unsupported Media Type or 400 Bad Request when the payload doesn't match.

func ProbeCrossOrigin

func ProbeCrossOrigin(ctx context.Context, t Target) ProbeResult

ProbeCrossOrigin sends a streamable-HTTP POST with an Origin header pointing at a foreign domain. Per SDK v1.4.1 (PR #842) and the CrossOriginProtection middleware shipped with go-sdk, compliant servers reject such requests with 403 Forbidden.

func ProbeDNSRebind

func ProbeDNSRebind(ctx context.Context, t Target) ProbeResult

ProbeDNSRebind sends a request to a 127.0.0.1 origin with a non-localhost Host header — the canonical DNS-rebinding attack shape. SDK v1.4.0 (PR #760) added DisableLocalhostProtection=false default; compliant streamable-HTTP servers reject with 403/421.

func ProbeMCPMethodHeaders

func ProbeMCPMethodHeaders(ctx context.Context, t Target) ProbeResult

ProbeMCPMethodHeaders verifies SEP-2243 MCP-Method/MCP-Name advisory headers reach the server when the client sets them. The probe doesn't check that the SERVER returns the headers (servers ignore unknown headers per spec) — instead it sends a tools/call request with the headers AND records what the server received via a custom HTTP client that captures the outbound request.

This is fundamentally a CLIENT-side check (does mcp-tui's --mcp-method-headers feature set them on the wire?), but framed as a "verify" probe so it shares the dispatcher with the security probes.

func ProbeOriginHeader

func ProbeOriginHeader(ctx context.Context, t Target) ProbeResult

ProbeOriginHeader confirms Origin enforcement applies to POST but NOT to GET/HEAD requests on the same endpoint. Streamable-HTTP allows GET-without-Origin for the listening stream; tightening it would break CORS preflight and proxy probes.

The probe sends two requests:

  1. GET without Origin — expected: 2xx, 405 Method Not Allowed, or any non-403 (server may simply not support GET, that's fine — what we care about is "GET without Origin is NOT rejected with 403").
  2. POST without Origin — expected: 4xx (rejection on the POST path).

func ProbeSetErrorContent

func ProbeSetErrorContent(ctx context.Context, t Target) ProbeResult

ProbeSetErrorContent invokes a tool and confirms isError:true responses carry their Content payload. SDK v1.6.0 (PR #864) reaffirmed that the CallToolResult.Content slice MUST be preserved when IsError is true — without it, the LLM can't see what went wrong and self-correct.

The probe connects via mcp.Service over stdio, calls the configured tool, and asserts:

  1. The call returned IsError=true (the tool is genuinely a "fails by design" tool — if it succeeds, the probe is misconfigured).
  2. The result has at least one Content entry with non-empty Text.

If the user's target tool doesn't naturally fail, the probe reports inconclusive (Pass=false with a Fix that explains the misconfig).

func Run

func Run(ctx context.Context, name string, target Target) ProbeResult

Run dispatches by name. Unknown names produce a failed ProbeResult rather than an error so callers don't have to handle two paths.

func RunAll

func RunAll(ctx context.Context, target Target) []ProbeResult

RunAll executes every probe in AllProbes order. Stops on context cancellation. The returned slice is in the same order as AllProbes for deterministic JSON output.

type Target

type Target struct {
	// URL is the streamable-HTTP endpoint for HTTP-class probes (cross-origin,
	// dns-rebind, content-type, origin-header, mcp-method-headers).
	URL string

	// Command + Args are the stdio command for the seterror-content probe
	// (and any future stdio probe). Treated as already-validated — the CLI
	// dispatcher runs config.ValidateCommand before constructing the Target.
	Command string
	Args    []string

	// ToolName overrides which tool the seterror-content probe will call.
	// Empty defaults to "everything"-style "echo" — left configurable so
	// users can point at their own server's known-isError-true tool.
	ToolName string

	// ToolArgs is the JSON-shaped argument map for the seterror probe's
	// tool call. Default empty object {} works for trivial tools.
	ToolArgs map[string]any

	// HTTPClient lets tests inject a custom client (e.g. one that allows
	// connections to httptest server addresses). Nil → http.DefaultClient
	// with a short per-probe timeout.
	HTTPClient *http.Client
}

Target carries everything a probe needs to drive a remote server. For HTTP probes only URL is consulted; for the stdio-only seterror-content probe, Command/Args take over. Both are populated from the same CLI argument (`mcp-tui verify <url|cmd>`).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL