How to Configure MCP Servers as Plugins in DeepSeek-Reasonix with Startup and Call Timeouts
Set startup_timeout_seconds and call_timeout_seconds in your TOML [[plugins]] array or .mcp.json file to control how long DeepSeek-Reasonix waits during server handshake and individual tool calls.
DeepSeek-Reasonix, from the esengine/DeepSeek-Reasonix repository, treats external Model Context Protocol (MCP) servers as plugins that require careful timeout management to balance responsiveness and long-running operations. When you configure MCP servers as plugins, you can define startup timeouts for the initial handshake sequence and call timeouts for individual tool invocations, with optional per-tool overrides for specialized operations.
Understanding MCP Plugin Timeout Architecture
The timeout system centers on the Spec struct defined in internal/plugin/plugin.go. This structure captures both global defaults and per-plugin overrides that govern how the Reasonix engine communicates with external MCP servers.
The Spec Struct and Timeout Fields
In internal/plugin/plugin.go (lines 71-90), the Spec struct declares two primary timeout fields:
StartupTimeout: Caps the duration for the initialization handshake (initializefollowed bytools/list)CallTimeout: Limits how long any individualtools/callRPC may execute after the server is ready
The struct also includes a ToolTimeouts map (lines 93-96) that assigns custom durations to specific tool names, allowing fine-grained control over long-running operations like video generation.
Global Defaults vs Per-Plugin Overrides
According to docs/SPEC.md (lines 177-182), global defaults apply when a plugin omits explicit timeout values:
- Startup default:
mcp_startup_timeout_seconds = 30 - Call default:
mcp_call_timeout_seconds = 300
When a plugin specifies its own values in the TOML configuration, the internal Spec.startupTimeout() helper selects the per-plugin value if non-zero, otherwise falling back to the global default.
Configuring Startup Timeouts
The startup timeout governs the initial handshake sequence that occurs when the Reasonix engine boots. This process involves sending the initialize request and retrieving the tools/list response from the MCP server.
If the handshake exceeds the configured limit, the engine records a startup failure via RecordFailure, though the server process may continue running in the background. To prevent false positives on slower systems, increase the startup timeout in your configuration:
[[plugins]]
name = "heavy-mcp"
type = "http"
url = "https://api.example.com/mcp"
# Allow 45 seconds for cold-start initialization
startup_timeout_seconds = 45
Configuring Call Timeouts
After the handshake completes successfully, the call timeout limits how long any single tool invocation may run. This prevents hung operations from blocking the Reasonix engine indefinitely.
Set the global default in your main configuration file:
# ~/.reasonix/config.toml or reasonix.toml
mcp_call_timeout_seconds = 300
[[plugins]]
name = "standard-mcp"
type = "stdio"
command = "./server"
Tool-Specific Timeout Overrides
For plugins that expose both fast queries and long-running tasks, the tool_timeout_seconds map (defined in internal/plugin/plugin.go lines 93-96) provides surgical control. When a tool call executes, the adapter merges the per-tool timeout into the RPC context, overriding the global CallTimeout for that specific operation.
[[plugins]]
name = "media-generator"
type = "http"
url = "https://media.example.com/mcp"
call_timeout_seconds = 300
# Give specific tools extra time
tool_timeout_seconds = {
"generate_video" = 1800, # 30 minutes for video generation
"transcribe_audio" = 600, # 10 minutes for transcription
"search_metadata" = 30 # 30 seconds for quick searches
}
Configuration File Formats
DeepSeek-Reasonix supports two methods to configure MCP servers as plugins: the central TOML configuration and project-local JSON files.
TOML Configuration (reasonix.toml)
The primary configuration uses TOML syntax with [[plugins]] array entries. As documented in docs/SPEC.md (lines 549-556) and demonstrated in reasonix.example.toml (lines 49-56), you declare timeouts directly within the plugin table:
# Global defaults applied to all plugins unless overridden
mcp_startup_timeout_seconds = 30
mcp_call_timeout_seconds = 300
[[plugins]]
name = "my-mcp"
type = "http"
url = "https://mcp.myservice.com"
headers = { Authorization = "Bearer ${MY_MCP_TOKEN}" }
# Per-plugin overrides take precedence over globals
startup_timeout_seconds = 45
call_timeout_seconds = 600
# Optional per-tool precision
tool_timeout_seconds = {
"generate_video" = 1800,
"search_index" = 120
}
Project-Local JSON (.mcp.json)
For repository-specific configurations, place a .mcp.json file in the project root. The schema mirrors Claude Code's mcpServers format. When present, Reasonix merges these definitions with the TOML [[plugins]] entries, preferring TOML values when name collisions occur (docs/SPEC.md lines 997-1001).
{
"mcpServers": {
"my-mcp": {
"type": "http",
"url": "https://mcp.myservice.com",
"headers": { "Authorization": "Bearer token" },
"startup_timeout_seconds": 45,
"call_timeout_seconds": 600,
"tool_timeout_seconds": {
"generate_video": 1800
}
}
}
}
How Timeouts Are Enforced at Runtime
Timeout enforcement occurs in internal/plugin/plugin.go through Go's context mechanism. During the start function, the engine creates a callCtx using Spec.startupTimeout() to establish the deadline for the initialization handshake. Similarly, ensureConnectedInBackground constructs a startupCtx with the same timeout value.
When the deadline passes, the RPC returns an error, triggering the failure recording mechanism. For tool calls after initialization, the system applies either the global CallTimeout or the specific value from ToolTimeouts if the tool name matches an entry in the map.
Summary
- Startup timeouts (
startup_timeout_seconds) control the handshake duration (initialize+tools/list) and default to 30 seconds globally - Call timeouts (
call_timeout_seconds) limit individual tool invocations and default to 300 seconds globally - Tool-specific overrides via
tool_timeout_secondsmap allow custom durations for specific tools, stored inSpec.ToolTimeouts - Configuration occurs in TOML (
[[plugins]]tables) or.mcp.jsonfiles, with TOML taking precedence on name collisions - Enforcement happens through context deadlines in
internal/plugin/plugin.go, with theSpec.startupTimeout()helper managing fallback logic
Frequently Asked Questions
What happens if a plugin exceeds the startup timeout?
If the handshake sequence (initialize and tools/list) takes longer than startup_timeout_seconds, the Reasonix engine records a startup failure via RecordFailure and marks the plugin as unavailable. However, the underlying MCP server process may continue running in the background; only the RPC context is cancelled.
Can I set different timeouts for different tools?
Yes. The tool_timeout_seconds configuration map (backed by Spec.ToolTimeouts in internal/plugin/plugin.go) allows you to specify custom durations for individual tools. When a tool call executes, the adapter checks this map and applies the specific timeout if found, otherwise falling back to the plugin's call_timeout_seconds or the global default.
Where are the default timeout values defined?
Default values are documented in docs/SPEC.md (lines 177-182) as mcp_startup_timeout_seconds = 30 and mcp_call_timeout_seconds = 300. These globals apply to any plugin that does not specify explicit timeout values in its configuration table.
Does Reasonix support environment variables in timeout configurations?
Yes. As shown in the TOML examples from docs/SPEC.md and reasonix.example.toml, you can use environment variable syntax such as ${MY_MCP_TOKEN} within configuration values. The engine resolves these variables when loading the configuration, allowing you to externalize sensitive tokens and timeout values without hardcoding them.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →