Martin9020 Tekla MCP Server
115 tools, 10 prompts, 6 resources
Ask AI about Martin9020 Tekla MCP Server
Powered by Claude Β· Grounded in docs
I know everything about Martin9020 Tekla MCP Server. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Tekla MCP Server
An MCP (Model Context Protocol) server that connects Claude to Tekla Structures, enabling AI-driven structural steel modeling and drawing automation through natural language. Built with native C# .NET β no bridge layers, no WebSocket middleware.
What This Is
This server exposes Tekla modeling, drawing, catalog, export, and settings operations as MCP tools that let an LLM (Claude) interact with a running Tekla Structures instance. Current live validation is focused on Tekla Structures 2023.0 and 2026.0. The same runtime-selection code has install/compile targets for 2024.0 and 2025.0, but those versions still need live validation. You describe what you want in natural language, and Claude translates that into Tekla API operations: creating beams, querying model data, generating and detailing drawings, running clash checks, and everything in between.
Example conversation:
You: Create a portal frame steel building in Tekla: 20m span, 6 bays at 6m
spacing, 7m eaves height, 10Β° roof pitch. Main columns UKC254*254*73 at
each frame on both sides. Gable columns UKC152*152*23 at X=5000, 10000,
15000 on both end walls (height to roof slope). Rafters UKB457*191*67
from eaves to ridge on both slopes, each frame. Eaves beams UKB305*165*40
running full length both sides at eaves level. Purlins CHS139.7*5.0 at
1500mm spacing along both roof slopes plus ridge beam, split between
frames (6m lengths), with rotationOffset matching roof pitch. Side rails
CHS139.7*5.0 at 2 rows on both long walls and gable end walls. Wall
bracing CHS88.9*4.0 as X-bracing on both side walls in end bays. Roof
bracing CHS88.9*4.0 as X-bracing in the roof plane in end bays on both
slopes. Material S355.
Claude: I'll build this step by step.
1. Verifying profiles and material in the catalog... [ListProfiles, ListMaterials]
2. Creating 14 main columns at each frame... [CreateColumns, CommitChanges]
3. Creating 14 rafters (left + right slopes)... [CreateBeams, CommitChanges]
4. Creating 2 eaves beams full length... [CreateBeams, CommitChanges]
5. Creating 130+ purlins with rotationOffset Β±10Β°... [CreateBeams, CommitChanges]
6. Creating 6 gable columns (height to roof slope)... [CreateColumns, CommitChanges]
7. Creating side rails on all 4 walls... [CreateBeams, CommitChanges]
8. Creating wall bracing X-patterns... [CreateBeams, CommitChanges]
9. Creating roof bracing X-patterns... [CreateBeams, CommitChanges]
Done. Complete portal frame building: 14 columns, 14 rafters, 2 eaves
beams, 130+ purlins, 6 gable columns, side rails, wall and roof bracing.
All S355 steel.

Then detail it with a single follow-up prompt:
You: Complete the following tasks on the current portal frame model. Do each
step in order and CommitChanges after each batch.
1. Eaves haunches β Select all columns and rafters. At every column-to-
rafter connection, apply Eaves haunch (102) with the column as primary
and the rafter as secondary.
2. Apex haunches β At the ridge where two rafters meet, apply Apex haunch
(106) with one rafter as primary and the other as secondary.
3. Base plates β Apply Base plate (1004) as a detail on every column
base. 20mm thick.
4. Concrete pads β Under every column, create a concrete pad footing
(material: C25, class: 8) at the column base position. Size the pad
to 1000x1000mm, thickness 300mm, centered on the column.
5. Purlin connections β Apply Purlin connections (93) at every purlin-to-
rafter intersection, with the rafter as primary and the purlin as
secondary.
Use SelectElementsByFilter or element class/name to identify columns,
rafters, and purlins. Use batch tools where possible. CommitChanges
between each major step.
Claude: I'll identify all elements and apply connections step by step.
1. Selecting columns (20) and rafters (14)... reading geometry to match pairs
2. Applying 14 eaves haunches at column-rafter connections... [PutComponents x14, CommitChanges]
3. Applying 7 apex haunches at ridge... [PutComponents x7, CommitChanges]
4. Applying 14 base plates (20mm) on all columns... [PutComponents x14, CommitChanges]
5. Creating 14 concrete pad footings (1000x1000, 300mm, C25)... [CreatePadFooting x14, CommitChanges]
6. Selecting 72 purlins, matching to rafters by position...
Applying 144 purlin connections at every intersection... [PutComponents x144, CommitChanges]
Done. 193 components created across 5 commits: 14 eaves haunches,
7 apex haunches, 14 base plates, 14 pad footings, 144 purlin connections.

