runtime

package
v1.3.4 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2025 License: Apache-2.0 Imports: 31 Imported by: 1

Documentation

Overview

Package runtime provides OAuth discovery and authorization URL handling for MCP servers.

OAuth Discovery Implementation Gap in MCP Ecosystem:

While the MCP Specification technically describes using /.well-known/oauth-protected-resource for discovery (RFC 9728, see https://www.speakeasy.com/mcp/building-servers/state-of-oauth-in-mcp), most current MCP servers actually look for /.well-known/oauth-authorization-server directly at the MCP server's domain (RFC 8414). This is how the OAuth dance works in practice today. The gap between specification and implementation is prevalent in the MCP ecosystem.

The mcp-go oauthHandler.GetAuthorizationURL doesn't handle this correctly and follows only the strict RFC 9728 path, which fails with most real-world MCP servers. While waiting for this PR https://github.com/mark3labs/mcp-go/pull/581 to fix the upstream discovery logic, we need a workaround that implements the correct discovery sequence that actually works with existing MCP servers.

This implementation bridges the gap by:

  1. First trying the RFC 9728 approach (/.well-known/oauth-protected-resource)
  2. Falling back to the RFC 8414 approach (/.well-known/oauth-authorization-server) which is what most MCP servers actually implement
  3. Providing sensible defaults as a final fallback

This ensures compatibility with both specification-compliant servers and the majority of existing MCP server implementations that follow the more common OAuth patterns.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeSessionIDFromState added in v1.3.1

func DecodeSessionIDFromState(state string) (string, error)

DecodeSessionIDFromState extracts the session ID from an OAuth state parameter.

This function is exported to allow OAuth callback handlers to decode session IDs. When the OAuth provider redirects back to our callback endpoint, they include the state parameter we originally sent. This function reverses the encoding done by generateStateWithSessionID to extract the session ID, allowing us to route the authorization code back to the correct agent session that initiated the OAuth flow.

This is the critical piece that bridges the browser-based OAuth callback back to the specific runtime session that needs the authorization.

func GetAuthorizationURL added in v1.3.1

func GetAuthorizationURL(ctx context.Context, oauthHandler *transport.OAuthHandler, state, codeChallenge string) (string, error)

GetAuthorizationURL gets the OAuth authorization URL using the correct discovery logic.

This function works around the mcp-go library's incomplete OAuth discovery implementation. The upstream GetAuthorizationURL method fails with most MCP servers because it only tries the RFC 9728 discovery path, while most servers implement RFC 8414 directly.

Our approach: 1. Use our custom discovery logic to find the correct authorization endpoint 2. Leverage the existing mcp-go logic for parameter construction (client_id, scope, etc.) 3. Combine the correct endpoint with the correct parameters

This ensures we get properly formatted OAuth URLs that work with real MCP servers.

Types

type AgentChoiceEvent

type AgentChoiceEvent struct {
	Type    string `json:"type"`
	Content string `json:"content"`
	AgentContext
}

type AgentChoiceReasoningEvent added in v1.0.5

type AgentChoiceReasoningEvent struct {
	Type    string `json:"type"`
	Content string `json:"content"`
	AgentContext
}

type AgentContext

type AgentContext struct {
	AgentName string `json:"agent_name,omitempty"`
}

AgentContext carries optional agent attribution for an event.

func (AgentContext) GetAgentName

func (a AgentContext) GetAgentName() string

GetAgentName returns the agent name for events embedding AgentContext.

type AuthServerMetadata added in v1.3.1

type AuthServerMetadata struct {
	Issuer                            string   `json:"issuer"`
	AuthorizationEndpoint             string   `json:"authorization_endpoint"`
	TokenEndpoint                     string   `json:"token_endpoint"`
	RegistrationEndpoint              string   `json:"registration_endpoint,omitempty"`
	JwksURI                           string   `json:"jwks_uri,omitempty"`
	ScopesSupported                   []string `json:"scopes_supported,omitempty"`
	ResponseTypesSupported            []string `json:"response_types_supported"`
	GrantTypesSupported               []string `json:"grant_types_supported,omitempty"`
	TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"`
}

AuthServerMetadata represents the OAuth 2.0 Authorization Server Metadata This is a copy from the mcp-go library to avoid importing internal types

type AuthorizationRequiredEvent added in v1.2.0

type AuthorizationRequiredEvent struct {
	Type         string `json:"type"`
	ServerURL    string `json:"server_url"`
	ServerType   string `json:"server_type"`
	Confirmation string `json:"confirmation"` // only  "pending" | "confirmed" | "denied"
}

func (*AuthorizationRequiredEvent) GetAgentName added in v1.2.0

func (e *AuthorizationRequiredEvent) GetAgentName() string

type Client added in v1.3.1

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

Client is an HTTP client for the cagent server API

func NewClient added in v1.3.1

func NewClient(baseURL string, opts ...ClientOption) (*Client, error)

NewClient creates a new HTTP client for the cagent server

func (*Client) CreateAgent added in v1.3.1

func (c *Client) CreateAgent(ctx context.Context, prompt string) (*api.CreateAgentResponse, error)

CreateAgent creates a new agent using a prompt

func (*Client) CreateAgentConfig added in v1.3.1

func (c *Client) CreateAgentConfig(ctx context.Context, filename, model, description, instruction string) (*api.CreateAgentConfigResponse, error)

CreateAgentConfig creates a new agent manually with YAML configuration

func (*Client) CreateSession added in v1.3.1

func (c *Client) CreateSession(ctx context.Context, sessTemplate *session.Session) (*session.Session, error)

CreateSession creates a new session

func (*Client) DeleteAgent added in v1.3.1

func (c *Client) DeleteAgent(ctx context.Context, filePath string) (*api.DeleteAgentResponse, error)

DeleteAgent deletes an agent by file path

func (*Client) DeleteSession added in v1.3.1

func (c *Client) DeleteSession(ctx context.Context, id string) error

DeleteSession deletes a session by ID

func (*Client) EditAgentConfig added in v1.3.1

func (c *Client) EditAgentConfig(ctx context.Context, filename string, config v2.Config) (*api.EditAgentConfigResponse, error)

EditAgentConfig edits an agent configuration

func (*Client) ExportAgents added in v1.3.1

func (c *Client) ExportAgents(ctx context.Context) (*api.ExportAgentsResponse, error)

ExportAgents exports multiple agents as a zip file

func (*Client) GetAgent added in v1.3.1

func (c *Client) GetAgent(ctx context.Context, id string) (*v2.Config, error)

GetAgent retrieves an agent by ID

func (*Client) GetAgents added in v1.3.1

func (c *Client) GetAgents(ctx context.Context) ([]api.Agent, error)

GetAgents retrieves all available agents

func (*Client) GetDesktopToken added in v1.3.1

func (c *Client) GetDesktopToken(ctx context.Context) (*api.DesktopTokenResponse, error)

GetDesktopToken retrieves a desktop authentication token

func (*Client) GetSession added in v1.3.1

func (c *Client) GetSession(ctx context.Context, id string) (*api.SessionResponse, error)

GetSession retrieves a session by ID

func (*Client) GetSessions added in v1.3.1

func (c *Client) GetSessions(ctx context.Context) ([]api.SessionsResponse, error)

GetSessions retrieves all sessions

func (*Client) ImportAgent added in v1.3.1

func (c *Client) ImportAgent(ctx context.Context, filePath string) (*api.ImportAgentResponse, error)

ImportAgent imports an agent from a file path

func (*Client) PullAgent added in v1.3.1

func (c *Client) PullAgent(ctx context.Context, name string) (*api.PullAgentResponse, error)

PullAgent pulls an agent from a remote registry

func (*Client) PushAgent added in v1.3.1

func (c *Client) PushAgent(ctx context.Context, filepath, tag string) (*api.PushAgentResponse, error)

PushAgent pushes an agent to a remote registry

func (*Client) ResumeCodeReceived added in v1.3.1

func (c *Client) ResumeCodeReceived(ctx context.Context, code string) error

func (*Client) ResumeSession added in v1.3.1

func (c *Client) ResumeSession(ctx context.Context, id, confirmation string) error

ResumeSession resumes a session by ID

func (*Client) ResumeStartAuthorizationFlow added in v1.3.1

func (c *Client) ResumeStartAuthorizationFlow(ctx context.Context, id string, confirmation bool) error

func (*Client) RunAgent added in v1.3.1

func (c *Client) RunAgent(ctx context.Context, sessionID, agent string, messages []api.Message) (<-chan Event, error)

RunAgent executes an agent and returns a channel of streaming events

func (*Client) RunAgentWithAgentName added in v1.3.1

func (c *Client) RunAgentWithAgentName(ctx context.Context, sessionID, agent, agentName string, messages []api.Message) (<-chan Event, error)

RunAgentWithAgentName executes an agent with a specific agent name and returns a channel of streaming events

type ClientOption added in v1.3.1

type ClientOption func(*Client)

ClientOption is a function for configuring the Client

func WithHTTPClient added in v1.3.1

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient sets a custom HTTP client

func WithTimeout added in v1.3.1

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the HTTP client timeout

type ErrorEvent

type ErrorEvent struct {
	Type  string `json:"type"`
	Error string `json:"error"`
	AgentContext
}

type ErrorResponse added in v1.3.1

type ErrorResponse struct {
	Error string `json:"error"`
}

ErrorResponse represents an error response from the API

type Event

type Event interface {
	GetAgentName() string
	// contains filtered or unexported methods
}

func AgentChoice

func AgentChoice(agentName string, content string) Event

func AgentChoiceReasoning added in v1.0.5

func AgentChoiceReasoning(agentName string, content string) Event

func AuthorizationRequired added in v1.2.0

func AuthorizationRequired(serverURL, serverType, confirmation string) Event

func Error

func Error(msg string) Event

func PartialToolCall

func PartialToolCall(toolCall tools.ToolCall, agentName string) Event

func SessionCompaction

func SessionCompaction(sessionID, status string) Event

func SessionSummary

func SessionSummary(sessionID, summary string) Event

func SessionTitle

func SessionTitle(sessionID, title string) Event

func ShellOutput added in v1.0.0

func ShellOutput(output string) Event

func StreamStarted

func StreamStarted() Event

func StreamStopped

func StreamStopped() Event

func TokenUsage

func TokenUsage(inputTokens, outputTokens, contextLength, contextLimit int, cost float64) Event

func ToolCall

func ToolCall(toolCall tools.ToolCall, agentName string) Event

func ToolCallConfirmation

func ToolCallConfirmation(toolCall tools.ToolCall, agentName string) Event

func ToolCallResponse

func ToolCallResponse(toolCall tools.ToolCall, response, agentName string) Event

func UserMessage

func UserMessage(message string) Event

type OAuthAuthorizationRequiredError added in v1.3.1

type OAuthAuthorizationRequiredError struct {
	Err        error
	ServerURL  string
	ServerType string
}

OAuthAuthorizationRequiredError wraps an OAuth authorization error with server information

func (*OAuthAuthorizationRequiredError) Error added in v1.3.1

func (*OAuthAuthorizationRequiredError) Unwrap added in v1.3.1

type OAuthProtectedResource added in v1.3.1

type OAuthProtectedResource struct {
	AuthorizationServers []string `json:"authorization_servers"`
	Resource             string   `json:"resource"`
	ResourceName         string   `json:"resource_name,omitempty"`
}

OAuthProtectedResource represents the response from /.well-known/oauth-protected-resource

type OAuthStateData added in v1.3.1

type OAuthStateData struct {
	SessionID string `json:"session_id"` // The session ID that initiated the OAuth flow
	Random    string `json:"random"`     // Random component for CSRF protection
}

OAuthStateData represents the data encoded in the OAuth state parameter.

In OAuth flows, the state parameter serves dual purposes:

  1. Security: CSRF protection by including random data
  2. Session tracking: When the browser returns from authorization, we need to know which session triggered the OAuth flow to route the callback correctly.

Since OAuth authorization happens in a browser (different context from our runtime), we embed the session ID in the state parameter so we can retrieve it when the authorization server redirects back to us with the authorization code.

type Opt

type Opt func(*runtime)

func WithCurrentAgent

func WithCurrentAgent(agentName string) Opt

func WithSessionCompaction

func WithSessionCompaction(sessionCompaction bool) Opt

func WithTracer

func WithTracer(t trace.Tracer) Opt

WithTracer sets a custom OpenTelemetry tracer; if not provided, tracing is disabled (no-op).

type PartialToolCallEvent

type PartialToolCallEvent struct {
	Type     string         `json:"type"`
	ToolCall tools.ToolCall `json:"tool_call"`
	AgentContext
}

ToolCallEvent is sent when a tool call is received PartialToolCallEvent is sent when a tool call is first received (partial/complete)

type RemoteRuntime added in v1.3.1

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

RemoteRuntime implements the Interface using a remote client

func NewRemoteRuntime added in v1.3.1

func NewRemoteRuntime(client *Client, opts ...RemoteRuntimeOption) (*RemoteRuntime, error)

NewRemoteRuntime creates a new remote runtime that implements the Interface

func (*RemoteRuntime) CurrentAgent added in v1.3.1

func (r *RemoteRuntime) CurrentAgent() *agent.Agent

CurrentAgent returns the currently active agent

func (*RemoteRuntime) Resume added in v1.3.1

func (r *RemoteRuntime) Resume(ctx context.Context, confirmationType string)

Resume allows resuming execution after user confirmation

func (*RemoteRuntime) ResumeCodeReceived added in v1.3.1

func (r *RemoteRuntime) ResumeCodeReceived(ctx context.Context, code string) error

Resume allows resuming execution after user confirmation

func (*RemoteRuntime) ResumeStartAuthorizationFlow added in v1.3.1

func (r *RemoteRuntime) ResumeStartAuthorizationFlow(ctx context.Context, confirmationType bool)

Resume allows resuming execution after user confirmation

func (*RemoteRuntime) Run added in v1.3.1

func (r *RemoteRuntime) Run(ctx context.Context, sess *session.Session) ([]session.Message, error)

Run starts the agent's interaction loop and returns the final messages

func (*RemoteRuntime) RunStream added in v1.3.1

func (r *RemoteRuntime) RunStream(ctx context.Context, sess *session.Session) <-chan Event

RunStream starts the agent's interaction loop and returns a channel of events

func (*RemoteRuntime) Summarize added in v1.3.1

func (r *RemoteRuntime) Summarize(ctx context.Context, sess *session.Session, events chan Event)

Summarize generates a summary for the session

type RemoteRuntimeOption added in v1.3.1

type RemoteRuntimeOption func(*RemoteRuntime)

RemoteRuntimeOption is a function for configuring the RemoteRuntime

func WithRemoteAgentFilename added in v1.3.1

func WithRemoteAgentFilename(filename string) RemoteRuntimeOption

WithRemoteAgentFilename sets the agent filename to use with the remote API

func WithRemoteCurrentAgent added in v1.3.1

func WithRemoteCurrentAgent(agentName string) RemoteRuntimeOption

WithRemoteCurrentAgent sets the current agent name

func WithRemoteSessionID added in v1.3.1

func WithRemoteSessionID(sessionID string) RemoteRuntimeOption

WithRemoteSessionID sets the session ID for the remote runtime

type ResumeType

type ResumeType string
const (
	ResumeTypeApprove        ResumeType = "approve"
	ResumeTypeApproveSession ResumeType = "approve-session"
	ResumeTypeReject         ResumeType = "reject"
)

type Runtime

type Runtime interface {
	// CurrentAgent returns the currently active agent
	CurrentAgent() *agent.Agent
	// RunStream starts the agent's interaction loop and returns a channel of events
	RunStream(ctx context.Context, sess *session.Session) <-chan Event
	// Run starts the agent's interaction loop and returns the final messages
	Run(ctx context.Context, sess *session.Session) ([]session.Message, error)
	// Resume allows resuming execution after user confirmation
	Resume(ctx context.Context, confirmationType string)
	// Summarize generates a summary for the session
	Summarize(ctx context.Context, sess *session.Session, events chan Event)
	// ResumeStartAuthorizationFlow signals that user confirmation has been given to start the OAuth flow
	ResumeStartAuthorizationFlow(_ context.Context, confirmation bool)
	// ResumeCodeReceived sends the OAuth authorization code to the runtime after user has completed the OAuth flow in their browser
	ResumeCodeReceived(_ context.Context, code string) error
}

Runtime defines the contract for runtime execution

func New

func New(agents *team.Team, opts ...Opt) (Runtime, error)

New creates a new runtime for an agent and its team

type ServerInfoProvider added in v1.3.1

type ServerInfoProvider interface {
	GetServerInfo() (serverURL, serverType string)
}

ServerInfoProvider interface for toolsets that can provide server information

type SessionCompactionEvent

type SessionCompactionEvent struct {
	Type      string `json:"type"`
	SessionID string `json:"session_id"`
	Status    string `json:"status"`
	AgentContext
}

type SessionSummaryEvent

type SessionSummaryEvent struct {
	Type      string `json:"type"`
	SessionID string `json:"session_id"`
	Summary   string `json:"summary"`
	AgentContext
}

type SessionTitleEvent

type SessionTitleEvent struct {
	Type      string `json:"type"`
	SessionID string `json:"session_id"`
	Title     string `json:"title"`
	AgentContext
}

type ShellOutputEvent added in v1.0.0

type ShellOutputEvent struct {
	Type   string `json:"type"`
	Output string `json:"error"`
}

func (*ShellOutputEvent) GetAgentName added in v1.0.0

func (e *ShellOutputEvent) GetAgentName() string

type StreamStartedEvent

type StreamStartedEvent struct {
	Type string `json:"type"`
}

func (*StreamStartedEvent) GetAgentName

func (e *StreamStartedEvent) GetAgentName() string

type StreamStoppedEvent

type StreamStoppedEvent struct {
	Type string `json:"type"`
}

func (*StreamStoppedEvent) GetAgentName

func (e *StreamStoppedEvent) GetAgentName() string

type TokenUsageEvent

type TokenUsageEvent struct {
	Type  string `json:"type"`
	Usage *Usage `json:"usage"`
	AgentContext
}

type ToolCallConfirmationEvent

type ToolCallConfirmationEvent struct {
	Type     string         `json:"type"`
	ToolCall tools.ToolCall `json:"tool_call"`
	AgentContext
}

type ToolCallEvent

type ToolCallEvent struct {
	Type     string         `json:"type"`
	ToolCall tools.ToolCall `json:"tool_call"`
	AgentContext
}

type ToolCallResponseEvent

type ToolCallResponseEvent struct {
	Type     string         `json:"type"`
	ToolCall tools.ToolCall `json:"tool_call"`
	Response string         `json:"response"`
	AgentContext
}

type ToolHandler

type ToolHandler func(ctx context.Context, sess *session.Session, toolCall tools.ToolCall, events chan Event) (*tools.ToolCallResult, error)

ToolHandler is a function type for handling tool calls

type Usage

type Usage struct {
	InputTokens   int     `json:"input_tokens"`
	OutputTokens  int     `json:"output_tokens"`
	ContextLength int     `json:"context_length"`
	ContextLimit  int     `json:"context_limit"`
	Cost          float64 `json:"cost"`
}

type UserMessageEvent

type UserMessageEvent struct {
	Type    string `json:"type"`
	Message string `json:"message"`
}

UserMessageEvent is sent when a user message is received

func (*UserMessageEvent) GetAgentName

func (e *UserMessageEvent) GetAgentName() string

Jump to

Keyboard shortcuts

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