MXCP Configuration Guide
This guide covers all aspects of MXCP configuration, from user settings to endpoint definitions.
User Configuration
The user configuration file (~/.mxcp/config.yml
) stores user-specific settings and secrets.
Dynamic Value Interpolation
The user configuration file supports several methods for injecting values dynamically:
- Environment Variables - Use
$\{ENV_VAR\}
syntax - Vault Secrets - Use
vault://path/to/secret#key
URLs - File References - Use
file://path/to/file
URLs
Example:
mxcp: 1
projects:
my_project:
profiles:
dev:
secrets:
- name: "db_credentials"
type: "database"
parameters:
host: "localhost"
port: "5432"
database: "${DB_NAME}" # From environment variable
username: "${DB_USER}" # From environment variable
password: "vault://secret/db#password" # From Vault
ssl_cert: "file:///etc/ssl/db.crt" # From file
If any referenced value cannot be resolved (missing environment variable, Vault secret, or file), MXCP will raise an error when loading the configuration.
Schema Version
mxcp: 1 # Always use this version
Transport Configuration
transport:
provider: "streamable-http" # Default transport: streamable-http, sse, or stdio
http:
port: 8000 # Default port for HTTP transport
host: "localhost" # Default host for HTTP transport
stateless: false # Enable stateless HTTP mode (default: false)
The transport configuration sets the default behavior for the mxcp serve
command. You can override these settings using command-line options.
Transport Options:
-
provider: The transport protocol to use
streamable-http
: HTTP with streaming support (default)sse
: Server-sent eventsstdio
: Standard input/output
-
http: HTTP-specific configuration
- port: Port number to bind to (default: 8000)
- host: Host address to bind to (default: "localhost")
- stateless: Enable stateless HTTP mode (default: false)
- When
true
, no session state is maintained between requests - Required for serverless deployments
- Can be overridden with
mxcp serve --stateless
- When
Example with stateless mode for serverless deployment:
transport:
provider: "streamable-http"
http:
port: 8080
host: "0.0.0.0"
stateless: true
Projects Configuration
projects:
my_project: # Project name
profiles:
dev: # Profile name
secrets: # List of secrets for this profile
- name: "db_credentials"
type: "database"
parameters:
host: "localhost"
port: "5432"
database: "mydb"
username: "user"
password: "pass"
auth: # Authentication configuration for this profile
provider: "github"
github:
client_id: "your_github_client_id"
client_secret: "your_github_client_secret"
auth_url: "https://github.com/login/oauth/authorize"
token_url: "https://github.com/login/oauth/access_token"
Vault Integration (Optional)
MXCP supports HashiCorp Vault for secure secret management. When enabled, you can use vault://
URLs in your configuration to retrieve secrets from Vault.
vault:
enabled: true
address: "https://vault.example.com"
token_env: "VAULT_TOKEN" # Environment variable containing the Vault token
Using Vault URLs
Once Vault is configured, you can use vault://
URLs anywhere in your configuration where you would normally put sensitive values:
mxcp: 1
vault:
enabled: true
address: "https://vault.example.com"
token_env: "VAULT_TOKEN"
projects:
my_project:
profiles:
dev:
secrets:
- name: "db_credentials"
type: "database"
parameters:
host: "localhost"
port: "5432"
database: "mydb"
username: "vault://secret/database#username"
password: "vault://secret/database#password"
Vault URL Format: vault://path/to/secret#key
path/to/secret
: The path to the secret in Vaultkey
: The specific key within that secret
Requirements:
- The
hvac
Python library must be installed:pip install "mxcp[vault]"
orpip install hvac
- Vault must be configured with
enabled: true
- The Vault token must be available in the specified environment variable (default:
VAULT_TOKEN
)
Supported Secret Engines:
- KV Secrets Engine v2 (default)
- KV Secrets Engine v1 (fallback)
1Password Integration (Optional)
MXCP supports 1Password for secure secret management using service accounts. When enabled, you can use op://
URLs in your configuration to retrieve secrets from 1Password.
onepassword:
enabled: true
token_env: "OP_SERVICE_ACCOUNT_TOKEN" # Environment variable containing the service account token
Using 1Password URLs
Once 1Password is configured, you can use op://
URLs anywhere in your configuration where you would normally put sensitive values:
mxcp: 1
onepassword:
enabled: true
token_env: "OP_SERVICE_ACCOUNT_TOKEN"
projects:
my_project:
profiles:
dev:
secrets:
- name: "db_credentials"
type: "database"
parameters:
host: "localhost"
port: "5432"
database: "mydb"
username: "op://vault/database-creds/username"
password: "op://vault/database-creds/password"
totp: "op://vault/database-creds/totp?attribute=otp"
1Password URL Format: op://vault/item/field[?attribute=otp]
vault
: The name or ID of the vault in 1Passworditem
: The name or ID of the item in 1Passwordfield
: The name or ID of the field within the item?attribute=otp
: Optional parameter to retrieve TOTP/OTP value
Requirements:
- The
onepassword-sdk
Python library must be installed:pip install "mxcp[onepassword]"
orpip install onepassword-sdk
- 1Password service account must be configured with appropriate vault access
- 1Password must be configured with
enabled: true
- The service account token must be available in the specified environment variable (default:
OP_SERVICE_ACCOUNT_TOKEN
)
Examples:
- Basic field:
op://Private/Login Item/username
- Password field:
op://Private/Login Item/password
- TOTP/OTP:
op://Private/Login Item/totp?attribute=otp
- Using vault ID:
op://hfnjvi6aymbsnfc2gshk5b6o5q/Login Item/password
- Using item ID:
op://Private/j5hbqmr7nz3uqsw3j5qam2fgji/password
File References
MXCP supports reading configuration values from local files using file://
URLs. This is useful for:
- Loading certificates or keys from files
- Reading API tokens from secure file locations
- Separating sensitive data from configuration files
File URL Format:
- Absolute paths:
file:///absolute/path/to/file
- Relative paths:
file://relative/path/to/file
(relative to current working directory)
Example:
mxcp: 1
projects:
my_project:
profiles:
dev:
secrets:
- name: "ssl_certificates"
type: "custom"
parameters:
cert: "file:///etc/ssl/certs/server.crt"
key: "file:///etc/ssl/private/server.key"
- name: "api_config"
type: "api"
parameters:
api_key: "file://secrets/api_key.txt"
endpoint: "https://api.example.com"
Important Notes:
- The file content is read when the configuration is loaded
- Whitespace (including newlines) is automatically stripped from the file content
- The file must exist and be readable when the configuration is loaded
- Use appropriate file permissions to protect sensitive files
- Relative paths are resolved from the current working directory, not the config file location
Combining Interpolation Methods
You can combine environment variables, Vault URLs, 1Password URLs, and file references in the same configuration:
mxcp: 1
vault:
enabled: true
address: "${VAULT_ADDR}"
token_env: "VAULT_TOKEN"
onepassword:
enabled: true
token_env: "OP_SERVICE_ACCOUNT_TOKEN"
projects:
my_project:
profiles:
dev:
secrets:
- name: "app_config"
type: "custom"
parameters:
database_host: "${DB_HOST}" # Environment variable
database_password: "vault://secret/db#password" # Vault secret
api_key: "op://Private/api-keys/production" # 1Password secret
totp: "op://Private/api-keys/totp?attribute=otp" # 1Password TOTP
ssl_cert: "file:///etc/ssl/app.crt" # File reference
ssl_key: "file://keys/app.key" # Relative file path
Repository Configuration
The repository configuration file (mxcp-site.yml
) defines project-specific settings.
Basic Configuration
mxcp: 1 # Schema version
project: "my_project" # Must match a project in ~/.mxcp/config.yml
profile: "dev" # Profile to use
Secrets
secrets:
- "db_credentials" # List of secret names used by this repo
- "api_key"
Extensions
extensions:
- "httpfs" # Core extension
- "parquet" # Core extension
- name: "h3" # Community extension
repo: "community"
- name: "uc_catalog" # Nightly extension
repo: "core_nightly"
dbt Integration
dbt:
enabled: true
model_paths: ["models"] # Paths to dbt model directories
Note: While MXCP doesn't provide built-in caching, you can implement caching strategies using:
- dbt materializations (tables, incremental models)
- DuckDB persistent tables
- External caching layers
Profile-Specific Settings
profiles:
dev:
duckdb:
path: "db-dev.duckdb"
readonly: false
drift:
path: "drift-dev.json"
prod:
duckdb:
path: "db-prod.duckdb"
readonly: true
drift:
path: "drift-prod.json"
Drift Detection Configuration
The drift
section configures drift detection for each profile:
profiles:
default:
drift:
path: "drift-default.json" # Path to drift snapshot file
- path: Path to the drift snapshot file (relative to project root)
- Used as the default baseline for
mxcp drift-check
- Created by
mxcp drift-snapshot
- Should be unique per profile to avoid conflicts
- Used as the default baseline for
For more details on drift detection, see the Drift Detection Guide.
SQL Tools
sql_tools:
enabled: false # Enable built-in SQL querying tools (disabled by default)
Endpoint Definitions
Endpoints are defined in YAML files and can be of three types: tools, resources, or prompts.
Tool Definition
mxcp: 1
tool:
name: "my_tool"
description: "A tool that does something"
tags: ["tag1", "tag2"]
annotations:
title: "My Tool"
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
parameters:
- name: "param1"
type: "string"
description: "First parameter"
examples: ["example1"]
- name: "param2"
type: "number"
description: "Second parameter"
minimum: 0
maximum: 100
return:
type: "object"
properties:
result:
type: "string"
description: "The result"
language: "sql"
source:
file: "my_tool.sql" # Or use code: "SELECT ..."
enabled: true
tests:
- name: "basic_test"
description: "Tests basic functionality"
arguments:
- key: "param1"
value: "test"
- key: "param2"
value: 42
result: "expected result"
policies: # Optional: Define access control policies
input:
- condition: "user.role in ['admin', 'user']"
action: deny
reason: "Only admins and users can access this tool"
output:
- condition: "user.role != 'admin'"
action: filter_fields
fields: ["sensitive_data"]
Resource Definition
mxcp: 1
resource:
uri: "my://resource/{id}"
description: "A resource that provides data"
tags: ["tag1", "tag2"]
mime_type: "application/json"
parameters:
- name: "id"
type: "string"
description: "Resource ID"
return:
type: "object"
properties:
data:
type: "array"
items:
type: "string"
language: "sql"
source:
file: "my_resource.sql"
enabled: true
policies: # Optional: Define access control policies
input:
- condition: "!('resource.read' in user.permissions)"
action: deny
reason: "Missing resource.read permission"
Prompt Definition
mxcp: 1
prompt:
name: "my_prompt"
description: "A prompt template"
tags: ["tag1", "tag2"]
parameters:
- name: "name"
type: "string"
description: "Name to use in prompt"
messages:
- role: "system"
type: "text"
prompt: "You are a helpful assistant."
- role: "user"
type: "text"
prompt: "Hello, {{ name }}!"
policies: # Optional: Define access control policies
input:
- condition: "user.role == 'guest'"
action: deny
reason: "Guests cannot use AI prompts"
Policy Enforcement
MXCP supports policy-based access control for endpoints. Policies can control who can access endpoints and what data they can see.
Key features:
- Input policies: Control access before execution
- Output policies: Filter or mask sensitive data
- CEL expressions: Flexible condition evaluation
- User context: Role-based and permission-based access
For detailed information on policy configuration and examples, see the Policy Enforcement Guide.
SQL Source Files
SQL can be defined either inline in the YAML or in separate files:
Inline SQL
source:
code: |
SELECT *
FROM my_table
WHERE id = :id
External SQL File
source:
file: "queries/my_query.sql"
Type System
MXCP uses a comprehensive type system for input validation and output conversion. See the Type System documentation for details.
Jinja Templates in Prompts
Prompts support Jinja2 templating syntax:
prompt: |
Hello, {{ name }}!
{% if role == "admin" %}
You have admin privileges.
{% else %}
You have user privileges.
{% endif %}
{% for item in items %}
- {{ item }}
{% endfor %}
Environment Variables
MXCP can be configured using environment variables:
MXCP_CONFIG
: Path to user config file (default:~/.mxcp/config.yml
)MXCP_DISABLE_ANALYTICS
: Disable analytics (set to "1", "true", or "yes")MXCP_DEBUG
: Enable debug loggingMXCP_PROFILE
: Set default profileMXCP_READONLY
: Enable read-only modeMXCP_DUCKDB_PATH
: Override the DuckDB file location (see below)
DuckDB Path Override
The MXCP_DUCKDB_PATH
environment variable allows you to override the DuckDB database file location configured in mxcp-site.yml
. This is useful for:
- Using a centralized database location across different projects
- Running tests with a temporary database
- Deploying to environments where the configured path isn't writable
Example:
# Override DuckDB location for all commands
export MXCP_DUCKDB_PATH="/tmp/test.duckdb"
mxcp run my_tool
# Or set it for a single command
MXCP_DUCKDB_PATH="/path/to/shared.db" mxcp serve
When MXCP_DUCKDB_PATH
is set, it overrides the path specified in profiles.<profile>.duckdb.path
for all profiles.
Configuration Reload
For long-running MCP servers, you can reload external configuration values (secrets from vault://, file://, and environment variables) without restarting the service:
# Send SIGHUP signal to reload external values
kill -HUP <pid>
The reload process:
- Only external references are refreshed - the configuration file structure is NOT re-read
- Service remains available - queries wait for the reload to complete
- Automatic rollback on failure - if new values cause errors, the server continues with old values
What gets refreshed:
- ✅ Vault secrets (vault://)
- ✅ File contents (file://)
- ✅ Environment variables (${VAR})
- ✅ DuckDB connection (always recreated to pick up any database file changes)
- ✅ Python runtimes with updated configs
What does NOT change:
- ❌ Configuration file structure
- ❌ OAuth provider settings
- ❌ Server host/port settings
- ❌ Registered endpoints
This design ensures that only the values that are meant to be dynamic (secrets, tokens, etc.) are refreshed, while the service structure remains stable. This prevents accidental service disruption from configuration file changes.
Note on DuckDB Reload: The DuckDB connection is always recreated during a reload, regardless of whether configuration values have changed. This ensures that any external changes to the DuckDB database file (new tables, data updates, etc.) are visible after the reload.
Model Configuration (for Evals)
MXCP supports configuring LLM models for evaluation tests. This configuration is used by the mxcp evals
command to test how AI models interact with your endpoints.
User Config Model Settings
Add model configuration to your user config file (~/.mxcp/config.yml
):
models:
default: "claude-4-sonnet" # Default model to use for evals
models:
claude-4-opus:
type: "claude"
api_key: "${ANTHROPIC_API_KEY}" # Environment variable containing API key
timeout: 60 # Request timeout in seconds
max_retries: 3 # Number of retries on failure
claude-4-sonnet:
type: "claude"
api_key: "${ANTHROPIC_API_KEY}"
timeout: 30
gpt-4o:
type: "openai"
api_key: "${OPENAI_API_KEY}"
base_url: "https://api.openai.com/v1" # Optional custom endpoint
timeout: 45
gpt-4.1:
type: "openai"
api_key: "${OPENAI_API_KEY}"
timeout: 30
Model Configuration Options
- default: The model to use when not specified in eval suite or CLI
- models: Dictionary of model configurations
- type: Either "claude" or "openai"
- api_key: API key (you can use environment variables references)
- base_url: Custom API endpoint (optional, for OpenAI-compatible services)
- timeout: Request timeout in seconds
- max_retries: Number of retries on failure
For more information on using evals, see the LLM Evaluation section in the Quality & Testing Guide.
Best Practices
-
Secrets Management
- Never commit secrets to version control
- Use environment variables or Vault for sensitive data
- Keep secrets in
~/.mxcp/config.yml
-
Configuration Organization
- Use profiles for different environments
- Keep SQL in separate files for better version control
- Use meaningful names for tools and resources
-
Type Safety
- Always define parameter types
- Use format annotations for strings
- Provide examples for better documentation
-
Quality Assurance
- Validate: Run
mxcp validate
to ensure all endpoints are structurally correct - Test: Write comprehensive tests for all endpoints and run
mxcp test
regularly - Lint: Use
mxcp lint
to improve metadata for better LLM understanding - Evals: Create eval suites to test LLM interactions with
mxcp evals
- Include these checks in your CI/CD pipeline
- Validate: Run
-
Testing Best Practices
- Write tests for all endpoints in the YAML definition
- Test edge cases and error conditions
- Use realistic test data
- Test with different user contexts for policy-protected endpoints
- Write eval tests to ensure LLMs use your tools safely
-
Documentation
- Add clear descriptions to all endpoints, parameters, and return types
- Use tags for categorization
- Include meaningful examples in parameter definitions
- Document behavioral hints (readOnlyHint, destructiveHint, etc.)
- Run
mxcp lint
to identify missing documentation
-
Development Workflow
# During development
mxcp validate # Check structure
mxcp test # Run tests
mxcp lint # Improve metadata
# Before deployment
mxcp drift-snapshot # Create baseline
mxcp evals # Test LLM behavior
# In production
mxcp drift-check # Monitor changes