Documentation
¶
Index ¶
- Constants
- Variables
- func ReadFrame(r io.Reader) ([]byte, error)
- func WriteFrame(w io.Writer, payload []byte) error
- type BodyCodec
- type Capabilities
- type ClaimProbeParams
- type ClaimProbeResult
- type CoreInvokeParams
- type CoreInvokeResult
- type DialUpstreamParams
- type DialUpstreamResult
- type DialUpstreamTLS
- type EarlyClaim
- type Error
- type ErrorData
- type Flow
- type FlowMessage
- type Handler
- type HandlerFuncs
- type Header
- type InjectionTarget
- type InvokeAdapterParams
- type InvokeAdapterResult
- type InvokeToolParams
- type InvokeToolResult
- type LogParams
- type MCPTool
- type Message
- type Mutation
- type Peer
- func (p *Peer) Call(ctx context.Context, method string, params, result any) *Error
- func (p *Peer) Close() error
- func (p *Peer) Closed() bool
- func (p *Peer) Done() <-chan struct{}
- func (p *Peer) Notify(method string, params any) error
- func (p *Peer) Run(ctx context.Context) error
- func (p *Peer) SetHandler(h Handler)
- type PortRange
- type ProtocolVersion
- type PushFlowParams
- type PushFlowResult
- type RegisterParams
- type RegisterResult
- type ReportMetricsParams
- type Rule
- type ShutdownParams
- type ShutdownResult
- type SidecarSendParams
- type SidecarSendResult
- type StreamEndedParams
- type StreamOpenParams
- type StreamResult
- type StreamWrite
- type StreamWriteParams
- type SyncRulesParams
- type SyncRulesResult
- type TLSCertSpec
- type TLSClaim
- type UpgradeClaim
Constants ¶
const ( CodeRegistrationRejected = -33000 CodeVersionUnsupported = -33001 CodeDuplicateRegistration = -33002 CodeCapabilityConflict = -33003 CodeToolNameConflict = -33004 CodeNotRegistered = -33005 )
Registration / lifecycle codes.
const ( CodeFlowRejected = -33100 CodeCoreInvokeRejected = -33101 CodeRuleRejected = -33102 )
Rule and flow codes; also cover flow emission and core_invoke validation.
const ( CodeFramingViolation = -33200 CodeOversizedMessage = -33201 CodeUnknownStream = -33202 CodeClaimProbeFault = -33203 CodeTransportInternal = -33299 )
Transport codes.
const ( CodeDialScopeRejected = -33300 CodeDialFailed = -33301 CodeDialTLSFailed = -33302 )
dial_upstream codes.
const ( CodeUnknownDestAdapter = -33400 CodeNoInjectionTarget = -33401 CodeInjectSendFailed = -33402 )
invoke_adapter codes.
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.
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.
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.
const AnnotationReplay = "replay"
AnnotationReplay is the Flow.Annotations key marking a flow as a replay.
const JSONRPCVersion = "2.0"
JSONRPCVersion is the protocol identifier carried in every message.
const MaxFrameBytes uint64 = 0xFFFFFFFF
MaxFrameBytes bounds a single message, the ceiling of the 4-byte big-endian uint32 length prefix.
Variables ¶
var ErrPeerClosed = errors.New("sidecar: peer closed")
ErrPeerClosed is returned when an operation is attempted on a closed peer.
Functions ¶
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.
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 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 (*Message) IsResponse ¶
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 ¶
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) Done ¶
func (p *Peer) Done() <-chan struct{}
Done returns a channel closed when the peer closes.
func (*Peer) Run ¶
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 ¶
SetHandler swaps the inbound handler. Safe to call before Run starts handling traffic (e.g. between Dial's handshake and Serve).
type ProtocolVersion ¶
ProtocolVersion is the major.minor contract version.
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 ¶
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.