Everything happens inside Tekla's GUI β you see parts appear in real time.
How It Works
The MCP Protocol
MCP is a standard protocol that lets AI models call external tools. This server implements MCP over stdio (standard input/output), which means:
- Claude Code (or any MCP client) starts the server as a subprocess
- The client sends JSON-RPC requests ("call this tool with these parameters")
- The server executes the Tekla API operation and returns the result
- Claude uses the result to decide what to do next
The server is stateless between calls β each tool invocation creates a fresh connection to Tekla.
Architecture
Claude Code / Claude Desktop / Any MCP Client
|
+-- stdio (JSON-RPC) --> C# MCP Server (.NET 4.8)
|
+-- Tekla Open API (.NET) --> Tekla Structures GUI
|
+-- spawns on first search --> Python subprocess
+-- MiniLM embeddings
+-- ChromaDB vectors
Why C# and not Python? Tekla's API is native .NET. Python-based servers commonly use pythonnet as a bridge, which adds a translation layer. This server calls the Tekla API directly: same language, same runtime, same type system. The only Python component is the optional semantic search subprocess.
Why a subprocess for search? Sentence-transformers and ChromaDB are Python-native. Rather than porting ML inference to C#, the server spawns a lightweight Python process that communicates via JSON stdin/stdout. It starts on the first search request and stays alive for the session.
Selection-Based Workflow
The server follows Tekla's own UX pattern: select first, then operate. This is how structural engineers already work in Tekla.
Step 1: Select --> SelectElementsByFilter(material: "S355")
Returns: { count: 302, summary: "...", queryId: "q_20260331_153414_733", sampleIds: [...] }
Step 2: Inspect --> GetQueryInfo(queryId: "q_20260331_153414_733")
Returns: count, summary, sampleIds, availableFields
Step 3: Inspect --> ProjectQuery(queryId: "q_20260331_153414_733",
fieldsJson: ["id","profile","material","startPoint.z"])
Returns: only the fields requested
Step 4: Modify --> SetElementsProperties(queryId: "q_20260331_153414_733",
name: "MODIFIED", class: "10")
Changes applied to the saved query result
Step 5: Commit --> CommitChanges()
Persists all changes to the Tekla model database
Every create/modify/delete operation requires a CommitChanges() call to persist. This is a Tekla API requirement, not a server limitation.
Prerequisites
- Tekla Structures 2023.0 or 2026.0 installed for runtime/live-tested use. Tekla 2024.0 and 2025.0 are compile targets but still need live validation.
- A matching Tekla model open in the version you want to control
- Claude Code (CLI, Desktop app, or IDE extension) or any MCP-compatible client
- .NET Framework 4.8 β pre-installed on Windows 10/11
- Python 3.11+ β optional, only needed for semantic search (no API key required)
Quick Start
1. Clone and Build
git clone https://github.com/martin9020/Tekla-MCP-Server.git
cd Tekla-MCP-Server
powershell -ExecutionPolicy Bypass -File .\requirements\build-project.ps1
That bootstrap script:
- restores and builds the canonical C# server
- runs the semantic Python setup
- runs the unit tests
The GitHub repository intentionally does not include .nuget/ or downloaded DLLs. Visual Studio and dotnet restore restore the pinned PackageReference dependencies from the root NuGet.config. In Visual Studio, use Restore NuGet Packages or enable automatic package restore under Tools > Options > NuGet Package Manager > General if restore is disabled.
Before copying the rebuilt exe, the project stops any running repo-local TeklaMcpServer.exe that matches the target output path. This prevents locked-output build failures when the MCP server is already running.
Pass -p:StopRunningMcpServerBeforeBuild=false to dotnet build only when you explicitly want to leave the running server untouched.
Compile-time Tekla Open API references are restored from NuGet. By default, the project build target stays on Tekla 2026.0, using NuGet package version 2026.0.0. The bootstrap script also accepts -TeklaVersion / -TeklaBinDir and honors the matching environment variables when you need a different compile target:
$teklaVersion = '<TEKLA_VERSION>' # for example 2023.0
powershell -ExecutionPolicy Bypass -File .\requirements\build-project.ps1 `
-TeklaVersion $teklaVersion
Direct dotnet build still works if you want to bypass the bootstrap script:
$teklaVersion = '<TEKLA_VERSION>' # for example 2023.0
dotnet build src\TeklaMcpServer\TeklaMcpServer.csproj -c Release `
-p:Platform=x64 `
-p:TeklaVersion=$teklaVersion
For the deployed MCP server binary, keep the default 2026.0 build unless you have a specific reason to validate an older reference set.
At runtime, the server resolves Tekla in this order:
TEKLA_BIN_DIRTEKLA_VERSION- the single running
TeklaStructures.exeinstance, if there is exactly one version running config/settings.json- the default fallback (
2026.0)
If multiple Tekla versions are running at the same time, the server does not guess. Set TEKLA_VERSION, TEKLA_BIN_DIR, or config/settings.json to the version you want that MCP process to control.
If both TEKLA_BIN_DIR and TEKLA_VERSION are set, TEKLA_BIN_DIR wins. The server also derives the effective version from that folder so version-based paths stay aligned with the assemblies that were actually loaded.
The runtime output does not ship version-pinned Tekla/Trimble assemblies. The build removes restored Tekla/Trimble DLLs from the output so the running server resolves the installed Tekla DLLs from the selected bin folder. It falls back to the matching Tekla.Structures NuGet package only when newer Tekla installs do not place that DLL directly in bin.
The canonical MCP binary is:
src/TeklaMcpServer/bin/x64/Release/net48/TeklaMcpServer.exe
2. Configure Your MCP Client
Claude Code β add to ~/.claude.json:
{
"mcpServers": {
"tekla": {
"type": "stdio",
"command": "C:\\path\\to\\src\\TeklaMcpServer\\bin\\x64\\Release\\net48\\TeklaMcpServer.exe",
"args": [],
"env": {}
}
}
}
Claude Desktop β add to claude_desktop_config.json (same format).
After configuring, restart your client. In Claude Code, run /mcp to verify the server is connected.
Leave env empty for version-agnostic auto-detection. Only set TEKLA_VERSION or TEKLA_BIN_DIR when you need this MCP process to target a specific Tekla installation.
3. Start Using It
Make sure Tekla Structures is running with a model open, then:
> Check the connection to Tekla
> What profiles are available in the catalog?
> Create 4 HEB300 columns at (0,0), (6000,0), (0,8000), (6000,8000), height 4000mm, S355
> Select all beams with profile IPE400
> Run a clash check on the entire model
> Export the model to IFC
Tools Reference
Connection & Commit
| Tool | What it does |
|---|---|
CheckConnection | Verify Tekla is running and a model is open |
CommitChanges | Persist all pending create/modify/delete operations to the model |
GetProjectInfo | Get project properties (name, number, address, designer, etc.) |
Selection & Query
These tools follow the "select then operate" pattern. Selecting elements in the server also selects them in Tekla's GUI.
| Tool | What it does |
|---|---|
SelectElementsByFilter | Select parts by objectType, profile, material, name, and/or class. Uses Tekla server-side filters for simple filters, returns compact {count, summary, queryId} |
SelectElementsByGuid | Select specific parts by their GUIDs |
SelectElementsByFilterName | Apply a saved Tekla selection filter (.SObjGrp file) |
SelectAssembliesOrMainParts | Expand selection to assemblies or find main parts |
GetSelectedElements | Get the currently selected elements in Tekla (with optional filters) |
GetQueryInfo | Inspect a saved query snapshot and list available field paths |
ProjectQuery | Fetch only selected fields from a saved query, with filter/sort/limit support |
GetQueryDistinctValues | Group a saved query by one field (profile, material, phase, class, etc.) |
GetElementsProperties | Read detailed properties of specific parts by ID or queryId |
SetElementsProperties | Modify properties (name, profile, material, class, finish, position) by ID or queryId |
GetElementsCutParts | Get boolean cuts applied to parts |
ClearElementsUDAs | Remove user-defined attributes from parts |
CompareElements | Compare properties between two sets of elements |
GetModelInfo | Model summary with object counts (beams, columns, plates, bolts, welds) |
SelectInUI | Highlight specific objects in Tekla's viewport |
Catalog
| Tool | What it does |
|---|---|
ListProfiles | Search available profiles (e.g. "HEB*", "IPE400") |
ListMaterials | Search available materials (e.g. "S355", "S275JR") |
ListBoltAssemblies | List available bolt assembly standards |
RenameLibraryProfiles | Dry-run or execute fixed/library profile renames by prefix, with exact-name input to avoid broad catalog scans |
EnsureOriginalProfileCatalogRule | Insert or update a top-level rules.lis group rule for the original profile catalog when XS_USE_OLD_PROFILE_CATALOG=TRUE |
Spatial & Model Info
| Tool | What it does |
|---|---|
GetModelExtents | Bounding box of the entire model |
GetModelStatistics | Count of parts, bolts, welds, etc. |
GetGridInfo | Read grid line positions and labels |
GetPartBoundingBox | Bounding box of a specific part |
GetDistanceBetweenParts | Measure distance between two parts |
Model Creation & Modification
| Tool | What it does |
|---|---|
CreateBeam / CreateBeams | Create one or many beams (start point, end point, profile, material, rotationOffset) |
CreateColumn / CreateColumns | Create one or many columns (position, height, profile, material) |
CreatePlate / CreatePlates | Create one or many contour plates (corner points, thickness, material) |
CreatePolyBeam | Create a curved/multi-segment beam from a point list |
CreateCurvedBeam / CreateCurvedBeams | Create true arc beams from a chord plus Tekla cambering |
CreateBeamsOnArc | Parametric: generate purlins along an arc from chord, cambering, and bay parameters |
CreateColumnsOnGrid | Parametric: create columns at grid intersections |
CreateGrid | Create a coordinate grid (X, Y, Z labels and spacings) |
CreateControlPoint | Place a reference control point |
ModifyPart | Change properties of an existing part (profile, material, position) |
MovePart / MoveParts | Translate parts by a displacement vector |
CopyPart / CopyParts | Duplicate parts with an offset |
DeleteObject / DeleteObjects | Remove parts from the model |
CreatePadFooting | Create a concrete pad footing under a column (auto-reads column base position) |
CutElementWithPart | Create a boolean cut (cut one part with another) |
Components & Macros
| Tool | What it does |
|---|---|
PutComponents | Insert steel connection components (base plates, end plates, haunches, etc.) |
RemoveComponents | Remove connection components |
ListComponents | List available component definitions from config |
ListComponentCatalog | List all 969 system components in the Tekla catalog |
GetComponentAttributes | Read attributes of a component by ID |
ModifyComponentAttributes | Modify attributes on an existing component |
GetSelectedComponents | Get currently selected components in Tekla UI |
SelectAllComponents | Select all components in the model |
GetAdvancedOptions | Read live Tekla advanced options by supplied option names |
RunMacro | Execute a Tekla macro (.cs file) by name |
ListMacros | List available macros from model and system directories |
Bundled macros include NumberModifiedObjects, NumberAllParts, NumberSelectedParts, and NumberSelectedDrawingComments for writing drawing COMMENT UDAs in n/m format over the current Document Manager drawing selection.
View & Visualization
| Tool | What it does |
|---|---|
ZoomToSelection | Zoom the viewport to show selected objects |
RedrawView | Force a view refresh |
ColorSelected | Color selected parts (for visual highlighting) |
DrawElementsLabels | Add text labels to elements in the view |
DrawTemporaryText | Display temporary text at a 3D position |
DrawTemporaryLine | Draw a temporary line between two points |
ListViews | List all model views |
DisplayPrompt | Show a message in Tekla's status bar |
Steel Connections
| Tool | What it does |
|---|---|
CreateBoltGroup | Create a bolt group between two parts |
CreateWeld / CreateWelds | Create welds between parts |
CreateFitting | Add an end fitting (cut/cope) to a part |
Phase & Assembly
| Tool | What it does |
|---|---|
GetPhases | List all phases in the model |
CreatePhase | Create a new construction phase |
SetObjectPhase / SetObjectsPhase | Assign parts to a phase |
GetAssemblyInfo | Get assembly hierarchy and properties |
ModifyAssembly | Change assembly properties (prefix, position number) |
Drawings & Drawing Automation
| Tool | What it does |
|---|---|
ListDrawings | List all drawings in the model |
CreateAssemblyDrawing / CreateAssemblyDrawings | Generate assembly drawings |
CreateSinglePartDrawing / CreateSinglePartDrawings | Generate single-part workshop drawings |
CreateGADrawing | Create general arrangement drawings |
OpenDrawing | Open a drawing in Tekla's editor by mark |
CloseDrawing | Save and close the active drawing |
GetActiveDrawing | Get info about the open drawing (sheet size, view count) |
CommitDrawingChanges | Commit pending drawing edits |
UpdateDrawing | Force-recalculate drawing after model changes |
GetDrawingUserProperty | Read a drawing string UDA such as COMMENT |
SetDrawingUserProperty | Write a drawing string UDA such as COMMENT |
SetDrawingUserPropertySequence | Number an explicit ordered list of drawing marks as n/m |
SetSelectedDrawingsUserPropertySequence | Number the current Document Manager drawing selection as n/m |
GetDrawingViews | List all views with semantic viewType, displayName, optional explicit label, scale, position, size, part count, and a viewKey |
GetViewParts | List model parts visible in a drawing view |
GetViewObjects | List existing annotations (dims, marks, text) in a view |
GetPartDrawingGeometry | Get part endpoints projected into 2D drawing view coordinates |
CreateDrawingView | Create front/top/back/bottom views |
CreateSectionView | Create section cuts through a view |
CreateDetailView | Create detail views with boundary circle |
MoveDrawingView | Reposition a view on the drawing sheet |
SetDrawingViewScale | Change the scale of a drawing view |
SetDrawingViewUnfolded | Force an existing drawing view to use unfolded display |
CreateDimensions | Straight dimension sets from point arrays using horizontal, vertical, or a custom vector |
CreateAngleDimension | Angle dimensions for roof pitch, braces |
CreateRadiusDimension | Radius dimensions for curved members |
CreateMark | Part marks with leader lines |
CreateLevelMark | Elevation marks relative to datum |
CreateText | Free text annotations with optional rotation |
DeleteDrawingObjects | Remove annotations by category |
PrintDrawing | Export a drawing to PDF |
PrintDrawings | Batch export multiple drawings to PDF |
IssueDrawing | Lock drawing and record issue date |
Export & Operations
| Tool | What it does |
|---|---|
ExportIFC | Export the model to IFC format |
ExportNCFiles | Generate CNC/NC files for fabrication; default output is <modelPath>\\DSTV\\ |
GenerateReport | Run a Tekla report template |
RunClashCheck | Detect clashing parts in the model |
GetReferenceModels | List reference models attached to the project |
Semantic Search
| Tool | What it does |
|---|---|
SearchAttributes | Find Tekla template attribute keys by natural language description |
SearchApi | Find Tekla API classes and methods by natural language description |
Prompts (10)
MCP prompts are pre-built instruction sets that guide Claude through multi-step workflows:
| Prompt | Steps | Purpose |
|---|---|---|
| TeklaGuide | - | System instructions: all coordinates in mm, always CommitChanges, verify profiles against catalog |
| CreateSteelStructure | 7 | Create steel from a description: verify catalog, create grid, place columns and beams, add connections, commit |
| CreateBarrelCanopy | 8 | Parametric barrel vault canopy: arched hoops, purlins, eaves beams, stub columns, optional gutters |
| CreatePortalFrame | 11 | Parametric portal frame building: columns, rafters, purlins, eaves beams, gable columns, side rails, bracing |
| ModifyElements | 6 | Modify existing parts: select by filter, inspect properties, verify new values, apply changes, commit |
| GenerateDrawings | 6 | Drawing production: list existing drawings, select parts, create assembly and single-part drawings |
| ExportAndValidate | 6 | Export and QA: run clash check, export IFC, generate NC files, run reports |
| AddConnections | 8 | Steel connections: list components, select parts, add components/bolts/welds/fittings, commit |
| ManagePhases | 7 | Phase management: review phases, create new phases, assign elements, review assemblies |
| InspectModel | 7 | Model inspection: check connection, get statistics, measure extents, list grids and reference models |
Resources (6 + 1 template)
MCP resources provide read-only context that Claude can request on demand (not sent automatically):
| URI | Returns |
|---|---|
tekla://connection_status | Whether Tekla is connected, model name and path |
tekla://model_info | Model summary with object counts (beams, columns, plates, bolts) |
tekla://components | Available steel connection component definitions from config/components.json |
tekla://components/{name} | Property schema for a specific component (e.g. tekla://components/base_plate) |
tekla://macros | Available Tekla macros (.cs files) from model and system macro directories |
tekla://filters/selection | Available selection filter names from .SObjGrp files |
tekla://filters/view | Available view filter names from .VObjGrp files |
Token Optimization
LLM context windows are finite and expensive. A naive "return all element data inline" approach burns ~10,000 tokens on a 200-element query. This server is designed to minimize token consumption:
SelectElementsByFilter saves the full query snapshot under the active model's queries/ folder and returns a compact response:
{
"status": "success",
"selectedInTeklaUI": true,
"count": 302,
"queryId": "q_20260327_211432_616",
"summary": "302 parts selected",
"sampleIds": [123, 456, 789],
"availableFields": ["id", "profile", "material", "name", "startPoint.z"]
}
Then inspect only what you need:
GetQueryInfo(queryId: "q_20260327_211432_616")
ProjectQuery(
queryId: "q_20260327_211432_616",
fieldsJson: ["id", "profile", "material", "startPoint.z"],
filterJson: {"name": "COLUMN"},
orderBy: "-startPoint.z",
limit: 20
)
The saved query file is a server-side persistence/debug artifact. Normal LLM workflows should use GetQueryInfo, ProjectQuery, and GetQueryDistinctValues instead of reading raw query files or requesting full ID arrays.
Result: ~50 tokens per query response instead of ~10,000. That's a 99.5% reduction.
Semantic Search
Tekla has 24,071 template attributes (e.g. PROFILE, WEIGHT_GROSS, FLANGE_THICKNESS_U) and 14,380 API members. Nobody memorizes these. Semantic search lets Claude find them by description:
"flange thickness" --> FLANGE_THICKNESS_U, FLANGE_THICKNESS_L (confidence: 0.89)
"create plate" --> ContourPlate.Insert(), ContourPlate class (confidence: 0.92)
"bolt diameter" --> BOLT_DIAMETER, BOLT_STANDARD (confidence: 0.85)
The search uses a local MiniLM-compatible sentence-transformers model. The default is sentence-transformers/all-MiniLM-L6-v2, and production deployments can override it with TEKLA_MCP_EMBEDDING_MODEL. No API key is required after the model is available locally.
Data:
- 15,092 attribute embeddings (from 24,071 template attributes + PDF descriptions)
- 14,257 API member embeddings (from the full Tekla Open API reference)
- 65 hand-curated instant mappings for common queries (bypasses embedding lookup)
Setting Up Semantic Search (optional)
powershell -ExecutionPolicy Bypass -File .\semantic-service\deploy.ps1
This setup path is now production-proven:
- cold-start rebuild works when
semantic-service/chroma_dbis missing - warm semantic search works against the rebuilt database
Manual fallback:
cd semantic-service
python -m pip install -r requirements.txt
# Build the vector database (one-time, takes ~5 minutes)
python build_local_db.py
The server auto-spawns the Python subprocess on the first SearchAttributes or SearchApi call. If chroma_db is missing, the C# bridge bootstraps it by running build_local_db.py. If Python isn't installed, all non-semantic tools still work normally.
Configuration
| File | What to customize |
|---|---|
config/settings.json | Tekla runtime selection (default: 2026.0), bin directory path, log level |
config/components.json | Steel connection component definitions β add new component types here without touching code |
config/element_types.json | Mapping of Tekla class numbers to element type names |
config/semantic_overrides.json | 65 hand-curated attribute mappings for instant lookup (add your own shortcuts) |
Environment Variables (optional)
| Variable | Default | Purpose |
|---|---|---|
TEKLA_VERSION | Unset | Version hint/override for runtime selection and build helpers |
TEKLA_BIN_DIR | Auto-detected | Absolute Tekla bin override; wins if both Tekla selectors are set |
PYTHON_PATH | Auto-detected | Optional override for the Python executable used by semantic search |
SEMANTIC_SERVICE_DIR | Auto-detected | Path to semantic-service/ directory |
TEKLA_MCP_EMBEDDING_MODEL | sentence-transformers/all-MiniLM-L6-v2 | Optional sentence-transformers model id/path for rebuilding and querying the local semantic database |
TEKLA_MCP_USE_SERVER_FILTERS | 1 | Set to 0 to disable the optimized Tekla GetObjectsByFilter path for SelectElementsByFilter |
Project Structure
Tekla-MCP-Server/
+-- src/TeklaMcpServer/
| +-- Program.cs Entry point, assembly resolver, MCP host setup
| +-- TeklaInit.cs Assembly resolution + Tekla bin directory lookup
| +-- Tools/ MCP tool implementations
| | +-- ConnectionTools.cs CheckConnection, CommitChanges, GetProjectInfo
| | +-- SelectionTools.cs Filter selection, GUID selection, properties
| | +-- QueryTools.cs Element properties, model info, statistics
| | +-- CatalogTools.cs Profile/material/bolt catalog queries
| | +-- SpatialTools.cs Bounding boxes, distances, grid info
| | +-- ModelTools.cs Create/modify/delete/move/copy parts
| | +-- ComponentTools.cs Insert/remove steel connections
| | +-- MacroTools.cs Run/list Tekla macros
| | +-- ViewTools.cs Zoom, color, labels, temporary graphics
| | +-- SteelConnectionTools.cs Bolts, welds, fittings
| | +-- PhaseAssemblyTools.cs Construction phases, assemblies
| | +-- DrawingTools.cs Drawing lifecycle, print, GA, issue
| | +-- DrawingDetailTools.cs Views, dimensions, marks, text, geometry
| | +-- ExportOperationsTools.cs IFC, NC files, reports, clash check
| | +-- SettingsTools.cs Advanced option inspection
| | +-- SemanticSearchTools.cs SearchAttributes, SearchApi
| +-- Prompts/TeklaPrompts.cs Guided workflow prompts
| +-- Resources/TeklaResources.cs Read-only resources and resource templates
| +-- Utils/
| +-- SemanticSearchBridge.cs Python subprocess manager
| +-- ProfileRulesLisHelper.cs Original profile catalog rules.lis updater
| +-- TeklaConnectionGuard.cs Connection check wrapper
+-- config/ Component definitions, settings, overrides
+-- semantic-service/
| +-- semantic_bridge.py JSON stdin/stdout bridge (spawned by C# server)
| +-- search_server.py Standalone Python MCP server (legacy, still works)
| +-- build_local_db.py Builds ChromaDB from source data
| +-- parsed_attributes.json 15,092 Tekla template attributes with descriptions
+-- tests/
| +-- unit/ TeklaInit tests (no Tekla dependency)
| +-- functional/ Manual live smoke harness (requires running Tekla)
+-- Knowledge/
| +-- api-catalog.txt 1,278 Tekla API types (used by build_local_db.py)
| +-- api-members.txt 14,380 API methods/properties
| +-- contentattributes_global.lst 24,071 template attribute definitions
+-- AGENTS.md Codex/agent working context
+-- mcp-config-example.json Example MCP client configuration
Development
# Bootstrap dependencies + build the canonical MCP binary
powershell -ExecutionPolicy Bypass -File .\requirements\build-project.ps1
# Semantic search only
powershell -ExecutionPolicy Bypass -File .\semantic-service\deploy.ps1
# Run the manual live smoke harness (Tekla must be running with a model open)
dotnet build tests/functional/TeklaMcpServer.Functional.Tests.csproj -c Release
./tests/functional/bin/Release/net48/TeklaMcpServer.Functional.Smoke.exe
# Unit tests (no Tekla needed)
dotnet test tests/unit/TeklaMcpServer.Unit.Tests.csproj
# Test with MCP Inspector (interactive tool testing)
npx @modelcontextprotocol/inspector -- dotnet run --project src/TeklaMcpServer/TeklaMcpServer.csproj
Recent validation snapshots:
- Live Tekla 2023 read-only smoke:
34/34passed - Live Tekla 2023 mutating smoke:
82/82passed - Live Tekla 2026 read-only smoke:
34/34passed - Live Tekla 2026 mutating smoke:
82/82passed - Explicit Tekla 2023 build + startup probe: passed
- Unit tests:
28/28passed - Explicit Tekla 2026 x64 build: passed
- Direct MCP startup benchmark: server startup about
1.3s, tool list about0.09s, check connection about0.27s SelectElementsByFilterexact part query benchmark: improved from tens of seconds to about1.5sby using Tekla server-side filters
When you need a specific live version during testing, run the harness with an explicit override, for example:
$env:TEKLA_VERSION = '2023.0'
.\tests\functional\bin\Release\net48\TeklaMcpServer.Functional.Smoke.exe --allow-write
Key Technical Constraints
-
Supported Tekla versions the same codebase targets
2023.0,2024.0,2025.0, and2026.0. Live smoke is documented for2023.0and2026.0;2024.0and2025.0still need their own live validation snapshot. -
.NET Framework 4.8 β Tekla 2023 and 2026 target net48. Do not use .NET 8/9 features.
-
x64 only β Tekla's native DLLs are 64-bit.
-
Tekla must be running β the server connects to an active Tekla GUI instance via .NET Remoting.
-
Fresh
Model()per call β Tekla Model instances must not be cached across tool invocations. -
Always
CommitChanges()β every create/modify/delete must be followed by CommitChanges. -
All coordinates in millimeters β Tekla's API uses mm for all dimensions.
-
Profile/material strings must match catalog β use
ListProfiles/ListMaterialsto verify before creating parts. -
Multiple live Tekla versions require an explicit selection use
TEKLA_VERSION,TEKLA_BIN_DIR, orconfig/settings.jsonwhen more than one Tekla version is open at once.
Design Position
This server is a native C# Tekla Open API host with optional local Python semantic search. The main production choices are:
- direct .NET API calls instead of a runtime bridge
- stdio MCP transport only; no WebSocket or REST middle layer
- compact query snapshots on disk with
queryIdhandoff for batch work - batch-first create/modify/delete/drawing tools
- exact catalog validation for profile and material names
- dry-run-first catalog mutation tools with timeouts to avoid stalled Tekla catalog sessions
License
Copyright (c) 2025-2026 Martin Velichkov. All Rights Reserved. See LICENSE for details.
