mcp_server

package
v0.10.557 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 24 Imported by: 0

README

StackQL MCP Server Package

This package implements a Model Context Protocol (MCP) server for StackQL, enabling LLMs to consume StackQL as a first-class information source.

Overview

The mcp_server package provides:

  1. Backend Interface Abstraction: A clean interface for executing queries that can be implemented for in-memory, TCP, or other communication methods
  2. Configuration Management: Comprehensive configuration structures with JSON and YAML support
  3. MCP Server Implementation: A complete MCP server supporting multiple transports (stdio, TCP, WebSocket)

Architecture

The package is designed with zero dependencies on StackQL internals, making it modular and reusable. The key components are:

  • Backend: Interface for query execution and schema retrieval
  • Config: Configuration structures with validation
  • MCPServer: Main server implementation supporting MCP protocol
  • ExampleBackend: Sample implementation for testing and demonstration

Usage

Basic Usage
package main

import (
    "context"
    "log"
    
    "github.com/stackql/stackql/pkg/mcp_server"
)

func main() {
    // Create server with default configuration and example backend
    server, err := mcp_server.NewMCPServerWithExampleBackend(nil)
    if err != nil {
        log.Fatal(err)
    }
    
    // Start the server
    ctx := context.Background()
    if err := server.Start(ctx); err != nil {
        log.Fatal(err)
    }
    
    // Server will run until context is cancelled
    <-ctx.Done()
    
    // Graceful shutdown
    server.Stop(context.Background())
}
Custom Configuration
config := &mcp_server.Config{
    Server: mcp_server.ServerConfig{
        Name:                  "My StackQL MCP Server",
        Version:               "1.0.0",
        Description:           "Custom MCP server for StackQL",
        MaxConcurrentRequests: 50,
        RequestTimeout:        mcp_server.Duration(30 * time.Second),
    },
    Backend: mcp_server.BackendConfig{
        Type:              "stackql",
        ConnectionString:  "stackql://localhost:5432",
        MaxConnections:    20,
        ConnectionTimeout: mcp_server.Duration(10 * time.Second),
        QueryTimeout:      mcp_server.Duration(60 * time.Second),
    },
    Transport: mcp_server.TransportConfig{
        EnabledTransports: []string{"stdio", "tcp"},
        TCP: mcp_server.TCPTransportConfig{
            Address: "0.0.0.0",
            Port:    8080,
        },
    },
    Logging: mcp_server.LoggingConfig{
        Level:  "info",
        Format: "json",
        Output: "/var/log/mcp-server.log",
    },
}

server, err := mcp_server.NewMCPServer(config, backend, logger)
Implementing a Custom Backend
type MyBackend struct {
    // Your backend implementation
}

func (b *MyBackend) Execute(ctx context.Context, query string, params map[string]interface{}) (*mcp_server.QueryResult, error) {
    // Execute the query using your preferred method
    // Return structured results
}

func (b *MyBackend) GetSchema(ctx context.Context) (*mcp_server.Schema, error) {
    // Return schema information about available providers and resources
}

func (b *MyBackend) Ping(ctx context.Context) error {
    // Verify backend connectivity
}

func (b *MyBackend) Close() error {
    // Clean up resources
}

Configuration

JSON Configuration Example
{
  "server": {
    "name": "StackQL MCP Server",
    "version": "1.0.0",
    "description": "Model Context Protocol server for StackQL",
    "max_concurrent_requests": 100,
    "request_timeout": "30s"
  },
  "backend": {
    "type": "stackql",
    "connection_string": "stackql://localhost",
    "max_connections": 10,
    "connection_timeout": "10s",
    "query_timeout": "30s",
    "retry": {
      "enabled": true,
      "max_attempts": 3,
      "initial_delay": "100ms",
      "max_delay": "5s",
      "multiplier": 2.0
    }
  },
  "transport": {
    "enabled_transports": ["stdio", "tcp"],
    "tcp": {
      "address": "localhost",
      "port": 8080,
      "max_connections": 100,
      "read_timeout": "30s",
      "write_timeout": "30s"
    }
  },
  "logging": {
    "level": "info",
    "format": "text",
    "output": "stdout",
    "enable_request_logging": false
  }
}
YAML Configuration Example
server:
  name: "StackQL MCP Server"
  version: "1.0.0"
  description: "Model Context Protocol server for StackQL"
  max_concurrent_requests: 100
  request_timeout: "30s"

