Documentation
¶
Overview ¶
CLI projection — call tools from command-line arguments or request files.
Format: ServiceName Method [-r request]
Values for -r are auto-detected:
- Existing file path → load by extension (.json, .binpb, .pb)
- Otherwise → parse as inline JSON
Internally proto-first: input is deserialized directly into a proto.Message, passed through invoke() (proto in/out), then marshaled to JSON only at the terminal output boundary.
Package invariant parses FileDescriptorSets into typed descriptor info and projects gRPC services into MCP/CLI/HTTP tools.
Index ¶
- func DefaultHTTPMetadataMapper(r *http.Request) metadata.MD
- func ParseDescriptorBytes(data []byte) (*invpb.ParsedDescriptor, error)
- func Validation() (grpc.UnaryServerInterceptor, error)
- func ValidationStream() (grpc.StreamServerInterceptor, error)
- type HTTPHeaderProvider
- type HTTPMetadataMapper
- type MethodConfig
- type OutboundHTTPRequest
- type Projection
- type Server
- func (s *Server) ConfigureMethod(methodPath string, cfg MethodConfig)
- func (s *Server) Connect(conn grpc.ClientConnInterface) errordeprecated
- func (s *Server) ConnectGRPC(conn grpc.ClientConnInterface, defaultCallOptions ...grpc.CallOption) error
- func (s *Server) ConnectHTTP(baseURL string, serviceName ...string) error
- func (s *Server) Exclude(patterns ...string)
- func (s *Server) GRPCServer() *grpc.Server
- func (s *Server) GetServiceInfo() map[string]grpc.ServiceInfo
- func (s *Server) GracefulStop()
- func (s *Server) HTTPHandler() (http.Handler, error)
- func (s *Server) Include(patterns ...string)
- func (s *Server) Invoke(ctx context.Context, toolName string, req proto.Message) (proto.Message, error)
- func (s *Server) InvokeStream(ctx context.Context, toolName string, req proto.Message, ...) error
- func (s *Server) Register(servicer any, serviceName ...string) errordeprecated
- func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl any)
- func (s *Server) Serve(listener net.Listener) error
- func (s *Server) ServeGRPC(listener net.Listener) error
- func (s *Server) ServeProjections(ctx context.Context, projections ...Projection) error
- func (s *Server) SetMaxStreamRequestBytes(n int64)
- func (s *Server) SetMaxStreamResponseBytes(n int64)
- func (s *Server) SetMaxUnaryRequestBytes(n int64)
- func (s *Server) SetMaxUnaryResponseBytes(n int64)
- func (s *Server) Stop()
- func (s *Server) ToolCatalog() []map[string]any
- func (s *Server) Tools() map[string]*Tool
- func (s *Server) Use(interceptor grpc.UnaryServerInterceptor)
- func (s *Server) UseHTTPHeaderProvider(provider HTTPHeaderProvider)
- func (s *Server) UseHTTPMetadataMapper(mapper HTTPMetadataMapper)
- func (s *Server) UseStream(interceptor grpc.StreamServerInterceptor)
- type ServerCallInfodeprecated
- type ServerStreamdeprecated
- type StreamHandlerdeprecated
- type StreamServerInterceptordeprecated
- type Tool
- type UnaryHandlerdeprecated
- type UnaryServerInterceptordeprecated
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultHTTPMetadataMapper ¶ added in v0.3.0
DefaultHTTPMetadataMapper forwards only common tracing/correlation headers. Authentication middleware should validate credentials and place trusted identity in context, not copy caller-provided identity headers into metadata.
func ParseDescriptorBytes ¶
func ParseDescriptorBytes(data []byte) (*invpb.ParsedDescriptor, error)
ParseDescriptorBytes parses a serialized FileDescriptorSet and returns a ParsedDescriptor. Use this with go:embed to avoid runtime file dependencies.
func Validation ¶ added in v0.0.2
func Validation() (grpc.UnaryServerInterceptor, error)
Validation returns an interceptor that runs protovalidate on each request.
Validation failures are returned as INVALID_ARGUMENT with field-level BadRequest details. Requests of types without protovalidate constraints pass through unchanged.
v, err := invariant.Validation()
if err != nil {
return err
}
server.Use(v)
Streaming RPCs are not covered by the unary interceptor — pair it with ValidationStream and `server.UseStream(vs)` when you have streaming methods with protovalidate constraints.
func ValidationStream ¶ added in v0.0.3
func ValidationStream() (grpc.StreamServerInterceptor, error)
ValidationStream returns a stream interceptor that runs protovalidate on the request before opening the stream. Failures short-circuit with INVALID_ARGUMENT and never produce any response messages — the same guarantee callers expect from the unary variant.
Types ¶
type HTTPHeaderProvider ¶
type HTTPHeaderProvider func(ctx context.Context, req *OutboundHTTPRequest) (map[string]string, error)
HTTPHeaderProvider returns extra outbound HTTP headers for ConnectHTTP requests. Typical use: API signatures, short-lived tokens, per-request timestamps.
type HTTPMetadataMapper ¶ added in v0.3.0
HTTPMetadataMapper selects untrusted HTTP request values that may be exposed to handlers as incoming gRPC metadata. Invariant applies a reserved-key filter after the mapper returns; identity and authorization metadata cannot be asserted by naming an HTTP header.
type MethodConfig ¶ added in v0.2.3
type MethodConfig struct {
// MaxUnaryRequestBytes overrides the per-server unary cap. Zero =
// inherit. Use a positive value for methods that legitimately need
// large bodies (e.g. an object-store Upload accepting hundreds of
// MiB) while keeping the rest of the surface tight.
MaxUnaryRequestBytes int64
// MaxUnaryResponseBytes overrides the encoded unary HTTP response cap.
// The selected wire encoding (JSON or protobuf) is measured.
MaxUnaryResponseBytes int64
// MaxStreamRequestBytes overrides the per-server Connect-streaming
// request envelope cap. Zero = inherit.
MaxStreamRequestBytes int64
// MaxStreamResponseBytes overrides the encoded Connect response-message
// cap. It applies independently to each message, like gRPC limits.
MaxStreamResponseBytes int64
}
MethodConfig overrides per-server defaults for one RPC method. Zero-valued fields fall back to the server-level setting. Apply via `Server.ConfigureMethod("/pkg.Service/Method", MethodConfig{...})`.
Request and response limits are independent because protobuf and JSON wire sizes are not interchangeable.
type OutboundHTTPRequest ¶
type OutboundHTTPRequest struct {
MethodPath string // e.g. "/greet.v1.GreetService/Greet"
Method string // e.g. "GET", "POST"
URL string // fully expanded URL with query string
Body []byte // JSON body bytes (may be empty)
}
OutboundHTTPRequest describes an HTTP request that will be sent by ConnectHTTP. It is passed to HTTPHeaderProvider so callers can compute dynamic auth headers.
type Projection ¶
type Projection struct {
// contains filtered or unexported fields
}
Projection specifies a protocol to serve.
func GRPC
deprecated
func GRPC(port int, opts ...grpc.ServerOption) Projection
GRPC returns the deprecated port-owning gRPC projection. The variadic options remain for source compatibility but are rejected at serve time; pass ordinary grpc.ServerOption values to ServerFromDescriptor/ServerFromBytes instead.
Deprecated: create a listener and call Server.Serve.
func HTTP ¶
func HTTP(port int) Projection
HTTP returns a projection that serves HTTP on the given port.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds parsed descriptors and registered tools.
func ServerFromBytes ¶
func ServerFromBytes(data []byte, grpcOptions ...grpc.ServerOption) (*Server, error)
ServerFromBytes parses an embedded FileDescriptorSet and returns a configured Server.
func ServerFromDescriptor ¶
func ServerFromDescriptor(path string, grpcOptions ...grpc.ServerOption) (*Server, error)
ServerFromDescriptor reads a descriptor file and returns a configured Server.
func (*Server) ConfigureMethod ¶ added in v0.2.3
func (s *Server) ConfigureMethod(methodPath string, cfg MethodConfig)
ConfigureMethod registers a per-method override. The method path is the Connect/gRPC URL form — `/pkg.Service/Method`. Same identity Register and Connect use, so callers can copy-paste from their proto schema. Zero-valued fields in `cfg` inherit from the server-level setting; non-zero fields override.
Typical use: a service has one big RPC (Upload, BulkImport) plus lots of small ones; set the server cap tight and raise just the outlier.
srv := invariant.ServerFromBytes(desc)
srv.SetMaxUnaryRequestBytes(16 * 1024 * 1024)
srv.ConfigureMethod("/files.v1.FileService/Upload", invariant.MethodConfig{
MaxUnaryRequestBytes: 1 << 30, // 1 GiB
})
Last write wins; re-calling overrides the previous config for that method.
func (*Server) Connect
deprecated
func (s *Server) Connect(conn grpc.ClientConnInterface) error
Connect is the compatibility spelling for ConnectGRPC.
Deprecated: use ConnectGRPC to supply a grpc.ClientConnInterface and optional default grpc.CallOption values.
func (*Server) ConnectGRPC ¶ added in v0.3.0
func (s *Server) ConnectGRPC(conn grpc.ClientConnInterface, defaultCallOptions ...grpc.CallOption) error
ConnectGRPC registers a gRPC client connection's methods as tools. The caller creates and owns the grpc.ClientConnInterface. Default call options are applied to every projected unary call. Use Include/Exclude to filter optional projection tools; the native proxy service retains every supported unary method.
func (*Server) ConnectHTTP ¶
ConnectHTTP registers tools that proxy to a remote HTTP endpoint. Routes are derived from google.api.http annotations when present, otherwise fallback to canonical RPC route: POST /{serviceFullName}/{method}.
func (*Server) Exclude ¶ added in v0.0.2
Exclude adds glob patterns for methods to exclude. Methods matching any exclude pattern are skipped during projection registration. Exclude is applied after include. Patterns use the same syntax as Include.
func (*Server) GRPCServer ¶ added in v0.3.0
GRPCServer returns the owned native grpc.Server. Access freezes Invariant registration so serving it directly cannot race projection metadata capture.
func (*Server) GetServiceInfo ¶ added in v0.3.0
func (s *Server) GetServiceInfo() map[string]grpc.ServiceInfo
func (*Server) GracefulStop ¶ added in v0.3.0
func (s *Server) GracefulStop()
func (*Server) HTTPHandler ¶ added in v0.0.2
HTTPHandler returns an http.Handler that serves all registered tools over the Connect protocol. Mount on an existing http.ServeMux or framework router instead of binding a separate port:
mux := http.NewServeMux()
h, _ := server.HTTPHandler()
mux.Handle("/inv/", http.StripPrefix("/inv", h))
Routes:
POST /{package.Service}/{Method} — invoke a tool (Connect protocol)
GET / — tool catalog (same shape as MCP tools/list)
GET /__invariant/tools — tool catalog
GET /__invariant/descriptor.binpb — raw FileDescriptorSet bytes
func (*Server) Include ¶ added in v0.0.2
Include adds glob patterns for methods to include. Only methods matching at least one include pattern are registered. Patterns are matched against the fully qualified method path: "service.full.Name.MethodName". Use "*" to match any sequence of characters (including dots). Examples: "temporal.api.workflowservice.v1.WorkflowService.*", "*.StartWorkflow*".
func (*Server) Invoke ¶ added in v0.0.2
func (s *Server) Invoke(ctx context.Context, toolName string, req proto.Message) (proto.Message, error)
Invoke dispatches a unary request to a registered tool by name. Useful for in-process callers (workflow runtimes, tests) that don't need to spin up a projection.
Returns NOT_FOUND if the tool is unknown, and FAILED_PRECONDITION if the tool is server-streaming — use InvokeStream for those. Both errors project to the right code through every projection.
func (*Server) InvokeStream ¶ added in v0.0.2
func (s *Server) InvokeStream(ctx context.Context, toolName string, req proto.Message, send func(proto.Message) error) error
InvokeStream dispatches a server-streaming tool by name. Each emitted response message is delivered to send; the call returns once the handler returns or send returns an error.
Like Invoke, this is the in-process entry point — no projection required.
func (*Server) Register
deprecated
Register discovers methods on servicer that match the service's RPCs and creates tools for each unary (non-streaming) method. If serviceName is empty, auto-matches by finding services whose RPC method names exist on the servicer.
Deprecated: implement the generated server interface and call its Register<Service>Server function with this Server.
func (*Server) RegisterService ¶ added in v0.3.0
func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl any)
RegisterService implements grpc.ServiceRegistrar. Generated Register<Service>Server functions can register directly with an Invariant server; the same descriptor and implementation are retained for HTTP, MCP, and CLI projection dispatch.
grpc.ServiceRegistrar cannot return an error, so invalid or late registrations panic with a deterministic invariant-prefixed message, just as generated registration is expected to fail during process setup.
func (*Server) ServeGRPC ¶ added in v0.3.0
ServeGRPC serves the registered generated services on listener.
func (*Server) ServeProjections ¶ added in v0.3.0
func (s *Server) ServeProjections(ctx context.Context, projections ...Projection) error
ServeProjections starts the specified optional projections and blocks until ctx is canceled or the first projection returns an error.
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() server.ServeProjections(ctx, invariant.HTTP(8080)) server.ServeProjections(ctx, invariant.HTTP(8080), invariant.MCP())
On error or cancellation, all projections receive a graceful shutdown signal.
func (*Server) SetMaxStreamRequestBytes ¶ added in v0.0.3
SetMaxStreamRequestBytes overrides the Connect streaming request envelope cap. Pass 0 to reset to the default (16 MiB).
func (*Server) SetMaxStreamResponseBytes ¶ added in v0.3.0
SetMaxStreamResponseBytes overrides the per-message encoded Connect stream response cap. Pass 0 to reset to the default (16 MiB).
func (*Server) SetMaxUnaryRequestBytes ¶ added in v0.0.3
SetMaxUnaryRequestBytes overrides the HTTP unary body-size cap. Pass 0 to reset to the default (16 MiB).
func (*Server) SetMaxUnaryResponseBytes ¶ added in v0.3.0
SetMaxUnaryResponseBytes overrides the encoded HTTP unary response cap. Pass 0 to reset to the default (16 MiB).
func (*Server) ToolCatalog ¶ added in v0.0.2
ToolCatalog returns the canonical tool catalog (same shape as MCP `tools/list`). Used by both the HTTP `GET /` endpoint and MCP's `tools/list`.
Streaming tools carry `_meta.streaming: true` so clients can render and consume them differently from unary tools. The MCP spec reserves `_meta` for exactly this kind of server-specific annotation.
func (*Server) Tools ¶ added in v0.0.2
Tools returns a snapshot of the registered tool names to their Tool metadata.
func (*Server) Use ¶
func (s *Server) Use(interceptor grpc.UnaryServerInterceptor)
Use registers a unary interceptor. Runs in registration order (first registered = outermost) on every unary tool invocation across all projections. Stream RPCs are not affected — use UseStream for those.
func (*Server) UseHTTPHeaderProvider ¶
func (s *Server) UseHTTPHeaderProvider(provider HTTPHeaderProvider)
UseHTTPHeaderProvider sets an optional outbound header provider for ConnectHTTP. The current provider is called for every outbound HTTP request. Like other configuration, it may be changed until serving or invocation begins.
func (*Server) UseHTTPMetadataMapper ¶ added in v0.3.0
func (s *Server) UseHTTPMetadataMapper(mapper HTTPMetadataMapper)
UseHTTPMetadataMapper replaces the inbound HTTP metadata mapper. Reserved protocol, authorization, tenant, principal, role, and internal identity keys are removed from the mapper's result before it reaches application code.
func (*Server) UseStream ¶ added in v0.0.2
func (s *Server) UseStream(interceptor grpc.StreamServerInterceptor)
UseStream registers a server-streaming interceptor. Mirrors Use but for server-streaming RPCs. Same registration-order semantics.
type ServerCallInfo
deprecated
type ServerCallInfo = grpc.UnaryServerInfo
ServerCallInfo is the compatibility name for grpc.UnaryServerInfo.
Deprecated: use grpc.UnaryServerInfo.
type StreamHandler
deprecated
added in
v0.0.2
type StreamHandler = grpc.StreamHandler
StreamHandler is the compatibility name for grpc.StreamHandler.
Deprecated: use grpc.StreamHandler.
type StreamServerInterceptor
deprecated
added in
v0.0.2
type StreamServerInterceptor = grpc.StreamServerInterceptor
StreamServerInterceptor is the compatibility name for grpc.StreamServerInterceptor.
Deprecated: use grpc.StreamServerInterceptor.
type Tool ¶
type Tool struct {
Name string
Description string
InputSchema map[string]any
Handler any
InputType string
OutputType string
ServiceFullName string
MethodName string
ServerStreaming bool
// contains filtered or unexported fields
}
Tool represents a single registered RPC method projected as a tool.
type UnaryHandler
deprecated
type UnaryHandler = grpc.UnaryHandler
UnaryHandler is the compatibility name for grpc.UnaryHandler.
Deprecated: use grpc.UnaryHandler.
type UnaryServerInterceptor
deprecated
type UnaryServerInterceptor = grpc.UnaryServerInterceptor
UnaryServerInterceptor is the compatibility name for grpc.UnaryServerInterceptor.
Deprecated: use grpc.UnaryServerInterceptor.