spec

package
v2.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	KindREST      = "rest"      // default; strict path-validity against the spec
	KindSynthetic = "synthetic" // multi-source / combo CLI; dogfood + scorecard relax path-validity
)

Valid values for APISpec.Kind. A bare string with no const was the established convention for sibling fields (SpecSource, ClientPattern), but Kind is compared in production code at multiple sites, so the constant prevents typos from silently falling through to the default-rest path.

View Source
const (
	HTTPTransportStandard        = "standard"          // default for official API clients
	HTTPTransportBrowserChrome   = "browser-chrome"    // Chrome-impersonated transport for browser-facing web surfaces
	HTTPTransportBrowserChromeH3 = "browser-chrome-h3" // Chrome-impersonated transport forced through HTTP/3 for stricter bot screens
)
View Source
const (
	ResponseFormatJSON = "json"
	ResponseFormatHTML = "html"
)
View Source
const (
	HTMLExtractModePage         = "page"
	HTMLExtractModeLinks        = "links"
	HTMLExtractModeEmbeddedJSON = "embedded-json"
)
View Source
const DefaultEmbeddedJSONScriptSelector = "script#__NEXT_DATA__"

DefaultEmbeddedJSONScriptSelector is the script-tag selector used when `html_extract.mode: embedded-json` is set without an explicit `script_selector`. Targets Next.js's pages-router `<script id="__NEXT_DATA__">` block — the most common shape and the one the food52 retro surfaced. Other SSR frameworks declare different selectors:

  • Nuxt: script#__NUXT__
  • Remix: script:contains("window.__remixContext") (use selector with type or id when available)
  • Astro: site-specific; declare per spec
View Source
const DefaultOrchestrationThreshold = 50

DefaultOrchestrationThreshold is the endpoint-count above which the generator recommends (but does not require) code-orchestration. At 50+ endpoints, even intent-grouped tools tend to overflow an agent's usable context; code-orchestration covers the full surface in a pair of tools.

Variables

View Source
var ReservedCLIResourceNames = map[string]struct{}{
	"agent_context":    {},
	"api_discovery":    {},
	"auth":             {},
	"auto_refresh":     {},
	"cache":            {},
	"channel_workflow": {},
	"client":           {},
	"data_source":      {},
	"deliver":          {},
	"doctor":           {},
	"export":           {},
	"feedback":         {},
	"helpers":          {},
	"html_extract":     {},
	"import":           {},
	"profile":          {},
	"root":             {},
	"search":           {},
	"share_commands":   {},
	"sync":             {},
	"tail":             {},
	"types":            {},
	"which":            {},
	"workflow":         {},
}

ReservedCLIResourceNames is the set of resource names that would collide with reserved single-file templates emitted into the printed CLI's internal/cli/ directory. Two collisions occur if a spec uses one of these as a resource name: the resource template's <name>.go overwrites the reserved file (losing helpers like FeedbackEndpointConfigured() from feedback.go), AND the resource's `new<Name>Cmd` cobra-builder shadows the reserved template's same-named function, breaking the build with a redeclaration error.

Renaming the file alone is not enough; the function-name collision still breaks the build. Reject at parse time and ask the author to rename the resource (e.g., `feedback` → `customer_feedback`, `auth` → `accounts`).

The contract is intentionally stable: removing an entry is allowed only when the corresponding reserved template is also removed from the generator.

Functions

This section is empty.

Types

type APISpec

