wire

package
v0.1.19 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CodeRegistrationRejected  = -33000
	CodeVersionUnsupported    = -33001
	CodeDuplicateRegistration = -33002
	CodeCapabilityConflict    = -33003
	CodeToolNameConflict      = -33004
	CodeNotRegistered         = -33005
)

Registration / lifecycle codes.

View Source
const (
	CodeFlowRejected       = -33100
	CodeCoreInvokeRejected = -33101
	CodeRuleRejected       = -33102
)

Rule and flow codes; also cover flow emission and core_invoke validation.

View Source
const (
	CodeFramingViolation  = -33200
	CodeOversizedMessage  = -33201
	CodeUnknownStream     = -33202
	CodeClaimProbeFault   = -33203
	CodeTransportInternal = -33299
)

Transport codes.

View Source
const (
	CodeDialScopeRejected = -33300
	CodeDialFailed        = -33301
	CodeDialTLSFailed     = -33302
)

dial_upstream codes.

View Source
const (
	CodeUnknownDestAdapter = -33400
	CodeNoInjectionTarget  = -33401
	CodeInjectSendFailed   = -33402
)

invoke_adapter codes.

View Source
const (
	VersionMajor = 1
	VersionMinor = 0
)

Contract version advertised at registration. Major mismatch is a fast fail; within a shared major the session runs at min(local, remote) minor.

View Source
const (
	MethodRegister      = "register"
	MethodPing          = "ping"
	MethodPong          = "pong"
	MethodShutdown      = "shutdown"
	MethodPushFlow      = "push_flow"
	MethodLog           = "log"
	MethodReportMetrics = "report_metrics"
	MethodCoreInvoke    = "core_invoke"
	MethodStreamOpen    = "stream_open"
	MethodStreamDeliver = "stream_deliver"
	MethodStreamEnded   = "stream_ended"
	MethodCloseStream   = "close_stream"
	MethodStreamWrite   = "stream_write"
	MethodClaimProbe    = "claim_probe"
	MethodDialUpstream  = "dial_upstream"
	MethodSyncRules     = "sync_rules"
	MethodSidecarSend   = "sidecar_send"
	MethodInvokeAdapter = "invoke_adapter"
	MethodInvokeTool    = "invoke_tool"
)

JSON-RPC method names exchanged over the connection.

View Source
const (
	RuleTypeRequestHeader  = "request_header"
	RuleTypeRequestBody    = "request_body"
	RuleTypeResponseHeader = "response_header"
	RuleTypeResponseBody   = "response_body"
	RuleTypeWSToServer     = "ws:to-server"
	RuleTypeWSToClient     = "ws:to-client"
	RuleTypeWSBoth         = "ws:both"
)

Rule type values for the Type field, shared by sectool and sidecars.

View Source
const AnnotationReplay = "replay"

AnnotationReplay is the Flow.Annotations key marking a flow as a replay.

View Source
const JSONRPCVersion = "2.0"

JSONRPCVersion is the protocol identifier carried in every message.

View Source
const MaxFrameBytes uint64 = 0xFFFFFFFF

MaxFrameBytes bounds a single message, the ceiling of the 4-byte big-endian uint32 length prefix.

Variables

View Source
var ErrPeerClosed = errors.New("sidecar: peer closed")

ErrPeerClosed is returned when an operation is attempted on a closed peer.

Functions

func ReadFrame

func ReadFrame(r io.Reader) ([]byte, error)

ReadFrame reads one length-prefixed message. Returns the underlying read error (e.g. io.EOF) on a closed connection.

func WriteFrame

func WriteFrame(w io.Writer, payload []byte) error

WriteFrame writes payload as a 4-byte big-endian length prefix followed by the payload bytes.

Types

type BodyCodec

type BodyCodec struct {
	// Transforms is the ordered transform chain (e.g. decryption, decompression, de-framing).
	Transforms []string `json:"transforms,omitempty"`
	// ContentType is the logical content-type.
	ContentType string `json:"content_type,omitempty"`
}