backend:
  type: "stackql"
  connection_string: "stackql://localhost"
  max_connections: 10
  connection_timeout: "10s"
  query_timeout: "30s"
  retry:
    enabled: true
    max_attempts: 3
    initial_delay: "100ms"
    max_delay: "5s"
    multiplier: 2.0

transport:
  enabled_transports: ["stdio", "tcp"]
  tcp:
    address: "localhost"
    port: 8080
    max_connections: 100
    read_timeout: "30s"
    write_timeout: "30s"

logging:
  level: "info"
  format: "text"
  output: "stdout"
  enable_request_logging: false
Published Tools

The server publishes the following 14 tools. Each tool's rendered output is a markdown table (uniform multi-row results) or a markdown KV record (sparse / single-record / mixed-shape results). Every tool also returns a typed structured DTO for programmatic clients.

Tool Renderer Description
server_info KV Server identity and runtime: stackql version, backing SQL engine, provider registry location, read-only flag. Call once at session start.
list_providers Table Available cloud/SaaS providers (top of the hierarchy). No inputs.
list_services Table Services under a provider. Requires provider.
list_resources Table Resources under a provider.service. Requires provider and service.
list_methods Table Access methods (HTTP operations) for a resource. Call before writing any query. Requires provider, service, resource.
describe_resource KV Output fields for a resource's primary read method. Requires provider, service, resource.
describe_method KV Full I/O contract for one method. Requires provider, service, resource, method.
validate_select_query KV Parse and plan a SELECT without executing. Returns {valid, errors}. SELECT only.
run_select_query Table Execute a SELECT. Returns {rows}. Reads only.
run_mutation_query KV Execute INSERT/UPDATE/REPLACE/DELETE against the provider. Real side effects. Returns {messages, timestamp}. Gated by the server mode.
run_lifecycle_operation KV Execute a stackql EXEC lifecycle operation. Returns {messages, timestamp}. Gated by the server mode.
list_registry Table Providers (and their versions) available in the configured registry. Optional provider lists versions for that provider.
pull_provider KV Install a provider from the registry into the local approot cache. Requires provider; version optional. Local cache write only.
reload_credentials Table Re-source credentials from the backend's configured dotenv file into the process environment and report per-provider resolution status (issue #688). Never returns secret values. Optional provider scopes the report. Allowed in every mode.
Published Prompts

The server publishes one static prompt:

  • write_safe_select — guidance for writing safe SELECT queries against stackql resources. The prompt body explains how to use SHOW METHODS IN <provider>.<service>.<resource> to discover the best read method and the required WHERE parameters.
Restricting Published Tools and Prompts

The top-level enabled_tools and enabled_prompts fields on Config are independent allowlists.

  • Omitted, null, or empty list — every built-in tool (or prompt) is registered. This is the default.
  • Populated list — only the named items are registered. Any other tool or prompt is absent from tools/list / prompts/list and the corresponding tools/call or prompts/get returns an unknown tool/unknown prompt error.

Enforcement happens at registration time in pkg/mcp_server/server.go via the addToolIfEnabled and addPromptIfEnabled helpers, which consult Config.IsToolEnabled(name) / Config.IsPromptEnabled(name) before delegating to the SDK. There is no runtime cost for items that are not enabled — they are never bound to the server.

JSON example — a single-purpose server that exposes only server_info:

{
  "server": {
    "transport": "http",
    "address": "127.0.0.1:9915"
  },
  "enabled_tools": ["server_info"]
}

When the server is launched via the stackql mcp (or stackql srv --mcp.server.type=...) command, these fields are parsed from the same --mcp.config JSON blob as the rest of the configuration — no additional flag is required. For example, stackql mcp --mcp.config='{"server": { "transport": "http", "address": "127.0.0.1:9915"}, "enabled_tools": ["server_info"]}'.

