Documentation
¶
Overview ¶
Package connect provides functionality to register MCPProxy as an MCP server in various client configuration files (Claude Code, Cursor, VS Code, Windsurf, Codex, Gemini).
Index ¶
- func ConfigPath(clientID, homeDir string) string
- type AccessError
- type AccessOutcome
- type ClientDef
- type ClientStatus
- type ConnectPreview
- type ConnectResult
- type Service
- func (s *Service) Connect(clientID, serverName string, force bool) (*ConnectResult, error)
- func (s *Service) DetectAppDataDenial() (denied bool, remediation string)
- func (s *Service) Disconnect(clientID, serverName string) (*ConnectResult, error)
- func (s *Service) GetAllStatus() []ClientStatus
- func (s *Service) GetConnectedCount() int
- func (s *Service) GetConnectedIDs() []string
- func (s *Service) GetStatus(clientID string) (ClientStatus, error)
- func (s *Service) Preview(clientID, serverName string) (*ConnectPreview, error)
- func (s *Service) WithConfigProvider(fn func() (listenAddr, apiKey string, requireMCPAuth bool)) *Service
- func (s *Service) WithRequireMCPAuth(v bool) *Service
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConfigPath ¶
ConfigPath returns the expected configuration file path for the given client on the current operating system. homeDir overrides os.UserHomeDir when non-empty (useful for testing).
Types ¶
type AccessError ¶ added in v0.41.0
type AccessError struct {
Client string // client id/name
Path string // config path attempted
Outcome AccessOutcome // accessDenied (could also wrap malformed)
Remediation string // actionable fix text
Err error // underlying OS cause
}
AccessError is returned by connect/disconnect (and surfaced by GetStatus via the Remediation field) when a client-config access is permission-denied. It is errors.As-discoverable so the REST layer can map it to the right field, and unwraps to the underlying OS error so errors.Is(err, fs.ErrPermission) still holds (data-model.md AccessError).
func (*AccessError) Error ¶ added in v0.41.0
func (e *AccessError) Error() string
func (*AccessError) Unwrap ¶ added in v0.41.0
func (e *AccessError) Unwrap() error
Unwrap exposes the underlying OS error for errors.Is/errors.As.
type AccessOutcome ¶ added in v0.41.0
type AccessOutcome = string
AccessOutcome classifies an attempt to read or write a client config file (Spec 075 FR-003). It is an alias of string so it interoperates with the existing untyped access* constants and the ClientStatus.AccessState wire field, while giving classifier signatures a documented, enum-like type.
Valid values are the access* constants in connect.go: accessAccessible, accessAbsent, accessDenied, accessMalformed. (accessUnknown is the overall, not-content-checked status default, not a classification outcome.)
type ClientDef ¶
type ClientDef struct {
ID string // Unique identifier, e.g. "claude-code"
Name string // Human-readable name, e.g. "Claude Code"
Format string // File format: "json" or "toml"
ServerKey string // Top-level key for server entries: "mcpServers" or "servers"
Supported bool // Whether this client can be connected (directly or via a bridge)
Reason string // Explanation when Supported is false
Note string // Optional caveat shown for supported clients (e.g. bridge requirement)
Bridge bool // Connects via a stdio bridge; Connect can create the config when absent
Icon string // Icon identifier for frontend use
}
ClientDef describes a known MCP client and its configuration file format.
func FindClient ¶
FindClient looks up a client definition by ID. Returns nil if not found.
func GetAllClients ¶
func GetAllClients() []ClientDef
GetAllClients returns the definitions of all known clients.
type ClientStatus ¶
type ClientStatus struct {
ID string `json:"id"`
Name string `json:"name"`
ConfigPath string `json:"config_path"`
Exists bool `json:"exists"` // config file exists on disk
Connected bool `json:"connected"` // mcpproxy entry present in config
Supported bool `json:"supported"` // client can be connected (directly or via a bridge)
Reason string `json:"reason,omitempty"` // why not supported
Note string `json:"note,omitempty"` // caveat for supported clients (e.g. bridge requirement)
Bridge bool `json:"bridge,omitempty"` // connects via a stdio bridge; connectable even without an existing config
Icon string `json:"icon"`
ServerName string `json:"server_name,omitempty"` // name under which mcpproxy is registered
// AccessState classifies the per-client content access (Spec 075, additive).
// Empty/"unknown" in the content-read-free overall status; resolved to
// "accessible"/"absent"/"malformed" (and "denied" in US2) by on-demand reads.
AccessState string `json:"access_state"`
// Remediation carries actionable fix text, populated only when access is denied.
Remediation string `json:"remediation,omitempty"`
}
ClientStatus describes the current state of a client's configuration with respect to an MCPProxy entry.
type ConnectPreview ¶ added in v0.47.0
type ConnectPreview struct {
Client string `json:"client"`
ConfigPath string `json:"config_path"`
Format string `json:"format"` // "json" | "toml"
ServerKey string `json:"server_key"` // mcpServers / servers / mcp_servers / mcp
ServerName string `json:"server_name"` // key written into the config ("mcpproxy")
Entry map[string]interface{} `json:"entry"` // exact entry (masked) that will be written
EntryText string `json:"entry_text"` // entry rendered in the client's format (masked)
EntryExists bool `json:"entry_exists"` // an entry with this name already exists (overwrite/force case)
ContainsAPIKey bool `json:"contains_api_key"` // the written URL embeds an apikey credential
Bridge bool `json:"bridge,omitempty"` // connects via a stdio bridge (config created if absent)
// AccessState classifies the on-demand config read used to determine
// EntryExists (Spec 075): accessible|absent|malformed. A denied read never
// reaches here — it is returned as a typed *AccessError (403 + remediation).
AccessState string `json:"access_state"`
}
ConnectPreview describes the exact change a subsequent Connect would make to a client config, WITHOUT modifying the file or creating a backup (Spec 078 US1). The entry is derived from the same buildServerEntry used by the real write, so what is previewed equals what is written for the same client and configuration (FR-002); the embedded API key is masked for display (FR-004).
type ConnectResult ¶
type ConnectResult struct {
Success bool `json:"success"`
Client string `json:"client"`
ConfigPath string `json:"config_path"`
BackupPath string `json:"backup_path,omitempty"`
ServerName string `json:"server_name"`
Action string `json:"action"` // "created", "updated", "already_exists", "removed", "not_found"
Message string `json:"message"`
}
ConnectResult describes the outcome of a connect or disconnect operation.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service provides connect/disconnect operations for MCP client configurations.
func NewService ¶
NewService creates a Service that will inject the given listen address and optional API key into client configurations.
func NewServiceWithHome ¶
NewServiceWithHome creates a Service with a custom home directory (for testing).
func NewServiceWithReader ¶ added in v0.41.0
func NewServiceWithReader(listenAddr, apiKey, homeDir string, readFile func(string) ([]byte, error)) *Service
NewServiceWithReader creates a Service with a custom content reader (for testing the access-classification seam without a real OS denial).
func (*Service) Connect ¶
func (s *Service) Connect(clientID, serverName string, force bool) (*ConnectResult, error)
Connect registers MCPProxy in the specified client's configuration file. serverName defaults to "mcpproxy" if empty. If force is false and an entry already exists, an error is returned.
func (*Service) DetectAppDataDenial ¶ added in v0.43.0
DetectAppDataDenial probes installed client configs for a persisted macOS App-Data (TCC) permission denial, for the doctor diagnostic (Spec 075 US3, FR-007/008). It walks the supported clients and, for the first whose config file exists (os.Stat metadata only), performs a single content read through the seam; if that read classifies as accessDenied it reports the denial with the canonical, one-command remediation. It returns (false, "") when no installed client config is permission-denied — including when none are installed — so the check never raises a false positive on a machine that simply has no clients or has granted access (FR-008, T022).
Unlike GetAllStatus this DOES read content: the doctor command is an explicit user action, the one place a macOS App-Data prompt may legitimately appear.
func (*Service) Disconnect ¶
func (s *Service) Disconnect(clientID, serverName string) (*ConnectResult, error)
Disconnect removes the MCPProxy entry from the specified client's configuration.
func (*Service) GetAllStatus ¶
func (s *Service) GetAllStatus() []ClientStatus
GetAllStatus returns the connection status for every known client.
It determines "installed" via os.Stat metadata only and performs ZERO config content reads (Spec 075 FR-001): no client config file is opened, so simply viewing status raises no macOS App-Data privacy prompt. AccessState is left as "unknown" and Connected stays false for installed clients until an explicit per-client read via GetStatus.
func (*Service) GetConnectedCount ¶ added in v0.29.0
GetConnectedCount returns the number of supported clients in which mcpproxy is currently registered. Used as the "has any client connected?" wizard predicate (Spec 046).
func (*Service) GetConnectedIDs ¶ added in v0.29.0
GetConnectedIDs returns the identifiers of supported clients in which mcpproxy is currently registered. Identifiers come from the fixed per-client adapter table; user-entered values never appear here.
func (*Service) GetStatus ¶ added in v0.41.0
func (s *Service) GetStatus(clientID string) (ClientStatus, error)
GetStatus returns the status for a single client, reading its config contents on demand (Spec 075 FR-002). This is the scoped, explicit-action path where a macOS App-Data prompt may legitimately appear. It resolves Connected and AccessState (accessible/absent/malformed; "denied" is added in US2).
func (*Service) Preview ¶ added in v0.47.0
func (s *Service) Preview(clientID, serverName string) (*ConnectPreview, error)
Preview computes the exact entry a Connect would write for the given client, without modifying the config or creating a backup (Spec 078 FR-001). It reads the config on demand only to classify create-vs-overwrite (FR-003) and to resolve the Spec 075 access state; a permission denial surfaces as the same typed *AccessError that connect/disconnect return (FR-012).
func (*Service) WithConfigProvider ¶ added in v0.47.0
func (s *Service) WithConfigProvider(fn func() (listenAddr, apiKey string, requireMCPAuth bool)) *Service
WithConfigProvider installs a live-config accessor so the service reflects runtime changes to listen/api_key/require_mcp_auth (hot-reloaded via the file watcher or the wizard's require_mcp_auth toggle) rather than a startup snapshot. Wired only for the long-lived HTTP server; CLI one-shots leave it nil. Returns the receiver for chaining.
func (*Service) WithRequireMCPAuth ¶ added in v0.47.0
WithRequireMCPAuth sets whether the /mcp endpoint requires authentication, which decides whether connect embeds a credential in client configs at all. Threaded from config.RequireMCPAuth at the wiring sites, alongside listenAddr and apiKey. Returns the receiver for chaining.