revit-bridge 0.1.0__tar.gz

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.
Files changed (44) hide show
  1. revit_bridge-0.1.0/.gitignore +17 -0
  2. revit_bridge-0.1.0/CHANGELOG.md +48 -0
  3. revit_bridge-0.1.0/LICENSE +21 -0
  4. revit_bridge-0.1.0/PKG-INFO +133 -0
  5. revit_bridge-0.1.0/README.md +107 -0
  6. revit_bridge-0.1.0/capabilities/create_beam.yaml +72 -0
  7. revit_bridge-0.1.0/capabilities/create_column.yaml +33 -0
  8. revit_bridge-0.1.0/capabilities/create_column_2.yaml +29 -0
  9. revit_bridge-0.1.0/capabilities/create_floor.yaml +54 -0
  10. revit_bridge-0.1.0/capabilities/create_room.yaml +55 -0
  11. revit_bridge-0.1.0/capabilities/create_structural_column.yaml +43 -0
  12. revit_bridge-0.1.0/capabilities/create_wall.yaml +48 -0
  13. revit_bridge-0.1.0/capabilities/delete_elements_by_category.yaml +36 -0
  14. revit_bridge-0.1.0/capabilities/examples/create_wall_v2.yaml +93 -0
  15. revit_bridge-0.1.0/capabilities/modify_wall_height.yaml +34 -0
  16. revit_bridge-0.1.0/capabilities/query_levels.yaml +25 -0
  17. revit_bridge-0.1.0/capabilities/query_model_stats.yaml +23 -0
  18. revit_bridge-0.1.0/pyproject.toml +64 -0
  19. revit_bridge-0.1.0/revit_bridge/__init__.py +17 -0
  20. revit_bridge-0.1.0/revit_bridge/auth/__init__.py +9 -0
  21. revit_bridge-0.1.0/revit_bridge/auth/tokens.py +113 -0
  22. revit_bridge-0.1.0/revit_bridge/capabilities/__init__.py +16 -0
  23. revit_bridge-0.1.0/revit_bridge/capabilities/store.py +472 -0
  24. revit_bridge-0.1.0/revit_bridge/evidence/__init__.py +4 -0
  25. revit_bridge-0.1.0/revit_bridge/mcp_server.py +363 -0
  26. revit_bridge-0.1.0/revit_bridge/revit/__init__.py +12 -0
  27. revit_bridge-0.1.0/revit_bridge/revit/client.py +259 -0
  28. revit_bridge-0.1.0/revit_bridge/revit/pool.py +61 -0
  29. revit_bridge-0.1.0/revit_bridge/revit/sandbox.py +60 -0
  30. revit_bridge-0.1.0/revit_bridge/revit/settings.py +80 -0
  31. revit_bridge-0.1.0/revit_bridge/snapshot/__init__.py +32 -0
  32. revit_bridge-0.1.0/revit_bridge/snapshot/atoms.py +647 -0
  33. revit_bridge-0.1.0/revit_bridge/snapshot/query.py +244 -0
  34. revit_bridge-0.1.0/revit_bridge/spec/__init__.py +11 -0
  35. revit_bridge-0.1.0/revit_bridge/spec/models.py +96 -0
  36. revit_bridge-0.1.0/revit_bridge/validators/__init__.py +5 -0
  37. revit_bridge-0.1.0/tests/__init__.py +0 -0
  38. revit_bridge-0.1.0/tests/fake_revit.py +91 -0
  39. revit_bridge-0.1.0/tests/test_client.py +139 -0
  40. revit_bridge-0.1.0/tests/test_gate.py +186 -0
  41. revit_bridge-0.1.0/tests/test_package.py +59 -0
  42. revit_bridge-0.1.0/tests/test_query.py +93 -0
  43. revit_bridge-0.1.0/tests/test_store.py +103 -0
  44. revit_bridge-0.1.0/tests/test_tokens.py +78 -0