type APISpec struct {
	Name string `yaml:"name" json:"name"`
	// Description describes the API itself ("REST API for ordering pizza").
	// It flows into generated docs and SKILL.md but is intentionally NOT used
	// as the printed CLI's --help text; that's CLIDescription's job.
	Description string `yaml:"description" json:"description"`
	// CLIDescription, when set, becomes the printed CLI's root cobra command
	// `Short:` text. Spec authors should phrase it as what the CLI does
	// ("Order Seattle pizza from the terminal"), not what the API is. When
	// blank the generator falls back to the research narrative's headline,
	// then to a generic "Manage <api> resources via the <api> API". Adding
	// this field eliminates a recurring manual rewrite step that the main
	// skill used to instruct Claude to perform after every generation.
	CLIDescription  string              `yaml:"cli_description,omitempty" json:"cli_description,omitempty"`
	Version         string              `yaml:"version" json:"version"`
	BaseURL         string              `yaml:"base_url" json:"base_url"`
	BasePath        string              `yaml:"base_path,omitempty" json:"base_path,omitempty"`
	Owner           string              `yaml:"owner,omitempty" json:"owner,omitempty"`                   // GitHub owner for import paths and Homebrew tap
	Kind            string              `yaml:"kind,omitempty" json:"kind,omitempty"`                     // "rest" (default) or "synthetic" — synthetic CLIs aggregate multiple sources beyond the spec; dogfood's path-validity check is relaxed accordingly
	SpecSource      string              `yaml:"spec_source,omitempty" json:"spec_source,omitempty"`       // official, community, sniffed, docs — affects generated client defaults
	ClientPattern   string              `yaml:"client_pattern,omitempty" json:"client_pattern,omitempty"` // rest (default), proxy-envelope — affects generated HTTP client
	HTTPTransport   string              `yaml:"http_transport,omitempty" json:"http_transport,omitempty"` // standard (default for official APIs), browser-chrome, or browser-chrome-h3
	ProxyRoutes     map[string]string   `yaml:"proxy_routes,omitempty" json:"proxy_routes,omitempty"`     // path prefix → service name for proxy-envelope routing
	WebsiteURL      string              `yaml:"website_url,omitempty" json:"website_url,omitempty"`       // product/company website (not the API base URL)
	Category        string              `yaml:"category,omitempty" json:"category,omitempty"`             // catalog category (e.g., productivity, developer-tools) — used for library install path
	Auth            AuthConfig          `yaml:"auth" json:"auth"`
	RequiredHeaders []RequiredHeader    `yaml:"required_headers,omitempty" json:"required_headers,omitempty"`
	Config          ConfigSpec          `yaml:"config" json:"config"`
	Resources       map[string]Resource `yaml:"resources" json:"resources"`
	Types           map[string]TypeDef  `yaml:"types" json:"types"`
	ExtraCommands   []ExtraCommand      `yaml:"extra_commands,omitempty" json:"extra_commands,omitempty"` // hand-written cobra commands declared so SKILL.md can document them; spec-only metadata, no code generated
	Cache           CacheConfig         `yaml:"cache,omitempty" json:"cache"`                             // cache freshness + auto-refresh config; when enabled, generated read commands auto-refresh stale local data before serving
	Share           ShareConfig         `yaml:"share,omitempty" json:"share"`                             // git-backed snapshot sharing config; when enabled, emits a `share` subcommand that publishes/subscribes to a git repo
	MCP             MCPConfig           `yaml:"mcp,omitempty" json:"mcp"`                                 // MCP server generation config; when unset, the emitted MCP binary is stdio-only (today's default). Opting into http adds a --transport/--addr flag surface so the same binary can serve cloud-hosted agents.
}

func Parse

func Parse(path string) (*APISpec, error)

func ParseBytes

func ParseBytes(data []byte) (*APISpec, error)

func (*APISpec) CountMCPTools

func (s *APISpec) CountMCPTools() (total, public int)

CountMCPTools counts total endpoints and public (NoAuth) endpoints across all resources and sub-resources.

func (*APISpec) EffectiveHTTPTransport

func (s *APISpec) EffectiveHTTPTransport() string

func (*APISpec) HasHTMLExtractMode

func (s *APISpec) HasHTMLExtractMode(mode string) bool

HasHTMLExtractMode reports whether any endpoint in the spec declares html_extract with the given effective mode. Used by the html_extract template to gate per-mode helpers: a CLI that uses only HTMLExtractModeEmbeddedJSON does not need the page-mode DOM walkers or links-mode anchor parsing, and vice versa.