Server Modes

Config.Server.Mode chooses one of four safety contracts. All four allow SELECT and metadata reads; they differ in how they handle mutations and lifecycle operations.

Mode SELECT / metadata INSERT / UPDATE / REPLACE DELETE EXEC (lifecycle)
read_only allow refuse refuse refuse
safe (default) allow needs approval needs approval needs approval
delete_safe allow allow needs approval needs approval
full_access allow allow allow allow

refuse means the tool returns an error immediately. needs approval means the server tries to elicit user consent via the MCP elicitation flow:

  • If the client advertised the elicitation capability at initialise, the server sends an elicitation/create request with a short message describing the action and the SQL. The user accepts, declines, or cancels.
  • If the client did NOT advertise elicitation, the tool is refused with a message that explains the gap and points the operator at full_access mode.

The mode is global per server. There is no per-tool override in this release.

Default-mode change (breaking)

PR1 had a single read_only: true / false flag; the default behaviour was "no enforcement, mutations proceed." PR2 replaces that flag with mode: safe as the default, which means mutations now require user approval out of the box. Operators running an elicitation-capable client should see one approval prompt per mutation. Operators running a non-elicitation client (or an automated pipeline) must explicitly opt into full_access.

For back-compat, the legacy read_only: true JSON / YAML key still parses and is treated as equivalent to mode: read_only. When both are set, mode wins.

Audit Log

Audit recording is on by default in PR2. Every tool call produces one JSONL record with the tool name, mode, decision, query class, SQL (for query tools), input args (for hierarchy tools), duration, and error. Result rows from SELECTs are intentionally not recorded - the audit answers "what did the agent do," not "what did the agent see."

File sink

The only sink kind shipped in this release is file, which writes one JSON object per line and fsyncs after each record. Lumberjack-style rotation by size, age, and backup count.

The sink implementation lives in pkg/sink so it can be reused outside MCP (future activity / telemetry channels, etc). The MCP audit subsystem feeds audit.Event values into a generic sink.Sink; the sink JSON-marshals whatever payload it is given. Adding alternative sinks (rotation policies, Kafka, S3) only requires implementing sink.Sink once; it benefits every subsystem that records through this path.

The generic sink.FileConfig requires the caller to specify where the file lives via either Path (a complete file path) or Dir (a directory in which the sink picks a filename via DefaultFilename). The sink package never silently picks a directory; the MCP server defaults Dir to . (cwd) on the operator's behalf when neither field is set in mcp.config.

server:
  mode: safe
  audit:
    disabled: false       # default false (audit is on)
    failure_mode: strict  # strict | strict_mutations | best_effort
    sink: file            # currently the only kind
    file:
      # Specify either `path` (a complete file path) or `dir` (the directory
      # in which the sink chooses a stackql_mcp_server_<UTC>.log basename).
      # When both are empty the MCP server defaults `dir` to cwd (".") for
      # back-compat; the underlying pkg/sink itself refuses to silently
      # pick a directory.
      path: ""
      dir: ""
      max_size_mb: 100
      max_backups: 5
      max_age_days: 30

The resolved absolute path is logged to stderr at startup as sink file: /path/to/file.log so operators can find the file later.

Failure modes

When the sink returns an error, the response depends on failure_mode:

failure_mode Effect on tool call
strict (default) The tool call returns the audit error to the client, even if the underlying tool succeeded. This is intentional: better an ambiguous client response than an undetected DELETE.
strict_mutations SELECT and metadata reads log the audit error to stderr and proceed. Mutations and lifecycle ops surface the error.
best_effort Always log to stderr and proceed.
Sequencing

The audit write happens AFTER the tool has executed (or been gated out) but BEFORE the response returns to the client. In strict mode, an audit-write failure on a successful DELETE means the row is gone but the client receives an error - by design, so no mutation slips through unaudited.

Audit-on change (breaking)

