Skip to content

Server Configuration

Configure how agents connect to MCP servers using StdioServerSpec for local servers and HTTPServerSpec for remote ones.

Quick Example

from promptise.config import StdioServerSpec

servers = {
    "math": StdioServerSpec(
        command="python",
        args=["-m", "math_server"],
    ),
}
from promptise.config import HTTPServerSpec

servers = {
    "api": HTTPServerSpec(
        url="http://localhost:8000/mcp",
        bearer_token="eyJhbGciOiJIUzI1NiIs...",
    ),
}

Concepts

Every Promptise agent receives a servers dict that maps a human-readable name to a server specification. The agent connects to each server at startup, discovers its tools, and makes them available to the LLM.

There are two spec types:

  • StdioServerSpec -- launches a local process and communicates over stdin/stdout. Best for local development and bundled servers.
  • HTTPServerSpec -- connects to a remote server over HTTP, Streamable HTTP, or SSE. Best for production deployments and shared services.

Both are Pydantic models with strict validation (extra="forbid"), so typos in field names are caught immediately.

StdioServerSpec

Use StdioServerSpec when the MCP server is a local process that the agent should launch and manage.

from promptise.config import StdioServerSpec

spec = StdioServerSpec(
    command="python",
    args=["-m", "mypackage.server", "--port", "0"],
    env={"API_KEY": "sk-..."},
    cwd="/path/to/project",
    keep_alive=True,
)

Fields

Field Type Default Description
command str required Executable to launch (e.g. "python", "node", "npx").
args list[str] [] Positional arguments for the process.
env dict[str, str] {} Environment variables set for the child process.
cwd str \| None None Working directory for the process.
keep_alive bool True Whether the client should maintain a persistent session.

Examples

StdioServerSpec(
    command="python",
    args=["-m", "my_mcp_server"],
    env={"DATABASE_URL": "sqlite:///data.db"},
)
StdioServerSpec(
    command="npx",
    args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp/data"],
)
StdioServerSpec(
    command="/usr/local/bin/my-server",
    args=["--verbose"],
    cwd="/opt/servers",
)

HTTPServerSpec

Use HTTPServerSpec for remote MCP servers accessible over the network. Supports three transport protocols and multiple authentication methods.

from promptise.config import HTTPServerSpec

spec = HTTPServerSpec(
    url="https://mcp.example.com/mcp",
    transport="streamable-http",
    bearer_token="eyJhbGciOiJIUzI1NiIs...",
)

Fields

Field Type Default Description
url str required Full endpoint URL (e.g. "http://127.0.0.1:8080/mcp").
transport "http" \| "streamable-http" \| "sse" "http" Transport protocol.
headers dict[str, str] {} Extra HTTP headers sent on every request.
bearer_token str \| None None Pre-issued Bearer token. Automatically injected as Authorization: Bearer <token>.
api_key str \| None None Pre-shared API key. Automatically injected as x-api-key: <key>.
auth str \| None None Legacy auth hint (kept for backward compatibility).

Transport Protocols

Transport When to Use
"http" Default. Standard HTTP request/response. Works everywhere.
"streamable-http" Streaming HTTP for long-running tool calls that return incremental results.
"sse" Server-Sent Events. Useful when your server already exposes an SSE endpoint.

Authentication

HTTPServerSpec supports three authentication approaches. Use whichever matches your server's requirements.

HTTPServerSpec(
    url="http://localhost:8080/mcp",
    bearer_token="eyJhbGciOiJIUzI1NiIs...",
)
# Sends: Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
HTTPServerSpec(
    url="http://localhost:8080/mcp",
    api_key="my-secret-key",
)
# Sends: x-api-key: my-secret-key
HTTPServerSpec(
    url="http://localhost:8080/mcp",
    headers={
        "Authorization": "Bearer <token>",
        "X-Custom-Header": "value",
    },
)

Token source

Tokens should be obtained from your Identity Provider (Auth0, Keycloak, Okta, etc.) or from the MCP server's built-in token endpoint. The agent never generates tokens itself.

Combining Multiple Servers

An agent can connect to any number of servers simultaneously. Each server's tools are discovered independently and merged into a single toolset.

from promptise import build_agent
from promptise.config import StdioServerSpec, HTTPServerSpec

agent = await build_agent(
    servers={
        "filesystem": StdioServerSpec(
            command="npx",
            args=["-y", "@modelcontextprotocol/server-filesystem", "/data"],
        ),
        "database": HTTPServerSpec(
            url="http://localhost:9000/mcp",
            api_key="db-secret",
        ),
        "search": HTTPServerSpec(
            url="https://search.example.com/mcp",
            transport="streamable-http",
            bearer_token="eyJ...",
        ),
    },
    model="openai:gpt-5-mini",
)

Tools from all three servers are available to the agent as a flat list. If two servers expose a tool with the same name, both are included -- the LLM decides which to call based on their descriptions.

API Summary

Symbol Import Description
StdioServerSpec from promptise.config import StdioServerSpec Local process server launched via stdin/stdout.
HTTPServerSpec from promptise.config import HTTPServerSpec Remote server over HTTP, Streamable HTTP, or SSE.
ServerSpec from promptise.config import ServerSpec Union type: StdioServerSpec \| HTTPServerSpec.

Validation catches typos

Both specs use extra="forbid" in their Pydantic config. Passing an unknown field like commnad instead of command raises a validation error immediately rather than silently ignoring it.

Empty servers dict

Passing servers={} is valid but the agent will have no MCP tools. This is useful when you rely solely on extra_tools or cross_agents, but if unintentional, double-check your configuration.

What's Next?