`mode` should be one of the HTMLExtractMode* constants. Modes that don't appear in any endpoint return false; modes are matched by their effective value (so an unset Mode counts as page).

func (*APISpec) HasHTMLExtraction

func (s *APISpec) HasHTMLExtraction() bool

func (*APISpec) IsSynthetic

func (s *APISpec) IsSynthetic() bool

IsSynthetic reports whether this spec declares a multi-source / combo CLI where hand-built commands intentionally go beyond the spec. Dogfood skips strict path-validity and scorecard marks path_validity as unscored.

func (*APISpec) UsesBrowserHTTP3Transport

func (s *APISpec) UsesBrowserHTTP3Transport() bool

func (*APISpec) UsesBrowserHTTPTransport

func (s *APISpec) UsesBrowserHTTPTransport() bool

func (*APISpec) UsesBrowserManagedUserAgent

func (s *APISpec) UsesBrowserManagedUserAgent() bool

func (*APISpec) Validate

func (s *APISpec) Validate() error

type AuthConfig

type AuthConfig struct {
	Type             string   `yaml:"type" json:"type"` // api_key, oauth2, bearer_token, cookie, composed, session_handshake, none
	Header           string   `yaml:"header" json:"header"`
	Format           string   `yaml:"format" json:"format"`
	EnvVars          []string `yaml:"env_vars" json:"env_vars"`
	Optional         bool     `yaml:"optional,omitempty" json:"optional,omitempty"` // true when the key enhances a subset of features (e.g., USDA nutrition backfill) rather than gating core functionality; doctor treats unconfigured optional auth as INFO not FAIL and README frames the section as "Optional"
	Scheme           string   `yaml:"scheme,omitempty" json:"scheme,omitempty"`     // OpenAPI security scheme name
	In               string   `yaml:"in,omitempty" json:"in,omitempty"`             // header, query, cookie
	KeyURL           string   `yaml:"key_url,omitempty" json:"key_url,omitempty"`   // URL where users can register for an API key
	AuthorizationURL string   `yaml:"authorization_url,omitempty" json:"authorization_url,omitempty"`
	TokenURL         string   `yaml:"token_url,omitempty" json:"token_url,omitempty"`
	Scopes           []string `yaml:"scopes,omitempty" json:"scopes,omitempty"`
	CookieDomain     string   `yaml:"cookie_domain,omitempty" json:"cookie_domain,omitempty"` // domain to read browser cookies from (e.g. ".notion.so")
	Cookies          []string `yaml:"cookies,omitempty" json:"cookies,omitempty"`             // named cookies to extract for composed auth (e.g. ["customerId", "authToken"])
	Inferred         bool     `yaml:"inferred,omitempty" json:"inferred,omitempty"`           // true when auth was inferred from spec description, not declared in securitySchemes

	// VerifyPath is an optional path appended to base_url that the doctor
	// command probes to validate credentials. Set this to a known-good
	// authenticated GET endpoint that returns 2xx for any valid token (e.g.
	// "/me?fields=id" for Meta, "/v1/account" for Stripe, "/user" for GitHub,
	// "/users/@me" for Discord). When empty, doctor falls back to probing
	// the bare base URL and classifies 401/403 as "inconclusive" rather than
	// "invalid", because many versioned API roots return 401 regardless of
	// token validity (the path isn't a routed endpoint, but the gateway
	// still demands credentials in a meaningful context).
	VerifyPath string `yaml:"verify_path,omitempty" json:"verify_path,omitempty"`

	// Browser-session verification fields. Used when a website-facing CLI
	// depends on browser-derived cookies or clearance state for its required
	// happy path. The generator emits validation and proof handling, and the
	// shipcheck pipeline treats a missing proof as a blocker.
	RequiresBrowserSession         bool   `yaml:"requires_browser_session,omitempty" json:"requires_browser_session,omitempty"`
	BrowserSessionReason           string `yaml:"browser_session_reason,omitempty" json:"browser_session_reason,omitempty"`
	BrowserSessionValidationPath   string `yaml:"browser_session_validation_path,omitempty" json:"browser_session_validation_path,omitempty"`
	BrowserSessionValidationMethod string `yaml:"browser_session_validation_method,omitempty" json:"browser_session_validation_method,omitempty"`

	// Session-handshake fields. Used only when Type == "session_handshake".
	// The pattern: GET BootstrapURL to seed cookies → GET TokenURL to receive
	// an anti-CSRF token (the "crumb" on Yahoo Finance, similarly named on
	// Walmart, some streaming APIs, Facebook's internal graph) → pass that
	// token on every subsequent data request as TokenParamName in TokenParamIn.
	// The generator emits a cookie jar, disk-persisted session file, and auto-
	// invalidation on InvalidateOnStatus responses.
	BootstrapURL       string `yaml:"bootstrap_url,omitempty" json:"bootstrap_url,omitempty"`               // optional GET to seed cookies before token fetch (e.g. "https://fc.yahoo.com/")
	SessionTokenURL    string `yaml:"session_token_url,omitempty" json:"session_token_url,omitempty"`       // endpoint that returns the token (e.g. "https://query2.finance.yahoo.com/v1/test/getcrumb"); distinct from TokenURL (OAuth) to avoid conflation
	TokenFormat        string `yaml:"token_format,omitempty" json:"token_format,omitempty"`                 // "text" (raw body) or "json" (extract via TokenJSONPath); default "text"
	TokenJSONPath      string `yaml:"token_json_path,omitempty" json:"token_json_path,omitempty"`           // when TokenFormat is "json", dot-path to the token field (e.g. "data.crumb")
	TokenParamName     string `yaml:"token_param_name,omitempty" json:"token_param_name,omitempty"`         // parameter name to attach to requests (e.g. "crumb")
	TokenParamIn       string `yaml:"token_param_in,omitempty" json:"token_param_in,omitempty"`             // "query" or "header"; default "query"
	InvalidateOnStatus []int  `yaml:"invalidate_on_status,omitempty" json:"invalidate_on_status,omitempty"` // HTTP status codes that should invalidate the cached token and re-bootstrap (e.g. [401, 403])
	SessionTTLHours    int    `yaml:"session_ttl_hours,omitempty" json:"session_ttl_hours,omitempty"`       // how long to trust a cached session (default 24)
}

