pub struct ServerConfig {
pub mcp: McpConfig,
pub workspace: WorkspaceConfig,
pub lsp_servers: Vec<LspServerConfig>,
pub project_config_status: ProjectConfigStatus,
pub workspace_trust: WorkspaceTrust,
}Expand description
Main configuration for the MCPLS server.
Fields§
§mcp: McpConfigMCP serverInfo/initialize presentation overrides.
workspace: WorkspaceConfigWorkspace configuration.
lsp_servers: Vec<LspServerConfig>LSP server configurations.
project_config_status: ProjectConfigStatusWhether a CWD-discovered ./mcpls.toml was ignored as untrusted
during this load (see ProjectConfigTrust).
Load-time metadata, not user-configurable: never read from or written
to a TOML file. Consumed by McplsServer::get_info (the
ServerHandler implementation in crate::mcp::server) to surface
the ignore decision in-band to MCP clients, supplementing the
tracing::warn! emitted at load time (which is stderr-only and
typically invisible to an MCP client).
workspace_trust: WorkspaceTrustWhether the analyzed workspace is trusted (see WorkspaceTrust).
Never read from or written to a TOML file: consent comes only from the command line of whoever launches mcpls, so a config file planted in the workspace cannot grant it.
Implementations§
Source§impl ServerConfig
impl ServerConfig
Sourcepub fn build_effective_language_map(&self) -> LanguageMap
pub fn build_effective_language_map(&self) -> LanguageMap
Build the effective language map used for language detection.
Starts with workspace mappings and overlays mappings inferred from
configured LSP server file_patterns: *.EXT patterns map extensions
and bare NAME patterns map extensionless file names.
Sourcepub fn load() -> Result<Self>
pub fn load() -> Result<Self>
Load configuration from the default path, treating a CWD-discovered
./mcpls.toml as untrusted.
Default paths checked in order:
$MCPLS_CONFIGenvironment variable (always trusted)./mcpls.toml(current directory) — skipped; seeload_with_trustto opt in- Platform user-config directory:
- Linux:
$XDG_CONFIG_HOME/mcpls/mcpls.toml, else~/.config/mcpls/mcpls.toml - macOS:
~/Library/Application Support/mcpls/mcpls.toml
- Linux:
%APPDATA%\mcpls\mcpls.toml(Windows)
If no configuration file exists, creates a default configuration file in the user’s config directory with all default language extensions.
This is a thin wrapper around
load_with_trust(ProjectConfigTrust::Untrusted) —
the safe default for library callers that haven’t made a trust
decision.
§Errors
Returns an error if parsing an existing config fails. If config creation fails, returns default config with graceful degradation.
Sourcepub fn load_with_trust(trust: ProjectConfigTrust) -> Result<Self>
pub fn load_with_trust(trust: ProjectConfigTrust) -> Result<Self>
Load configuration from the default path, with explicit control over
whether a CWD-discovered ./mcpls.toml is honored.
Behaves like load, except a ./mcpls.toml found in
the current directory is only loaded when trust is
ProjectConfigTrust::Trusted. When untrusted, the file is skipped
entirely (including its [workspace] section) and a warning is
logged naming the ignored path; discovery falls through to the
global config tier or built-in defaults, so project-marker
heuristics (e.g. Cargo.toml → rust-analyzer) still apply normally.
The returned config’s project_config_status
is ProjectConfigStatus::IgnoredUntrusted in that case, so callers with access to the loaded
config (e.g. McplsServer::get_info) can surface the ignore decision
in-band, not just via the stderr-only warning.
$MCPLS_CONFIG and an explicit path are unaffected by trust and
are always loaded: naming a path is itself the user’s consent.
Unlike load_from’s documented default (relative
WorkspaceConfig::roots joined to the config file’s own
directory), the global/user config tier
(~/.config/mcpls/mcpls.toml, or the platform equivalent) leaves
relative roots relative, so they resolve against the process’s
current working directory at startup – it isn’t tied to any
particular project, so cwd is the more intuitive base (#348).
§Errors
Returns an error if parsing an existing config fails. If config creation fails, returns default config with graceful degradation.
Sourcepub fn load_discovered(
trust: ProjectConfigTrust,
workspace: &WorkspaceTrust,
) -> Result<Self>
pub fn load_discovered( trust: ProjectConfigTrust, workspace: &WorkspaceTrust, ) -> Result<Self>
Discovers the configuration like load_with_trust
for a workspace trusted as workspace, applying that trust to the result.
With WorkspaceTrust::Untrusted the file that was actually loaded is
checked with ensure_outside_workspace
(it is environment-derived: $HOME, $XDG_CONFIG_HOME,
$MCPLS_CONFIG), and no default config file is created, so nothing is
written on behalf of an untrusted checkout.
§Errors
As load_with_trust, plus
Error::ConfigInsideWorkspace when the loaded file is inside the
workspace.
Sourcepub fn load_explicit(
path: &Path,
origin: ConfigOrigin,
workspace: &WorkspaceTrust,
) -> Result<Self>
pub fn load_explicit( path: &Path, origin: ConfigOrigin, workspace: &WorkspaceTrust, ) -> Result<Self>
Loads the config file the user named (--config or $MCPLS_CONFIG) for
a workspace trusted as workspace, applying that trust to the result.
Naming a path is consent to load it, so no project-config trust applies.
With WorkspaceTrust::Untrusted the file must lie outside the
workspace, as ensure_outside_workspace
checks.
§Errors
As load_from, plus Error::ConfigInsideWorkspace
when the file is inside an untrusted workspace.
§Examples
use std::path::Path;
use mcpls_core::config::ConfigOrigin;
use mcpls_core::{ServerConfig, WorkspaceTrust};
let missing = Path::new("/nonexistent/mcpls.toml");
assert!(
ServerConfig::load_explicit(missing, ConfigOrigin::Argument, &WorkspaceTrust::Trusted)
.is_err()
);Sourcepub fn load_from(path: &Path) -> Result<Self>
pub fn load_from(path: &Path) -> Result<Self>
Load configuration from a specific path.
Relative WorkspaceConfig::roots are joined to the directory
containing path and must exist, which keeps an explicitly named
config portable when mcpls is launched from a different working
directory. Roots are kept as written, not canonicalized, so the
spelling an operator configured (for example through a symlink) stays
admissible; a relative path yields roots that stay relative.
crate::bridge::WorkspaceRoots::from_configured canonicalizes them
at startup.
§Errors
Returns an error if the file doesn’t exist, exceeds the maximum allowed config file size, or parsing fails.
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Validate a configuration built in code.
Covers the rules that no field type enforces: today, that every id
allowed by an untrusted Self::workspace_trust names a configured
server. Value ranges (timeouts, position_encodings, language_id) are
not checked here: their types (TimeoutSecs,
IndexingReadyTimeoutSecs, PositionEncodings, LanguageId)
reject invalid values at construction. Workspace-scoped routing rules
(duplicate ServerId, conflicting handles claims across applicable
servers) are enforced later, by ToolRouter::from_configs over the
post-heuristics config subset in serve_with, because two servers for
one language with mutually exclusive heuristics are a legitimate
config.
The load_* functions check the allowlist as they apply the trust, so a
loaded config needs no call; crate::serve and crate::serve_with
run this once for every config regardless of origin.
§Errors
Returns Error::Config on the first rule violated.
§Examples
use mcpls_core::config::ServerConfig;
let config = ServerConfig::default();
assert!(config.validate().is_ok());Sourcepub fn ensure_outside_workspace(
&self,
source: &Path,
origin: ConfigOrigin,
) -> Result<()>
pub fn ensure_outside_workspace( &self, source: &Path, origin: ConfigOrigin, ) -> Result<()>
Rejects a config file that the analyzed checkout controls.
Untrusted mode must not run such a config. The file chooses the roots,
so it is always checked against the configured roots (or, with none,
the working directory); checking only those would let
roots = ["/elsewhere"] evade it. The working directory is also
checked when origin is the environment or source is relative, since
a project-scoped client config or .envrc launches mcpls there. A
working directory that is the filesystem root or the home directory is
never taken for a checkout.
§Errors
Error::ConfigInsideWorkspace when source is inside; Error::Io
when source or the working directory cannot be resolved.