Documentation
¶
Overview ¶
Package apigateway provides an HTTP API gateway toolkit that proxies authenticated REST API calls through the platform's auth, persona, and audit pipeline. Sibling to pkg/toolkits/gateway, which proxies upstream MCP servers; this toolkit proxies arbitrary HTTP/JSON APIs.
The toolkit exposes a small fixed set of MCP tools regardless of how many connections are registered or how many endpoints each upstream API has. v1 ships api_invoke_endpoint; api_list_endpoints and api_get_endpoint_schema follow once OpenAPI ingestion lands (see the RFC at issue #364).
Index ¶
- Constants
- Variables
- type Authenticator
- type Config
- type ExportAsset
- type ExportAssetRef
- type ExportAssetStore
- type ExportConfig
- type ExportDeps
- type ExportProvenance
- type ExportProvenanceCall
- type ExportS3Client
- type ExportShareCreator
- type ExportUserContext
- type ExportVersion
- type ExportVersionStore
- type FieldEncryptor
- type InvokeInput
- type InvokeOutput
- type ListEndpointsInput
- type ListEndpointsOutput
- type MultiConfig
- type OAuth2Config
- type OperationSummary
- type PaginationInfo
- type PersistedToken
- type PostgresTokenStore
- type RankingMode
- type RoutePolicy
- type TokenStore
- type Toolkit
- func (t *Toolkit) AddConnection(name string, config map[string]any) error
- func (t *Toolkit) Close() error
- func (t *Toolkit) Connection() string
- func (t *Toolkit) HasConnection(name string) bool
- func (*Toolkit) Kind() string
- func (t *Toolkit) ListConnections() []toolkit.ConnectionDetail
- func (t *Toolkit) Name() string
- func (t *Toolkit) RegisterTools(s *mcp.Server)
- func (t *Toolkit) RemoveConnection(name string) error
- func (t *Toolkit) RoutePolicy() RoutePolicy
- func (t *Toolkit) SetEmbeddingProvider(p embedding.Provider)
- func (t *Toolkit) SetExportDeps(deps ExportDeps)
- func (t *Toolkit) SetQueryProvider(provider query.Provider)
- func (t *Toolkit) SetRoutePolicy(p RoutePolicy)
- func (t *Toolkit) SetSemanticProvider(provider semantic.Provider)
- func (t *Toolkit) SetTokenStore(s TokenStore)
- func (t *Toolkit) TokenStore() TokenStore
- func (t *Toolkit) Tools() []string
Constants ¶
const ( // Kind is the connection-instance kind discriminator. Operators see // this in the admin UI's connection picker. Kind = "api" // AuthModeNone disables outbound authentication. AuthModeNone = "none" // AuthModeBearer sends "Authorization: Bearer <credential>". AuthModeBearer = "bearer" // AuthModeAPIKey sends the credential as a header (default // "X-API-Key") or as a query parameter; placement and key name are // per-connection so APIs that use non-standard schemes (e.g. an // "api_key" query parameter, or a custom "X-Api-Token" header) can // be onboarded without code changes. AuthModeAPIKey = "api_key" // AuthModeOAuth2ClientCredentials acquires a bearer token via // the OAuth 2.1 client_credentials grant — server-to-server, // no human in the loop. The platform exchanges the configured // client_id + client_secret for a token at OAuth.TokenURL and // applies it as "Authorization: Bearer <token>" on outbound // calls. Tokens are cached + refreshed automatically by the // underlying golang.org/x/oauth2 library; no DB state is // required because every restart can re-acquire from credentials. // The authorization_code grant (which DOES require DB-persisted // refresh tokens + a browser flow) is its own follow-up issue. AuthModeOAuth2ClientCredentials = "oauth2_client_credentials" // #nosec G101 -- mode name, not a credential // AuthModeOAuth2AuthorizationCode runs the user-driven OAuth 2.1 // authorization-code grant: an admin completes a one-time browser // flow at connection setup; the resulting refresh token is // persisted (encrypted) so subsequent platform restarts and // background workloads keep working without further interaction. // Tokens are refreshed automatically before expiry. Requires the // platform's database (refresh-token state survives restarts). AuthModeOAuth2AuthorizationCode = "oauth2_authorization_code" // #nosec G101 -- mode name, not a credential // APIKeyPlacementHeader (default) sends the credential as an HTTP // header named by APIKeyHeader. APIKeyPlacementHeader = "header" // APIKeyPlacementQuery sends the credential as a URL query parameter // named by APIKeyParam. APIKeyPlacementQuery = "query" // DefaultAPIKeyHeader is the conventional API-key header name when // the connection does not specify one. DefaultAPIKeyHeader = "X-API-Key" // #nosec G101 -- header name, not a credential // TrustLevelUntrusted is the default. Advisory only in v1: the // field is parsed and validated but no platform code reads it. // Reserved for future response-shaping enforcement (see issue // #373) — operators setting this today get the same behavior as // not setting it. TrustLevelUntrusted = "untrusted" // TrustLevelTrusted is advisory only in v1; see TrustLevelUntrusted. TrustLevelTrusted = "trusted" // DefaultConnectTimeout caps the time spent establishing the // outbound connection (TCP + TLS handshake) on each invocation. DefaultConnectTimeout = 10 * time.Second // DefaultCallTimeout caps the total per-call time including // upstream processing and response read. DefaultCallTimeout = 60 * time.Second // DefaultMaxResponseBytes caps how much of the upstream response // body the toolkit will return to the model. Larger payloads are // truncated; the response envelope flags truncation so the model // can react. Operators with a need for large bodies can raise this // per-connection or, when #372 lands, use the streaming-to-S3 // variant to bypass the model entirely. DefaultMaxResponseBytes = int64(10 * 1024 * 1024) )
const ( OAuth2AuthStyleHeader = "header" OAuth2AuthStyleParams = "params" )
EndpointAuthStyle values.
const ( // ToolInvokeEndpoint is the MCP tool name for the invoke // operation. Exported so audit code and tests reference the same // literal as the registration site. ToolInvokeEndpoint = "api_invoke_endpoint" // ToolListEndpoints names the tool that returns OperationSummary // candidates from a connection's parsed OpenAPI spec. Companion // to ToolInvokeEndpoint: the model uses list to discover what's // available, then invoke to call it. ToolListEndpoints = "api_list_endpoints" )
Variables ¶
var ErrConnectionExists = errors.New("apigateway: connection already exists")
ErrConnectionExists is returned when AddConnection is called with a name already registered in the toolkit.
var ErrConnectionNotFound = errors.New("apigateway: connection not found")
ErrConnectionNotFound is returned when an operation is requested against a connection that has not been registered.
var ErrNeedsReauth = errors.New("apigateway: oauth2 connection needs admin reconnect")
ErrNeedsReauth is the structured error api_invoke_endpoint surfaces when an authorization_code connection's stored refresh token is missing, expired beyond refresh_expires_at, or definitively rejected by the IdP (RFC 6749 §5.2 invalid_grant on the refresh_token grant). Transient failures (network, 5xx, request cancellation) DO NOT produce this error — see Apply for the distinction.
The error message intentionally points the operator at the platform's reauth path rather than echoing the underlying IdP response (which can include sensitive material from a partial grant exchange). See tokenFetchError for the parallel scrubber on transport failures.
var ErrTokenNotFound = errors.New("apigateway: oauth token not found")
ErrTokenNotFound is returned by TokenStore.Get when no row exists for a connection. Distinct from a transport error so callers can distinguish a never-authorized connection from a database that is merely unreachable.
Functions ¶
This section is empty.
Types ¶
type Authenticator ¶
Authenticator applies a connection's authentication scheme to an outbound HTTP request before it is sent. Implementations must be safe for concurrent use — a single Authenticator is shared across all in-flight invocations of a connection.
Implementations MUST NOT log credential material. The toolkit's audit pipeline expects no Authorization or X-API-Key value to ever appear in slog output, error messages, or audit rows; carelessly formatted error strings are the most common leak path.
func NewAuthenticator ¶
func NewAuthenticator(c Config) (Authenticator, error)
NewAuthenticator returns the Authenticator implementation for a validated Config. ParseConfig has already rejected unknown auth modes, so the default branch only fires if a future mode is added without a matching case here.
type Config ¶
type Config struct {
// BaseURL is the upstream API root (e.g. "https://api.example.com").
// Required. Trailing slash is stripped at parse time.
BaseURL string
// AuthMode is "none", "bearer", or "api_key" in v1. OAuth modes
// land with #368.
AuthMode string
// Credential is the bearer token or API key. Ignored when AuthMode
// is "none". Encrypted at rest via the platform's FieldEncryptor.
Credential string
// APIKeyPlacement is "header" (default) or "query" — only consulted
// when AuthMode is "api_key".
APIKeyPlacement string
// APIKeyHeader is the header name to set when APIKeyPlacement is
// "header". Defaults to "X-API-Key".
APIKeyHeader string
// APIKeyParam is the query parameter name when APIKeyPlacement is
// "query". No default — required when placement is "query".
APIKeyParam string
// ConnectionName is the audit-visible connection identifier and the
// value passed in the tool's `connection` argument. Defaults to
// the toolkit instance name when unset.
ConnectionName string
// ConnectTimeout caps the dial step on each invocation.
ConnectTimeout time.Duration
// CallTimeout caps the total per-invocation time.
CallTimeout time.Duration
// TrustLevel is "untrusted" (default) or "trusted".
TrustLevel string
// MaxResponseBytes caps how much of an upstream response body is
// returned to the model. Defaults to DefaultMaxResponseBytes.
MaxResponseBytes int64
// OpenAPISpec is the raw OpenAPI 3.x document (YAML or JSON)
// for this connection. Optional. When non-empty the toolkit
// parses it at AddConnection time and exposes its operations
// via api_list_endpoints; an unparseable spec fails the
// connection with a clear error rather than silently dropping.
// Inline-only in v1.
OpenAPISpec string
// OAuth2 carries the OAuth 2.1 parameters used when AuthMode
// is oauth2_client_credentials. Empty for non-OAuth modes.
OAuth2 OAuth2Config
}
Config holds api-gateway toolkit configuration for a single upstream HTTP API connection.
func ParseConfig ¶
ParseConfig parses a Config from a generic map (the form admin-saved connections take in the connection_instances table) and applies defaults. The returned Config is fully validated.
type ExportAsset ¶
type ExportAsset struct {
ID string
OwnerID string
OwnerEmail string
Name string
Description string
ContentType string
S3Bucket string
S3Key string
SizeBytes int64
Tags []string
Provenance ExportProvenance
SessionID string
IdempotencyKey string
}
ExportAsset is the row inserted into portal_assets when an api_export call succeeds. Field shape mirrors trinokit.ExportAsset so the platform-side adapter can reuse its conversion logic.
type ExportAssetRef ¶
ExportAssetRef is returned by idempotency-key lookup. We only need the id + size for the response — the model doesn't see the existing asset's full row.
type ExportAssetStore ¶
type ExportAssetStore interface {
InsertExportAsset(ctx context.Context, asset ExportAsset) error
GetByIdempotencyKey(ctx context.Context, ownerID, key string) (*ExportAssetRef, error)
}
ExportAssetStore is the subset of portal.AssetStore needed by api_export. Defined locally to avoid an import cycle (portal → registry → apigateway). Mirrors trinokit.ExportAssetStore.
type ExportConfig ¶
ExportConfig holds platform-level limits for api_export. MaxBytes caps any single export's size (above which the call returns an error rather than a truncated asset — partial-data assets would be misleading). DefaultTimeout / MaxTimeout bound how long a single call may run.
type ExportDeps ¶
type ExportDeps struct {
AssetStore ExportAssetStore
VersionStore ExportVersionStore
S3Client ExportS3Client
S3Bucket string
S3Prefix string
BaseURL string
Config ExportConfig
GetUserContext func(ctx context.Context) *ExportUserContext
}
ExportDeps holds platform-side dependencies injected into the api gateway toolkit. All types are defined locally to avoid import cycles. Mirrors trinokit.ExportDeps so the platform-side wiring can stay symmetric.
type ExportProvenance ¶
type ExportProvenance struct {
ToolCalls []ExportProvenanceCall
SessionID string
UserID string
}
ExportProvenance captures the chain of tool calls that produced an asset so portal viewers can render "exported via api_export from <connection> <method> <path>".
type ExportProvenanceCall ¶
ExportProvenanceCall is one step in the provenance chain.
type ExportS3Client ¶
type ExportS3Client interface {
PutObject(ctx context.Context, bucket, key string, data []byte, contentType string) error
}
ExportS3Client is the subset of portal.S3Client needed by api_export. Note: this is the same shape as trinokit's; the platform adapter implementing it can serve both toolkits.
type ExportShareCreator ¶
type ExportShareCreator interface {
}
ExportShareCreator creates public share links for exported assets. nil disables public-link creation.
type ExportUserContext ¶
ExportUserContext holds user identity extracted from the request context. Populated by the GetUserContext callback provided in ExportDeps so the toolkit doesn't import middleware directly.
type ExportVersion ¶
type ExportVersion struct {
ID string
AssetID string
S3Key string
S3Bucket string
ContentType string
SizeBytes int64
CreatedBy string
ChangeSummary string
}
ExportVersion is the row inserted into portal_asset_versions.
type ExportVersionStore ¶
type ExportVersionStore interface {
CreateExportVersion(ctx context.Context, version ExportVersion) (int, error)
}
ExportVersionStore is the subset of portal.VersionStore needed by api_export.
type FieldEncryptor ¶
type FieldEncryptor interface {
Encrypt(plaintext string) (string, error)
Decrypt(ciphertext string) (string, error)
}
FieldEncryptor abstracts the platform's at-rest field encryption. Used here so this package doesn't import pkg/platform (which would create a cycle via the registry's factory wiring). The concrete implementation comes from pkg/platform.FieldEncryptor at startup.
type InvokeInput ¶
type InvokeInput struct {
Connection string `json:"connection"`
Method string `json:"method"`
Path string `json:"path"`
Query map[string]any `json:"query_params,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Body any `json:"body,omitempty"`
TimeoutSeconds int `json:"timeout_seconds,omitempty"`
}
InvokeInput is the parsed argument shape for api_invoke_endpoint. Field names match the JSON schema.
type InvokeOutput ¶
type InvokeOutput struct {
Status int `json:"status"`
Headers map[string][]string `json:"headers,omitempty"`
Body any `json:"body,omitempty"`
BodyTruncated bool `json:"body_truncated,omitempty"`
// Pagination is populated when the upstream response carries a
// recognizable cursor (RFC 5988 Link rel="next", @odata.nextLink,
// next_cursor, etc). The model uses this to decide whether to
// issue a follow-up call. The gateway does NOT auto-follow so
// each loop iteration stays observable in audit + conversation.
Pagination *PaginationInfo `json:"pagination,omitempty"`
// Hint surfaces operator-actionable advice to the model when the
// response itself can't carry it — most importantly the "use
// api_export instead" suggestion when the body exceeded
// max_response_bytes. Distinct from Error: Hint is informational,
// the call still succeeded.
Hint string `json:"hint,omitempty"`
DurationMs int64 `json:"duration_ms"`
Error string `json:"error,omitempty"`
}
InvokeOutput is the structured result returned to the model. Errors reaching the upstream (DNS, connection refused, TLS failure, timeout) are surfaced via Error rather than as MCP tool errors so the model can branch on them without losing the rest of the response envelope.
type ListEndpointsInput ¶
type ListEndpointsInput struct {
Connection string `json:"connection"`
Query string `json:"query,omitempty"`
Limit int `json:"limit,omitempty"`
Ranking string `json:"ranking,omitempty"`
}
ListEndpointsInput is the parsed argument shape for api_list_endpoints. Field names match the JSON schema.
type ListEndpointsOutput ¶
type ListEndpointsOutput struct {
Operations []OperationSummary `json:"operations"`
Note string `json:"note,omitempty"`
}
ListEndpointsOutput is the structured result. Empty + Note when the connection has no OpenAPI spec configured (so the model can distinguish "no spec" from "no matches").
type MultiConfig ¶
MultiConfig holds parsed per-connection configs plus the aggregate toolkit's default connection name.
func ParseMultiConfig ¶
ParseMultiConfig validates and returns the parsed config for every instance. Per-instance parse errors fail the platform startup; HTTP connectivity failures are handled at invocation time, not here.
type OAuth2Config ¶
type OAuth2Config struct {
// TokenURL is the upstream's token endpoint. Required.
TokenURL string
// ClientID is the platform's registered client id. Required.
ClientID string
// ClientSecret is the platform's registered client secret.
// Required. Encrypted at rest via the platform's
// FieldEncryptor (sensitive-key list already includes
// "client_secret"; the nested map's value is encrypted before
// storage in connection_instances.config).
ClientSecret string
// Scopes is an optional list of OAuth scopes to request.
Scopes []string
// EndpointAuthStyle controls how the client credentials are
// transmitted at token-fetch time. "header" (default) sends
// them as HTTP Basic auth on the token request; "params"
// sends them as POST body parameters. Some IdPs require one
// or the other; "header" is the OAuth 2.1 default.
EndpointAuthStyle string
// AuthorizationURL is the upstream's authorization endpoint.
// Required only for the authorization_code grant — that's
// where the platform redirects the admin's browser to start
// the flow.
AuthorizationURL string
// Prompt is an optional OIDC prompt parameter (RFC OIDC
// §3.1.2.1). Common values: "login" (force credential prompt),
// "consent" (force consent screen), "select_account",
// "none" (silent auth). Empty by default — the IdP decides.
// Operators of strict OIDC realms (Keycloak, Auth0, Okta)
// typically set this to "login" so admin Reconnect actions
// always re-prompt the user. Pure-OAuth (non-OIDC) providers
// often reject unknown parameters with invalid_request, so
// leave empty for those.
Prompt string
}
OAuth2Config describes the OAuth 2.1 client_credentials grant parameters. The platform exchanges ClientID + ClientSecret at TokenURL for an access token (cached + refreshed by the golang.org/x/oauth2 library) and applies it as "Authorization: Bearer <token>" on outbound calls.
Authorization-code (browser-driven, refresh-token-persisting) grants are deferred to a follow-up — they require DB state (PKCE verifier table, refresh-token cache) and an admin reauth callback handler that this PR intentionally does not bring in.
type OperationSummary ¶
type OperationSummary struct {
OperationID string `json:"operation_id"`
Method string `json:"method"`
Path string `json:"path"`
Summary string `json:"summary,omitempty"`
Tags []string `json:"tags,omitempty"`
}
OperationSummary is the slim per-operation view returned by api_list_endpoints. Designed to be cheap on context: the model gets enough to decide whether an operation is relevant (operation_id, method, path, summary, tags) without paying for the full request / response schema. Schemas are fetched on demand via a follow-up api_get_endpoint_schema tool (deferred — see RFC #364).
type PaginationInfo ¶
type PaginationInfo struct {
HasMore bool `json:"has_more,omitempty"`
NextCursor string `json:"next_cursor,omitempty"`
NextURL string `json:"next_url,omitempty"`
Source string `json:"source,omitempty"`
}
PaginationInfo is the structured pagination state api_invoke_endpoint surfaces to the model on every response. The model uses HasMore + NextCursor (or NextURL) to decide whether to issue a follow-up call; the gateway does NOT auto-follow so each loop iteration stays observable in the conversation and audit log.
Fields are populated only when the upstream response carries a recognizable pagination signal. When none are populated the field is omitted from the JSON response — the model sees no pagination envelope and treats the response as terminal.
type PersistedToken ¶
type PersistedToken struct {
ConnectionName string
AccessToken string
RefreshToken string
ExpiresAt time.Time
RefreshExpiresAt time.Time
Scope string
AuthenticatedBy string
AuthenticatedAt time.Time
UpdatedAt time.Time
}
PersistedToken is the row shape stored in apigateway_oauth_tokens. Mirror of the MCP gateway's PersistedToken — kept separate so the two systems remain independent and changes to one don't ripple.
RefreshExpiresAt is optional — only populated when the IdP returned refresh_expires_in (Keycloak does, others may not). Zero means the database column is NULL; callers must NOT interpret a zero value as "no expiry"; it means the IdP did not disclose one.
type PostgresTokenStore ¶
type PostgresTokenStore struct {
// contains filtered or unexported fields
}
PostgresTokenStore is a sql-backed TokenStore against the apigateway_oauth_tokens table (migration #38).
func NewPostgresTokenStore ¶
func NewPostgresTokenStore(db *sql.DB, enc FieldEncryptor) *PostgresTokenStore
NewPostgresTokenStore builds a TokenStore against the supplied database. enc may be nil; if so, refresh tokens are stored unencrypted (callers that want at-rest encryption should pass the platform's FieldEncryptor).
func (*PostgresTokenStore) Delete ¶
func (s *PostgresTokenStore) Delete(ctx context.Context, connection string) error
Delete removes the token row, forcing the next call to surface a "needs reauth" signal. Used by the admin reauth path and by the Authenticator when the IdP rejects a refresh token (revoked or expired beyond refresh_expires_at).
func (*PostgresTokenStore) Get ¶
func (s *PostgresTokenStore) Get(ctx context.Context, connection string) (*PersistedToken, error)
Get returns the persisted token for connection or ErrTokenNotFound when no row matches. Refresh and access tokens are decrypted via the configured FieldEncryptor.
func (*PostgresTokenStore) Set ¶
func (s *PostgresTokenStore) Set(ctx context.Context, t PersistedToken) error
Set inserts or replaces the token row for a connection. Access and refresh tokens are encrypted via the configured FieldEncryptor before reaching the database.
type RankingMode ¶
type RankingMode string
RankingMode selects the algorithm api_list_endpoints uses to score candidate operations against the model's query.
Lexical (default) is the substring-match filter that v1 shipped: fast, deterministic, no embedding-provider dependency. Misses on natural-language queries when the model's phrasing doesn't share vocabulary with the spec author's (e.g. query "create order" vs summary "Place a new order").
Semantic uses cosine similarity between the query embedding and each operation's pre-computed embedding. Best for free-form intent queries; needs an embedding provider wired via SetEmbeddingProvider.
Hybrid blends a lexical signal (substring match) with the semantic cosine score. The blend recovers the precision of substring match for queries that DO share vocabulary while still returning semantically-related results when they don't. The blend weight (alpha) is fixed at hybridSemanticWeight; tuning is deferred to a config knob if a real-world deployment needs it.
const ( // RankingLexical is the v1 substring-match filter (default). RankingLexical RankingMode = "lexical" // RankingSemantic ranks by embedding cosine similarity only. RankingSemantic RankingMode = "semantic" // RankingHybrid blends a lexical signal with the cosine score. RankingHybrid RankingMode = "hybrid" )
RankingMode values exposed on the api_list_endpoints schema.
type RoutePolicy ¶
type RoutePolicy interface {
Allow(ctx context.Context, connection, method, path string) (allowed bool, reason string)
}
RoutePolicy gates an api_invoke_endpoint call by (connection, method, path) on top of the platform's existing tool/connection authorization. Layered design: the MCP middleware's Authorizer.IsAuthorized check covers "may this user call api_invoke_endpoint at all?" and "on this connection at all?". RoutePolicy answers the more specific question "may this user call THIS method on THIS path of this connection?".
Reason is included for audit/log clarity when Allowed is false. Implementations must read the caller's roles from ctx (typically via the middleware's pre-authenticated user or an Authenticator) and resolve them to a persona's APIRoutes rules.
type TokenStore ¶
type TokenStore interface {
Get(ctx context.Context, connection string) (*PersistedToken, error)
Set(ctx context.Context, t PersistedToken) error
Delete(ctx context.Context, connection string) error
}
TokenStore persists OAuth tokens for the authorization_code grant so a one-time browser-based authentication grants long-running background access. v1 stores a single shared identity per connection (matches the MCP gateway's design).
func NewMemoryTokenStore ¶
func NewMemoryTokenStore() TokenStore
NewMemoryTokenStore returns an in-process TokenStore. Not safe across process restarts — refresh tokens are lost.
type Toolkit ¶
type Toolkit struct {
// contains filtered or unexported fields
}
Toolkit is the api-gateway toolkit. A single Toolkit manages multiple named connections, each addressing a different upstream HTTP API. Connections are added either at startup (from the platform's merged YAML+DB config) or at runtime via AddConnection (used by the admin REST handler when an operator saves a new connection through the portal).
func New ¶
New builds an empty toolkit. Connections are added later via AddConnection (used both by NewMulti at startup and by the admin hot-add path at runtime).
func NewMulti ¶
func NewMulti(cfg MultiConfig) *Toolkit
NewMulti builds a Toolkit and pre-loads the given parsed connection configs. Per-connection materialization failures are logged and skipped so a single bad connection does not block platform startup.
func (*Toolkit) AddConnection ¶
AddConnection parses a raw config map, materializes the per- connection auth + HTTP client, and registers the connection. Used both at startup (via NewMulti) and at runtime via the admin hot-add path.
func (*Toolkit) Connection ¶
Connection returns the default connection name for audit attribution when a tool call does not carry one. Empty string when no default is configured (multi-connection deployments typically require the model to pass `connection` explicitly).
func (*Toolkit) HasConnection ¶
HasConnection reports whether a connection with the given name is registered.
func (*Toolkit) ListConnections ¶
func (t *Toolkit) ListConnections() []toolkit.ConnectionDetail
ListConnections returns details for every registered connection, in name-sorted order. Implements toolkit.ConnectionLister so the platform's unified list_connections tool surfaces api connections alongside trino, s3, and mcp.
func (*Toolkit) RegisterTools ¶
RegisterTools registers the api gateway's MCP tools. api_get_endpoint_schema (the third tool from RFC #364) lands in a follow-up PR; for v1 the model gets the operation summaries via api_list_endpoints and constructs invoke calls from there.
func (*Toolkit) RemoveConnection ¶
RemoveConnection drops a registered connection. Used by the admin hot-remove path when an operator deletes the connection in the portal. Idle keepalive sockets on the per-connection HTTP client are closed so they don't linger up to idleConnectionTimeout after the connection is gone.
func (*Toolkit) RoutePolicy ¶
func (t *Toolkit) RoutePolicy() RoutePolicy
RoutePolicy returns the currently installed route policy, or nil if none has been wired. Exposed so platform-side tests can verify that WireAPIGatewayRoutePolicy actually installed a policy and exercise it directly without spinning up a full MCP server.
func (*Toolkit) SetEmbeddingProvider ¶
SetEmbeddingProvider wires the embedding model used by the "semantic" and "hybrid" ranking modes of api_list_endpoints. nil (the default) disables non-lexical ranking; calls that request it fall back to lexical with a note. Per-connection embedding vectors are computed lazily on the first non-lexical call so an unreachable embedding service does not block platform startup.
func (*Toolkit) SetExportDeps ¶
func (t *Toolkit) SetExportDeps(deps ExportDeps)
SetExportDeps wires platform-side dependencies for api_export. Calling with nil-AssetStore deps is treated as "export disabled": registerExportTool checks t.exportDeps and skips registration so the model doesn't see a tool that would always fail.
func (*Toolkit) SetQueryProvider ¶
SetQueryProvider stores the query provider. Reserved for future warehouse-bridging features (see issue #372); not consumed in v1.
func (*Toolkit) SetRoutePolicy ¶
func (t *Toolkit) SetRoutePolicy(p RoutePolicy)
SetRoutePolicy installs a per-(connection, method, path) authorization gate. When set, api_invoke_endpoint consults the policy after the connection lookup and before the upstream call. A nil policy means no per-route gating — the platform's existing tool/connection authorization is the sole gate (backward-compatible).
func (*Toolkit) SetSemanticProvider ¶
SetSemanticProvider stores the semantic provider. Reserved for future enrichment (e.g. response shaping driven by DataHub PII tags, see issue #373); not consumed in v1.
func (*Toolkit) SetTokenStore ¶
func (t *Toolkit) SetTokenStore(s TokenStore)
SetTokenStore wires the persistent OAuth token store. Required for the authorization_code grant: the Authenticator reads existing tokens at first call and writes back rotated tokens after refresh. Connections registered before SetTokenStore is called will pick up the store on first use; the toolkit re-runs the wire step in addParsedConnection to keep startup-order independent (mirrors how the MCP gateway threads its TokenStore).
func (*Toolkit) TokenStore ¶
func (t *Toolkit) TokenStore() TokenStore
TokenStore returns the OAuth token store wired into this toolkit, or nil when the toolkit was constructed without one. The admin OAuth-callback handler calls this to persist tokens after the authorization-code exchange.