type CacheCommand

type CacheCommand struct {
	Name      string   `yaml:"name" json:"name"`           // lowercase cobra command path, without the binary name (e.g., "today" or "insights stale")
	Resources []string `yaml:"resources" json:"resources"` // resource names to refresh before serving the command
}

CacheCommand declares that a hand-authored command path reads one or more syncable resources and should participate in the generated freshness hook.

type CacheConfig

type CacheConfig struct {
	Enabled        bool              `yaml:"enabled,omitempty" json:"enabled,omitempty"`                 // master switch; when false, freshness helpers and pre-run refresh hook are not emitted
	StaleAfter     string            `yaml:"stale_after,omitempty" json:"stale_after,omitempty"`         // default duration after which any resource's last_synced_at is considered stale (e.g., "6h"). Blank means runtime default (6h).
	RefreshTimeout string            `yaml:"refresh_timeout,omitempty" json:"refresh_timeout,omitempty"` // max wall-clock the pre-run refresh may block the command (e.g., "30s"). On timeout the command serves stale data with a stderr warning. Blank means runtime default (30s).
	EnvOptOut      string            `yaml:"env_opt_out,omitempty" json:"env_opt_out,omitempty"`         // env var name that disables auto-refresh when set to "1" (e.g., LINEAR_NO_AUTO_REFRESH). Blank lets the template derive {{upper name}}_NO_AUTO_REFRESH.
	Resources      map[string]string `yaml:"resources,omitempty" json:"resources,omitempty"`             // per-resource override of stale_after (e.g., quotes: "5m", channels: "24h"). Resources not listed inherit StaleAfter.
	Commands       []CacheCommand    `yaml:"commands,omitempty" json:"commands,omitempty"`               // optional custom command-path coverage for hand-authored store-backed reads. Generated resource commands are covered automatically.
}