BodyCodec describes how Body was derived from BodyRaw, used on replay to re-encode a mutated Body back to the wire form.

type Capabilities

type Capabilities struct {
	EarlyClaims      []EarlyClaim      `json:"early_claims,omitempty"`
	UpgradeClaims    []UpgradeClaim    `json:"upgrade_claims,omitempty"`
	InjectionTargets []InjectionTarget `json:"injection_targets,omitempty"`
}

Capabilities are the parameterized seams a sidecar declares. Each kind is a list, so one registration can claim multiple protocol entry points.

type ClaimProbeParams

type ClaimProbeParams struct {
	Host     string `json:"host,omitempty"`
	Port     int    `json:"port,omitempty"`
	PeerAddr string `json:"peer_addr,omitempty"`
	SNI      string `json:"sni,omitempty"`
	Data     []byte `json:"data,omitempty"`
}

ClaimProbeParams asks the sidecar whether a buffered opening stream is its protocol, for an early_claim that set probe.

type ClaimProbeResult

type ClaimProbeResult struct {
	Claim bool `json:"claim"`
}

ClaimProbeResult is the sidecar's claim decision. A false claim is normal control flow, not an error.

type CoreInvokeParams

type CoreInvokeParams struct {
	Tool   string          `json:"tool"`
	Params json.RawMessage `json:"params,omitempty"`
}

CoreInvokeParams invokes a core MCP tool by name.

type CoreInvokeResult

type CoreInvokeResult struct {
	Content string `json:"content"`
	IsError bool   `json:"is_error,omitempty"`
}

CoreInvokeResult is the core tool's result text.

type DialUpstreamParams

type DialUpstreamParams struct {
	// Host and Port, when omitted, default to the original destination of
	// ParentFlowID's connection; supplying them redirects to a different upstream.
	Host         string           `json:"host,omitempty"`
	Port         int              `json:"port,omitempty"`
	TLS          *DialUpstreamTLS `json:"tls,omitempty"`
	ParentFlowID string           `json:"parent_flow_id,omitempty"`
}

DialUpstreamParams asks sectool to open an upstream TCP connection on the sidecar's behalf.

type DialUpstreamResult

type DialUpstreamResult struct {
	StreamID string `json:"stream_id"`
}

DialUpstreamResult carries the stream identifier for the opened upstream socket.

type DialUpstreamTLS

type DialUpstreamTLS struct {
	Enabled    bool     `json:"enabled"`
	SNI        string   `json:"sni,omitempty"`
	ALPN       []string `json:"alpn,omitempty"`
	SkipVerify bool     `json:"skip_verify,omitempty"`
}

DialUpstreamTLS configures TLS termination toward the upstream. When Enabled, sectool performs the handshake and bridges cleartext bytes to the sidecar.

type EarlyClaim

type EarlyClaim struct {
	PortRange PortRange `json:"port_range"`
	TLS       *TLSClaim `json:"tls,omitempty"`
	// MagicBytesPrefix carries base64-encoded opening bytes.
	MagicBytesPrefix string `json:"magic_bytes_prefix,omitempty"`
	HostMatch        string `json:"host_match,omitempty"`
	Probe            bool   `json:"probe,omitempty"`
	ProbeMaxBytes    int    `json:"probe_max_bytes,omitempty"`
}

EarlyClaim claims TCP connections at accept on a port range.

type Error

type Error struct {
	Code    int        `json:"code"`
	Message string     `json:"message"`
	Data    *ErrorData `json:"data,omitempty"`
}

Error is a JSON-RPC 2.0 error object; it implements the error interface.

func NewError

func NewError(code int, msg string) *Error

NewError builds an Error with the given code and message.

func (*Error) Error

func (e *Error) Error() string

func (*Error) WithData

func (e *Error) WithData(d *ErrorData) *Error

WithData attaches structured data and returns the error for chaining.

type ErrorData