PR1 had no audit subsystem; nothing was logged. PR2 enables audit by default. To preserve PR1 behaviour, set server.audit.disabled: true.

MCP Protocol Support

The server implements the Model Context Protocol specification and supports:

  • Initialization: Capability negotiation with MCP clients
  • Resources: Listing and reading StackQL resources (providers, services, resources)
  • Tools: Query execution tool for running StackQL queries
  • Multiple Transports: stdio, TCP, and WebSocket (WebSocket implementation is placeholder)
Supported MCP Methods
  • initialize: Server initialization and capability negotiation
  • resources/list: List available StackQL resources
  • resources/read: Read specific resource data
  • tools/list: List available tools (StackQL query execution)
  • tools/call: Execute StackQL queries

Transport Support

Stdio Transport
  • Primary transport for command-line integration
  • JSON-RPC over stdin/stdout
  • Ideal for shell integrations and CLI tools
TCP Transport
  • HTTP-based JSON-RPC
  • Suitable for network-based integrations
  • Configurable address, port, and connection limits
WebSocket Transport (Placeholder)
  • Real-time bidirectional communication
  • Suitable for web applications
  • Currently implemented as placeholder

Development

Testing

The package includes an example backend for testing:

go test ./pkg/mcp_server/...
Integration with StackQL

To integrate with actual StackQL:

  1. Implement the Backend interface using StackQL's query execution engine
  2. Map StackQL's schema information to the Schema structure
  3. Handle StackQL-specific error types and convert them to BackendError

Dependencies

The package uses minimal external dependencies:

  • github.com/gorilla/mux: HTTP routing (already available in StackQL)
  • golang.org/x/sync: Concurrency utilities (already available in StackQL)
  • gopkg.in/yaml.v2: YAML configuration support (already available in StackQL)

No MCP SDK dependency is required as the package implements the MCP protocol directly.

Future Enhancements

  1. Full WebSocket Implementation: Complete WebSocket transport support
  2. Stdio Transport: Complete stdio JSON-RPC implementation
  3. Authentication: Add authentication and authorization support
  4. Streaming: Support for streaming large query results
  5. Caching: Query result caching for improved performance
  6. Metrics: Prometheus metrics for monitoring and observability

Documentation

Index

Constants

View Source
const (
	MCPClientTypeHTTP  = "http"
	MCPClientTypeSTDIO = "stdio"
)
View Source
const (
	DefaultHTTPServerAddress = "127.0.0.1:9876"
)
View Source
const (
	// ExplainerPromptWriteSafeSelectTool is the static body of the write_safe_select prompt.
	ExplainerPromptWriteSafeSelectTool = `` /* 257-byte string literal not displayed */

)

Variables

This section is empty.

Functions

This section is empty.

Types

type AuditConfig added in v0.10.474