CacheConfig gates the auto-refresh machinery emitted into a printed CLI. Opt-in — CLIs whose local store is per-user state (carts, drafts) should leave Enabled at its zero value so reads never silently replace the user's state with a snapshot from a different session.

StaleAfter and RefreshTimeout are strings parsed to time.Duration at CLI runtime; keeping them as strings lets spec authors write "6h" or "30s" and preserves the yaml-level representation for round-trip tooling.

type ConfigSpec

type ConfigSpec struct {
	Format string `yaml:"format" json:"format"` // toml, yaml
	Path   string `yaml:"path" json:"path"`
}

type Endpoint

type Endpoint struct {
	Method          string            `yaml:"method" json:"method"`
	Path            string            `yaml:"path" json:"path"`
	Description     string            `yaml:"description" json:"description"`
	Params          []Param           `yaml:"params" json:"params"`
	Body            []Param           `yaml:"body" json:"body"`
	Response        ResponseDef       `yaml:"response" json:"response"`
	ResponseFormat  string            `yaml:"response_format,omitempty" json:"response_format,omitempty"` // json (default) or html
	HTMLExtract     *HTMLExtract      `yaml:"html_extract,omitempty" json:"html_extract,omitempty"`       // extraction options when response_format is html
	Pagination      *Pagination       `yaml:"pagination" json:"pagination"`
	ResponsePath    string            `yaml:"response_path,omitempty" json:"response_path,omitempty"`       // path to extract data array from response (e.g., "data", "results.items")
	Meta            map[string]string `yaml:"meta,omitempty" json:"meta,omitempty"`                         // per-endpoint metadata (e.g., source_tier, source_count from crowd-sniff)
	HeaderOverrides []RequiredHeader  `yaml:"header_overrides,omitempty" json:"header_overrides,omitempty"` // per-endpoint header overrides (e.g., different api-version)
	NoAuth          bool              `yaml:"no_auth,omitempty" json:"no_auth,omitempty"`                   // true when the endpoint does not require authentication
	Alias           string            `yaml:"-" json:"-"`                                                   // computed, not from YAML
}

func (Endpoint) EffectiveResponseFormat

func (e Endpoint) EffectiveResponseFormat() string

func (Endpoint) UsesHTMLResponse

func (e Endpoint) UsesHTMLResponse() bool

type ExtraCommand

type ExtraCommand struct {
	Name        string `yaml:"name" json:"name"`                     // command path, e.g. "boxscore" or "tv airing-today"
	Description string `yaml:"description" json:"description"`       // one-line description rendered after a dash
	Args        string `yaml:"args,omitempty" json:"args,omitempty"` // optional positional arg signature, e.g. "<event_id>" or "<team1> <team2>"
}

ExtraCommand declares a hand-written cobra command so the SKILL.md Command Reference can list it alongside spec-driven resources. The generator does not emit code for these — authors hand-write the command in internal/cli/. Without this declaration the SKILL.md template only sees .Resources and silently omits hand-written commands, which is the drift class that motivated this field.

type HTMLExtract

type HTMLExtract struct {
	Mode         string   `yaml:"mode,omitempty" json:"mode,omitempty"`                   // page (default), links, or embedded-json
	LinkPrefixes []string `yaml:"link_prefixes,omitempty" json:"link_prefixes,omitempty"` // URL path prefixes to keep when extracting links (mode: links)
	Limit        int      `yaml:"limit,omitempty" json:"limit,omitempty"`                 // max links to return; defaults at runtime (mode: links)
	// ScriptSelector identifies the <script> tag containing serialized
	// page state when mode is embedded-json. Defaults to
	// DefaultEmbeddedJSONScriptSelector ("script#__NEXT_DATA__") when
	// empty — the most common Next.js pages-router shape. Other SSR
	// frameworks declare per-site selectors (Nuxt: "script#__NUXT__",
	// etc.). Selector grammar is the simple "tag" / "tag#id" form
	// supported by the runtime extractor; expand later if needed.
	ScriptSelector string `yaml:"script_selector,omitempty" json:"script_selector,omitempty"`
	// JSONPath is a dot-notation walk into the parsed JSON inside the
	// matched script tag (mode: embedded-json). For Next.js the typical
	// value is "props.pageProps.<route-data>"; for Nuxt "data.<route>".
	// Empty path returns the entire parsed JSON. Missing intermediate
	// keys yield a typed-empty result rather than an error.
	JSONPath string `yaml:"json_path,omitempty" json:"json_path,omitempty"`
}