type ErrorData struct {
	Adapter         string `json:"adapter,omitempty"`
	ConflictAdapter string `json:"conflict_adapter,omitempty"`
	FlowID          string `json:"flow_id,omitempty"`
	StreamID        string `json:"stream_id,omitempty"`
}

ErrorData carries the adapter name plus any relevant identifiers on a sectool-specific error.

type Flow

type Flow struct {
	// FlowID is empty on first emission (sectool assigns) and set to re-target an
	// existing flow for two-phase completion or session/stream teardown.
	FlowID       string         `json:"flow_id,omitempty"`
	Adapter      string         `json:"adapter,omitempty"`
	ProtocolTag  string         `json:"protocol_tag,omitempty"`
	Direction    string         `json:"direction,omitempty"`
	ParentFlowID string         `json:"parent_flow_id,omitempty"`
	Scheme       string         `json:"scheme,omitempty"`
	Port         int            `json:"port,omitempty"`
	Request      *FlowMessage   `json:"request,omitempty"`
	Response     *FlowMessage   `json:"response,omitempty"`
	StartedAt    time.Time      `json:"started_at,omitempty"`
	CompletedAt  time.Time      `json:"completed_at,omitempty"`
	Annotations  map[string]any `json:"annotations,omitempty"`
}

Flow is a captured exchange a sidecar publishes via push_flow.

type FlowMessage

type FlowMessage struct {
	Method     string   `json:"method,omitempty"`
	Path       string   `json:"path,omitempty"`
	Query      string   `json:"query,omitempty"`
	StatusCode int      `json:"status_code,omitempty"`
	StatusText string   `json:"status_text,omitempty"`
	Headers    []Header `json:"headers,omitempty"`
	// Body is the logical payload every tool operates on.
	Body []byte `json:"body,omitempty"`
	// BodyRaw and BodyCodec carry the wire form when Body is not natively decodable by sectool.
	BodyRaw   []byte     `json:"body_raw,omitempty"`
	BodyCodec *BodyCodec `json:"body_codec,omitempty"`
}

FlowMessage is one side of a flow: request or response. Byte fields are base64 in JSON.

func (*FlowMessage) Clone added in v0.1.19

func (m *FlowMessage) Clone() *FlowMessage

Clone returns a copy whose Headers, Body, and BodyRaw can be mutated without touching the source. BodyCodec is immutable and shared.

type Handler

type Handler interface {
	HandleRequest(ctx context.Context, method string, params json.RawMessage) (any, *Error)
	HandleNotification(ctx context.Context, method string, params json.RawMessage)
}

Handler processes inbound requests and notifications from the remote peer. HandleRequest returns either a result (marshaled to the JSON-RPC response) or an *Error. HandleNotification has no reply.

type HandlerFuncs

type HandlerFuncs struct {
	Request      func(ctx context.Context, method string, params json.RawMessage) (any, *Error)
	Notification func(ctx context.Context, method string, params json.RawMessage)
}

HandlerFuncs adapts ordinary functions to the Handler interface. A nil Request function replies "method not found"; a nil Notification is a no-op.

func (HandlerFuncs) HandleNotification

func (h HandlerFuncs) HandleNotification(ctx context.Context, method string, params json.RawMessage)

func (HandlerFuncs) HandleRequest

func (h HandlerFuncs) HandleRequest(ctx context.Context, method string, params json.RawMessage) (any, *Error)
type Header struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

Header is a single name-value metadata entry on a message.

type InjectionTarget

type InjectionTarget struct {
	TargetSchema json.RawMessage `json:"target_schema,omitempty"`
}

InjectionTarget declares the sidecar can originate outbound messages.

type InvokeAdapterParams

type InvokeAdapterParams struct {
	Adapter         string          `json:"adapter"`
	Target          json.RawMessage `json:"target,omitempty"`
	Payload         json.RawMessage `json:"payload,omitempty"`
	Mutations       []Mutation      `json:"mutations,omitempty"`
	WaitForResponse *bool           `json:"wait_for_response,omitempty"`
}

