@rui.branco/revit-mcp 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -3,31 +3,34 @@
|
|
|
3
3
|
[](https://www.autodesk.com/products/revit/overview)
|
|
4
4
|
[](#installation)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
|
-
[](#development)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
9
|
**Drive Autodesk Revit from Claude.** Query the model open on your desktop, edit
|
|
10
10
|
it, and produce a full drawing set in plain language — levels and elements,
|
|
11
11
|
sheets and schedules, views and PDF exports.
|
|
12
12
|
|
|
13
|
-
**Windows · Revit 2025, 2026 or 2027
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
**Windows · Revit 2025, 2026 or 2027 · Node.js 18+.** The Revit add-in ships
|
|
14
|
+
precompiled and installs itself on first run — nothing to build, no .NET SDK,
|
|
15
|
+
and nothing to copy by hand.
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
19
19
|
### 1. Register the server
|
|
20
20
|
|
|
21
|
-
Same plugin either way
|
|
21
|
+
Same plugin either way, but the two apps add it differently.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
> It has to be the **Windows machine Revit runs on**. The server reaches Revit
|
|
24
|
+
> through a listener bound to `127.0.0.1`, so a cloud session or another
|
|
25
|
+
> computer cannot see it.
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
/plugin marketplace add rui-branco/revit-mcp
|
|
27
|
-
/plugin install revit@revit-tools
|
|
28
|
-
```
|
|
27
|
+
**Claude Desktop** — through Settings, not the chat box:
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
1. **Settings → Plugins → Add ▾ → Add marketplace → Add from a repository**
|
|
30
|
+
2. Enter `rui-branco/revit-mcp`
|
|
31
|
+
3. Install **revit** from the marketplace that appears
|
|
32
|
+
|
|
33
|
+
**Claude Code** — slash commands in the CLI:
|
|
31
34
|
|
|
32
35
|
```
|
|
33
36
|
/plugin marketplace add rui-branco/revit-mcp
|
|
@@ -45,8 +48,8 @@ claude plugin install revit@revit-tools
|
|
|
45
48
|
</details>
|
|
46
49
|
|
|
47
50
|
That is the whole step. The plugin updates itself from this repo, so there is
|
|
48
|
-
nothing to re-download when a new version ships;
|
|
49
|
-
early if you do not want to wait.
|
|
51
|
+
nothing to re-download when a new version ships; in Claude Code,
|
|
52
|
+
`/plugin update` pulls it early if you do not want to wait.
|
|
50
53
|
|
|
51
54
|
<details>
|
|
52
55
|
<summary><b>Other ways to install</b></summary>
|
|
@@ -93,12 +96,22 @@ arguments and needs no environment beyond the optional
|
|
|
93
96
|
|
|
94
97
|
</details>
|
|
95
98
|
|
|
96
|
-
### 2. Install the Revit add-in
|
|
99
|
+
### 2. Install the Revit add-in — automatic
|
|
100
|
+
|
|
101
|
+
Nothing to do. The server installs the add-in itself the first time it starts:
|
|
102
|
+
it looks for `RevitMcpBridge.addin` in
|
|
103
|
+
`%APPDATA%\Autodesk\Revit\Addins\<version>\` and, when no Revit has it, copies
|
|
104
|
+
the bundled add-in and its manifest into place for every Revit it finds. That
|
|
105
|
+
runs in the background on Windows, so it never delays or breaks the server, and
|
|
106
|
+
once the add-in is there it does nothing at all.
|
|
107
|
+
|
|
108
|
+
**If it is turned off or fails**, ask Claude to **install the Revit bridge**.
|
|
109
|
+
That runs `revit_install_bridge` — the same installer, on demand. Revit need not
|
|
110
|
+
be running, and re-running is safe. Auto-install is off whenever
|
|
111
|
+
`REVIT_MCP_NO_AUTO_INSTALL` is set; see [Configuration](#configuration).
|
|
97
112
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
`%APPDATA%\Autodesk\Revit\Addins\<version>\` for every Revit it finds. Revit
|
|
101
|
-
need not be running, and re-running is safe.
|
|
113
|
+
Either way the add-in is only on disk at this point. Revit does not load it
|
|
114
|
+
until it restarts, which is step 3.
|
|
102
115
|
|
|
103
116
|
### 3. Restart Revit and approve the add-in
|
|
104
117
|
|
|
@@ -408,6 +421,7 @@ Two habits worth keeping:
|
|
|
408
421
|
| `REVIT_MCP_URL` | `http://localhost:48884/revit-mcp` | Bridge base URL. Change it for a second Revit instance. |
|
|
409
422
|
| `REVIT_MCP_TIMEOUT` | `30000` | Per-request timeout, in milliseconds. |
|
|
410
423
|
| `REVIT_MCP_BRIDGE_TIMEOUT_MS` | `30000` | Read by the add-in: how long a request waits for Revit's main thread. Clamped to 1–600 s. |
|
|
424
|
+
| `REVIT_MCP_NO_AUTO_INSTALL` | unset | Set it to `1` to stop the server installing the add-in on startup. `revit_install_bridge` still installs it on demand. Either way, Revit must be restarted before it loads. |
|
|
411
425
|
|
|
412
426
|
## Unattended operation
|
|
413
427
|
|
|
@@ -484,7 +498,7 @@ npm install
|
|
|
484
498
|
npm test
|
|
485
499
|
```
|
|
486
500
|
|
|
487
|
-
`npm test` is `node --test` over `tests/` —
|
|
501
|
+
`npm test` is `node --test` over `tests/` — 521 tests. It touches no Revit and
|
|
488
502
|
opens no socket: the HTTP layer is stubbed and the tools are exercised through a
|
|
489
503
|
real MCP client over an in-memory transport.
|
|
490
504
|
|
package/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
|
+
import { autoInstallBridge } from "./lib/auto-install.js";
|
|
6
7
|
import { createBridge } from "./lib/bridge.js";
|
|
7
8
|
import { registerReadTools } from "./lib/tools/read.js";
|
|
8
9
|
import { registerWriteTools } from "./lib/tools/write.js";
|
|
@@ -111,6 +112,11 @@ async function main() {
|
|
|
111
112
|
const transport = new StdioServerTransport();
|
|
112
113
|
await server.connect(transport);
|
|
113
114
|
|
|
115
|
+
// Never awaited: the transport is already up, and a slow or failing install
|
|
116
|
+
// must not delay the handshake or stop the server from serving tool calls.
|
|
117
|
+
// It is startup only, so it stays out of createRevitServer().
|
|
118
|
+
autoInstallBridge();
|
|
119
|
+
|
|
114
120
|
process.stderr.write("Revit MCP server running on stdio\n");
|
|
115
121
|
}
|
|
116
122
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Installing the bridge add-in without being asked.
|
|
2
|
+
//
|
|
3
|
+
// The add-in already ships inside this package, so a new user should not have
|
|
4
|
+
// to ask for it to be copied into place: on startup, when no Revit has the
|
|
5
|
+
// manifest, we run the very installer revit_install_bridge runs.
|
|
6
|
+
//
|
|
7
|
+
// Two rules shape everything here. Nothing is awaited and every failure is
|
|
8
|
+
// swallowed — the MCP handshake must never wait on this, and a machine with no
|
|
9
|
+
// Revit on it is not an error. And stdout belongs to the JSON-RPC channel, so
|
|
10
|
+
// every byte written from here goes to stderr instead.
|
|
11
|
+
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { runInstaller } from "./tools/install.js";
|
|
15
|
+
|
|
16
|
+
// Set it to anything to never auto-install; revit_install_bridge still works.
|
|
17
|
+
export const OPT_OUT_ENV = "REVIT_MCP_NO_AUTO_INSTALL";
|
|
18
|
+
|
|
19
|
+
// Where install.ps1 puts the manifest, and what it calls it. Revit 2024 and
|
|
20
|
+
// earlier load add-ins on .NET Framework 4.8 and the installer refuses them, so
|
|
21
|
+
// a manifest under one of those years is not this add-in installed.
|
|
22
|
+
const MANIFEST_FILE = "RevitMcpBridge.addin";
|
|
23
|
+
const MINIMUM_REVIT_YEAR = 2025;
|
|
24
|
+
|
|
25
|
+
export function isInstalled({ env = process.env, fsImpl = fs } = {}) {
|
|
26
|
+
if (!env.APPDATA) return false;
|
|
27
|
+
|
|
28
|
+
const root = path.join(env.APPDATA, "Autodesk", "Revit", "Addins");
|
|
29
|
+
let years;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
years = fsImpl.readdirSync(root);
|
|
33
|
+
} catch {
|
|
34
|
+
// No add-ins folder at all, so nothing is installed.
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return years.some(
|
|
39
|
+
(year) =>
|
|
40
|
+
/^\d{4}$/.test(year) &&
|
|
41
|
+
Number(year) >= MINIMUM_REVIT_YEAR &&
|
|
42
|
+
fsImpl.existsSync(path.join(root, year, MANIFEST_FILE)),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function install(options, write) {
|
|
47
|
+
try {
|
|
48
|
+
const result = await runInstaller({}, options);
|
|
49
|
+
|
|
50
|
+
if (result.ok) {
|
|
51
|
+
write(
|
|
52
|
+
"revit-mcp: installed the Revit bridge add-in. RESTART REVIT to load it — Revit only scans the Addins folder at startup.\n",
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
write(
|
|
58
|
+
`revit-mcp: could not install the Revit bridge add-in automatically. ${result.explanation || result.message} Run revit_install_bridge to see the full result, or set ${OPT_OUT_ENV}=1 to stop trying.\n`,
|
|
59
|
+
);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
write(
|
|
62
|
+
`revit-mcp: could not install the Revit bridge add-in automatically: ${error.message} Set ${OPT_OUT_ENV}=1 to stop trying.\n`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Returns as soon as it has decided what to do. The install itself is
|
|
68
|
+
// deliberately left running: its promise is never handed back, so no caller can
|
|
69
|
+
// accidentally wait on it, and nothing it does can fail the server's startup.
|
|
70
|
+
export function autoInstallBridge(options = {}) {
|
|
71
|
+
const {
|
|
72
|
+
env = process.env,
|
|
73
|
+
platform = process.platform,
|
|
74
|
+
write = (line) => process.stderr.write(line),
|
|
75
|
+
} = options;
|
|
76
|
+
|
|
77
|
+
if (platform !== "win32") return "not-windows";
|
|
78
|
+
if (env[OPT_OUT_ENV]) return "opted-out";
|
|
79
|
+
if (isInstalled(options)) return "already-installed";
|
|
80
|
+
|
|
81
|
+
install(options, write);
|
|
82
|
+
return "started";
|
|
83
|
+
}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|