Skip to main content

Overview

Let’s say you’re building a weather server. You might want users to customize their preferred temperature unit (Celsius vs Fahrenheit), provide an API key for external weather services, or set their default location. Session configurations let you define these customizable parameters - each user connection gets its own configuration that doesn’t affect other sessions, perfect for passing secrets and personalizing behavior. When you provide a configuration schema, Smithery will:
  • Generate a configuration UI with appropriate form elements (text inputs, dropdowns, checkboxes, number fields)
  • Pass configurations to your server as URL parameters using dot notation
  • Show helpful descriptions as form labels and tooltips
  • Apply default values and enforce required fields
Configuration is passed to your server through URL parameters using dot notation (e.g., ?apiKey=xxx&model.name=gpt-4). Users can easily customize these settings through the Smithery interface when connecting to your server.

Defining Configuration

How you define your configuration schema depends on your deployment method:
  1. Smithery CLI (TypeScript & Python): Schema automatically extracted from Zod/Pydantic schemas in your code
  2. Custom Container (Any language): Manual schema definition in smithery.yaml file
  3. External MCP: Expose schema via /.well-known/mcp-config endpoint

Smithery CLI Approach

For TypeScript and Python servers using Smithery’s managed deployment With Smithery CLI, configuration schemas are automatically extracted from your code - no need to manually define them.
  • TypeScript with Zod
  • Python with Pydantic
Export a configSchema from your server entry point:
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

// Configuration schema - automatically detected by Smithery
export const configSchema = z.object({ 
  apiKey: z.string().describe("Your API key"), 
  modelName: z.string().default("gpt-4").describe("Model to use"), 
  temperature: z.number().min(0).max(1).default(0.7).describe("Temperature setting"), 
}); 

export default function createServer({ 
  config 
}: { 
  config: z.infer<typeof configSchema> 
}) {
  const server = new McpServer({
    name: "My Server",
    version: "1.0.0",
  });

  // Use config values in your tools
  console.log(`Using model: ${config.modelName}`);
  
  return server.server;
}
Key Points:
  • Configuration schema is automatically extracted from your Zod/Pydantic definitions
  • No manual configuration needed
  • Schema validation and UI generation handled automatically

Custom Container Approach

For any programming language using Docker containers With custom containers, you manually define configuration schemas in your smithery.yaml file.
smithery.yaml
runtime: "container"
startCommand:
  type: http
  configSchema:
    type: object
    required: ["apiKey"]
    properties:
      apiKey:
        type: string
        title: "Weather API Key"
        description: "API key for weather service"
      units:
        type: string
        title: "Temperature Units"
        description: "Temperature unit preference"
        default: "celsius"
        enum: ["celsius", "fahrenheit", "kelvin"]
      maxResults:
        type: integer
        title: "Max Results"
        description: "Maximum number of forecast days"
        default: 5
        minimum: 1
        maximum: 14
The configSchema supports all standard JSON Schema features:
  • Data types (string, number, boolean, etc.)
  • Required fields and default values
  • Min/max constraints and enums
  • Descriptive titles and documentation
Key Points:
  • Manual schema definition required in smithery.yaml
  • Must use runtime: "container" deployment mode
  • Full control over Docker environment and dependencies

Well-Known Endpoint Approach

External MCPs or custom containers can enable configuration forms by exposing a JSON Schema at a well-known endpoint.
The Smithery CLI approaches above also provide a /.well-known/mcp-config endpoint - it’s simply automatically generated for you based on your schema definitions.

1. Create the Schema Endpoint

Your server must expose a JSON Schema at:
https://your-server.com/.well-known/mcp-config

2. Schema Structure

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://your-server.com/.well-known/mcp-config",
  "title": "MCP Session Configuration",
  "description": "Configuration for connecting to this MCP server",
  "x-query-style": "dot+bracket",
  "type": "object",
  "properties": {
    "apiKey": {
      "type": "string",
      "title": "API Key",
      "description": "Your service API key for authentication"
    },
    "model": {
      "type": "object",
      "title": "Model Settings",
      "properties": {
        "name": {
          "type": "string",
          "title": "Model Name",
          "default": "gpt-4",
          "enum": ["gpt-4", "gpt-3.5-turbo", "claude-3"]
        },
        "temperature": {
          "type": "number",
          "title": "Temperature",
          "default": 0.7,
          "minimum": 0,
          "maximum": 2
        }
      }
    }
  },
  "required": ["apiKey"],
  "additionalProperties": false
}
Key Schema Properties:
  • $schema: Must reference JSON Schema Draft 07
  • $id: Your schema’s canonical URL
  • x-query-style: How parameters are formatted (use “dot+bracket”)
  • properties: Define your configuration fields
  • required: List mandatory fields