@@ -0,0 +1,17 @@
1
+ # Secrets never enter this repository
2
+ .env*
3
+ !.env.example
4
+ .secrets/
5
+ *.token
6
+
7
+ # Local Claude Code state
8
+ .claude/settings.local.json
9
+
10
+ # Python
11
+ __pycache__/
12
+ *.py[cod]
13
+ .venv/
14
+ dist/
15
+ build/
16
+ *.egg-info/
17
+ .pytest_cache/
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to `revit-bridge` are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-09-18
10
+
11
+ First release of the standalone package, extracted from the former
12
+ `revit-api-rag` monorepo.
13
+
14
+ ### Added
15
+
16
+ - MCP server `revit-bridge` (stdio) with tools `execute_code`, `solidify_tool`,
17
+ `list_tools`, `get_tool_choices`, `run_tool` and resources `revit://stats`,
18
+ `revit://tools/{name}`, `revit://connection-status`.
19
+ - `spec_confirmed` execution gate on `execute_code` and `run_tool`;
20
+ `REVIT_BRIDGE_ALLOW_UNCONFIRMED=1` lifts it for host-internal flows.
21
+ - `revit-bridge check` subcommand that pings the Revit add-in and exits 0/1.
22
+ - Connection settings from environment variables: `REVIT_BRIDGE_HOST`,
23
+ `REVIT_BRIDGE_PORT`, `REVIT_BRIDGE_TOKEN`, `REVIT_BRIDGE_TIMEOUT`;
24
+ the token is sent with every JSON-RPC request.
25
+ - Eleven built-in capability packs shipped inside the wheel (a reference pack
26
+ lives in `capabilities/examples/`, which the store never reads);
27
+ `REVIT_BRIDGE_CAPABILITIES_DIR` overrides the directory.
28
+ - Slot token helpers (`revit_bridge.auth.tokens`) for the web relay.
29
+ - `RevitQueryExecutor.get_tool_choices(dynamic_params)` resolves a pack's
30
+ `choices_from` sources (`levels`, `family_types:<OST_*>`, `floor_types`,
31
+ `elements:<OST_*>`) and `RevitQueryExecutor.get_project_units()` reads the
32
+ project's length unit. The MCP `get_tool_choices` tool and the web host both
33
+ call these instead of carrying their own Revit snippets.
34
+ - `escape_param_value` in `revit_bridge.capabilities`: `ToolStore.render_code`
35
+ escapes quotes, backslashes and newlines in string parameters so a value
36
+ cannot terminate the C# string literal it is rendered into.
37
+ - Claude Code plugin in `plugin/` (skill `revit-bridge` with pattern, workflow and
38
+ standards references, `.mcp.json`, PreToolUse spec gate hook) and the
39
+ marketplace manifest `.claude-plugin/marketplace.json`.
40
+ - Test suite with a fake Revit TCP server; CI and PyPI trusted publishing workflows.
41
+
42
+ ### Removed (compared with the monorepo server)
43
+
44
+ - RAG tools `search_revit_api`, `get_code_examples`, `generate_code` and every
45
+ model / vector-store dependency. Hosts bring their own model.
46
+
47
+ [Unreleased]: https://github.com/revitbridge/revit-bridge/compare/v0.1.0...HEAD
48
+ [0.1.0]: https://github.com/revitbridge/revit-bridge/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 revitbridge
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.5
2
+ Name: revit-bridge
3
+ Version: 0.1.0
4
+ Summary: Intent bridge between designers and AI for Revit: MCP server + Claude Code plugin
5
+ Project-URL: Homepage, https://github.com/revitbridge/revit-bridge
6
+ Project-URL: Issues, https://github.com/revitbridge/revit-bridge/issues
7
+ Project-URL: Changelog, https://github.com/revitbridge/revit-bridge/blob/main/CHANGELOG.md
8
+ Author: revitbridge
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: bim,claude-code,mcp,revit
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: mcp<3,>=2
22
+ Requires-Dist: pydantic>=2
23
+ Requires-Dist: pyyaml>=6
24
+ Requires-Dist: websockets>=12
25
+ Description-Content-Type: text/markdown
26
+
27
+ # revit-bridge
28
+
29
+ Intent bridge between designers and AI for Autodesk Revit: an MCP server that
30
+ executes code in a running Revit, keeps a library of reusable capability
31
+ packs, and refuses to run anything the designer has not confirmed.
32
+
33
+ The package contains no model SDK, no vector store and no web framework. Your
34
+ MCP host (Claude Desktop, Claude Code, any MCP client) brings the model; the
35
+ [revit-bridge-addin](https://github.com/revitbridge/revit-bridge-addin) inside
36
+ Revit executes the code.
37
+
38
+ ## Install
39
+
40
+ Prerequisites: Python 3.11+ with [`uv`](https://docs.astral.sh/uv/) (for `uvx`),
41
+ Revit 2026 with the add-in installed and its local TCP listener on (default
42
+ `127.0.0.1:18080`).
43
+
44
+ **Claude Desktop** — `claude_desktop_config.json`:
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "revit-bridge": {
50
+ "command": "uvx",
51
+ "args": ["revit-bridge"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ **Claude Code** - the plugin (skill + MCP server + confirmation hook, recommended):
58
+
59
+ ```
60
+ /plugin marketplace add revitbridge/revit-bridge
61
+ /plugin install revit-bridge@revit-bridge
62
+ ```
63
+
64
+ The plugin's `.mcp.json` starts the server with `uvx`; its `hooks/hooks.json`
65
+ denies `execute_code` / `run_tool` calls that lack `spec_confirmed=true`
66
+ (`uv run` executes `plugin/hooks/spec_gate.py`, so `uv` must be on PATH). The
67
+ skill is also installable on its own with
68
+ `npx skills add revitbridge/revit-bridge`.
69
+
70
+ MCP server only, without the skill and hook:
71
+
72
+ ```bash
73
+ claude mcp add revit-bridge -- uvx revit-bridge
74
+ ```
75
+
76
+ **Any MCP client** — run `uvx revit-bridge` as a stdio server. Pass connection
77
+ settings through environment variables (see Configure), for example in the
78
+ `env` block of the host's server entry.
79
+
80
+ From a checkout: `uv sync` then `uv run revit-bridge`.
81
+
82
+ ## Use
83
+
84
+ 1. Start Revit, open a project and make sure the add-in is listening.
85
+ 2. Check the connection:
86
+
87
+ ```bash
88
+ uvx revit-bridge check
89
+ ```
90
+
91
+ Prints host, port, whether a token is set and `"status": "connected"`; the
92
+ exit code is 0 when Revit answered, 1 otherwise.
93
+
94
+ 3. In your host, work in three steps:
95
+
96
+ - `list_tools` — see the capability packs (`create_wall`, `query_levels`, …).
97
+ - `get_tool_choices` with a tool name — Revit returns the real levels,
98
+ family types or elements for that tool's dynamic parameters.
99
+ - `run_tool` with the chosen values and `spec_confirmed=true`.
100
+
101
+ `execute_code` takes arbitrary C# for tasks no pack covers. The code runs
102
+ inside Revit with `document` in scope and a transaction already open; end it
103
+ with `return <object>;`. `solidify_tool` saves code that worked as a new pack.
104
+
105
+ **Confirmation gate.** `execute_code` and `run_tool` default to
106
+ `spec_confirmed=false` and return `refused_unconfirmed_spec` until the host has
107
+ shown the designer every parameter with its source and received confirmation.
108
+ Hosts that run their own confirmation flow can set
109
+ `REVIT_BRIDGE_ALLOW_UNCONFIRMED=1`.
110
+
111
+ Resources: `revit://stats`, `revit://tools/{name}`, `revit://connection-status`.
112
+
113
+ ## Configure
114
+
115
+ | Variable | Default | Meaning |
116
+ |---|---|---|
117
+ | `REVIT_BRIDGE_HOST` | `127.0.0.1` | Host where the add-in listens |
118
+ | `REVIT_BRIDGE_PORT` | `18080` | TCP port of the add-in |
119
+ | `REVIT_BRIDGE_TOKEN` | *(unset)* | Pre-shared token, sent with every request when the add-in has one configured |
120
+ | `REVIT_BRIDGE_TIMEOUT` | `60` | Seconds to wait for a command to finish |
121
+ | `REVIT_BRIDGE_ALLOW_UNCONFIRMED` | *(unset)* | `1` lifts the `spec_confirmed` gate (host-internal flows only) |
122
+ | `REVIT_BRIDGE_CAPABILITIES_DIR` | packaged packs | Directory of capability YAML files; new `solidify_tool` packs are written here |
123
+
124
+ Development:
125
+
126
+ ```bash
127
+ uv sync
128
+ uv run pytest
129
+ uv build
130
+ uvx --from . revit-bridge check
131
+ ```
132
+
133
+ License: MIT. Issues and discussion: <https://github.com/revitbridge/revit-bridge/issues>.
@@ -0,0 +1,107 @@
1
+ # revit-bridge
2
+
3
+ Intent bridge between designers and AI for Autodesk Revit: an MCP server that
4
+ executes code in a running Revit, keeps a library of reusable capability
5
+ packs, and refuses to run anything the designer has not confirmed.
6
+
7
+ The package contains no model SDK, no vector store and no web framework. Your
8
+ MCP host (Claude Desktop, Claude Code, any MCP client) brings the model; the
9
+ [revit-bridge-addin](https://github.com/revitbridge/revit-bridge-addin) inside
10
+ Revit executes the code.
11
+
12
+ ## Install
13
+
14
+ Prerequisites: Python 3.11+ with [`uv`](https://docs.astral.sh/uv/) (for `uvx`),
15
+ Revit 2026 with the add-in installed and its local TCP listener on (default
16
+ `127.0.0.1:18080`).
17
+
18
+ **Claude Desktop** — `claude_desktop_config.json`:
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "revit-bridge": {
24
+ "command": "uvx",
25
+ "args": ["revit-bridge"]
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ **Claude Code** - the plugin (skill + MCP server + confirmation hook, recommended):
32
+
33
+ ```
34
+ /plugin marketplace add revitbridge/revit-bridge
35
+ /plugin install revit-bridge@revit-bridge
36
+ ```
37
+
38
+ The plugin's `.mcp.json` starts the server with `uvx`; its `hooks/hooks.json`
39
+ denies `execute_code` / `run_tool` calls that lack `spec_confirmed=true`
40
+ (`uv run` executes `plugin/hooks/spec_gate.py`, so `uv` must be on PATH). The
41
+ skill is also installable on its own with
42
+ `npx skills add revitbridge/revit-bridge`.
43
+
44
+ MCP server only, without the skill and hook:
45
+
46
+ ```bash
47
+ claude mcp add revit-bridge -- uvx revit-bridge
48
+ ```
49
+
50
+ **Any MCP client** — run `uvx revit-bridge` as a stdio server. Pass connection
51
+ settings through environment variables (see Configure), for example in the
52
+ `env` block of the host's server entry.
53
+
54
+ From a checkout: `uv sync` then `uv run revit-bridge`.
55
+
56
+ ## Use
57
+
58
+ 1. Start Revit, open a project and make sure the add-in is listening.
59
+ 2. Check the connection:
60
+
61
+ ```bash
62
+ uvx revit-bridge check
63
+ ```
64
+
65
+ Prints host, port, whether a token is set and `"status": "connected"`; the
66
+ exit code is 0 when Revit answered, 1 otherwise.
67
+
68
+ 3. In your host, work in three steps:
69
+
70
+ - `list_tools` — see the capability packs (`create_wall`, `query_levels`, …).
71
+ - `get_tool_choices` with a tool name — Revit returns the real levels,
72
+ family types or elements for that tool's dynamic parameters.
73
+ - `run_tool` with the chosen values and `spec_confirmed=true`.
74
+
75
+ `execute_code` takes arbitrary C# for tasks no pack covers. The code runs
76
+ inside Revit with `document` in scope and a transaction already open; end it
77
+ with `return <object>;`. `solidify_tool` saves code that worked as a new pack.
78
+
79
+ **Confirmation gate.** `execute_code` and `run_tool` default to
80
+ `spec_confirmed=false` and return `refused_unconfirmed_spec` until the host has
81
+ shown the designer every parameter with its source and received confirmation.
82
+ Hosts that run their own confirmation flow can set
83
+ `REVIT_BRIDGE_ALLOW_UNCONFIRMED=1`.
84
+
85
+ Resources: `revit://stats`, `revit://tools/{name}`, `revit://connection-status`.
86
+
87
+ ## Configure
88
+
89
+ | Variable | Default | Meaning |
90
+ |---|---|---|
91
+ | `REVIT_BRIDGE_HOST` | `127.0.0.1` | Host where the add-in listens |
92
+ | `REVIT_BRIDGE_PORT` | `18080` | TCP port of the add-in |
93
+ | `REVIT_BRIDGE_TOKEN` | *(unset)* | Pre-shared token, sent with every request when the add-in has one configured |
94
+ | `REVIT_BRIDGE_TIMEOUT` | `60` | Seconds to wait for a command to finish |
95
+ | `REVIT_BRIDGE_ALLOW_UNCONFIRMED` | *(unset)* | `1` lifts the `spec_confirmed` gate (host-internal flows only) |
96
+ | `REVIT_BRIDGE_CAPABILITIES_DIR` | packaged packs | Directory of capability YAML files; new `solidify_tool` packs are written here |
97
+
98
+ Development:
99
+
100
+ ```bash
101
+ uv sync
102
+ uv run pytest
103
+ uv build
104
+ uvx --from . revit-bridge check
105
+ ```
106
+
107
+ License: MIT. Issues and discussion: <https://github.com/revitbridge/revit-bridge/issues>.
@@ -0,0 +1,72 @@
1
+ name: create_beam
2
+ display_name: Create Beam
3
+ description: Create a structural beam between two points using first available beam
4
+ family type.
5
+ code_template: |
6
+ // Step 1: Get beam family symbol by name
7
+ var symbol = new FilteredElementCollector(document)
8
+ .OfClass(typeof(FamilySymbol))
9
+ .OfCategory(BuiltInCategory.OST_StructuralFraming)
10
+ .Cast<FamilySymbol>()
11
+ .FirstOrDefault(s => s.Name == "{type_name}");
12
+ if (symbol == null)
13
+ return new { Status = "Error", Message = "Beam type '{type_name}' not found" };
14
+ if (!symbol.IsActive) symbol.Activate();
15
+
16
+ // Step 2: Get level by name
17
+ var level = new FilteredElementCollector(document)
18
+ .OfClass(typeof(Level))
19
+ .Cast<Level>()
20
+ .FirstOrDefault(l => l.Name == "{level_name}");
21
+ if (level == null)
22
+ return new { Status = "Error", Message = "Level '{level_name}' not found" };
23
+
24
+ // Step 3: Create beam line (mm -> feet)
25
+ XYZ start = new XYZ({start_x} / 304.8, {start_y} / 304.8, {elevation} / 304.8);
26
+ XYZ end = new XYZ({end_x} / 304.8, {end_y} / 304.8, {elevation} / 304.8);
27
+ Line beamLine = Line.CreateBound(start, end);
28
+
29
+ // Step 4: Create beam instance
30
+ var beam = document.Create.NewFamilyInstance(
31
+ beamLine, symbol, level,
32
+ Autodesk.Revit.DB.Structure.StructuralType.Beam);
33
+
34
+ return new { ElementId = beam.Id.Value, Status = "Created",
35
+ FamilyType = symbol.Name, Level = level.Name };
36
+ parameters:
37
+ - name: type_name
38
+ type: string
39
+ description: Beam family type name
40
+ choices_from: family_types:OST_StructuralFraming
41
+ - name: level_name
42
+ type: string
43
+ description: Target level name
44
+ choices_from: levels
45
+ - name: start_x
46
+ type: double
47
+ description: Beam start X (mm)
48
+ default: '0'
49
+ - name: start_y
50
+ type: double
51
+ description: Beam start Y (mm)
52
+ default: '0'
53
+ - name: end_x
54
+ type: double
55
+ description: Beam end X (mm)
56
+ default: '5000'
57
+ - name: end_y
58
+ type: double
59
+ description: Beam end Y (mm)
60
+ default: '0'
61
+ - name: elevation
62
+ type: double
63
+ description: Beam elevation (mm)
64
+ default: '3000'
65
+ tags:
66
+ - beam
67
+ - structural
68
+ - create
69
+ created_at: '2026-03-13T00:00:00'
70
+ source_query: create a structural beam
71
+ execution_count: 0
72
+ last_used: ''
@@ -0,0 +1,33 @@
1
+ name: create_column
2
+ display_name: Create Column
3
+ description: create column
4
+ code_template: "// Step 1: Parse the position — convert mm to feet (Revit internal\
5
+ \ units)\ndouble xFeet = 100.0 / 304.8; // 100mm -> feet\ndouble yFeet = 0.0 /\
6
+ \ 304.8; // 0mm -> feet\ndouble zFeet = 0.0;\n\n// Step 2: Find the Level \"\
7
+ L1\" — filter by exact name from user selection\nLevel level = new FilteredElementCollector(document)\n\
8
+ \ .OfClass(typeof(Level))\n .Cast<Level>()\n .FirstOrDefault(l => l.Name\
9
+ \ == \"L1\");\n\nif (level == null)\n return new { Status = \"Error\", Message\
10
+ \ = \"Level 'L1' not found.\" };\n\n// Step 3: Find the FamilySymbol \"600 x 750mm\"\
11
+ \ in family \"M_Concrete-Rectangular-Column\"\nFamilySymbol columnSymbol = new FilteredElementCollector(document)\n\
12
+ \ .OfClass(typeof(FamilySymbol))\n .Cast<FamilySymbol>()\n .FirstOrDefault(s\
13
+ \ => s.Family.Name == \"M_Concrete-Rectangular-Column\" && s.Name == \"600 x 750mm\"\
14
+ );\n\nif (columnSymbol == null)\n return new { Status = \"Error\", Message =\
15
+ \ \"FamilySymbol '600 x 750mm' not found in family 'M_Concrete-Rectangular-Column'.\"\
16
+ \ };\n\n// Step 4: Activate the FamilySymbol if not already active — required before\
17
+ \ placing instances\nif (!columnSymbol.IsActive)\n{\n columnSymbol.Activate();\n\
18
+ \ document.Regenerate();\n}\n\n// Step 5: Define the insertion point in Revit\
19
+ \ internal units (feet)\nXYZ insertionPoint = new XYZ(xFeet, yFeet, zFeet);\n\n\
20
+ // Step 6: Place the structural column using NewFamilyInstance with StructuralType.Column\n\
21
+ FamilyInstance columnInstance = document.Create.NewFamilyInstance(\n insertionPoint,\n\
22
+ \ columnSymbol,\n level,\n Autodesk.Revit.DB.Structure.StructuralType.Column);\n\
23
+ \nif (columnInstance == null)\n return new { Status = \"Error\", Message = \"\
24
+ Failed to create structural column instance.\" };\n\n// Step 7: Return result with\
25
+ \ element info\nreturn new\n{\n Status = \"Success\",\n ElementId = columnInstance.Id.Value,\n\
26
+ \ FamilyName = columnSymbol.Family.Name,\n TypeName = columnSymbol.Name,\n\
27
+ \ Level = level.Name,\n PositionX_mm = 100.0,\n PositionY_mm = 0.0\n};"
28
+ parameters: []
29
+ tags: []
30
+ created_at: '2026-03-15T10:44:05.472069'
31
+ source_query: 创建结构柱100,0,0
32
+ execution_count: 0
33
+ last_used: ''
@@ -0,0 +1,29 @@
1
+ name: create_column_2
2
+ display_name: Create Column 2
3
+ description: create column
4
+ code_template: "// Step 1: Find the FamilySymbol for the structural column type\n\
5
+ FamilySymbol columnSymbol = new FilteredElementCollector(document)\n .OfClass(typeof(FamilySymbol))\n\
6
+ \ .OfCategory(BuiltInCategory.OST_StructuralColumns)\n .Cast<FamilySymbol>()\n\
7
+ \ .FirstOrDefault(s => s.Name == \"300 x 450mm\");\n\nif (columnSymbol == null)\n\
8
+ \ return new { Status = \"Error\", Message = \"FamilySymbol '300 x 450mm' not\
9
+ \ found.\" };\n\n// Step 2: Activate the FamilySymbol if not already active\nif\
10
+ \ (!columnSymbol.IsActive)\n{\n columnSymbol.Activate();\n document.Regenerate();\n\
11
+ }\n\n// Step 3: Find the base level (L1 at elevation 0)\nLevel baseLevel = new FilteredElementCollector(document)\n\
12
+ \ .OfClass(typeof(Level))\n .Cast<Level>()\n .FirstOrDefault(l => l.Name\
13
+ \ == \"L1\");\n\nif (baseLevel == null)\n return new { Status = \"Error\", Message\
14
+ \ = \"Level 'L1' not found.\" };\n\n// Step 4: Define the insertion point — 200mm\
15
+ \ = 200/304.8 feet\ndouble x = 200.0 / 304.8;\ndouble y = 0.0 / 304.8;\ndouble z\
16
+ \ = 0.0;\nXYZ insertionPoint = new XYZ(x, y, z);\n\n// Step 5: Place the structural\
17
+ \ column instance using NewFamilyInstance\nFamilyInstance column = document.Create.NewFamilyInstance(\n\
18
+ \ insertionPoint,\n columnSymbol,\n baseLevel,\n Autodesk.Revit.DB.Structure.StructuralType.Column);\n\
19
+ \nif (column == null)\n return new { Status = \"Error\", Message = \"Failed to\
20
+ \ create column instance.\" };\n\nreturn new\n{\n Status = \"Created\",\n \
21
+ \ ElementId = column.Id.Value,\n FamilyName = columnSymbol.FamilyName,\n TypeName\
22
+ \ = columnSymbol.Name,\n Level = baseLevel.Name,\n PositionX_mm = 200,\n \
23
+ \ PositionY_mm = 0\n};"
24
+ parameters: []
25
+ tags: []
26
+ created_at: '2026-03-15T11:09:58.645698'
27
+ source_query: 创建结构柱在200,0,0
28
+ execution_count: 2
29
+ last_used: '2026-03-20T09:51:45.627432'
@@ -0,0 +1,54 @@
1
+ name: create_floor
2
+ display_name: Create Floor
3
+ description: Create a rectangular floor slab at specified coordinates and dimensions.
4
+ code_template: "// Step 1: Get floor type by name\nvar floorType = new FilteredElementCollector(document)\n\
5
+ \ .OfClass(typeof(FloorType))\n .Cast<FloorType>()\n .FirstOrDefault(ft\
6
+ \ => ft.Name == \"{type_name}\");\nif (floorType == null)\n return new { Status\
7
+ \ = \"Error\", Message = \"Floor type '{type_name}' not found\" };\n\n// Step 2:\
8
+ \ Get level by name\nvar level = new FilteredElementCollector(document)\n .OfClass(typeof(Level))\n\
9
+ \ .Cast<Level>()\n .FirstOrDefault(l => l.Name == \"{level_name}\");\nif (level\
10
+ \ == null)\n return new { Status = \"Error\", Message = \"Level '{level_name}'\
11
+ \ not found\" };\n\n// Step 3: Create rectangular profile (mm -> feet)\ndouble x0\
12
+ \ = {x} / 304.8, y0 = {y} / 304.8;\ndouble w = {width} / 304.8, h = {length} / 304.8;\n\
13
+ var profile = new List<Curve>();\nprofile.Add(Line.CreateBound(new XYZ(x0, y0, 0),\
14
+ \ new XYZ(x0 + w, y0, 0)));\nprofile.Add(Line.CreateBound(new XYZ(x0 + w, y0, 0),\
15
+ \ new XYZ(x0 + w, y0 + h, 0)));\nprofile.Add(Line.CreateBound(new XYZ(x0 + w, y0\
16
+ \ + h, 0), new XYZ(x0, y0 + h, 0)));\nprofile.Add(Line.CreateBound(new XYZ(x0, y0\
17
+ \ + h, 0), new XYZ(x0, y0, 0)));\nvar curveLoop = CurveLoop.Create(profile);\n\n\
18
+ // Step 4: Create floor\nvar floor = Floor.Create(document, new List<CurveLoop>\
19
+ \ { curveLoop },\n floorType.Id, level.Id);\n\nreturn new\
20
+ \ { ElementId = floor.Id.Value, Status = \"Created\",\n FloorType =\
21
+ \ floorType.Name, Level = level.Name };\n"
22
+ parameters:
23
+ - name: type_name
24
+ type: string
25
+ description: Floor type name
26
+ choices_from: floor_types
27
+ - name: level_name
28
+ type: string
29
+ description: Target level name
30
+ choices_from: levels
31
+ - name: x
32
+ type: double
33
+ description: Floor origin X (mm)
34
+ default: '0'
35
+ - name: y
36
+ type: double
37
+ description: Floor origin Y (mm)
38
+ default: '0'
39
+ - name: width
40
+ type: double
41
+ description: Floor width (mm)
42
+ default: '6000'
43
+ - name: length
44
+ type: double
45
+ description: Floor length (mm)
46
+ default: '8000'
47
+ tags:
48
+ - floor
49
+ - create
50
+ - basic
51
+ created_at: '2026-03-13T00:00:00'
52
+ source_query: create a floor slab
53
+ execution_count: 1
54
+ last_used: '2026-03-15T14:31:09.972751'
@@ -0,0 +1,55 @@
1
+ name: create_room
2
+ display_name: Create Room
3
+ description: create room by height , width and height
4
+ code_template: "// Step 1: Get the wall type \"Generic - 150mm\" — using FilteredElementCollector\
5
+ \ with OfClass(WallType)\nWallType wallType = new FilteredElementCollector(document)\n\
6
+ \ .OfClass(typeof(WallType))\n .Cast<WallType>()\n .FirstOrDefault(wt =>\
7
+ \ wt.Name == \"Generic - 150mm\");\n\nif (wallType == null)\n return new { Status\
8
+ \ = \"Error\", Message = \"WallType 'Generic - 150mm' not found.\" };\n\n// Step\
9
+ \ 2: Get the level \"L1\" — using FilteredElementCollector with OfClass(Level)\n\
10
+ Level level = new FilteredElementCollector(document)\n .OfClass(typeof(Level))\n\
11
+ \ .Cast<Level>()\n .FirstOrDefault(l => l.Name == \"L1\");\n\nif (level ==\
12
+ \ null)\n return new { Status = \"Error\", Message = \"Level 'L1' not found.\"\
13
+ \ };\n\n// Step 3: Define the room dimensions — 5m x 4m in feet (1m = 1/0.3048 ft)\n\
14
+ double width = 5.0 / 0.3048; // 5m in feet\ndouble depth = 4.0 / 0.3048; // 4m\
15
+ \ in feet\ndouble height = 3.0 / 0.3048; // 3m wall height in feet\n\n// Step 4:\
16
+ \ Define the four corner points of the room\nXYZ pt0 = new XYZ(0, 0, level.Elevation);\n\
17
+ XYZ pt1 = new XYZ(width, 0, level.Elevation);\nXYZ pt2 = new XYZ(width, depth,\
18
+ \ level.Elevation);\nXYZ pt3 = new XYZ(0, depth, level.Elevation);\n\n// Step\
19
+ \ 5: Define the four wall curves (closed loop)\nList<Curve> wallCurves = new List<Curve>\n\
20
+ {\n Line.CreateBound(pt0, pt1), // South wall\n Line.CreateBound(pt1, pt2),\
21
+ \ // East wall\n Line.CreateBound(pt2, pt3), // North wall\n Line.CreateBound(pt3,\
22
+ \ pt0) // West wall\n};\n\n// Step 6: Create the four walls using Wall.Create —\
23
+ \ structural = false\nList<Wall> createdWalls = new List<Wall>();\nforeach (Curve\
24
+ \ curve in wallCurves)\n{\n Wall wall = Wall.Create(\n document,\n \
25
+ \ curve,\n wallType.Id,\n level.Id,\n height,\n \
26
+ \ 0.0, // offset from level\n false, // flip\n false // structural\n\
27
+ \ );\n createdWalls.Add(wall);\n}\n\n// Step 7: Create a Room at the center\
28
+ \ of the office — using document.Create.NewRoom\n// Room center point (UV for plan\
29
+ \ placement)\ndouble centerX = width / 2.0;\ndouble centerY = depth / 2.0;\nUV\
30
+ \ roomCenter = new UV(centerX, centerY);\n\nAutodesk.Revit.DB.Architecture.Room\
31
+ \ room =\n document.Create.NewRoom(level, roomCenter);\n\nif (room == null)\n\
32
+ \ return new { Status = \"Error\", Message = \"Failed to create room.\" };\n\n\
33
+ // Step 8: Set the room name and number\nroom.Name = \"办公室\";\nroom.Number = \"\
34
+ 101\";\n\n// Step 9: Get the active view to place the room tag\n// Use the first\
35
+ \ floor plan view associated with L1\nView tagView = new FilteredElementCollector(document)\n\
36
+ \ .OfClass(typeof(ViewPlan))\n .Cast<ViewPlan>()\n .FirstOrDefault(v =>\
37
+ \ v.GenLevel != null && v.GenLevel.Id == level.Id && !v.IsTemplate);\n\nif (tagView\
38
+ \ == null)\n{\n // Fallback: any floor plan view\n tagView = new FilteredElementCollector(document)\n\
39
+ \ .OfClass(typeof(ViewPlan))\n .Cast<ViewPlan>()\n .FirstOrDefault(v\
40
+ \ => !v.IsTemplate);\n}\n\nAutodesk.Revit.DB.Architecture.RoomTag roomTag = null;\n\
41
+ if (tagView != null)\n{\n // Step 10: Create a RoomTag at the room center — using\
42
+ \ document.Create.NewRoomTag\n roomTag = document.Create.NewRoomTag(\n \
43
+ \ new LinkElementId(room.Id),\n roomCenter,\n tagView.Id\n );\n\
44
+ }\n\n// Step 11: Return summary of created elements\nreturn new\n{\n Status \
45
+ \ = \"Success\",\n Message = \"办公室创建成功 (5m x 4m)\",\n WallCount\
46
+ \ = createdWalls.Count,\n WallIds = createdWalls.Select(w => w.Id.Value).ToList(),\n\
47
+ \ RoomId = room.Id.Value,\n RoomName = room.Name,\n RoomNumber\
48
+ \ = room.Number,\n RoomTagId = roomTag != null ? roomTag.Id.Value : -1L,\n\
49
+ \ LevelName = level.Name,\n WallTypeName = wallType.Name\n};"
50
+ parameters: []
51
+ tags: []
52
+ created_at: '2026-03-15T14:37:20.232999'
53
+ source_query: 创建一个5m x 4m的办公室,包含4面墙、房间和房间标签
54
+ execution_count: 0
55
+ last_used: ''
@@ -0,0 +1,43 @@
1
+ name: create_structural_column
2
+ display_name: Create Structural Column
3
+ description: Create a structural column at specified coordinates using first available
4
+ structural column family type.
5
+ code_template: "// Step 1: Get structural column family symbol by name\nvar symbol\
6
+ \ = new FilteredElementCollector(document)\n .OfClass(typeof(FamilySymbol))\n\
7
+ \ .OfCategory(BuiltInCategory.OST_StructuralColumns)\n .Cast<FamilySymbol>()\n\
8
+ \ .FirstOrDefault(s => s.Name == \"{type_name}\");\nif (symbol == null)\n \
9
+ \ return new { Status = \"Error\", Message = \"Column type '{type_name}' not found\"\
10
+ \ };\nif (!symbol.IsActive) symbol.Activate();\n\n// Step 2: Get level by name\n\
11
+ var level = new FilteredElementCollector(document)\n .OfClass(typeof(Level))\n\
12
+ \ .Cast<Level>()\n .FirstOrDefault(l => l.Name == \"{level_name}\");\nif (level\
13
+ \ == null)\n return new { Status = \"Error\", Message = \"Level '{level_name}'\
14
+ \ not found\" };\n\n// Step 3: Create column at position (mm -> feet)\nXYZ location\
15
+ \ = new XYZ({x} / 304.8, {y} / 304.8, 0);\nvar column = document.Create.NewFamilyInstance(\n\
16
+ \ location, symbol, level,\n Autodesk.Revit.DB.Structure.StructuralType.Column);\n\
17
+ \nreturn new { ElementId = column.Id.Value, Status = \"Created\",\n \
18
+ \ FamilyType = symbol.Name, Level = level.Name };\n"
19
+ parameters:
20
+ - name: type_name
21
+ type: string
22
+ description: Structural column family type name
23
+ choices_from: family_types:OST_StructuralColumns
24
+ - name: level_name
25
+ type: string
26
+ description: Target level name
27
+ choices_from: levels
28
+ - name: x
29
+ type: double
30
+ description: Column X position (mm)
31
+ default: '0'
32
+ - name: y
33
+ type: double
34
+ description: Column Y position (mm)
35
+ default: '0'
36
+ tags:
37
+ - column
38
+ - structural
39
+ - create
40
+ created_at: '2026-03-13T00:00:00'
41
+ source_query: create a structural column
42
+ execution_count: 1
43
+ last_used: '2026-03-15T13:51:40.434751'
@@ -0,0 +1,48 @@
1
+ name: create_wall
2
+ display_name: Create Wall
3
+ description: Create a wall between two points with specified height. Uses first available
4
+ wall type and first level.
5
+ code_template: "// Step 1: Get level by name\nvar level = new FilteredElementCollector(document)\n\
6
+ \ .OfClass(typeof(Level))\n .Cast<Level>()\n .FirstOrDefault(l => l.Name\
7
+ \ == \"{level_name}\");\nif (level == null)\n return new { Status = \"Error\"\
8
+ , Message = \"Level '{level_name}' not found\" };\n\n// Step 2: Create wall line\
9
+ \ from mm coordinates\nXYZ start = new XYZ({start_x} / 304.8, {start_y} / 304.8,\
10
+ \ 0);\nXYZ end = new XYZ({end_x} / 304.8, {end_y} / 304.8, 0);\nLine wallLine =\
11
+ \ Line.CreateBound(start, end);\n\n// Step 3: Create wall (Transaction already active\
12
+ \ — do NOT create one)\nWall wall = Wall.Create(document, wallLine, level.Id, false);\n\
13
+ wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM)\n .Set({height} /\
14
+ \ 304.8);\n\nreturn new { ElementId = wall.Id.Value, Status = \"Created\", Level\
15
+ \ = level.Name };\n"
16
+ parameters:
17
+ - name: level_name
18
+ type: string
19
+ description: Target level name
20
+ choices_from: levels
21
+ - name: start_x
22
+ type: double
23
+ description: Wall start X (mm)
24
+ default: '0'
25
+ - name: start_y
26
+ type: double
27
+ description: Wall start Y (mm)
28
+ default: '0'
29
+ - name: end_x
30
+ type: double
31
+ description: Wall end X (mm)
32
+ default: '5000'
33
+ - name: end_y
34
+ type: double
35
+ description: Wall end Y (mm)
36
+ default: '0'
37
+ - name: height
38
+ type: double
39
+ description: Wall height (mm)
40
+ default: '3000'
41
+ tags:
42
+ - wall
43
+ - create
44
+ - basic
45
+ created_at: '2026-03-13T00:00:00'
46
+ source_query: create a wall
47
+ execution_count: 1
48
+ last_used: '2026-03-15T14:12:46.748985'