mcp

package
v4.0.0-beta.9 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package mcp hosts the Gothic dev session's MCP surface over Streamable HTTP.

The dev proxy process serves it at /_gothicframework/mcp (default-on; the hot-reload command mounts it and --no-mcp opts out). The surface is the machine port of the framework's own tooling: the managed browser (view, act, record), the build pipeline (build_*, sync, build_status), the request trace and the dev bus (trace, logs), and the bundled skill documents (skillsearch/skillinfo/skill, also reachable as gothic-skill:// resources).

Results stay small: heavy content (skill document bodies, page-view grids, take frame lists) is returned only on an explicit named request.

Concurrency: every tool serializes on the machinery's own locks (the browser Manager, the build Controller); the surface adds one mutex only for its own small per-session state (the diff baseline, the last take).

Index

Constants

View Source
const MCPEndpointPath = "/_gothicframework/mcp"

MCPEndpointPath is where the dev proxy mux serves the MCP endpoint.

Variables

This section is empty.

Functions

func Handler

func Handler(factory func() *Capability) http.Handler

Handler builds the whole MCP surface as an http.Handler: one server, every contract tool, the skill resources, and Streamable HTTP with plain-JSON responses (the dev server's own traffic pattern: one request, one answer).

Types

type BrowserPort

type BrowserPort interface {
	Open(url string) error
	Act(ctx context.Context, steps []browser.Step) error
	CaptureStill(ctx context.Context, opts browser.StillOptions) ([]browser.StillResult, error)
	StartRecording(opts browser.RecordOptions) (TakePort, error)
	ActiveTake() TakePort
	SetHeadless(headless bool) error
	// SetViewport pins a device-metrics override on the managed page until
	// ClearViewport; height 0 keeps the page's current height.
	SetViewport(width, height int, mobile bool) error
	ClearViewport() error
	// Console returns the page's retained console errors/warnings, newest
	// first; last <= 0 returns the whole ring.
	Console(last int) []browser.ConsoleEntry
	Running() bool
	// Eval runs one rod-style JS function expression ("() => …") in the page
	// and returns its value serialized. Promise results are awaited.
	Eval(js string) (string, error)
}

BrowserPort is the managed-browser surface the tools use. NewBrowserPort adapts cli/internal/browser.Manager (whose StartRecording returns the concrete *Take) to the interface.

func NewBrowserPort

func NewBrowserPort(m *browser.Manager) BrowserPort

NewBrowserPort adapts a managed browser Manager to the BrowserPort.

type BuildPort

type BuildPort interface {
	BuildTempl(file string) buildctl.BuildResult
	BuildRoutes() buildctl.BuildResult
	BuildTopics() buildctl.BuildResult
	BuildWasm(target string) buildctl.BuildResult
	BuildGo() buildctl.BuildResult
	BuildCSS(page string) buildctl.BuildResult
	Sync() buildctl.BuildResult
	BuildStatus() buildctl.StatusResult
}

BuildPort is the build-pipeline surface the tools use. cli/internal/buildctl.Controller implements it exactly.

type Capability

type Capability struct {
	// Browser is the managed browser (nil when the session has none).
	Browser BrowserPort

	// Build is the build controller (nil when the session has none).
	Build BuildPort

	// Timeline reads the observation timeline (server trace + dev bus).
	Timeline TimelinePort

	// Skills serves the bundled skill documents.
	Skills SkillsPort

	// MarkSink injects a named mark into the dev bus (nil disables record_mark).
	MarkSink MarkSink

	// Marks pulls the act marks out of the dev bus ring (newest first) — the
	// closure the recording takes run on. Production binds it to
	// browser.MarksFromRecords over the proxy's ring; nil falls back to the
	// Timeline port's Bus read.
	Marks func() []browser.TakeMark

	// Engine is the managed browser's engine label reported in page-view
	// payloads (e.g. "chromium 131"); empty when unknown.
	Engine string

	// Version is the CLI version reported as the MCP server's version
	// (passed in — the cmd package owns the constant).
	Version string
}

Capability is the machinery one dev session exposes to MCP clients. The hot-reload command builds it once over its real subsystems; tests build fakes. Nil members make the matching tools fail with a clean tool error instead of a panic.

type HTTPBaseTimeline

type HTTPBaseTimeline struct {
	// Base is the dev proxy's origin.
	Base string

	// Client is the HTTP client (zero value = a 5s-timeout default).
	Client *http.Client
}

HTTPBaseTimeline reads the observation timeline over the dev proxy's own HTTP surface. Construct it with the proxy's base URL (e.g. "http://127.0.0.1:3000").

func (HTTPBaseTimeline) Bus

func (t HTTPBaseTimeline) Bus(last int) ([]map[string]any, error)

LogsPort — GET /_gothicframework/reload/bus?last=N (the dev bus ring's read endpoint).

func (HTTPBaseTimeline) Trace

func (t HTTPBaseTimeline) Trace(ctx context.Context, last int) ([]map[string]any, error)

TracePort — GET /_gothicframework/trace?last=N (the app's tracer endpoint, passed through by the proxy).

type MarkSink

type MarkSink func(event string, payload map[string]any) error

MarkSink injects one named mark into the dev bus (a kind:"mark" record), so the active take's marks poller and every record reader see it on the same timeline. Production posts to the proxy's bus ingest endpoint.

type SkillsPort

type SkillsPort interface {
	Search(query string) []skills.Ref
	Info(names []string) []skills.SkillInfo
	Load(names []string) []skills.Document
	Names() []string
}

SkillsPort serves the bundled skill documents. cli/internal/skills.Set implements it exactly.

type TakePort

type TakePort interface {
	Stop(discard bool) (browser.TakeManifest, error)
	Wait() (browser.TakeManifest, error)
	Done() <-chan struct{}
}

TakePort is the recording handle the record tools drive. *browser.Take implements it exactly.

type TimelinePort

type TimelinePort interface {
	// Trace returns the newest N server-side trace records.
	Trace(ctx context.Context, last int) ([]map[string]any, error)
	// Bus returns the newest N dev-bus records, newest first.
	Bus(last int) ([]map[string]any, error)
}

TimelinePort reads the session's observation timeline from both planes: the app's server-side request trace and the dev bus (topic/durable/control/mark traffic decoded by the injected observer). Production wires both planes to HTTP reads over the dev proxy; tests stub them in memory.

Jump to

Keyboard shortcuts

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