func (*HTMLExtract) EffectiveMode

func (h *HTMLExtract) EffectiveMode() string

func (*HTMLExtract) EffectiveScriptSelector

func (h *HTMLExtract) EffectiveScriptSelector() string

EffectiveScriptSelector returns the configured script selector, or the default Next.js pages-router selector when unset. Only meaningful when EffectiveMode() == HTMLExtractModeEmbeddedJSON.

type Intent

type Intent struct {
	Name        string        `yaml:"name" json:"name"`                           // MCP tool name; snake_case, unique within the spec
	Description string        `yaml:"description" json:"description"`             // agent-facing description; should name the *intent*, not the endpoints
	Params      []IntentParam `yaml:"params,omitempty" json:"params,omitempty"`   // input parameters the intent tool exposes to MCP callers
	Steps       []IntentStep  `yaml:"steps" json:"steps"`                         // ordered list of endpoint calls; at least one required
	Returns     string        `yaml:"returns,omitempty" json:"returns,omitempty"` // capture name whose value is returned to the caller; defaults to the last step's capture when blank
}

Intent declares an MCP tool that composes multiple endpoint calls into a single agent-facing operation. The generator emits one handler per intent that resolves bindings, calls each endpoint in order against the CLI's existing HTTP client, and returns the captured value named by Returns.

Binding syntax — each value in a step's Bind map is a string expression:

  • `${input.<name>}` resolves to the MCP request's input parameter
  • `${<capture>.<field>}` resolves to a field of a previous step's captured JSON response
  • anything else is used as a string literal

Type coercion: all bound values are rendered as strings at runtime; JSON bodies for POST/PUT/PATCH are built from the resolved map. The intent surface intentionally does not support array indexing, conditional branching, or looping in v1 — those escapes belong in U3's code-orchestration pattern, not here.

type IntentParam

type IntentParam struct {
	Name        string `yaml:"name" json:"name"`
	Type        string `yaml:"type" json:"type"` // one of: string, integer, boolean
	Required    bool   `yaml:"required,omitempty" json:"required,omitempty"`
	Description string `yaml:"description" json:"description"`
}

IntentParam mirrors a narrow slice of the endpoint Param type. Kept small by design: intents are compositions, so parameter shapes should be simple string/int/bool inputs that bind into step calls, not full nested bodies.

type IntentStep

type IntentStep struct {
	Endpoint string            `yaml:"endpoint" json:"endpoint"`                   // dotted path into the spec's resources, e.g., "messages.get_thread"
	Bind     map[string]string `yaml:"bind,omitempty" json:"bind,omitempty"`       // map of endpoint param name -> binding expression
	Capture  string            `yaml:"capture,omitempty" json:"capture,omitempty"` // name to bind this step's response under for subsequent steps / returns; must be unique within the intent
}

IntentStep declares one endpoint call inside an intent. Endpoint references are `resource.endpoint` or `resource.sub_resource.endpoint`; the validator confirms the path resolves against APISpec.Resources at spec load.

type MCPConfig

