mcp

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package mcp exposes ghostchrome as a Model Context Protocol server so that LLM agents (Claude Code, Codex, Cursor, ...) can drive the browser via stdio JSON-RPC instead of forking the CLI per call.

The server holds a single long-lived *engine.Browser + *rod.Page across tool calls so refs (@1, @2) extracted by one tool stay valid for the next click/type.

Package mcp tool registrations.

MCP v2.0 surface: 16 tools for an LLM-agent browser loop (snapshot, navigate, click, type, select, press, wait_for, eval, screenshot, hover, drag, fill_form, upload, tabs, back, forward). Everything that isn't on the hot path (sniff/trace/cookies/storage/viewport/dialog/blocker_stats) lives in the CLI only — adding tools here has a real token cost in every `tools/list` the model receives, so we stay deliberately small.

Index

Constants

This section is empty.

Variables

View Source
var ExtraToolRegistrars []func(srv *mcpsrv.MCPServer)

ExtraToolRegistrars lets optional, build-tagged recipes (compiled with `-tags recipes`) attach extra MCP tools without touching the core tool set. A recipe appends to it from an init(); Build() applies them after the core tools. Empty in the default binary — zero token cost when no recipe is on.

Functions

This section is empty.

Types

type Options

type Options struct {
	Connect        string // ws:// URL or "auto" to discover, empty = auto-launch
	Headless       bool
	Invisible      bool
	UserProfile    string
	Stealth        bool
	DismissCookies bool
	Proxy          string
	TimeoutSec     int
	// BlockTrackers enables the curated anti-bot script blocker
	// (engine.AntiBotPatterns). Auto-enabled when Stealth is true unless
	// GHOSTCHROME_MCP_NO_BLOCKER=1 is set.
	BlockTrackers bool
	// IdleTimeout, when > 0, releases the held Chrome after this long with no
	// tool activity. Unlike the serve daemon (which exits), the MCP server
	// stays up and relaunches Chrome on the next tool call — bounding the RAM a
	// forgotten-but-still-open session holds. The zero value disables reaping;
	// cmd/mcp.go supplies a 15m default (GHOSTCHROME_IDLE_TIMEOUT overrides,
	// =0 disables).
	IdleTimeout time.Duration
	// Policy restricts which domains can be navigated to, and which actions
	// (eval, upload, clipboard) are allowed. Nil means no restrictions.
	Policy *policy.Policy
}

Options configure the shared browser the MCP server attaches to. Mirrors the global flags exposed by the ghostchrome CLI.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server holds the shared browser and exposes tool handlers backed by the engine package. Methods are concurrency-safe via mu.

func New

func New(opts Options) *Server

New returns a Server that lazy-initializes the browser on the first tool call. Build registers all tools on a fresh MCP server and returns it.

func (*Server) Build

func (s *Server) Build(name, version string) *mcpsrv.MCPServer

Build returns an MCP server with every ghostchrome tool registered. Caller is expected to call mcpsrv.ServeStdio on it.

func (*Server) Close

func (s *Server) Close()

Close releases the underlying browser. Safe to call multiple times.

func (*Server) PrewarmAsync

func (s *Server) PrewarmAsync()

PrewarmAsync spawns Chrome in the background so the first user-facing tool call doesn't pay the ~1.3s cold-start. Safe to call from main(): if the browser is already up it's a no-op; if init fails, the next withPage() will surface the error normally.

func (*Server) StartIdleReaper added in v0.4.1

func (s *Server) StartIdleReaper()

StartIdleReaper launches a background loop that releases the held browser after opts.IdleTimeout of no tool activity. The MCP server itself stays alive: the next tool call relaunches Chrome via ensurePageLocked (the same path as crash-recovery), so a forgotten-but-open session stops squatting ~600MB of idle Chrome. No-op when IdleTimeout <= 0. The goroutine lives for the process lifetime; once the browser is released, ticks are near-free (browser == nil short-circuits) until the next call relaunches it.

Jump to

Keyboard shortcuts

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