InvokeAdapterParams routes an outbound message through another adapter's injection_target. Target/Payload are validated by the destination adapter, not sectool. WaitForResponse defaults to true when nil.

type InvokeAdapterResult

type InvokeAdapterResult struct {
	NewFlowIDs []string     `json:"new_flow_ids,omitempty"`
	Response   *FlowMessage `json:"response,omitempty"`
}

InvokeAdapterResult carries the produced flows and optional response form.

type InvokeToolParams

type InvokeToolParams struct {
	Name      string          `json:"name"`
	Arguments json.RawMessage `json:"arguments,omitempty"`
}

InvokeToolParams delegates an MCP client's call of a sidecar-registered tool. Arguments are validated against the tool's input_schema before delegation.

type InvokeToolResult

type InvokeToolResult struct {
	// Content is markdown text.
	Content string `json:"content,omitempty"`
	// StructuredContent is optional structured content.
	StructuredContent json.RawMessage `json:"structured_content,omitempty"`
	IsError           bool            `json:"is_error,omitempty"`
}

InvokeToolResult is the sidecar tool's result, returned verbatim to the MCP client.

type LogParams

type LogParams struct {
	Level   string         `json:"level,omitempty"`
	Message string         `json:"message"`
	Fields  map[string]any `json:"fields,omitempty"`
}

LogParams is a structured diagnostic log line.

type MCPTool

type MCPTool struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	InputSchema json.RawMessage `json:"input_schema,omitempty"`
	Annotations json.RawMessage `json:"annotations,omitempty"`
}

MCPTool is a tool definition the sidecar provides.

type Message

type Message struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      json.RawMessage `json:"id,omitempty"`
	Method  string          `json:"method,omitempty"`
	Params  json.RawMessage `json:"params,omitempty"`
	Result  json.RawMessage `json:"result,omitempty"`
	Error   *Error          `json:"error,omitempty"`
}

Message is the single on-wire JSON-RPC 2.0 envelope. Both peers send and receive Messages; the discriminators classify each one:

  • request: has id and method
  • response: has id, no method (carries result or error)
  • notification: no id, has method

func (*Message) IsNotification

func (m *Message) IsNotification() bool

func (*Message) IsRequest

func (m *Message) IsRequest() bool

func (*Message) IsResponse

func (m *Message) IsResponse() bool

type Mutation

type Mutation struct {
	// Op names a shared mutation: set_header/remove_header, set_json/remove_json,
	// set_form/remove_form, set_query/remove_query, method, path, query, body.
	Op string `json:"op"`
	// Name holds the header name, JSON/query path, or form field for the keyed ops.
	Name string `json:"name,omitempty"`
	// Value holds the new value (the whole payload for method/path/query/body).
	Value string `json:"value,omitempty"`
}

Mutation is one replay/origination edit applied in array order.

type Peer

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

Peer is a both-directions JSON-RPC 2.0 endpoint over one length-prefixed stream. Either side may issue Requests (Call) and Notifications (Notify).

func NewPeer

func NewPeer(rw io.ReadWriteCloser, h Handler) *Peer

NewPeer wraps rw with the given inbound Handler. Call Run to start the reader.

func (*Peer) Call

func (p *Peer) Call(ctx context.Context, method string, params, result any) *Error

Call issues a request and blocks until the response arrives, ctx is cancelled, or the peer closes. params and result may be nil. A non-nil return is the remote *Error or a transport-level *Error.

func (*Peer) Close

func (p *Peer) Close() error

Close closes the underlying connection and wakes any pending callers.

func (*Peer) Closed

func (p *Peer) Closed() bool

Closed reports whether the peer has been closed.

func (*Peer) Done

func (p *Peer) Done() <-chan struct{}

Done returns a channel closed when the peer closes.

func (*Peer) Notify

func (p *Peer) Notify(method string, params any) error

Notify sends a fire-and-forget notification.

func (*Peer) Run

func (p *Peer) Run(ctx context.Context) error

