Understanding the 2-Minute Command Timeout in revit-mcp
The revit-mcp server enforces a hard-coded 2-minute (120,000ms) timeout on all commands sent to Revit via TCP socket, automatically rejecting the promise with an error if the Revit client fails to respond within this window.
The revit-mcp repository provides a Model Context Protocol (MCP) server that bridges AI assistants with Autodesk Revit through TCP socket communication. Understanding the 2-minute command timeout in revit-mcp is critical for preventing indefinite hangs when Revit becomes unresponsive during complex operations like large model exports or geometry calculations.
How the 2-Minute Command Timeout Works in revit-mcp
When you invoke RevitClientConnection.sendCommand in src/utils/SocketClient.ts, the client writes the JSON-RPC command to the TCP socket and registers a response callback. Immediately after sending, it initializes a setTimeout timer set to 120,000 milliseconds (2 minutes).
If the Revit side processes the command and returns a JSON-RPC response within the 2-minute window, the timer is cleared and the promise resolves with the result. However, if the timer fires before a response arrives, the client executes the following logic:
setTimeout(() => {
if (this.responseCallbacks.has(requestId)) {
this.responseCallbacks.delete(requestId);
reject(new Error(`Command timed out after 2 minutes: ${command}`));
}
}, 120000);
This ensures that any call such as client.sendCommand('GetElements') fails explicitly rather than waiting indefinitely for a frozen Revit process.
Locating the Timeout Configuration in the Source Code
The timeout duration is currently hard-coded in the SocketClient.ts file. You will find the setTimeout declaration inside the command-sending method, with the literal value 120000 representing the 2-minute limit.
Key files involved in the timeout mechanism:
src/utils/SocketClient.ts— ImplementsRevitClientConnection.sendCommandand the 120,000mssetTimeoutlogicsrc/utils/ConnectionManager.ts— Handles connection establishment viawithRevitConnectionbefore commands are dispatched
How to Configure the Command Timeout in revit-mcp
Because the timeout is hard-coded, configuring it requires modifying the source code. The recommended approach is to externalize the timeout value into a configuration constant or environment variable.
Making the Timeout Configurable via Environment Variables
First, create or modify a configuration file (e.g., src/config.ts) to read from environment variables:
// src/config.ts
export const COMMAND_TIMEOUT_MS = Number(process.env.COMMAND_TIMEOUT_MS) || 120000;
Next, update src/utils/SocketClient.ts to import and use this constant:
import { COMMAND_TIMEOUT_MS } from "../config.js";
// Inside the sendCommand method:
setTimeout(() => {
if (this.responseCallbacks.has(requestId)) {
this.responseCallbacks.delete(requestId);
reject(
new Error(
`Command timed out after ${COMMAND_TIMEOUT_MS / 60000} minutes: ${command}`
)
);
}
}, COMMAND_TIMEOUT_MS);
After modifying the source, rebuild the package:
npm run build
You can now override the timeout at runtime:
COMMAND_TIMEOUT_MS=300000 node dist/index.js # 5 minutes
Disabling the Timeout (Not Recommended)
To disable the timeout entirely, you can pass 0 to setTimeout, though this risks indefinite hangs if Revit becomes unresponsive:
setTimeout(() => {
if (this.responseCallbacks.has(requestId)) {
this.responseCallbacks.delete(requestId);
reject(new Error(`Command timed out: ${command}`));
}
}, 0); // Disables the timer
Practical Code Examples
Using the Default 2-Minute Timeout
The following example demonstrates standard usage where commands automatically fail after 2 minutes of inactivity:
import { withRevitConnection } from "./utils/ConnectionManager.js";
async function listAllWalls() {
return await withRevitConnection(async (client) => {
// Will reject after 2 minutes if Revit does not answer
const walls = await client.sendCommand("GetAllWalls");
console.log("Walls:", walls);
return walls;
});
}
Extending the Timeout for Heavy Operations
For operations like exporting large models or complex geometry calculations, extend the timeout to 5 minutes using the environment variable approach:
// src/config.ts
export const COMMAND_TIMEOUT_MS = Number(process.env.COMMAND_TIMEOUT_MS) || 300000; // 5 min default
Run your server with the extended timeout:
export COMMAND_TIMEOUT_MS=300000
npm start
Summary
- The 2-minute command timeout in revit-mcp is hard-coded to 120,000ms in
src/utils/SocketClient.tswithin thesendCommandmethod. - When triggered, the timeout rejects the promise with
Command timed out after 2 minutes: <commandName>, preventing indefinite waits. - To configure the timeout, you must modify the source code to replace the literal
120000with a configurable constant (e.g., from an environment variable). - After modifying
SocketClient.ts, rebuild the project to apply changes.
Frequently Asked Questions
What happens when a Revit command exceeds the 2-minute timeout?
When the Revit client fails to return a JSON-RPC response within 120,000ms, the setTimeout callback in src/utils/SocketClient.ts fires, deleting the pending callback and rejecting the promise with the error message Command timed out after 2 minutes: <commandName>. This forces the operation to fail rather than hanging indefinitely.
Can I configure the timeout without modifying the source code?
Currently, no. The timeout value is hard-coded as the literal 120000 in the setTimeout call within src/utils/SocketClient.ts. To change the duration, you must edit this file to use a variable (such as an environment variable or configuration import) and then rebuild the package.
Why is the default timeout set to 2 minutes?
The 2-minute default represents a balance between allowing sufficient time for complex Revit operations (such as geometry calculations or element filtering) while preventing the MCP server from hanging indefinitely if the Revit process becomes unresponsive or the TCP connection stalls. This safeguards server resources and improves error visibility.
Where is the timeout logic implemented in the codebase?
The timeout logic resides in src/utils/SocketClient.ts inside the RevitClientConnection.sendCommand method. Specifically, it uses a setTimeout of 120,000ms that checks this.responseCallbacks for the pending request ID and rejects the promise if the callback remains when the timer fires.
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 →