Documentation
¶
Overview ¶
Package mcp implements Dynamic Client Registration Protocol (RFC 7591)
Package mcp provides a client for the Model Control Protocol (MCP) that allows the AI plugin to access external tools provided by MCP servers.
The UserClients represents a single user's connection to multiple MCP servers. The Client represents a connection to a single MCP server. The UserClients currently only supports authentication via Mattermost user ID header X-Mattermost-UserID. In the future it will support our OAuth implementation.
The ClientManager manages multiple UserClients, allowing for efficient mangement of connections. It is responsible for creating and closing UserClients as needed.
The organization reflects the need for each user to have their own connection to the MCP server given the design of MCP.
Index ¶
- Constants
- Variables
- func GetRegistrationEndpoint(ctx context.Context, httpClient *http.Client, serverURL string) (string, error)
- func IsMCPMetaTool(name string) bool
- func IsRemoteServerOrigin(origin string) bool
- func IsToolPolicyAutoRunEverywhere(policy string) bool
- func IsToolPolicyAutoRunInDM(policy string) bool
- func IsVettedHost(baseURL string) bool
- func LookupToolPolicy(cfg Config, serverBaseURL, toolName string) (string, bool)
- func NewMetaTools(registry *ToolRegistry) []llm.Tool
- func ToolPolicyLookupName(sc *ServerConfig, toolName string) string
- func ToolRetrievalOverrideKey(serverOrigin, toolName string) string
- func UnloadedMCPToolUserHint(name string) string
- func ValidateResourceMetadataMatchesServerBaseURL(serverBaseURL, metadataURL string) error
- func ValidateResourceMetadataURL(metadataURL string) error
- func ValidateUserPreferencesNormalized(prefs *UserToolProviderPreferences) error
- type AuthorizationServerMetadata
- type BM25Document
- type BM25Index
- type BM25Result
- type BeforeHookEntry
- type BeforeHookStore
- type CachedTools
- type Client
- type ClientCredentials
- type ClientManager
- func (m *ClientManager) Close()
- func (m *ClientManager) DisconnectUserOAuth(userID, serverName string) error
- func (m *ClientManager) DiscoverPluginServerTools(ctx context.Context, userID string, cfg PluginServerConfig) ([]ToolInfo, error)
- func (m *ClientManager) EnsureMCPSessionID(userID string) (string, error)
- func (m *ClientManager) GetConfig() Config
- func (m *ClientManager) GetEmbeddedServer() EmbeddedMCPServer
- func (m *ClientManager) GetHTTPClient() *http.Client
- func (m *ClientManager) GetOAuthManager() *OAuthManager
- func (m *ClientManager) GetPluginServer(pluginID string) (PluginServerConfig, bool)
- func (m *ClientManager) GetToolRetrievalOverrides() map[string]ToolRetrievalOverride
- func (m *ClientManager) GetToolsCache() *ToolsCache
- func (m *ClientManager) GetToolsForUser(ctx context.Context, userID string) ([]llm.Tool, *Errors)
- func (m *ClientManager) InvalidateUserClients(userID string)
- func (m *ClientManager) IsPluginRegistered(pluginID string) bool
- func (m *ClientManager) ListPluginServers() []PluginServerConfig
- func (m *ClientManager) MarkOAuthNeeded(userID, serverName, authURL string) error
- func (m *ClientManager) ProcessOAuthCallback(ctx context.Context, userID, state, code string) (*OAuthSession, error)
- func (m *ClientManager) ReInit(config Config, embeddedServer EmbeddedMCPServer)
- func (m *ClientManager) RefreshToolsForUser(ctx context.Context, userID string) ([]llm.Tool, *Errors, error)
- func (m *ClientManager) RegisterPluginServer(cfg PluginServerConfig)
- func (m *ClientManager) UnregisterPluginServer(pluginID string)
- type Config
- type EmbeddedMCPServer
- type EmbeddedServerClient
- type EmbeddedServerConfig
- type Errors
- type KVStore
- type LoadToolArgs
- type LoadToolResult
- type Logger
- type OAuthManager
- func (m *OAuthManager) DeleteAuthNeededState(userID, serverID string) error
- func (m *OAuthManager) DeleteUserToken(userID, serverID string) error
- func (m *OAuthManager) HasStoredToken(userID, serverID string) (bool, error)
- func (m *OAuthManager) InitiateOAuthFlow(ctx context.Context, userID, serverID, serverURL, metadataURL string, ...) (string, error)
- func (m *OAuthManager) InitiateOAuthFlowForServer(ctx context.Context, userID string, serverConfig ServerConfig) (string, error)
- func (m *OAuthManager) InitiateOAuthFlowForServerWithMetadata(ctx context.Context, userID string, serverConfig ServerConfig, ...) (string, error)
- func (m *OAuthManager) LoadAuthNeededState(userID, serverID string) (*OAuthNeededState, error)
- func (m *OAuthManager) ProcessCallback(ctx context.Context, loggedInUserID, state, code string) (*OAuthSession, error)
- func (m *OAuthManager) StartURL(serverID string) string
- func (m *OAuthManager) StoreAuthNeededState(userID, serverID, authURL string) error
- type OAuthNeededError
- type OAuthNeededState
- type OAuthSession
- type PluginHTTPRoundTripper
- type PluginServerConfig
- type ProtectedResourceMetadata
- type RegistrationError
- type RegistrationRequest
- type RegistrationResponse
- type SearchToolsArgs
- type SearchToolsResult
- type SearchToolsResultItem
- type ServerConfig
- type ServerConfigLookup
- type StaticOAuthCredentials
- type ToolConfig
- type ToolInfo
- func DiscoverEmbeddedServerTools(ctx context.Context, userID string, sessionID string, ...) ([]ToolInfo, error)
- func DiscoverPluginServerTools(ctx context.Context, userID string, cfg PluginServerConfig, ...) ([]ToolInfo, error)
- func DiscoverRemoteServerTools(ctx context.Context, userID string, serverConfig ServerConfig, ...) ([]ToolInfo, error)
- type ToolPolicyChecker
- type ToolPolicyFunc
- type ToolRegistry
- func (r *ToolRegistry) ClosestMatches(name string, limit int) []ToolSearchResult
- func (r *ToolRegistry) Len() int
- func (r *ToolRegistry) List() []ToolRegistryEntry
- func (r *ToolRegistry) Lookup(name string) (ToolRegistryEntry, bool)
- func (r *ToolRegistry) Search(query string, limit int) []ToolSearchResult
- type ToolRegistryEntry
- type ToolRegistryOption
- type ToolRetrievalOverride
- type ToolSearchResult
- type ToolsCache
- type UserClients
- func (c *UserClients) Close()
- func (c *UserClients) ConnectToEmbeddedServerIfAvailable(ctx context.Context, sessionID string, embeddedClient *EmbeddedServerClient, ...) error
- func (c *UserClients) ConnectToPluginServer(ctx context.Context, cfg PluginServerConfig, sourcePluginAPI mmapi.Client) error
- func (c *UserClients) ConnectToRemoteServers(ctx context.Context, servers []ServerConfig, forceRefresh bool) *Errors
- func (c *UserClients) GetTools(ctx context.Context) []llm.Tool
- func (c *UserClients) InitialRemoteConnectErrors() *Errors
- type UserToolProviderPreferences
Constants ¶
const ( MMUserIDHeader = "X-Mattermost-UserID" EmbeddedServerName = "Mattermost" EmbeddedClientKey = "embedded://mattermost" ToolPolicyAsk = config.MCPToolPolicyAsk ToolPolicyAutoRunInDM = config.MCPToolPolicyAutoRunInDM ToolPolicyAutoRunEverywhere = config.MCPToolPolicyAutoRunEverywhere )
const ( SearchToolsName = "search_tools" LoadToolName = "load_tool" )
const ( UserPreferencesMaxRequestBodyBytes = 256 << 10 // 256 KiB HTTP body cap for PUT /mcp/user-preferences UserPreferencesMaxDisabledServers = 256 UserPreferencesMaxServerEntryLen = 512 // max runes per disabled server identifier )
Limits for persisted user MCP provider preferences (stored in the plugin KV store). Mattermost's PluginKeyValue.IsValid does not cap value size; these bounds keep requests and stored JSON small and predictable (see model.PluginKeyValue in mattermost/server/public).
const (
BeforeHookKeyTTL = 30 * time.Minute
)
const DefaultMCPToolSearchLimit = 8
Variables ¶
var ( ErrBeforeHookKeyNotFound = errors.New("before-hook key not found") ErrInvalidBeforeHookConfig = errors.New("invalid before-hook config") )
var ErrOAuthNotConfigured = errors.New("oauth not configured")
var ErrUserPreferencesInvalid = errors.New("invalid user preferences")
ErrUserPreferencesInvalid indicates normalized preferences violate size or count limits.
Functions ¶
func GetRegistrationEndpoint ¶
func GetRegistrationEndpoint(ctx context.Context, httpClient *http.Client, serverURL string) (string, error)
GetRegistrationEndpoint discovers the registration endpoint from server metadata
func IsMCPMetaTool ¶
func IsRemoteServerOrigin ¶
IsRemoteServerOrigin reports whether an MCP server origin points at a remote/external server. Built-in tools carry an empty origin and the embedded Mattermost server uses EmbeddedClientKey; neither counts as remote. Every other origin — remote HTTP servers and plugin-registered servers — belongs to the licensed "MCP Support" feature.
func IsToolPolicyAutoRunInDM ¶
func IsVettedHost ¶
IsVettedHost returns true when the baseURL host matches one of the Mattermost-curated vetted MCP server hosts.
Matching semantics intentionally preserve the previous approved-server behavior: - host-only matching - path/query/fragment/port ignored - exact host or subdomain match - supports embedded://mattermost
func LookupToolPolicy ¶
LookupToolPolicy resolves a tool's policy for embedded, remote, and plugin origins. Unknown or disabled origins never auto-execute.
func NewMetaTools ¶
func NewMetaTools(registry *ToolRegistry) []llm.Tool
func ToolPolicyLookupName ¶
func ToolPolicyLookupName(sc *ServerConfig, toolName string) string
ToolPolicyLookupName returns the configured name to use for a runtime tool name. Runtime MCP tools may be namespaced while persisted policy config is usually stored by the server's bare tool name. An exact configured name still wins.
func UnloadedMCPToolUserHint ¶
UnloadedMCPToolUserHint returns the canonical message returned to the LLM when it tries to call an MCP tool that is visible in the registry but has not yet been loaded into the active tool store. Callers that surface this to the model should reuse this helper so the wording (and the suggested load_tool invocation) stays consistent across entry points.
func ValidateResourceMetadataMatchesServerBaseURL ¶
ValidateResourceMetadataMatchesServerBaseURL ensures resource_metadata is on the same origin as the admin-configured MCP server BaseURL (scheme + host + port). metadataURL must be non-empty; callers should skip when empty.
func ValidateResourceMetadataURL ¶
ValidateResourceMetadataURL validates a resource_metadata URL from an OAuth challenge or from the MCP OAuth start redirect query string.
func ValidateUserPreferencesNormalized ¶
func ValidateUserPreferencesNormalized(prefs *UserToolProviderPreferences) error
ValidateUserPreferencesNormalized returns an error if normalized preferences exceed storage limits.
Types ¶
type AuthorizationServerMetadata ¶
type AuthorizationServerMetadata struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
ResponseTypesSupported []string `json:"response_types_supported"`
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
}
AuthorizationServerMetadata represents the OAuth 2.0 Authorization Server Metadata (RFC 8414)
type BM25Document ¶
type BM25Index ¶
type BM25Index struct {
// contains filtered or unexported fields
}
func NewBM25Index ¶
func NewBM25Index(docs []BM25Document) *BM25Index
type BM25Result ¶
type BeforeHookEntry ¶
type BeforeHookEntry struct {
UserID string `json:"user_id"`
ToolName string `json:"tool_name"`
CallbackURL string `json:"callback_url"`
}
BeforeHookEntry is the trusted callback target stored for a short-lived hook key.
type BeforeHookStore ¶
type BeforeHookStore struct {
// contains filtered or unexported fields
}
BeforeHookStore owns short-lived before-hook key persistence.
func NewBeforeHookStore ¶
func NewBeforeHookStore(kv KVStore) *BeforeHookStore
NewBeforeHookStore creates a store for short-lived before-hook keys.
func (*BeforeHookStore) Delete ¶
func (s *BeforeHookStore) Delete(hookKey string) error
Delete removes a before-hook key. It is used for best-effort cleanup once a bridge request completes; TTL remains the fallback for interrupted requests.
func (*BeforeHookStore) Issue ¶
func (s *BeforeHookStore) Issue(userID, toolName, pluginID, beforeCallback string) (string, error)
Issue stores a trusted callback endpoint and returns an opaque key bound to the user and tool.
func (*BeforeHookStore) Resolve ¶
func (s *BeforeHookStore) Resolve(userID, toolName, hookKey string) (BeforeHookEntry, error)
Resolve returns a trusted callback URL for a key bound to userID and toolName. The key remains valid until its KV TTL expires so a single bridge run can call the same tool more than once.
type CachedTools ¶
type CachedTools struct {
Tools map[string]*mcp.Tool `json:"tools"`
Timestamp time.Time `json:"timestamp"`
ServerURL string `json:"server_url"`
ServerName string `json:"server_name"`
}
CachedTools represents a cached set of tools for a specific MCP server
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents the connection to a single MCP server
func NewClient ¶
func NewClient(ctx context.Context, userID string, serverConfig ServerConfig, log pluginapi.LogService, oauthManager *OAuthManager, httpClient *http.Client, toolsCache *ToolsCache, forceRefresh bool) (*Client, error)
NewClient creates a new MCP client for the given server and user and connects to the specified MCP server. forceRefresh bypasses the shared tools cache read. Its sole purpose is to close the race where a concurrent lookup repopulates the cache between a manual refresh's invalidation and this reconnect; a plain post-invalidation rediscovery would otherwise cache-miss on its own.
func NewPluginClient ¶
func NewPluginClient(ctx context.Context, userID string, cfg PluginServerConfig, sourcePluginAPI mmapi.Client, log pluginapi.LogService) (*Client, error)
NewPluginClient creates a per-user MCP client for a plugin-registered server. Plugin clients list tools at connect time and do not use the shared tools cache.
func (*Client) CallTool ¶
func (c *Client) CallTool(ctx context.Context, toolName string, args map[string]any) (string, error)
CallTool calls a tool on this MCP server
type ClientCredentials ¶
type ClientManager ¶
type ClientManager struct {
// contains filtered or unexported fields
}
ClientManager manages MCP clients for multiple users
func NewClientManager ¶
func NewClientManager(config Config, log pluginapi.LogService, pluginAPI *pluginapi.Client, oauthManager *OAuthManager, embeddedServer EmbeddedMCPServer, httpClient *http.Client, sourcePluginAPI mmapi.Client) *ClientManager
NewClientManager creates a new MCP client manager. embeddedServer may be nil. sourcePluginAPI routes PluginHTTP to source plugins; may be nil.
func (*ClientManager) Close ¶
func (m *ClientManager) Close()
Close closes the client manager and all managed clients The client manger should not be used after Close is called
func (*ClientManager) DisconnectUserOAuth ¶
func (m *ClientManager) DisconnectUserOAuth(userID, serverName string) error
DisconnectUserOAuth removes the stored OAuth token for a user and server, and invalidates the cached MCP client so a fresh connection is established on the next request.
func (*ClientManager) DiscoverPluginServerTools ¶
func (m *ClientManager) DiscoverPluginServerTools(ctx context.Context, userID string, cfg PluginServerConfig) ([]ToolInfo, error)
func (*ClientManager) EnsureMCPSessionID ¶
func (m *ClientManager) EnsureMCPSessionID(userID string) (string, error)
EnsureMCPSessionID ensures there is a valid MCP session for the user This is used by both embedded and HTTP MCP servers to get a dedicated session
func (*ClientManager) GetConfig ¶
func (m *ClientManager) GetConfig() Config
GetConfig returns a snapshot of the current MCP configuration.
func (*ClientManager) GetEmbeddedServer ¶
func (m *ClientManager) GetEmbeddedServer() EmbeddedMCPServer
GetEmbeddedServer returns the embedded MCP server instance (may be nil) This method is kept for API compatibility
func (*ClientManager) GetHTTPClient ¶
func (m *ClientManager) GetHTTPClient() *http.Client
GetHTTPClient returns the HTTP client for upstream requests
func (*ClientManager) GetOAuthManager ¶
func (m *ClientManager) GetOAuthManager() *OAuthManager
GetOAuthManager returns the OAuth manager instance
func (*ClientManager) GetPluginServer ¶
func (m *ClientManager) GetPluginServer(pluginID string) (PluginServerConfig, bool)
GetPluginServer returns a value-copy of the stored config for pluginID.
func (*ClientManager) GetToolRetrievalOverrides ¶
func (m *ClientManager) GetToolRetrievalOverrides() map[string]ToolRetrievalOverride
func (*ClientManager) GetToolsCache ¶
func (m *ClientManager) GetToolsCache() *ToolsCache
GetToolsCache returns the tools cache instance
func (*ClientManager) GetToolsForUser ¶
GetToolsForUser returns the tools available for a specific user, connecting to embedded server if session ID provided.
func (*ClientManager) InvalidateUserClients ¶
func (m *ClientManager) InvalidateUserClients(userID string)
InvalidateUserClients closes and removes cached MCP clients for a user.
func (*ClientManager) IsPluginRegistered ¶
func (m *ClientManager) IsPluginRegistered(pluginID string) bool
IsPluginRegistered reports whether the source plugin currently has a live in-process registration. Returns false for entries hydrated only from persisted config.
func (*ClientManager) ListPluginServers ¶
func (m *ClientManager) ListPluginServers() []PluginServerConfig
func (*ClientManager) MarkOAuthNeeded ¶
func (m *ClientManager) MarkOAuthNeeded(userID, serverName, authURL string) error
MarkOAuthNeeded stores the latest upstream OAuth-needed state for a user/server and drops any cached client so subsequent tool discovery reflects the reconnectable state.
func (*ClientManager) ProcessOAuthCallback ¶
func (m *ClientManager) ProcessOAuthCallback(ctx context.Context, userID, state, code string) (*OAuthSession, error)
ProcessOAuthCallback processes the OAuth callback for a user
func (*ClientManager) ReInit ¶
func (m *ClientManager) ReInit(config Config, embeddedServer EmbeddedMCPServer)
ReInit re-initializes the client manager with a new configuration and embedded server
func (*ClientManager) RefreshToolsForUser ¶
func (m *ClientManager) RefreshToolsForUser(ctx context.Context, userID string) ([]llm.Tool, *Errors, error)
RefreshToolsForUser drops cached user clients and shared server tool lists, pre-warms a fresh user client, then delegates to GetToolsForUser for the embedded/plugin connect + filtering it shares with the normal lookup path.
func (*ClientManager) RegisterPluginServer ¶
func (m *ClientManager) RegisterPluginServer(cfg PluginServerConfig)
RegisterPluginServer stores or overwrites a plugin-server registration. Callers must ensure cfg.PluginID is non-empty.
func (*ClientManager) UnregisterPluginServer ¶
func (m *ClientManager) UnregisterPluginServer(pluginID string)
type Config ¶
Type aliases for MCP config types, which are defined in the config package to avoid circular imports. Existing callers can continue to use mcp.Config, etc.
type EmbeddedMCPServer ¶
type EmbeddedMCPServer interface {
CreateClientTransport(userID, sessionID string, pluginAPI *pluginapi.Client) (*mcp.InMemoryTransport, error)
}
EmbeddedMCPServer interface for dependency injection
type EmbeddedServerClient ¶
type EmbeddedServerClient struct {
// contains filtered or unexported fields
}
EmbeddedServerClient handles connections to the embedded MCP server
func NewEmbeddedServerClient ¶
func NewEmbeddedServerClient(server EmbeddedMCPServer, log pluginapi.LogService, pluginAPI *pluginapi.Client) *EmbeddedServerClient
func NewEmbeddedServerClientWithCache ¶
func NewEmbeddedServerClientWithCache(server EmbeddedMCPServer, log pluginapi.LogService, pluginAPI *pluginapi.Client, toolsCache *ToolsCache) *EmbeddedServerClient
NewEmbeddedServerClientWithCache is the same as NewEmbeddedServerClient but also wires up a shared tools cache. Pass a non-nil cache when callers want per-user tool listings to be cached across requests.
func (*EmbeddedServerClient) CreateClient ¶
func (c *EmbeddedServerClient) CreateClient(ctx context.Context, userID, sessionID string) (*Client, error)
CreateClient creates an embedded MCP client using session ID for authentication. If sessionID is empty, creates an unauthenticated client (used for tool discovery).
type EmbeddedServerConfig ¶
type EmbeddedServerConfig = config.MCPEmbeddedServerConfig
type Errors ¶
type Errors struct {
ToolAuthErrors []llm.ToolAuthError // Authentication errors users need to resolve
Errors []error // Generic errors (connection, config, etc.)
}
Errors represents a collection of errors from MCP operations.
type KVStore ¶
type KVStore interface {
Get(key string, o any) error
Set(key string, value any, options ...pluginapi.KVSetOption) (bool, error)
Delete(key string) error
ListKeys(page, count int, options ...pluginapi.ListKeysOption) ([]string, error)
}
KVStore interface for key-value operations
type LoadToolArgs ¶
type LoadToolArgs struct {
Name string `json:"name" jsonschema:"Exact namespaced MCP tool name to load,minLength=1"`
}
type LoadToolResult ¶
type LoadToolResult struct {
Loaded bool `json:"loaded"`
Name string `json:"name,omitempty"`
Schema any `json:"schema,omitempty"`
Matches []SearchToolsResultItem `json:"matches,omitempty"`
Error string `json:"error,omitempty"`
}
type Logger ¶
type Logger interface {
Debug(msg string, keyValuePairs ...interface{})
Info(msg string, keyValuePairs ...interface{})
Warn(msg string, keyValuePairs ...interface{})
Error(msg string, keyValuePairs ...interface{})
}
Logger interface for logging operations
type OAuthManager ¶
type OAuthManager struct {
// contains filtered or unexported fields
}
func NewOAuthManager ¶
func NewOAuthManager(pluginAPI mmapi.Client, callbackURL string, httpClient *http.Client, serverConfigLookup ServerConfigLookup) *OAuthManager
func (*OAuthManager) DeleteAuthNeededState ¶
func (m *OAuthManager) DeleteAuthNeededState(userID, serverID string) error
func (*OAuthManager) DeleteUserToken ¶
func (m *OAuthManager) DeleteUserToken(userID, serverID string) error
DeleteUserToken removes the stored OAuth token for a user and server, effectively disconnecting the user from that MCP server.
func (*OAuthManager) HasStoredToken ¶
func (m *OAuthManager) HasStoredToken(userID, serverID string) (bool, error)
HasStoredToken returns true when a non-expired OAuth token exists for the given user and server. It does not refresh the token or contact upstream.
func (*OAuthManager) InitiateOAuthFlow ¶
func (m *OAuthManager) InitiateOAuthFlow(ctx context.Context, userID, serverID, serverURL, metadataURL string, staticCreds *StaticOAuthCredentials) (string, error)
func (*OAuthManager) InitiateOAuthFlowForServer ¶
func (m *OAuthManager) InitiateOAuthFlowForServer(ctx context.Context, userID string, serverConfig ServerConfig) (string, error)
func (*OAuthManager) InitiateOAuthFlowForServerWithMetadata ¶
func (m *OAuthManager) InitiateOAuthFlowForServerWithMetadata(ctx context.Context, userID string, serverConfig ServerConfig, metadataURL string) (string, error)
InitiateOAuthFlowForServerWithMetadata starts OAuth like InitiateOAuthFlowForServer but passes resource_metadata from the upstream 401 when present (RFC 9728).
func (*OAuthManager) LoadAuthNeededState ¶
func (m *OAuthManager) LoadAuthNeededState(userID, serverID string) (*OAuthNeededState, error)
func (*OAuthManager) ProcessCallback ¶
func (m *OAuthManager) ProcessCallback(ctx context.Context, loggedInUserID, state, code string) (*OAuthSession, error)
func (*OAuthManager) StartURL ¶
func (m *OAuthManager) StartURL(serverID string) string
func (*OAuthManager) StoreAuthNeededState ¶
func (m *OAuthManager) StoreAuthNeededState(userID, serverID, authURL string) error
type OAuthNeededError ¶
type OAuthNeededError struct {
// contains filtered or unexported fields
}
func (*OAuthNeededError) AuthURL ¶
func (e *OAuthNeededError) AuthURL() string
func (*OAuthNeededError) Error ¶
func (e *OAuthNeededError) Error() string
func (*OAuthNeededError) MetadataURL ¶
func (e *OAuthNeededError) MetadataURL() string
MetadataURL returns the RFC 9728 resource_metadata URL from the upstream 401 challenge when known (may be empty).
func (*OAuthNeededError) Unwrap ¶
func (e *OAuthNeededError) Unwrap() error
type OAuthNeededState ¶
type OAuthSession ¶
type OAuthSession struct {
UserID string `json:"userID"`
ServerID string `json:"serverID"`
ServerURL string `json:"serverURL"`
ServerMetadataURL string `json:"serverMetadataURL"`
CodeVerifier string `json:"codeVerifier"`
State string `json:"state"`
StaticClientID string `json:"staticClientID,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
type PluginHTTPRoundTripper ¶
type PluginHTTPRoundTripper struct {
// contains filtered or unexported fields
}
PluginHTTPRoundTripper routes requests to a source plugin's MCP endpoint via PluginHTTP. Callers layer user headers above it.
func NewPluginHTTPRoundTripper ¶
func NewPluginHTTPRoundTripper(pluginID, basePath string, pluginAPI mmapi.Client) *PluginHTTPRoundTripper
NewPluginHTTPRoundTripper constructs a PluginHTTP-based transport for a source plugin MCP endpoint.
type PluginServerConfig ¶
type PluginServerConfig = config.PluginServerConfig
type ProtectedResourceMetadata ¶
type ProtectedResourceMetadata struct {
Resource string `json:"resource"`
AuthorizationServers []string `json:"authorization_servers"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
}
ProtectedResourceMetadata represents the OAuth 2.0 Protected Resource Metadata (RFC 9728)
type RegistrationError ¶
type RegistrationError struct {
ErrorCode string `json:"error"`
ErrorDescription string `json:"error_description,omitempty"`
HTTPStatusCode int `json:"-"`
HTTPResponse *http.Response `json:"-"`
}
RegistrationError represents an error response per RFC 7591
func (*RegistrationError) Error ¶
func (e *RegistrationError) Error() string
type RegistrationRequest ¶
type RegistrationRequest struct {
// Required fields
RedirectURIs []string `json:"redirect_uris"`
// Optional fields commonly used
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
GrantTypes []string `json:"grant_types,omitempty"`
ResponseTypes []string `json:"response_types,omitempty"`
ClientName string `json:"client_name,omitempty"`
Scope string `json:"scope,omitempty"`
Contacts []string `json:"contacts,omitempty"`
// Additional optional fields can be added as needed
ClientURI string `json:"client_uri,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
ToSURI string `json:"tos_uri,omitempty"`
PolicyURI string `json:"policy_uri,omitempty"`
}
RegistrationRequest represents a client registration request per RFC 7591
func DefaultRegistrationRequest ¶
func DefaultRegistrationRequest(redirectURI, clientName string) *RegistrationRequest
DefaultRegistrationRequest creates a default registration request for MCP clients
type RegistrationResponse ¶
type RegistrationResponse struct {
// Required fields
ClientID string `json:"client_id"`
// Optional fields
ClientSecret string `json:"client_secret,omitempty"`
ClientIDIssuedAt *int64 `json:"client_id_issued_at,omitempty"`
ClientSecretExpiresAt *int64 `json:"client_secret_expires_at,omitempty"`
// Echo back the registration metadata
RedirectURIs []string `json:"redirect_uris,omitempty"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
GrantTypes []string `json:"grant_types,omitempty"`
ResponseTypes []string `json:"response_types,omitempty"`
ClientName string `json:"client_name,omitempty"`
Scope string `json:"scope,omitempty"`
Contacts []string `json:"contacts,omitempty"`
ClientURI string `json:"client_uri,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
ToSURI string `json:"tos_uri,omitempty"`
PolicyURI string `json:"policy_uri,omitempty"`
}
RegistrationResponse represents the server's response per RFC 7591
func DiscoverAndRegisterClient ¶
func DiscoverAndRegisterClient(ctx context.Context, httpClient *http.Client, serverURL, callbackURL, clientID, initialAccessToken string) (*RegistrationResponse, error)
DiscoverAndRegisterClient performs the complete client registration flow: 1. Discovers the registration endpoint from server metadata 2. Creates a default registration request 3. Registers the client with the server
func RegisterClient ¶
func RegisterClient(ctx context.Context, httpClient *http.Client, registrationEndpoint string, request *RegistrationRequest, initialAccessToken string) (*RegistrationResponse, error)
RegisterClient performs dynamic client registration per RFC 7591
type SearchToolsArgs ¶
type SearchToolsArgs struct {
Query string `json:"query" jsonschema:"Search query for finding available MCP tools,minLength=1"`
}
type SearchToolsResult ¶
type SearchToolsResult struct {
Tools []SearchToolsResultItem `json:"tools"`
}
type SearchToolsResultItem ¶
type ServerConfig ¶
type ServerConfig = config.MCPServerConfig
type ServerConfigLookup ¶
type ServerConfigLookup func(serverID string) (ServerConfig, bool)
ServerConfigLookup resolves a server's current configuration by its ID. It returns the config and true if found, or a zero value and false if not.
type StaticOAuthCredentials ¶
StaticOAuthCredentials holds pre-configured OAuth client credentials from server config. When set, these bypass Dynamic Client Registration (RFC 7591) for providers that require a pre-registered OAuth application.
type ToolConfig ¶
type ToolConfig = config.MCPToolConfig
func SeedVettedToolConfigs ¶
func SeedVettedToolConfigs(baseURL string) []ToolConfig
SeedVettedToolConfigs returns one-time seed tool configs for vetted MCP hosts.
Only Mattermost-curated READ-only tools are seeded. Most are enabled with policy auto_run_in_dm; GitHub security-scanning reads default to policy ask (admins may switch). Non-READ tools are intentionally not persisted here; tools without config fall back to the runtime default of policy="ask", enabled=true until an admin explicitly configures them.
type ToolInfo ¶
type ToolInfo struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema any `json:"inputSchema"`
}
ToolInfo represents a tool's metadata for discovery purposes
func DiscoverEmbeddedServerTools ¶
func DiscoverEmbeddedServerTools( ctx context.Context, userID string, sessionID string, embeddedServerConfig EmbeddedServerConfig, embeddedServer EmbeddedMCPServer, log pluginapi.LogService, pluginAPI *pluginapi.Client, ) ([]ToolInfo, error)
DiscoverEmbeddedServerTools creates a temporary connection to an embedded MCP server and discovers its tools
func DiscoverPluginServerTools ¶
func DiscoverPluginServerTools( ctx context.Context, userID string, cfg PluginServerConfig, sourcePluginAPI mmapi.Client, log pluginapi.LogService, ) ([]ToolInfo, error)
DiscoverPluginServerTools lists tools from a plugin-registered MCP server over PluginHTTP, bypassing the per-user client cache.
func DiscoverRemoteServerTools ¶
func DiscoverRemoteServerTools( ctx context.Context, userID string, serverConfig ServerConfig, log pluginapi.LogService, oauthManger *OAuthManager, httpClient *http.Client, toolsCache *ToolsCache, ) ([]ToolInfo, error)
DiscoverRemoteServerTools creates a temporary connection to a remote MCP server and discovers its tools
type ToolPolicyChecker ¶
type ToolPolicyChecker interface {
GetToolPolicy(serverBaseURL string, toolName string) (policy string, enabled bool)
}
ToolPolicyChecker looks up the per-tool policy for a given MCP server/tool.
type ToolPolicyFunc ¶
ToolPolicyFunc is a function adapter that implements ToolPolicyChecker.
func (ToolPolicyFunc) GetToolPolicy ¶
func (f ToolPolicyFunc) GetToolPolicy(serverBaseURL string, toolName string) (string, bool)
GetToolPolicy implements ToolPolicyChecker.
type ToolRegistry ¶
type ToolRegistry struct {
// contains filtered or unexported fields
}
func NewToolRegistry ¶
func NewToolRegistry(tools []llm.Tool, opts ...ToolRegistryOption) *ToolRegistry
func (*ToolRegistry) ClosestMatches ¶
func (r *ToolRegistry) ClosestMatches(name string, limit int) []ToolSearchResult
func (*ToolRegistry) Len ¶
func (r *ToolRegistry) Len() int
func (*ToolRegistry) List ¶
func (r *ToolRegistry) List() []ToolRegistryEntry
func (*ToolRegistry) Lookup ¶
func (r *ToolRegistry) Lookup(name string) (ToolRegistryEntry, bool)
func (*ToolRegistry) Search ¶
func (r *ToolRegistry) Search(query string, limit int) []ToolSearchResult
type ToolRegistryEntry ¶
type ToolRegistryOption ¶
type ToolRegistryOption func(*toolRegistryOptions)
func WithToolRetrievalOverrides ¶
func WithToolRetrievalOverrides(overrides map[string]ToolRetrievalOverride) ToolRegistryOption
type ToolRetrievalOverride ¶
type ToolRetrievalOverride struct {
Summary string
}
type ToolSearchResult ¶
type ToolsCache ¶
type ToolsCache struct {
// contains filtered or unexported fields
}
ToolsCache manages the global cache of MCP tools across all users It uses the KV store directly for HA mode compatibility
func NewToolsCache ¶
func NewToolsCache(kvAPI KVStore, log Logger) *ToolsCache
NewToolsCache creates a new ToolsCache instance
func (*ToolsCache) ClearAll ¶
func (tc *ToolsCache) ClearAll() (int, error)
ClearAll removes all cached tools from KV store
func (*ToolsCache) GetTools ¶
func (tc *ToolsCache) GetTools(serverID string) map[string]*mcp.Tool
GetTools retrieves cached tools for a server, returns nil if missing
func (*ToolsCache) InvalidateServer ¶
func (tc *ToolsCache) InvalidateServer(serverID string) error
InvalidateServer removes a server's cache entry from KV store Delete returns no error for non-existent keys, only errors on actual failures
type UserClients ¶
type UserClients struct {
// contains filtered or unexported fields
}
UserClients represents a per-user MCP client with multiple server connections
func NewUserClients ¶
func NewUserClients(userID string, log pluginapi.LogService, oauthManager *OAuthManager, httpClient *http.Client, toolsCache *ToolsCache) *UserClients
func (*UserClients) Close ¶
func (c *UserClients) Close()
Close closes all server connections for a user client
func (*UserClients) ConnectToEmbeddedServerIfAvailable ¶
func (c *UserClients) ConnectToEmbeddedServerIfAvailable(ctx context.Context, sessionID string, embeddedClient *EmbeddedServerClient, embeddedConfig EmbeddedServerConfig) error
ConnectToEmbeddedServerIfAvailable connects to the embedded server if session ID is provided. If a connection already exists, it is reused.
func (*UserClients) ConnectToPluginServer ¶
func (c *UserClients) ConnectToPluginServer(ctx context.Context, cfg PluginServerConfig, sourcePluginAPI mmapi.Client) error
ConnectToPluginServer establishes a cached MCP session with a source plugin over PluginHTTP, injecting X-Mattermost-UserID. Plugin servers use inter-plugin auth, not user OAuth.
func (*UserClients) ConnectToRemoteServers ¶
func (c *UserClients) ConnectToRemoteServers(ctx context.Context, servers []ServerConfig, forceRefresh bool) *Errors
ConnectToRemoteServers initializes connections to remote MCP servers.
func (*UserClients) GetTools ¶
func (c *UserClients) GetTools(ctx context.Context) []llm.Tool
GetTools returns the tools available from the clients
func (*UserClients) InitialRemoteConnectErrors ¶
func (c *UserClients) InitialRemoteConnectErrors() *Errors
type UserToolProviderPreferences ¶
type UserToolProviderPreferences struct {
DisabledServers []string `json:"disabled_servers"`
}
UserToolProviderPreferences stores per-user provider toggle state.
func LoadUserPreferences ¶
func LoadUserPreferences(pluginAPI mmapi.Client, userID string) (*UserToolProviderPreferences, error)
LoadUserPreferences loads the user's tool provider preferences from KV. Returns a default (empty disabled list) when no entry exists.
func SaveUserPreferences ¶
func SaveUserPreferences(pluginAPI mmapi.Client, userID string, prefs *UserToolProviderPreferences) (*UserToolProviderPreferences, error)
SaveUserPreferences normalizes and persists the user's tool provider preferences.
Source Files
¶
- before_hook_store.go
- bm25.go
- client.go
- client_manager.go
- dcrp.go
- dynamic_registry.go
- embedded_session_store.go
- http_client.go
- mcp.go
- meta_tools.go
- oauth_manager.go
- oauth_metadata.go
- oauth_store.go
- oauth_transport.go
- plugin_roundtripper.go
- resource_metadata_origin.go
- retrieval_overrides.go
- tool_policy.go
- tools_cache.go
- user_clients.go
- user_preferences.go
- vetted_tools.go
- www_authenticate.go