Run reads and dispatches messages until the connection closes or errors. Returns nil on a clean close (local Close or remote EOF), otherwise the read error.

func (*Peer) SetHandler

func (p *Peer) SetHandler(h Handler)

SetHandler swaps the inbound handler. Safe to call before Run starts handling traffic (e.g. between Dial's handshake and Serve).

type PortRange

type PortRange struct {
	Low  int `json:"low"`
	High int `json:"high"`
}

PortRange is an inclusive TCP port span [Low, High].

type ProtocolVersion

type ProtocolVersion struct {
	Major int `json:"major"`
	Minor int `json:"minor"`
}

ProtocolVersion is the major.minor contract version.

type PushFlowParams

type PushFlowParams = Flow

PushFlowParams is the Flow emitted via push_flow.

type PushFlowResult

type PushFlowResult struct {
	FlowID string `json:"flow_id"`
}

PushFlowResult carries the flow_id sectool assigned (or echoed back).

type RegisterParams

type RegisterParams struct {
	Name            string          `json:"name"`
	ProtocolVersion ProtocolVersion `json:"protocol_version"`
	Protocols       []string        `json:"protocols"`
	Capabilities    Capabilities    `json:"capabilities"`
	MCPTools        []MCPTool       `json:"mcp_tools,omitempty"`
	InstanceID      string          `json:"instance_id,omitempty"`
	Resume          bool            `json:"resume,omitempty"`
}

RegisterParams is the sidecar's first message.

type RegisterResult

type RegisterResult struct {
	ProtocolVersion ProtocolVersion `json:"protocol_version"`
	RulesSnapshot   []Rule          `json:"rules_snapshot"`
	ServerTime      string          `json:"server_time"`
}

RegisterResult is sectool's response to register.

type ReportMetricsParams

type ReportMetricsParams struct {
	Counters map[string]int64   `json:"counters,omitempty"`
	Gauges   map[string]float64 `json:"gauges,omitempty"`
}

ReportMetricsParams carries counter and gauge samples.

type Rule

type Rule struct {
	RuleID  string `json:"rule_id"`
	Type    string `json:"type"`
	Label   string `json:"label,omitempty"`
	IsRegex bool   `json:"is_regex,omitempty"`
	Find    string `json:"find,omitempty"`
	Replace string `json:"replace,omitempty"`
	// Adapter scopes the rule: empty applies to every adapter, otherwise names the owning sidecar.
	Adapter string `json:"adapter,omitempty"`
}

Rule is a find/replace rule the sidecar applies on its hot path.

type ShutdownParams

type ShutdownParams struct {
	DrainSeconds int `json:"drain_seconds"`
}

ShutdownParams requests a graceful close.

type ShutdownResult

type ShutdownResult struct {
	Ack bool `json:"ack"`
}

ShutdownResult acknowledges a shutdown request.

type SidecarSendParams

type SidecarSendParams struct {
	// FlowID, when set, selects the flow to replay.
	FlowID string `json:"flow_id,omitempty"`
	// Flow carries the resolved source so the adapter has body/body_raw/body_codec without a round-trip.
	Flow *Flow `json:"flow,omitempty"`
	// Destination is an optional scheme://host[:port] routing override (replay).
	Destination     string          `json:"destination,omitempty"`
	Target          json.RawMessage `json:"target,omitempty"`
	Payload         json.RawMessage `json:"payload,omitempty"`
	Mutations       []Mutation      `json:"mutations,omitempty"`
	FollowRedirects bool            `json:"follow_redirects,omitempty"`
	Force           bool            `json:"force,omitempty"`
	// WaitForResponse defaults to true when nil.
	WaitForResponse *bool  `json:"wait_for_response,omitempty"`
	StreamStrategy  string `json:"stream_strategy,omitempty"`
}

SidecarSendParams drives a replay or origination on the owning adapter.

type SidecarSendResult

type SidecarSendResult struct {
	// NewFlowIDs are the flows the replay/origination produced.
	NewFlowIDs []string `json:"new_flow_ids,omitempty"`
	// Writes are the optional first outbound bytes.
	Writes []StreamWrite `json:"writes,omitempty"`
	// Response is the completed response form when WaitForResponse was set.
	Response *FlowMessage `json:"response,omitempty"`
}

SidecarSendResult reports the outcome of a replay/origination.

type StreamEndedParams

type StreamEndedParams struct {
	StreamID string `json:"stream_id"`
	Reason   string `json:"reason,omitempty"`
}

StreamEndedParams signals a stream close in either direction: sectool's stream_ended notification to the sidecar, and the sidecar's proactive close_stream.

type StreamOpenParams

type StreamOpenParams struct {
	StreamID string `json:"stream_id"`
	Host     string `json:"host,omitempty"`
	Path     string `json:"path,omitempty"`
	PeerAddr string `json:"peer_addr,omitempty"`
	// RequestFlowID is the captured triggering request's flow, set only for an
	// upgrade_claim; absent for an early_claim.
	RequestFlowID string `json:"request_flow_id,omitempty"`
	// RequestHeaders are the triggering request's headers, set only for an
	// upgrade_claim; absent for an early_claim.
	RequestHeaders []Header `json:"request_headers,omitempty"`
}

StreamOpenParams announces that a claim fired and a new stream exists.

type StreamResult

type StreamResult struct {
	Writes []StreamWrite `json:"writes,omitempty"`
}

StreamResult replies to stream_open and stream_deliver with optional bytes to write back to one or more sockets.

type StreamWrite

type StreamWrite struct {
	// StreamID names the target stream, which may differ from the stream the event arrived on.
	StreamID string `json:"stream_id"`
	Data     []byte `json:"data"`
}

StreamWrite is one entry in a writes array: bytes for sectool to write to the named stream's socket.

type StreamWriteParams

type StreamWriteParams struct {
	StreamID string `json:"stream_id"`
	Data     []byte `json:"data"`
}

StreamWriteParams carries stream bytes in either direction: sectool's stream_deliver of inbound socket bytes to the sidecar, and the sidecar's proactive stream_write for keepalives and other timer-driven output.

type SyncRulesParams

type SyncRulesParams struct {
	SnapshotVersion uint64 `json:"snapshot_version"`
	Rules           []Rule `json:"rules"`
}

SyncRulesParams pushes the full ordered rule list a sidecar should apply.

type SyncRulesResult

type SyncRulesResult struct {
	Ack            bool   `json:"ack"`
	AppliedVersion uint64 `json:"applied_version"`
}

SyncRulesResult acks a sync_rules push with the version the sidecar applied.

type TLSCertSpec added in v0.1.19

type TLSCertSpec struct {
	DNSNames    []string `json:"dns_names,omitempty"`
	IPAddresses []string `json:"ip_addresses,omitempty"`
	URIs        []string `json:"uris,omitempty"`
	Emails      []string `json:"emails,omitempty"`
	CommonName  string   `json:"common_name,omitempty"`
}

TLSCertSpec declares additive Subject Alternative Names (and a legacy CommonName) to include on the minted terminated leaf, beyond the SNI-derived SAN. All fields are additive; the leaf always retains the dialed name.

type TLSClaim

type TLSClaim struct {
	Terminate bool   `json:"terminate"`
	SNIMatch  string `json:"sni_match,omitempty"`
	// Cert declares additive SANs for the leaf sectool mints when terminating.
	Cert *TLSCertSpec `json:"cert,omitempty"`
}

TLSClaim configures TLS termination for an early claim.

type UpgradeClaim

type UpgradeClaim struct {
	HostPattern   string   `json:"host_pattern,omitempty"`
	PathPattern   string   `json:"path_pattern,omitempty"`
	UpgradeSignal string   `json:"upgrade_signal,omitempty"` // http_101 | connect
	MethodSet     []string `json:"method_set,omitempty"`
}

UpgradeClaim claims a byte stream after an HTTP upgrade signal.

Jump to

Keyboard shortcuts

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