type AuditConfig struct {
	// Disabled turns the audit subsystem off entirely.  Default false
	// (audit is on by default).
	Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`

	// FailureMode controls what happens when the sink returns an error.
	// Legal values: "strict" (default), "strict_mutations", "best_effort".
	FailureMode string `json:"failure_mode,omitempty" yaml:"failure_mode,omitempty"`

	// Sink selects the destination kind.  Currently only "file" is
	// implemented; other values are reserved.  Empty defaults to "file".
	Sink string `json:"sink,omitempty" yaml:"sink,omitempty"`

	// File holds file-sink-specific options.  Only consulted when Sink is
	// "file" (the default).
	File sink.FileConfig `json:"file,omitempty" yaml:"file,omitempty"`
}

AuditConfig configures the audit subsystem.

func (AuditConfig) GetFailureMode added in v0.10.474

func (a AuditConfig) GetFailureMode() string

GetFailureMode returns the effective failure-mode string with the default substituted for empty input.

type Backend

type Backend interface {

	// Ping verifies the backend connection is active.
	Ping(ctx context.Context) error

	// Close gracefully shuts down the backend connection.
	Close() error

	// ServerInfo returns server identity and runtime metadata.
	ServerInfo(ctx context.Context, args any) (dto.ServerInfoOutput, error)

	// ExecQuery executes a non-row-returning SQL statement (mutations, EXEC).
	ExecQuery(ctx context.Context, query string) (map[string]any, error)

	// ValidateQuery parses and plans a SELECT without executing it.
	ValidateQuery(ctx context.Context, query string) ([]map[string]any, error)

	// RunQueryJSON executes a SELECT and returns the rows.
	RunQueryJSON(ctx context.Context, input dto.QueryJSONInput) ([]map[string]interface{}, error)

	// ListProviders lists available providers.
	ListProviders(ctx context.Context) ([]map[string]any, error)

	// ListServices lists services under a provider.
	ListServices(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

	// ListResources lists resources under a provider/service.
	ListResources(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

	// ListMethods lists access methods for a resource.
	ListMethods(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

	// DescribeResource returns the output fields for a resource's primary read method.
	DescribeResource(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

	// DescribeMethod returns the full I/O contract for one method.
	DescribeMethod(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

	// ListRegistry lists providers (and their versions) available in the registry.
	// When input.Provider is empty, lists all available providers; otherwise lists
	// versions for that provider.  Distinct from ListProviders, which lists only
	// providers already pulled into the local cache.
	ListRegistry(ctx context.Context, input dto.RegistryInput) ([]map[string]any, error)

	// PullProvider installs a provider from the registry into the local approot
	// cache.  input.Provider is required; input.Version is optional (empty pulls
	// the latest published version).  Returns the same shape as ExecQuery.
	PullProvider(ctx context.Context, input dto.RegistryInput) (map[string]any, error)

	// ReloadCredentials (re)sources credentials from the backend's configured
	// env file into the process environment and reports per-provider
	// resolution status; secret values are never returned (issue #688).
	ReloadCredentials(ctx context.Context, input dto.CredentialsReloadInput) (dto.CredentialsReloadDTO, error)
}

func NewExampleBackend

func NewExampleBackend(connectionString string) Backend

NewExampleBackend creates a new example backend instance.

type BackendConfig

type BackendConfig struct {
	// Type specifies the backend type ("tcp", "memory").
	Type string `json:"type" yaml:"type"`

	// AppName is an optional application name describing the backend.
	// In the first instance, this is stackql.
	// **Possible** future use case for the backing db (e.g., "postgres", "mysql", etc).
	AppName string `json:"app_name" yaml:"app_name"`

	// ConnectionString contains the connection details for the backend.
	// Format depends on the backend type.
	ConnectionString string `json:"dsn" yaml:"dsn"`

	// MaxConnections limits the number of backend connections.
	MaxConnections int `json:"max_connections" yaml:"max_connections"`

	// ConnectionTimeout specifies the timeout for backend connections.
	ConnectionTimeout Duration `json:"connection_timeout" yaml:"connection_timeout"`

	// QueryTimeout specifies the timeout for individual queries.
	QueryTimeout Duration `json:"query_timeout" yaml:"query_timeout"`
}

BackendConfig contains configuration for the backend connection.

type BackendError

type BackendError struct {
	// Code is a machine-readable error code.
	Code string `json:"code"`

	// Message is a human-readable error message.
	Message string `json:"message"`

	// Details contains additional context about the error.
	Details map[string]interface{} `json:"details,omitempty"`
}

BackendError represents an error that occurred in the backend.

func (*BackendError) Error

func (e *BackendError) Error() string

func (*BackendError) Value

func (e *BackendError) Value() (driver.Value, error)

Ensure BackendError implements the driver.Valuer interface for database compatibility.

type ColumnInfo

type ColumnInfo interface {
	// GetName returns the column name as returned by the query.
	GetName() string

	// GetType returns the data type of the column (e.g., "string", "int64", "float64").
	GetType() string

	// IsNullable indicates whether the column can contain null values.
	IsNullable() bool
}

ColumnInfo provides metadata about a result column.

func NewColumnInfo

func NewColumnInfo(name, colType string, nullable bool) ColumnInfo

NewColumnInfo creates a new ColumnInfo instance.

type Config

type Config struct {
	// Server contains server-specific configuration.
	Server ServerConfig `json:"server" yaml:"server"`

	// Backend contains backend-specific configuration.
	Backend BackendConfig `json:"backend" yaml:"backend"`

	// EnabledTools restricts which MCP tools the server publishes.
	// When nil or empty, every built-in tool is published (default behavior).
	// When populated, only the named tools are registered.
	EnabledTools []string `json:"enabled_tools,omitempty" yaml:"enabled_tools,omitempty"`

	// EnabledPrompts restricts which MCP prompts the server publishes.
	// Same semantics as EnabledTools: nil or empty means all registered prompts are published.
	EnabledPrompts []string `json:"enabled_prompts,omitempty" yaml:"enabled_prompts,omitempty"`
}

Config represents the complete configuration for the MCP server.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration with sensible defaults.

func DefaultHTTPConfig

func DefaultHTTPConfig() *Config

func DefaultSSEConfig

func DefaultSSEConfig() *Config

func LoadFromJSON

func LoadFromJSON(data []byte) (*Config, error)

LoadFromJSON loads configuration from JSON data.

func LoadFromYAML

func LoadFromYAML(data []byte) (*Config, error)

LoadFromYAML loads configuration from YAML data.

func (*Config) GetBackendConnectionString

func (c *Config) GetBackendConnectionString() string

func (*Config) GetMode added in v0.10.474

func (c *Config) GetMode() string

GetMode returns the server's effective mode. Empty string is mapped to the safe default.

func (*Config) GetRender added in v0.10.542

func (c *Config) GetRender() string

GetRender returns the server-level default render format for tool result text content. Empty string is mapped to the markdown default.

func (*Config) GetServerAddress

func (c *Config) GetServerAddress() string

func (*Config) GetServerTransport

func (c *Config) GetServerTransport() string

func (*Config) IsAuditEnabled added in v0.10.474

func (c *Config) IsAuditEnabled() bool

IsAuditEnabled reports whether audit logging should run. Audit is on by default unless explicitly disabled.

func (*Config) IsPromptEnabled added in v0.10.474

func (c *Config) IsPromptEnabled(name string) bool

IsPromptEnabled reports whether the named prompt should be published. Empty/nil EnabledPrompts means all prompts are enabled.

func (*Config) IsTcpBackend

func (c *Config) IsTcpBackend() bool

func (*Config) IsToolEnabled added in v0.10.474

func (c *Config) IsToolEnabled(name string) bool

IsToolEnabled reports whether the named tool should be published. Empty/nil EnabledTools means all tools are enabled.

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration and returns an error if invalid.

type Duration

type Duration time.Duration

Duration is a wrapper around time.Duration that can be marshaled to/from JSON and YAML.

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (Duration) MarshalYAML

func (d Duration) MarshalYAML() (interface{}, error)

MarshalYAML implements yaml.Marshaler.

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements yaml.Unmarshaler.

type ExampleBackend

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

ExampleBackend is a simple implementation of the Backend interface for demonstration purposes. This shows how to implement the Backend interface without depending on StackQL internals.

func (*ExampleBackend) Close

func (b *ExampleBackend) Close() error

Close implements the Backend interface.

func (*ExampleBackend) DescribeMethod added in v0.10.474

func (b *ExampleBackend) DescribeMethod(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

func (*ExampleBackend) DescribeResource added in v0.10.474

func (b *ExampleBackend) DescribeResource(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

func (*ExampleBackend) ExecQuery added in v0.9.266

func (b *ExampleBackend) ExecQuery(ctx context.Context, query string) (map[string]any, error)

func (*ExampleBackend) ListMethods

func (b *ExampleBackend) ListMethods(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

func (*ExampleBackend) ListProviders

func (b *ExampleBackend) ListProviders(ctx context.Context) ([]map[string]any, error)

func (*ExampleBackend) ListRegistry added in v0.10.500

func (b *ExampleBackend) ListRegistry(ctx context.Context, input dto.RegistryInput) ([]map[string]any, error)

func (*ExampleBackend) ListResources

func (b *ExampleBackend) ListResources(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

func (*ExampleBackend) ListServices

func (b *ExampleBackend) ListServices(ctx context.Context, hI dto.HierarchyInput) ([]map[string]any, error)

func (*ExampleBackend) Ping

func (b *ExampleBackend) Ping(ctx context.Context) error

Ping implements the Backend interface.

func (*ExampleBackend) PullProvider added in v0.10.500

func (b *ExampleBackend) PullProvider(ctx context.Context, input dto.RegistryInput) (map[string]any, error)

func (*ExampleBackend) ReloadCredentials added in v0.10.557

func (b *ExampleBackend) ReloadCredentials(
	ctx context.Context,
	input dto.CredentialsReloadInput,
) (dto.CredentialsReloadDTO, error)

func (*ExampleBackend) RunQueryJSON

func (b *ExampleBackend) RunQueryJSON(ctx context.Context, input dto.QueryJSONInput) ([]map[string]interface{}, error)

func (*ExampleBackend) ServerInfo

func (b *ExampleBackend) ServerInfo(ctx context.Context, _ any) (dto.ServerInfoOutput, error)

func (*ExampleBackend) ValidateQuery added in v0.9.266

func (b *ExampleBackend) ValidateQuery(ctx context.Context, query string) ([]map[string]any, error)

type Field

type Field interface {
	// GetName returns the field identifier.
	GetName() string

	// GetType returns the field data type.
	GetType() string

	// IsRequired indicates if this field is mandatory for certain operations.
	IsRequired() bool

	// GetDescription returns human-readable documentation for the field.
	GetDescription() string
}

Field represents a field within a resource.

func NewField

func NewField(name, fieldType string, required bool, description string) Field

NewField creates a new Field instance.

type MCPClient

type MCPClient interface {
	InspectTools() ([]map[string]any, error)
	CallToolText(toolName string, args map[string]any) (string, error)
}

func NewMCPClient

func NewMCPClient(clientType string, baseURL string, clientCfgMap map[string]any, logger *logrus.Logger) (MCPClient, error)

type MCPServer

type MCPServer interface {
	Start(context.Context) error
	Stop() error
}

func NewAgnosticBackendServer

func NewAgnosticBackendServer(backend Backend, config *Config, logger *logrus.Logger) (MCPServer, error)

func NewExampleBackendServer

func NewExampleBackendServer(config *Config, logger *logrus.Logger) (MCPServer, error)

func NewMCPServerWithExampleBackend

func NewMCPServerWithExampleBackend(config *Config) (MCPServer, error)

NewMCPServerWithExampleBackend creates a new MCP server with an example backend. This is a convenience function for testing and demonstration purposes.

type Provider

type Provider interface {
	// GetName returns the provider identifier (e.g., "aws", "google").
	GetName() string

	// GetVersion returns the provider version.
	GetVersion() string

	// GetServices returns all services available in this provider.
	GetServices() []Service
}

Provider represents a StackQL provider with its services and resources.

func NewProvider

func NewProvider(name, version string, services []Service) Provider

NewProvider creates a new Provider instance.

type QueryResult

type QueryResult interface {
	// GetColumns returns metadata about each column in the result set.
	GetColumns() []ColumnInfo

	// GetRows returns the actual data returned by the query.
	GetRows() [][]interface{}

	// GetRowsAffected returns the number of rows affected by DML operations.
	GetRowsAffected() int64

	// GetExecutionTime returns the time taken to execute the query in milliseconds.
	GetExecutionTime() int64
}

QueryResult represents the result of a query execution.

func NewQueryResult

func NewQueryResult(columns []ColumnInfo, rows [][]interface{}, rowsAffected, executionTime int64) QueryResult

NewQueryResult creates a new QueryResult instance.

type Resource

type Resource interface {
	// GetName returns the resource identifier (e.g., "instances", "buckets").
	GetName() string

	// GetMethods returns the available operations for this resource.
	GetMethods() []string

	// GetFields returns the available fields in this resource.
	GetFields() []Field
}

Resource represents a queryable resource.

func NewResource

func NewResource(name string, methods []string, fields []Field) Resource

NewResource creates a new Resource instance.

type SchemaProvider

type SchemaProvider interface {
	// GetProviders returns all available providers (e.g., aws, google, azure).
	GetProviders() []Provider
}

SchemaProvider represents the metadata structure of available resources.

func NewSchemaProvider

func NewSchemaProvider(providers []Provider) SchemaProvider

NewSchemaProvider creates a new SchemaProvider instance.

type ServerConfig

type ServerConfig struct {
	// Name is the server name advertised to clients.
	Name string `json:"name" yaml:"name"`

	// Transport specifies the transport configuration for the server.
	Transport string `json:"transport" yaml:"transport"`

	// Address is the server Address advertised to clients.
	Address string `json:"address" yaml:"address"`

	// Scheme is the protocol scheme used by the server.
	Scheme string `json:"scheme" yaml:"scheme"`

	// Version is the server version advertised to clients.
	Version string `json:"version" yaml:"version"`

	TLSCertFile string `json:"tls_cert_file,omitempty" yaml:"tls_cert_file,omitempty"`
	TLSKeyFile  string `json:"tls_key_file,omitempty" yaml:"tls_key_file,omitempty"`

	TransportCfg map[string]any `json:"transport_cfg,omitempty" yaml:"transport_cfg,omitempty"`

	// Description is a human-readable description of the server.
	Description string `json:"description" yaml:"description"`

	// MaxConcurrentRequests limits the number of concurrent client requests.
	MaxConcurrentRequests int `json:"max_concurrent_requests" yaml:"max_concurrent_requests"`

	// RequestTimeout specifies the timeout for individual requests.
	RequestTimeout Duration `json:"request_timeout" yaml:"request_timeout"`

	// Mode controls the safety contract for query / mutation / lifecycle tools.
	// Legal values: "read_only", "safe", "delete_safe", "full_access".
	// Empty string is treated as "safe".
	//
	// For back-compat with PR1, the JSON/YAML key `read_only: true` is also
	// accepted and is equivalent to Mode = "read_only".  When both `mode`
	// and `read_only` are set, `mode` wins.
	Mode string `json:"mode,omitempty" yaml:"mode,omitempty"`

	// Render sets the server-level default for tool result text content.
	// Legal values: "markdown" (default), "json".  A per-call `format`
	// argument on a tool overrides this default (issue #669).
	Render string `json:"render,omitempty" yaml:"render,omitempty"`

	// Audit configures the audit subsystem.  Audit is enabled by default
	// (Disabled is false) and writes to a file sink.
	Audit AuditConfig `json:"audit,omitempty" yaml:"audit,omitempty"`
}

ServerConfig contains configuration for the MCP server itself.

func (*ServerConfig) UnmarshalJSON added in v0.10.474

func (s *ServerConfig) UnmarshalJSON(data []byte) error

UnmarshalJSON honours the legacy `read_only: true` shim.

func (*ServerConfig) UnmarshalYAML added in v0.10.474

func (s *ServerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML honours the legacy `read_only: true` shim.

type Service

type Service interface {
	// GetName returns the service identifier (e.g., "ec2", "compute").
	GetName() string

	// GetResources returns all resources available in this service.
	GetResources() []Resource
}

Service represents a service within a provider.

func NewService

func NewService(name string, resources []Resource) Service

NewService creates a new Service instance.

Directories

Path Synopsis
Package audit holds the MCP-specific audit event shape and the string constants for decisions and failure modes recorded in that shape.
Package audit holds the MCP-specific audit event shape and the string constants for decisions and failure modes recorded in that shape.
Package policy classifies SQL queries and decides whether the server should allow, refuse, or seek approval for a tool call based on the configured server mode.
Package policy classifies SQL queries and decides whether the server should allow, refuse, or seek approval for a tool call based on the configured server mode.
Package render produces text renderings of tool results for MCP clients.
Package render produces text renderings of tool results for MCP clients.

Jump to

Keyboard shortcuts

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