type MCPConfig struct {
	Transport              []string `yaml:"transport,omitempty" json:"transport,omitempty"`                             // allowed transports the generated binary compiles support for; empty == [stdio]. Runtime transport is chosen via the --transport flag and PP_MCP_TRANSPORT env.
	Addr                   string   `yaml:"addr,omitempty" json:"addr,omitempty"`                                       // default bind address for the http transport (e.g., ":7777"). Blank means runtime default (":7777"). Ignored unless http is in Transport.
	Intents                []Intent `yaml:"intents,omitempty" json:"intents,omitempty"`                                 // higher-level MCP tools that compose multiple endpoint calls. The agent sees one intent tool; the generator emits a handler that fans out to the declared endpoints sequentially. Anti-pattern to fight: one-tool-per-endpoint mirrors that force agents to stitch primitives.
	EndpointTools          string   `yaml:"endpoint_tools,omitempty" json:"endpoint_tools,omitempty"`                   // "visible" (default) keeps the per-endpoint MCP tools; "hidden" suppresses them so only intents + generator-emitted tools appear. Use "hidden" when intents fully cover the surface and raw endpoints would be noise.
	Orchestration          string   `yaml:"orchestration,omitempty" json:"orchestration,omitempty"`                     // "endpoint-mirror" (default), "intent", or "code". Code-orchestration emits a thin <api>_search + <api>_execute pair covering the full surface in ~1K tokens; used for very large APIs where even intent-grouped tools would overflow context. Mutually exclusive with endpoint-mirror at emission time.
	OrchestrationThreshold int      `yaml:"orchestration_threshold,omitempty" json:"orchestration_threshold,omitempty"` // endpoint count above which the generator warns that code-orchestration would be a better default. Zero means use the built-in default (50).
}

MCPConfig declares how the generated MCP server binary is shaped. When empty the generator emits today's behavior: a stdio-only server via server.ServeStdio. Opting http into Transport adds a --transport flag (stdio|http) and, for http, an --addr flag so the same binary can also serve an HTTP streamable transport.

Rationale: stdio-only servers can only reach clients that share a filesystem and can spawn a subprocess. Cloud-hosted agents (hosted Claude Code sessions, Managed Agents, web clients) cannot, so they need a remote transport option. Declaring transports in the spec rather than inferring at generate time keeps the decision visible and reviewable in the published CLI's source spec.

Allowed Transport values: "stdio", "http". An empty list is treated as ["stdio"] for backward compatibility. Unknown values are rejected at spec load; this prevents silent drift when new transports are introduced.

func (MCPConfig) EffectiveOrchestrationThreshold

func (m MCPConfig) EffectiveOrchestrationThreshold() int

EffectiveOrchestrationThreshold returns the resolved threshold, applying the built-in default when the spec leaves it unset.

func (MCPConfig) EffectiveTransports

func (m MCPConfig) EffectiveTransports() []string

EffectiveTransports returns the transports the generated binary should support, defaulting to stdio when none are declared. Using this helper from templates and the generator avoids sprinkling the default in two places.

func (MCPConfig) HasTransport

func (m MCPConfig) HasTransport(t string) bool

HasTransport reports whether t is among the effective transports for this MCPConfig. Case-insensitive on the comparison since spec authors may write "HTTP" and the generator normalizes to lowercase at validation time.

func (MCPConfig) IsCodeOrchestration

func (m MCPConfig) IsCodeOrchestration() bool

IsCodeOrchestration reports whether this MCP config opts into the code-orchestration thin surface. Templates branch on this to emit only <api>_search + <api>_execute instead of the endpoint-mirror.

type Pagination

type Pagination struct {
	Type           string `yaml:"type" json:"type"`                         // cursor, offset, page_token
	LimitParam     string `yaml:"limit_param" json:"limit_param"`           // query param name for page size (limit, maxResults, pageSize)
	CursorParam    string `yaml:"cursor_param" json:"cursor_param"`         // query param name for cursor (after, pageToken, offset)
	NextCursorPath string `yaml:"next_cursor_path" json:"next_cursor_path"` // response field with next cursor (nextPageToken, cursor)
	HasMoreField   string `yaml:"has_more_field" json:"has_more_field"`     // response field indicating more pages (has_more)
}

type Param

