# Directory Structure
```
├── .gitignore
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── README.zh-CN.md
├── src
│ ├── index.ts
│ ├── revitService.ts
│ ├── revitSocketClient.ts
│ └── types.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
node_modules/
build/
*.log
.env*
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# 🏗️ Revit MCP Server
A Model Context Protocol server for Revit integration, enabling seamless communication between Claude AI and Autodesk Revit.
[English](./README.md) | [中文](./README.zh-CN.md)
## 🎯 Overview
This TypeScript-based MCP server provides a bridge between Claude AI and Revit, allowing direct interaction with Revit models through a WebSocket connection. It implements the Model Context Protocol to enable:
- ⚡ Real-time access to Revit model information
- 🔍 Element querying and filtering
- 👀 View and level management
- 🛡️ Robust error handling with fallback mock data
## ✨ Features
### 🔌 Revit Integration
- 📡 WebSocket-based communication with Revit plugin
- 🔄 Real-time model data access
- 🔁 Graceful fallback to mock data when connection fails
- ⚙️ Configurable connection settings via environment variables
### 🚀 Core Functionalities
- **📊 Model Information**
- Access basic model metadata (name, path, version)
- Get element counts and last modification date
- Real-time model state synchronization
- **🏗️ Element Management**
- Query elements with flexible filtering
- Access element properties and geometry
- Batch element operations
- **🎪 View & Level Control**
- List all available views
- Access level information
- Navigate through model hierarchy
## 💻 Development
### 📋 Prerequisites
- Node.js (v14 or higher)
- npm
- Autodesk Revit (2023 or later)
- Revit WebSocket Plugin (companion plugin)
### 🔧 Installation
Install dependencies:
```bash
npm install
```
Build the server:
```bash
npm run build
```
For development with auto-rebuild:
```bash
npm run watch
```
### ⚙️ Configuration
The server can be configured using environment variables:
```plaintext
REVIT_HOST=127.0.0.1 # Revit plugin WebSocket host
REVIT_PORT=8080 # Revit plugin WebSocket port
```
## 🔗 Integration with Claude Desktop
Add the server configuration to Claude Desktop:
Windows:
```bash
%APPDATA%/Claude/claude_desktop_config.json
```
Configuration format:
```json
{
"mcpServers": {
"revit-mcp-server": {
"command": "D:/path/to/revit-mcp-server/build/index.js"
}
}
}
```
### 🐛 Debugging
For debugging the MCP communication:
1. Use the built-in MCP Inspector:
```bash
npm run inspector
```
2. Monitor WebSocket communication with Revit plugin
3. Check server logs for connection and operation status
## ⚠️ Error Handling
The server implements robust error handling:
- Automatic fallback to mock data when Revit connection fails
- Detailed error logging
- Graceful connection recovery
## 📄 License
MIT License
## 🤝 Contributing
Contributions are welcome! Please feel free to submit pull requests.
## 📬 Contact
If you have any questions or suggestions, feel free to reach out:
- 📧 Email: [email protected]
- 💬 WeChat Account: modian4500
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
"name": "revit-mcp-server",
"version": "0.1.0",
"description": "A Model Context Protocol server",
"private": true,
"type": "module",
"bin": {
"revit-mcp-server": "./build/index.js"
},
"files": [
"build"
],
"scripts": {
"start": "node build/index.js",
"dev": "ts-node src/index.ts",
"build": "tsc",
"watch": "tsc -w"
},
"dependencies": {
"@modelcontextprotocol/sdk": "0.6.0",
"axios": "^1.8.4",
"dotenv": "^16.4.7",
"express": "^5.1.0",
"ws": "^8.18.1"
},
"devDependencies": {
"@types/node": "^20.17.28",
"@types/ws": "^8.18.0",
"typescript": "^5.3.3"
}
}
```
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
```typescript
export interface RevitModelInfo {
name: string;
path: string;
version: string;
elements_count: number;
last_modified: string;
}
export interface RevitElement {
id: string;
category: string;
family: string;
type: string;
name: string;
level: string;
parameters: Record<string, any>;
}
export interface GetElementsArgs {
category?: string;
family?: string;
type?: string;
level?: string;
limit?: number;
}
export interface GetElementInfoArgs {
elementId: string;
getItemPropertyInfo?: boolean;
getItemParameterInfo?: boolean;
}
// 类型守卫,用于验证查询参数
export function isValidElementsArgs(args: any): args is GetElementsArgs {
return (
typeof args === "object" &&
args !== null &&
(args.category === undefined || typeof args.category === "string") &&
(args.family === undefined || typeof args.family === "string") &&
(args.type === undefined || typeof args.type === "string") &&
(args.level === undefined || typeof args.level === "string") &&
(args.limit === undefined || typeof args.limit === "number")
);
}
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
ListToolsRequestSchema,
CallToolRequestSchema,
ErrorCode,
McpError
} from "@modelcontextprotocol/sdk/types.js";
import dotenv from "dotenv";
import { RevitService } from "./revitService.js";
import { isValidElementsArgs } from "./types.js";
dotenv.config();
class RevitMcpServer {
private server: Server;
private revitService: RevitService;
constructor() {
this.server = new Server({
name: "revit-mcp-server",
version: "0.1.0"
}, {
capabilities: {
resources: {},
tools: {}
}
});
this.revitService = new RevitService();
this.setupHandlers();
this.setupErrorHandling();
}
private setupErrorHandling(): void {
this.server.onerror = (error) => {
console.error("[MCP Error]", error);
};
process.on('SIGINT', async () => {
await this.cleanup();
process.exit(0);
});
process.on('SIGTERM', async () => {
await this.cleanup();
process.exit(0);
});
}
private async cleanup(): Promise<void> {
console.error("[RevitMcpServer] 正在关闭服务...");
//await this.revitService.close();
await this.server.close();
console.error("[RevitMcpServer] 服务已关闭");
}
private setupHandlers(): void {
this.setupResourceHandlers();
this.setupToolHandlers();
}
private setupResourceHandlers(): void {
// 保持原有的资源处理程序不变
this.server.setRequestHandler(
ListResourcesRequestSchema,
async () => ({
resources: [{
uri: "revit://current/model-info",
name: "当前 Revit 模型信息",
mimeType: "application/json",
description: "提供当前打开的 Revit 模型的基本信息,包括名称、路径、版本和元素数量"
}]
})
);
this.server.setRequestHandler(
ReadResourceRequestSchema,
async (request) => {
if (request.params.uri !== "revit://current/model-info") {
throw new McpError(
ErrorCode.InvalidRequest,
`未知资源: ${request.params.uri}`
);
}
try {
const modelInfo = await this.revitService.getModelInfo();
//const modelInfo = '';
return {
contents: [{
uri: request.params.uri,
mimeType: "application/json",
text: JSON.stringify(modelInfo, null, 2)
}]
};
} catch (error) {
throw new McpError(
ErrorCode.InternalError,
`Revit API 错误: ${error instanceof Error ? error.message : String(error)}`
);
}
}
);
}
private setupToolHandlers(): void {
this.server.setRequestHandler(
ListToolsRequestSchema,
async () => ({
tools: [{
name: "get_categories",
description: "获取 Revit 模型中的所有类别",
inputSchema: {
type: "object",
properties: {}
}
}, {
name: "get_families",
description: "获取 Revit 模型中的所有族",
inputSchema: {
type: "object",
properties: {
categoryId: {
type: "string",
description: "族类别 ID(可选)"
},
name: {
type: "string",
description: "族名称过滤(可选)"
}
}
}
}, {
name: "get_elements",
description: "获取 Revit 模型中的元素",
inputSchema: {
type: "object",
properties: {
categoryIds: {
type: "array",
description: "需要获取的元素所属类别的Id集合"
},
viewIds: {
type: "array",
description: "需要获取的元素所处的视图的Id集合"
},
levelIds: {
type: "array",
description: "需要获取的元素所处的标高的Id集合"
}
}
}
},
{
name: "get_levels",
description: "获取 Revit 模型中的所有楼层",
inputSchema: {
type: "object",
properties: {}
}
}, {
name: "get_views",
description: "获取 Revit 模型中的所有视图",
inputSchema: {
type: "object",
properties: {}
}
}, {
name: "get_element_info",
description: "获取 Revit 元素的详细信息",
inputSchema: {
type: "object",
properties: {
elementId: {
type: "string",
description: "元素的 ID"
},
getItemPropertyInfo: {
type: "boolean",
description: "是否获取元素属性信息",
default: true
},
getItemParameterInfo: {
type: "boolean",
description: "是否获取元素参数信息",
default: false
}
},
required: ["elementId"]
}
}]
})
);
this.server.setRequestHandler(
CallToolRequestSchema,
async (request) => {
// 获取工具名称
const toolName = request.params.name;
// 将工具名称转换为 camelCase 方法名
const methodName = toolName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
// 检查 RevitService 是否有对应的方法
if (typeof (this.revitService as any)[methodName] !== 'function') {
throw new McpError(
ErrorCode.MethodNotFound,
`未知工具: ${toolName}`
);
}
try {
// 动态调用对应的方法
const result = await (this.revitService as any)[methodName](request.params.arguments || {});
//const result = '';
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}]
};
} catch (error) {
return {
content: [{
type: "text",
text: `Revit API 错误: ${error instanceof Error ? error.message : String(error)}`
}],
isError: true,
}
}
}
);
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
// 以避免干扰在 stdout 上发生的 MCP 通信
console.error("Revit MCP 服务器正在通过 stdio 运行");
}
}
const server = new RevitMcpServer();
server.run().catch(console.error);
```