Using Configuration in Your Server

Smithery CLI: Automatic Injection

  • TypeScript
  • Python
Configuration is automatically injected into your createServer function:
export default function createServer({ config }: { config: z.infer<typeof configSchema> }) {
  // config is already parsed and validated
  console.log(config.apiKey); // Direct access to config values
}

Custom Container & Well-Known Endpoint: Manual Parsing

Your MCP server receives configuration as URL parameters using dot notation:
GET /mcp?apiKey=your-key&units=celsius&maxResults=5

Using Smithery Libraries

  • TypeScript
  • Python
npm install @smithery/sdk
import { parseAndValidateConfig } from "@smithery/sdk";
import { z } from "zod";

const configSchema = z.object({
  apiKey: z.string(),
  units: z.string().default("celsius"),
  maxResults: z.number().default(5)
});

// In your Express handler
app.get('/mcp', (req, res) => {
  const result = parseAndValidateConfig(req, configSchema);
  if (result.error) {
    return res.status(result.value.status).json(result.value);
  }
  const config = result.value; // Parsed and validated
});

Manual Parsing

If not using our libraries, you’ll need to parse dot notation parameters manually by:
  1. Splitting parameter names by . to handle nested objects
  2. Parsing JSON values to handle booleans and numbers
  3. Skipping reserved parameters (api_key, profile)

Best Practices

  • Use descriptive titles and descriptions - These become form labels and help text
  • Set appropriate defaults - Make configuration as simple as possible
  • Use enums for fixed options - This creates dropdown menus
  • Group related settings - Use nested objects for logical grouping
  • Keep required fields minimal - Only require what’s absolutely necessary
  • Never log sensitive values - Treat API keys and tokens as secrets
  • Validate server-side - Always validate input even though Smithery validates too
  • Use HTTPS - Always serve your schema and MCP endpoint over HTTPS
  • Handle secrets securely - Never expose sensitive configuration values
  • Handle parsing errors gracefully - Invalid configuration shouldn’t crash your server
  • Use proper constraints - Set min/max values, required fields, and data types appropriately
Smithery CLI:
  • Use descriptive Zod/Pydantic field descriptions (these become UI help text)
  • Leverage schema validation features (.min(), .max(), .email() etc.)
  • Make frequently-used settings optional with defaults
Custom Container & Well-Known:
  • Follow JSON Schema standards for proper type definitions
  • Test your schema to ensure it generates the expected UI
  • Handle dot notation parsing and JSON type conversion gracefully

Testing Your Configuration

  1. Validate your schema - Use online JSON Schema validators for custom schemas
  2. Test the endpoint - For Well-Known approach, ensure /.well-known/mcp-config is accessible
  3. Verify parsing - Test with sample configurations to ensure correct parsing
  4. Check the UI - Confirm the generated form matches your expectations

Troubleshooting

Configuration not detected?
  • TypeScript: Export configSchema from the same file as your createServer function
  • Python: Use the @smithery.server(config_schema=YourSchema) decorator
  • Check that your schema is a valid Zod object or Pydantic BaseModel
Type errors in TypeScript?
  • Make sure your createServer function accepts { config } parameter
  • Use z.infer<typeof configSchema> for the config type
Python context issues?
  • Ensure you’re using ctx: Context parameter in your tool functions
  • Access config via ctx.session_config, not directly
Configuration not parsing?
  • Verify your server correctly parses dot notation parameters
  • For schema issues, ensure valid JSON Schema syntax
  • Check that /.well-known/mcp-config returns valid JSON (Well-Known approach)
  • Test with a simple configuration first
Schema not generating UI?
  • Ensure your schema has valid JSON Schema syntax
  • Test your schema with an online JSON Schema validator
  • Check that required fields are properly specified
Can I change configuration mid-session? No, configurations are bound at connection time. Establish a new connection for different settings.Can configurations be optional? Yes, in all approaches:
  • Smithery CLI: Use optional Zod/Pydantic fields with .optional() or default values
  • Custom Container & Well-Known: Don’t include fields in the required array, provide default values
Where can I find a server’s configuration schema? View any MCP server’s configuration schema in its API Tab on the server page.

See Also

I