type Param struct {
	Name        string   `yaml:"name" json:"name"`
	Type        string   `yaml:"type" json:"type"`
	Required    bool     `yaml:"required" json:"required"`
	Positional  bool     `yaml:"positional" json:"positional"`
	PathParam   bool     `yaml:"path_param,omitempty" json:"path_param,omitempty"` // true for path params rendered as flags (e.g., pagination)
	Default     any      `yaml:"default" json:"default"`
	Description string   `yaml:"description" json:"description"`
	Fields      []Param  `yaml:"fields" json:"fields"`                     // for nested objects
	Enum        []string `yaml:"enum,omitempty" json:"enum,omitempty"`     // enum constraints for the parameter
	Format      string   `yaml:"format,omitempty" json:"format,omitempty"` // OpenAPI format hints (date-time, email, uri, etc.)
	// IdentName, when set, overrides Name for Go identifier and CLI flag
	// derivation (camel/flagName). Name remains the wire-side parameter name
	// used in URLs, JSON keys, and path substitution. Populated by the
	// generator's flag-collision dedup pass when two params on the same
	// endpoint would otherwise produce identical Go identifiers or CLI flag
	// names — for example Twilio's StartTime/StartTime>/StartTime< all
	// collapsing to "StartTime" through camelization. Most params leave this
	// empty and template helpers fall back to Name.
	IdentName string `yaml:"-" json:"-"`
}

type RequiredHeader

type RequiredHeader struct {
	Name  string `yaml:"name" json:"name"`
	Value string `yaml:"value" json:"value"`
}

RequiredHeader represents a non-auth header that the API requires on most requests (e.g., cal-api-version, Stripe-Version, anthropic-version). Detected automatically from OpenAPI specs when a required header parameter appears on >80% of operations.

type Resource

type Resource struct {
	Description  string              `yaml:"description" json:"description"`
	Path         string              `yaml:"path,omitempty" json:"path,omitempty"`             // base path for operations shorthand (e.g., /api/items)
	Operations   []string            `yaml:"operations,omitempty" json:"operations,omitempty"` // shorthand: list, get, create, update, delete, search
	Endpoints    map[string]Endpoint `yaml:"endpoints" json:"endpoints"`
	SubResources map[string]Resource `yaml:"sub_resources,omitempty" json:"sub_resources,omitempty"`
}

type ResponseDef

type ResponseDef struct {
	Type string `yaml:"type" json:"type"` // object, array
	Item string `yaml:"item" json:"item"` // type name
}

type ShareConfig

type ShareConfig struct {
	Enabled        bool     `yaml:"enabled,omitempty" json:"enabled,omitempty"`                 // master switch; when false, the share package and command are not emitted
	SnapshotTables []string `yaml:"snapshot_tables,omitempty" json:"snapshot_tables,omitempty"` // explicit allowlist of SQLite tables included in the snapshot. Required when Enabled. Names matching denylisted patterns (*_cache, *_secrets, auth_*) are rejected at parse time.
	DefaultRepo    string   `yaml:"default_repo,omitempty" json:"default_repo,omitempty"`       // optional default git remote (e.g., "git@github.com:acme/linear-snapshots.git"); command-line --repo flag always wins
	DefaultBranch  string   `yaml:"default_branch,omitempty" json:"default_branch,omitempty"`   // optional default branch for push/pull; blank means "main"
}

ShareConfig gates the git-backed snapshot share surface emitted into a printed CLI. When Enabled, the generator emits an internal/share package plus a `share` cobra command (publish, subscribe, export, import). Share is off by default because it is a multi-user feature and most CLIs are single-user; enabling also requires an explicit SnapshotTables allowlist to prevent accidental export of auth or per-user state.

type TypeDef

type TypeDef struct {
	Fields []TypeField `yaml:"fields" json:"fields"`
}

type TypeField

type TypeField struct {
	Name string `yaml:"name" json:"name"`
	Type string `yaml:"type" json:"type"`
}

Jump to

Keyboard shortcuts

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