Skip to content

Commit d851529

Browse files
committed
处理合并
2 parents f3fac7f + fce779f commit d851529

18 files changed

+948
-29
lines changed

README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,111 @@
11
# revit-mcp-plugin
22

3+
[Chinese Version](#简介)
4+
5+
# Introduction
6+
7+
The revit-mcp-plugin allows you to interact with Revit through the MCP protocol using the Claude client.
8+
9+
This project is the Revit client (receives messages, operates Revit) and needs to be used in conjunction with [revit-mcp](https://github.com/revit-mcp/revit-mcp) (provides tools to AI).
10+
11+
## Environment Requirements
12+
* Revit 2019
13+
14+
## Usage Instructions
15+
16+
### Register Plugin
17+
Register the plugin and restart Revit:
18+
19+
```xml
20+
<?xml version="1.0" encoding="utf-8"?>
21+
<RevitAddIns>
22+
<AddIn Type="Application">
23+
<Name>revit-mcp</Name>
24+
<Assembly>revit-mcp-plugin.dll</Assembly>
25+
<FullClassName>revit_mcp_plugin.Core.Application</FullClassName>
26+
<ClientId>090A4C8C-61DC-426D-87DF-E4BAE0F80EC1</ClientId>
27+
<VendorId>revit-mcp</VendorId>
28+
<VendorDescription>https://github.com/revit-mcp/revit-mcp-plugin</VendorDescription>
29+
</AddIn>
30+
</RevitAddIns>
31+
```
32+
33+
### Enable Service
34+
Add-in Modules -> mcp -> Start mcp service listening
35+
36+
### Adding Commands
37+
To add commands, you only need to focus on the Commands directory (specific command implementation) and the Core/SocketService.cs file (command registration).
38+
39+
Each command in the Commands directory is divided into two parts:
40+
* `XXXCommand` is responsible for parsing parameters and triggering event handlers, while also handling timeouts and errors
41+
* `XXXEventHandler` is responsible for the actual operation, using transactions to ensure atomicity
42+
43+
Commands need to be registered in the RegisterCommands method of SocketService before they can be called by the mcp service.
44+
45+
**Process**
46+
1. Create a new feature subdirectory in the `Commands` directory (e.g., `Commands/window/`)
47+
2. Add an event handler (e.g., `CreateWindowEventHandler.cs`), which is based on Revit's external event
48+
3. Add a command class (e.g., `CreateWindowCommand.cs`), which parses information from the mcp server and calls the handler for implementation
49+
4. Register the new command in the `RegisterCommands` method of `SocketService`
50+
51+
## Project File Organization
52+
53+
```
54+
revit_mcp/
55+
├── Core/
56+
│ ├── Application.cs # Application entry point
57+
│ ├── MCPServiceConnection.cs # Revit external command
58+
│ ├── SocketService.cs # Socket service implementation
59+
│ └── JsonRPC/ # JSON-RPC related classes
60+
│ ├── JsonRPCRequest.cs # Request model
61+
│ ├── JsonRPCResponse.cs # Response model
62+
│ ├── JsonRPCErrorCodes.cs # Error code constants
63+
│ └── JsonRPCSerializer.cs # Serialization/deserialization helper
64+
65+
├── Commands/
66+
│ ├── Interfaces/ # Command interfaces
67+
│ │ ├── IRevitCommand.cs # Command interface
68+
│ │ └── IWaitableExternalEventHandler.cs # Event wait handler interface
69+
│ │
70+
│ ├── Base/
71+
│ │ └── ExternalEventCommandBase.cs # External event-based command base class
72+
│ │
73+
│ ├── Registry/
74+
│ │ └── RevitCommandRegistry.cs # Command registration
75+
│ │
76+
│ ├── Wall/ # Wall-related commands
77+
│ │ ├── CreateWallEventHandler.cs # Create wall event handler
78+
│ │ └── CreateWallCommand.cs # Create wall command
79+
│ │
80+
│ └── Code/ # Code execution related commands
81+
│ ├── ExecuteCodeEventHandler.cs # Execute code event handler
82+
│ └── ExecuteCodeCommand.cs # Execute code command
83+
84+
├── Utils/ # Utility classes
85+
86+
└── Models/ # Data models
87+
```
88+
89+
### Core Directory
90+
1. **Application.cs**: Application entry point, responsible for initializing the plugin
91+
2. **MCPServiceConnection.cs**: Revit external command, used to start the service
92+
3. **SocketService.cs**: Socket service implementation, responsible for communicating with external clients
93+
4. **JsonRPC Directory**: Contains classes and implementations related to the JSON-RPC protocol
94+
95+
### Commands Directory
96+
1. **Interfaces Directory**: Command-related interface definitions
97+
2. **Base Directory**: Contains base class implementations for commands
98+
3. **Registry Directory**: Command registration and management
99+
4. **Functional Directories** (Wall, Code, etc.): Contains specific functionality commands and event handlers
100+
101+
### Utils Directory
102+
Contains various utility classes to help handle repeatedly used functionality.
103+
104+
### Models Directory
105+
Contains data model classes used to pass data between different parts of the system.
106+
107+
108+
3109
## 简介
4110

5111
revit-mcp-plugin 允许你使用claude客户端通过 MCP 协议与 Revit 进行交互。

TestConsole/Program.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
4-
using System.Linq;
53
using System.Net.Sockets;
64
using System.Text;
7-
using System.Threading.Tasks;
85
using Newtonsoft.Json;
96
using Newtonsoft.Json.Linq;
107

revit-mcp-plugin/Commands/Access/GetAvailableFamilyTypesEventHandler.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public void Execute(UIApplication app)
6868
{
6969
filteredElements = filteredElements.Where(et =>
7070
{
71-
var categoryId = et.Category?.Id.IntegerValue;
72-
return categoryId != null && validCategoryIds.Contains(categoryId.Value);
71+
var categoryId = et.Category?.Id.Value;
72+
return categoryId != null && validCategoryIds.Contains((int)categoryId.Value);
7373
});
7474
}
7575
}
@@ -108,7 +108,7 @@ public void Execute(UIApplication app)
108108
}
109109
return new FamilyTypeInfo
110110
{
111-
FamilyTypeId = et.Id.IntegerValue,
111+
FamilyTypeId = et.Id.Value,
112112
UniqueId = et.UniqueId,
113113
FamilyName = familyName,
114114
TypeName = et.Name,
@@ -135,7 +135,7 @@ public string GetName()
135135

136136
public class FamilyTypeInfo
137137
{
138-
public int FamilyTypeId { get; set; }
138+
public long FamilyTypeId { get; set; }
139139
public string UniqueId { get; set; }
140140
public string FamilyName { get; set; }
141141
public string TypeName { get; set; }

revit-mcp-plugin/Commands/Access/GetCurrentViewElementsEventHandler.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public void Execute(UIApplication app)
142142
// 构建结果
143143
var elementInfos = elements.Select(e => new ElementInfo
144144
{
145-
Id = e.Id.IntegerValue,
145+
Id = e.Id.Value,
146146
UniqueId = e.UniqueId,
147147
Name = e.Name,
148148
Category = e.Category?.Name ?? "unknow",
@@ -151,7 +151,7 @@ public void Execute(UIApplication app)
151151

152152
ResultInfo = new ViewElementsResult
153153
{
154-
ViewId = activeView.Id.IntegerValue,
154+
ViewId = activeView.Id.Value,
155155
ViewName = activeView.Name,
156156
TotalElementsInView = new FilteredElementCollector(doc, activeView.Id).GetElementCount(),
157157
FilteredElementCount = elementInfos.Count,
@@ -174,7 +174,7 @@ private Dictionary<string, string> GetElementProperties(Element element)
174174
var properties = new Dictionary<string, string>();
175175

176176
// 添加通用属性
177-
properties.Add("ElementId", element.Id.IntegerValue.ToString());
177+
properties.Add("ElementId", element.Id.Value.ToString());
178178

179179
if (element.Location != null)
180180
{
@@ -208,7 +208,7 @@ private Dictionary<string, string> GetElementProperties(Element element)
208208
else if (param.StorageType == StorageType.Integer)
209209
properties.Add(paramName, param.AsInteger().ToString());
210210
else if (param.StorageType == StorageType.ElementId)
211-
properties.Add(paramName, param.AsElementId().IntegerValue.ToString());
211+
properties.Add(paramName, param.AsElementId().Value.ToString());
212212
}
213213
}
214214

@@ -226,7 +226,7 @@ public string GetName()
226226
/// </summary>
227227
public class ElementInfo
228228
{
229-
public int Id { get; set; }
229+
public long Id { get; set; }
230230
public string UniqueId { get; set; }
231231
public string Name { get; set; }
232232
public string Category { get; set; }
@@ -238,7 +238,7 @@ public class ElementInfo
238238
/// </summary>
239239
public class ViewElementsResult
240240
{
241-
public int ViewId { get; set; }
241+
public long ViewId { get; set; }
242242
public string ViewName { get; set; }
243243
public int TotalElementsInView { get; set; }
244244
public int FilteredElementCount { get; set; }

revit-mcp-plugin/Commands/Access/GetCurrentViewInfoEventHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Execute(UIApplication app)
3131

3232
ResultInfo = new ViewInfo
3333
{
34-
Id = activeView.Id.IntegerValue,
34+
Id = activeView.Id.Value,
3535
UniqueId = activeView.UniqueId,
3636
Name = activeView.Name,
3737
ViewType = activeView.ViewType.ToString(),

revit-mcp-plugin/Commands/Access/GetSelectedElementsEventHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void Execute(UIApplication app)
4646
// 转换为ElementInfo列表
4747
ResultElements = selectedElements.Select(element => new ElementInfo
4848
{
49-
Id = element.Id.IntegerValue,
49+
Id = element.Id.Value,
5050
UniqueId = element.UniqueId,
5151
Name = element.Name,
5252
Category = element.Category?.Name
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Autodesk.Revit.UI;
7+
using Newtonsoft.Json.Linq;
8+
using revit_mcp_plugin.Commands.Base;
9+
10+
namespace revit_mcp_plugin.Commands.Create
11+
{
12+
public class ColorSplashCommand : ExternalEventCommandBase
13+
{
14+
private ColorSplashEventHandler _handler => (ColorSplashEventHandler)Handler;
15+
16+
/// <summary>
17+
/// Command name
18+
/// </summary>
19+
public override string CommandName => "color_splash";
20+
21+
/// <summary>
22+
/// Constructor
23+
/// </summary>
24+
/// <param name="uiApp">Revit UIApplication</param>
25+
public ColorSplashCommand(UIApplication uiApp)
26+
: base(new ColorSplashEventHandler(), uiApp)
27+
{
28+
}
29+
30+
public override object Execute(JObject parameters, string requestId)
31+
{
32+
try
33+
{
34+
// Parse parameters
35+
string categoryName = null;
36+
if (parameters["categoryName"] != null)
37+
{
38+
categoryName = parameters["categoryName"].ToString();
39+
}
40+
else
41+
{
42+
throw new ArgumentException("Category name is required");
43+
}
44+
45+
string parameterName = null;
46+
if (parameters["parameterName"] != null)
47+
{
48+
parameterName = parameters["parameterName"].ToString();
49+
}
50+
else
51+
{
52+
throw new ArgumentException("Parameter name is required");
53+
}
54+
55+
bool useGradient = false;
56+
if (parameters["useGradient"] != null)
57+
{
58+
useGradient = parameters["useGradient"].ToObject<bool>();
59+
}
60+
61+
JArray customColors = null;
62+
if (parameters["customColors"] != null)
63+
{
64+
customColors = parameters["customColors"] as JArray;
65+
}
66+
67+
// Set parameters for the event handler
68+
_handler.SetParameters(categoryName, parameterName, useGradient, customColors);
69+
70+
// Trigger external event and wait for completion
71+
if (RaiseAndWaitForCompletion(20000)) // 20 second timeout
72+
{
73+
return _handler.ColoringResults;
74+
}
75+
else
76+
{
77+
throw new TimeoutException("Color splash operation timed out");
78+
}
79+
}
80+
catch (Exception ex)
81+
{
82+
throw new Exception($"Color splash failed: {ex.Message}");
83+
}
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)