JSON-RPC Message Format for Sending Commands to Revit: A Complete Technical Guide

The revit-mcp library uses a standard JSON-RPC 2.0 request object containing jsonrpc, method, params, and id fields, serialized and sent over TCP to execute Revit commands remotely.

When building integrations between MCP (Model Context Protocol) clients and Autodesk Revit, understanding the exact JSON-RPC message format is critical for reliable command execution. The mcp-servers-for-revit/revit-mcp repository implements a strict JSON-RPC 2.0 protocol to marshal commands from TypeScript clients into Revit's native API. This guide breaks down the message structure, construction logic, and practical implementation patterns used in the codebase.

Understanding the JSON-RPC 2.0 Request Structure

The revit-mcp library adheres strictly to the JSON-RPC 2.0 specification when formatting remote procedure calls. Every command sent to Revit must include four mandatory fields to ensure proper routing, execution, and response correlation.

Required Fields in the JSON-RPC Object

Field Type Description
jsonrpc String Fixed version identifier set to "2.0" as required by the specification.
method String The Revit command name to invoke (e.g., "CreateWall", "GetCurrentViewInfo").
params Object or Array Structured arguments required by the specific Revit method. Can be empty for parameterless commands.
id String or Number Unique request identifier generated per call, used to match asynchronous responses to their original requests.

The server-side Revit plugin parses this payload, executes the corresponding API method, and returns a response object containing the matching id and either a result or error field.

How Commands Are Constructed in SocketClient.ts

The actual construction of the JSON-RPC message occurs in src/utils/SocketClient.ts, specifically within the command transmission logic. Lines 103-108 demonstrate the exact object assembly before serialization:

// src/utils/SocketClient.ts (lines 103-108)
const commandObj = {
  jsonrpc: "2.0",          // JSON-RPC version specification
  method: command,         // Revit command name passed as argument
  params: params,          // Command parameters object
  id: requestId,           // Unique identifier for response matching
};

After construction, the library serializes the object using JSON.stringify() and transmits the payload through the TCP socket managed by src/utils/ConnectionManager.ts. The requestId is typically generated as a UUID or incrementing integer to ensure unique correlation for asynchronous operations.

Sending Commands to Revit: Practical Examples

The src/tools/send_code_to_revit.ts file demonstrates real-world usage patterns for the JSON-RPC message format. Below are practical implementations covering parameterless commands, complex structured parameters, and error handling.

Simple Commands Without Parameters

For Revit commands that require no arguments, pass an empty object or omit the params field entirely:

import { SocketClient } from "./utils/SocketClient";

const client = new SocketClient("localhost", 5000);

// GetCurrentViewInfo requires no parameters
client
  .sendCommand("GetCurrentViewInfo")
  .then((result) => {
    console.log("Current view info:", result);
  })
  .catch((err) => console.error("Error:", err));

Complex Commands With Structured Parameters

Commands like CreateWall require structured objects matching Revit's API expectations:

const wallParams = {
  startPoint: { x: 0, y: 0, z: 0 },
  endPoint:   { x: 10, y: 0, z: 0 },
  height:     3,
  typeId:     "WallType-Generic-01",
};

client
  .sendCommand("CreateWall", wallParams)
  .then((wallId) => {
    console.log("Wall created with ID:", wallId);
  })
  .catch((err) => console.error("Failed to create wall:", err));

Handling Error Responses

When Revit encounters an error (invalid element ID, parameter mismatch, etc.), the JSON-RPC response contains an error object rather than a result:

client
  .sendCommand("DeleteElement", { elementId: "invalid-id" })
  .then((res) => console.log("Deleted:", res))
  .catch((e) => {
    // Error object contains code, message, and optional data
    console.error("Revit reported an error:", e.message);
  });

The TCP Transport Layer

While the JSON-RPC format defines the message structure, the transport mechanism relies on src/utils/ConnectionManager.ts to establish and maintain the TCP socket connection to Revit. The SocketClient class depends on this connection manager to write the serialized JSON-RPC messages to the socket stream and to emit responses back to the appropriate request handlers based on the id field.

Summary

  • The revit-mcp library uses strict JSON-RPC 2.0 formatting for all Revit command communication.
  • Every request requires four fields: jsonrpc (version "2.0"), method (command name), params (arguments), and id (unique identifier).
  • Message construction occurs in src/utils/SocketClient.ts (lines 103-108), where the object is serialized and sent via TCP.
  • Responses are matched to requests using the id field and contain either a result or error object.
  • Complex parameters are passed as structured objects matching Revit's API expectations.

Frequently Asked Questions

What version of JSON-RPC does revit-mcp use?

The library implements JSON-RPC 2.0, as indicated by the fixed jsonrpc: "2.0" field in every request object constructed in src/utils/SocketClient.ts. This version supports the structured parameter objects and error handling patterns used throughout the codebase.

How does the request ID mechanism work?

Each command invocation generates a unique request identifier (typically a UUID or incrementing integer) stored in the id field. When the Revit server processes the command and returns a response, it includes this same id value, allowing the SocketClient to match the asynchronous response to the original promise-based request.

What happens if a command fails in Revit?

When Revit encounters an execution error (invalid parameters, missing elements, or API exceptions), the JSON-RPC response contains an error object instead of a result field. This object includes a standardized error code, message string, and optional data payload. The SocketClient parses this and rejects the promise, propagating the error details to the caller's .catch() handler.

Where is the JSON-RPC message actually built in the codebase?

The message construction logic resides in src/utils/SocketClient.ts at lines 103-108. This section creates the JavaScript object literal with the four required JSON-RPC fields, which is then serialized using JSON.stringify() and transmitted through the TCP socket managed by ConnectionManager.ts.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →