Skip to main content
Glama
BentleySystems

OpenSTAAD MCP Server

Official

OpenSTAAD MCP Server

A Model Context Protocol (MCP) server for Bentley STAAD.Pro that enables AI agents like Claude Desktop, Gemini, or VSCode Copilot to interact with your STAAD.Pro models and perform various time-consuming tasks like load cases definition, data extraction, repetitive property setting and more.

This MCP server was introduced as part of Bentley's Infrastructure AI Co-Innovation Initiative to help our users and accounts discover opportunities and innovate faster, while connecting Bentley's unique engineering tool capabilities to their emerging agentic workflows.

Key Features

  • Fast and flexible: Enjoy minimal latency, interact with every STAAD.Pro features covered by the OpenSTAAD API.

  • AI-friendly: Provides documentation, guidance and feedback via dedicated tools to help your AI agent ramp up quickly on the STAAD.Pro API.

  • Multi-instance support: Connects to multiple running STAAD.Pro instances simultaneously to parallelize tasks across models.

  • Privacy-first: All processing happens locally on your machine. No data is sent to the cloud. No telemetry.

Related MCP server: Tekla MCP Server

Prerequisites

  • OS: Windows 11 or newer

  • STAAD.Pro 2025 or newer installed and running

Quick Start with Claude Desktop (<2min)

  1. Download the latest openstaad-mcp.mcpb file from the GitHub Releases page.

  2. Open Claude Desktop.

  3. Click the ☰ menu (top-left) → FileSettingsExtensions.

  4. Click AdvancedInstall Extensions.

  5. Select the downloaded .mcpb file.

  6. Click the ☰ menu (top-left) → FileExit

  7. Restart Claude Desktop.

Claude Desktop will install the server automatically. Open a new conversation and ask Claude to interact with your STAAD.Pro model.

Tip: Make sure STAAD.Pro is running with a model open before you start chatting.


Other Clients & Configuration

TL;DR:

If not already installed, install uv with the command:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Configure your client to start the server in stdio mode with the command:

uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp

VS Code with GitHub Copilot

  • For stdio: Open the Command Palette → MCP: Add Server...Command (stdio) and enter the following command:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp
  • For http: First, start the server in a terminal:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp --transport http

    Look for the generated token and URL in the terminal output. It should look like this:

    WARNING: No --token provided. Auto-generated token: abc123def456ghi789jkl012mno345pq
    INFO:  Starting MCP server 'OpenSTAAD MCP' with transport 'http' (stateless) on http://127.0.0.1:18120/mcp

    Then, in VS Code, open the Command Palette → MCP: Add Server...HTTP URL and enter the URL shown in the terminal (e.g. http://127.0.0.1:18120/mcp). 18120 is the default port, but yours may differ if you have multiple instances running or if you changed the default. Add the header Authorization: Bearer <token> with the token shown in the MCP server terminal.

GitHub Copilot CLI

Use the /mcp add command inside a Copilot CLI session to add the server. See the Copilot CLI documentation for more details.

  • For stdio transport, use the command:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp
  • For HTTP transport, first start the server in a terminal:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp --transport http

    Look for the generated token and URL in the terminal output. It should look like this:

    WARNING: No --token provided. Auto-generated token: abc123def456ghi789jkl012mno345pq
    INFO:  Starting MCP server 'OpenSTAAD MCP' with transport 'http' (stateless) on http://127.0.0.1:18120/mcp

    Then add the server in Copilot CLI using the URL shown in the terminal (e.g. http://127.0.0.1:18120/mcp). 18120 is the default port, but yours may differ if you have multiple instances running or if you changed the default. Add the header Authorization: Bearer <token> with the token shown in the MCP server terminal.

Claude Desktop (manual configuration)

If you prefer manual setup over the .mcpb bundle, edit the Claude Desktop config file directly:

  • Windows (MSIX): %LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude_desktop_config.json

  • Windows (classic): %APPDATA%\Claude\claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "openstaad": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/BentleySystems/openstaad-mcp", "openstaad-mcp"]
    }
  }
}

Claude Code (CLI)

  • For stdio transport, use the command:

    claude mcp add --transport stdio openstaad -- uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp
  • For HTTP transport, first start the server in a terminal:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp --transport http

    Look for the generated token and URL in the terminal output. It should look like this:

    WARNING: No --token provided. Auto-generated token: abc123def456ghi789jkl012mno345pq
    INFO:  Starting MCP server 'OpenSTAAD MCP' with transport 'http' (stateless) on http://127.0.0.1:18120/mcp

    Then add the server in Claude Code with the command:

    claude mcp add --transport http openstaad http://127.0.0.1:18120/mcp --header "Authorization: Bearer <your-token>"

    18120 is the default port, but yours may differ if you have multiple instances running or if you changed the default.

Gemini CLI

  • For stdio transport, use the command:

    gemini mcp add openstaad uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp
  • For HTTP transport, first start the server in a terminal:

    uvx --from git+https://github.com/BentleySystems/openstaad-mcp openstaad-mcp --transport http

    Look for the generated token and URL in the terminal output. It should look like this:

    WARNING: No --token provided. Auto-generated token: abc123def456ghi789jkl012mno345pq
    INFO:  Starting MCP server 'OpenSTAAD MCP' with transport 'http' (stateless) on http://127.0.0.1:18120/mcp

    Then add the server in Gemini CLI with the command:

    gemini mcp add --transport http --header "Authorization: Bearer <your-token>" openstaad http://127.0.0.1:18120/mcp

    18120 is the default port, but yours may differ if you have multiple instances running or if you changed the default.

Transport Modes

The server supports two transport modes:

Mode

When to use

stdio (default)

The MCP client launches the server process directly. Used by Claude Desktop, Claude Code, VS Code Copilot (stdio config).

HTTP

The server runs persistently and clients connect over the network.

CLI Options

Flag

Default

Description

--transport {stdio,http}

stdio

Transport mode

--log-level LEVEL

INFO

DEBUG, INFO, WARNING, or ERROR

--log-file PATH

OS default

Path to log file

--port PORT

18120

[http] TCP port to listen on

--token TOKEN

-

[http] Bearer token for authentication


Available MCP Tools

Tool

Description

discover_api

Lists available API skills and usage guidance

read_skills

Returns detailed guidance for requested skills

list_instances

Lists active STAAD.Pro instances with model paths and versions

execute_code

Runs validated Python code against the connected STAAD.Pro model

get_status

Returns connection state, STAAD version, model path, analysis status

File I/O

The execute_code tool supports optional server-side file I/O for bulk data workflows. Instead of passing large datasets through the agent's context window, the server reads/writes CSV and XLSX files directly and injects the data into the sandbox as the input_data variable.

Parameter

Description

input_data_path

Path to a .csv or .xlsx file. The server reads and parses it, then injects as the input_data variable in the sandbox.

output_data_path

Path where the sandbox return value will be written. The return value must be a list-of-lists (CSV) or a {sheet_name: {columns, rows}} dict (multi-sheet XLSX).

overwrite

Allow overwriting an existing output file (default false).

input_data has a stable, extension-specific shape:

  • CSV: a list of row lists. If a header is detected, it is input_data[0] and data rows start at input_data[1:].

  • XLSX: a dict: {sheet_name: {"columns": list, "rows": list_of_rows}}.

Path containment: File paths must resolve inside a configured allowed boundary before any read/write occurs. The server supports both client-configured MCP roots and server-configured allowed directories (via --allowed-dirs or user_config.allowed_directories in the manifest). The server validates paths against these boundaries before any file access.

Limits: Max file size 50 MB, max 100K rows, max 500 columns, max 50 input sheets.

Security Notes

  • Bearer token authentication. Pass --token MY_SECRET_TOKEN when running in HTTP mode and include Authorization: Bearer <token> in client requests.

  • DNS rebinding protection. Starlette Middlewares validate Host, Sec-Fetch-Site and Origin headers.

  • Code sandbox. The execute_code tool validates all Python code via AST analysis before execution. Imports, file access, and dangerous builtins are blocked.

Privacy Policy

Please find the Bentley Systems privacy policy here.


Development Setup

1. Clone the repository

git clone https://github.com/BentleySystems/openstaad-mcp.git
cd openstaad-mcp

2. Create a virtual environment

python -m venv .venv

# Windows (PowerShell)
.\.venv\Scripts\Activate.ps1

# Windows (cmd)
.venv\Scripts\activate.bat

3. Install in editable mode with dev dependencies

pip install -e ".[dev]"

4. Run the server from source

# stdio mode (default)
openstaad-mcp

# HTTP mode
openstaad-mcp --transport http

5. Run tests

# All unit tests (no STAAD.Pro needed)
pytest

# Specific test files
pytest tests/test_skills.py tests/test_connection.py -v

# Integration tests (requires a running STAAD.Pro instance on Windows)
pytest -m integration -v

6. Lint

ruff check .
ruff format --check .

7. Building the MCPB Bundler

  1. To produce the standalone .exe files distributed via the installer:

pip install -e ".[build]"
pyinstaller mcpb/openstaad-mcp.spec --noconfirm

This creates one file in the dist/ directory:

  • openstaad-mcp.exe: console executable (stdio & http transport)

  1. To create the .mcpb installer bundle, run:

npm install -g @anthropic-ai/mcpb
New-Item -ItemType Directory -Path mcpb-staging -Force
Copy-Item dist/openstaad-mcp.exe mcpb-staging/

$version = (Select-String -Path pyproject.toml -Pattern '^version\s*=\s*"(.+)"$').Matches[0].Groups[1].Value
$manifest = Get-Content mcpb/manifest.json -Raw | ConvertFrom-Json
$manifest.version = $version
$manifest | ConvertTo-Json -Depth 10 | Set-Content mcpb-staging/manifest.json -Encoding utf8

mcpb pack mcpb-staging/ openstaad-mcp.mcpb

The output MCPB bundle is written to .\openstaad-mcp.mcpb.

Contributing

See CONTRIBUTING.md for guidelines on setting up your development environment, branch naming, running tests, and submitting pull requests.

Available Tools

5 tools
discover_apiDiscover API and skillsA
Read-onlyIdempotent

Discover available API guidance and skills.

Call this FIRST before using other openstaad-mcp tools. Then use read_skills with one or more specific skill names to load full guidance.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the tool is known to be safe. The description adds the behavioral directive to call it first, providing context beyond structured annotations. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words, front-loaded with purpose and immediately providing actionable usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema available and zero parameters, the description fully covers the tool's purpose and usage, making it complete for an agent to select and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description has no parameter semantics to cover. The baseline of 4 applies as there is nothing to clarify.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action ('Discover') and resource ('available API guidance and skills'), distinguishing it from sibling tools like read_skills (which loads guidance) and list_instances (which lists instances).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs 'Call this FIRST before using other openstaad-mcp tools' and directs to 'read_skills' for loading full guidance, providing clear when-to-use and an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_codeExecute Python codeA
Destructive

Execute Python code in a sandbox against the OpenSTAAD API (don't forget to call discover_api and read_skills for API guidance).

The sandbox provides pre-connected staad (the OpenSTAAD root object) and input_data (if input_data_path is provided) variables (plus json and math modules). import statements, dir(), getattr(), ... are BLOCKED.

The last expression value or an explicit result = ... assignment is returned as the result. If output_data_path is provided, the sandbox will write the result to the specified file.

Paths must be on the user LOCAL filesystem and inside MCP roots or configured allowed_dirs. On Claude Desktop, users can configure allowed directories in the extension settings and Claude can use the filesystem copy_file_to_claude tool to move files to Claude's filesystem.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesPython source code to execute. Use the pre-injected ``staad`` variable to interact with the API. (don't forget to call discover_api and read_skills for API guidance)
instanceNoAlias (from ``list_instances``, e.g. ``staadPro1``) of the STAAD instance to target. If omitted, last opened instance is selected.
overwriteNoAllow overwriting an existing output file.
input_data_pathNoPath on user LOCAL filesystem to a ``.csv`` or ``.xlsx`` file. Its content is injected as the immutable `input_data` variable inside the sandbox. Use this to feed large datasets (e.g. node loads, section properties) into your code without hardcoding them.
output_data_pathNoPath on user LOCAL filesystem to a ``.csv`` or ``.xlsx`` file where to write the ``result`` value. Use this to avoid flooding the context window with large amount of data. The ``result`` variable must be formatted as one of: - List-of-lists → written as CSV or single-sheet xlsx: result = [["Node ID", "X", "Y", "Z"], [1, 0.0, 0.0, 0.0], ...] - Dict of sheet dicts → written as multi-sheet xlsx: result = { "Nodes": {"columns": ["Node ID", "X", "Y", "Z"], "rows": [[1, 0.0, 0.0, 0.0], ...]}, "Members": {"columns": ["Member ID", "Start", "End"], "rows": [[1, 1, 2], ...]} }

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the `destructiveHint: true` annotation, the description discloses exactly what the sandbox does: it blocks `import`, `dir()`, and `getattr()`, pre-injects `staad`/`input_data`/`json`/`math`, and returns either the last expression value or an explicit `result` assignment. It also reveals file-write behavior, overwrite guard, and local filesystem/path restrictions, which is substantial behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear paragraphs (environment, result semantics, file paths, local-path rules) and front-loads the purpose. However, the reminder to call `discover_api` and `read_skills` appears both in the main description and in the `code` parameter description, creating minor redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex code-execution tool, the description covers the sandbox environment, blocked operations, result return, output file behavior, and path security, and an output schema exists for return values. It does not explicitly warn that API calls through `staad` may mutate the STAAD model or describe failure/timeout behavior, which is a minor gap given the destructive annotation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All five parameters have rich descriptions in the input schema (100% coverage), so the description does not need to re-describe them. It adds useful context for the `code` and `output_data_path` parameters by explaining the sandbox result mechanism and file-writing behavior, but this is complementary rather than essential because the schema already covers parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence precisely states the action ('Execute Python code in a sandbox against the OpenSTAAD API') and names the concrete resources (`staad`, `input_data`). It is clearly distinguishable from sibling tools like `discover_api`, `read_skills`, `list_instances`, and `get_status`, which are all informational or instance-selection tools rather than execution tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear context for use: it instructs the agent to call `discover_api` and `read_skills` first, notes the pre-connected `staad` and `input_data` variables, and explains when to use `output_data_path` to avoid flooding the context window. It does not explicitly state when *not* to use the tool or name an alternative for code execution, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_statusGet STAAD.Pro instance statusA
Read-only

Check the connection to a STAAD.Pro instance.

Pass instance (alias from list_instances) to target a specific instance. Omit it when only one instance is running.

Returns connection state, STAAD version, and model path.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it readOnly, and the description reinforces this by describing a connection check. It adds useful behavioral context by stating return values (connection state, STAAD version, model path) and the dependency on list_instances for the alias. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, with three short blocks that front-load the purpose. No filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with one optional parameter, the description covers purpose, parameter usage, return values, and a cross-reference to list_instances. It is complete enough to guide selection and invocation without needing additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates by explaining the instance parameter's origin (alias from list_instances) and when to omit it. It does not specify exact type constraints beyond the schema's anyOf, but for a single optional parameter this is sufficient semantic guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses 'Check the connection' to specify the action and resource, clearly identifying it as a status/inspection tool for a STAAD.Pro instance. It distinguishes itself from siblings like list_instances by focusing on connection state, version, and model path rather than enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit context on parameter usage: pass the instance alias from list_instances, and omit it when only one instance is running. It does not explicitly mention exclusions or when to prefer other sibling tools, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_instancesList running STAAD.Pro instancesA
Read-only

List all running STAAD.Pro instances.

Returns a list of instances with their alias, process ID, currently open file path, and STAAD version. Call this before execute_code when multiple STAAD instances may be running so you can pick the right one. The alias (e.g. staadPro1) is stable for the server session even if the model file changes.

If a version is below the minimum supported (25.0.1), a warning field is included with details about potential data inaccuracies.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, but the description adds valuable behavioral context: the alias is stable across model file changes, and a warning field appears for versions below 25.0.1. These details go beyond what annotations provide and help the agent anticipate edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, front-loaded with the core purpose, and uses a short second paragraph for usage and conditional behavior. Every sentence contributes useful information, making it appropriately sized and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (0 params), rich output schema, and strong annotations, the description covers the essential aspects: what it lists, when to use it, and a notable behavior (version warning). No important gaps are evident.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema is empty. The baseline for 0 params is 4. The description reinforces 'all instances' and the return fields, but since there are no parameters to explain, it cannot add more parameter-specific meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List all running STAAD.Pro instances.' It clearly states the tool's function and distinguishes it from siblings by mentioning the returned fields (alias, process ID, file path, version) and its role as a precursor to execute_code.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Call this before execute_code when multiple STAAD instances may be running so you can pick the right one.' This gives a clear when-to-use directive and a rationale, which is more than the minimal context needed for a simple listing tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_skillsRead OpenSTAAD skillsA
Read-onlyIdempotent

Read one or more skills by name.

Use discover_api first to list available skills. Each skill provides domain-specific guidance (e.g. analysis, geometry, loads).

Pass skill names like ["staad-analysis"] or sub-paths like ["staad-steel-design/assets/DESIGN_CODES"] to read reference files within a skill.

ParametersJSON Schema
NameRequiredDescriptionDefault
skillsYesList of skill names or sub-paths to read. Use ``discover_api`` to see available skills.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and idempotentHint=true, so the description doesn't need to restate safety. It adds useful behavior context by mentioning sub-paths like 'staad-steel-design/assets/DESIGN_CODES' to read reference files, and explains skills provide domain-specific guidance.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the primary purpose, followed by prerequisite guidance and examples. No redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with a single parameter and an output schema, the description fully covers how to use it: what it reads, how to discover available skills, and how to pass names or sub-paths. The output schema handles return values, so no additional explanation is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers 100% of the parameter description, but the description adds concrete examples ('["staad-analysis"]' and sub-paths) and clarifies that sub-paths read reference files within a skill. This goes beyond the schema's generic 'List of skill names or sub-paths'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads one or more skills by name, with the verb 'read' and resource 'skills'. It also distinguishes from sibling tools like discover_api (lists skills) by describing the sub-path capability for reading reference files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs to 'Use discover_api first to list available skills', providing a clear prerequisite and context. It doesn't explicitly state when not to use this tool, but the read-only nature and examples suggest it is for accessing skill content, not for executing commands.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv1.2.0
    • First observeddiscover_api
    • First observedexecute_code
    • First observedget_status
    • First observedlist_instances
    • First observedread_skills

TDQS

A4.6/5.0
Disambiguation4/5

discover_api and read_skills are sequential but distinct; list_instances and get_status both report instance state, though one enumerates all instances and the other checks a single connection. No severe ambiguity.

Naming Consistency5/5

All five tools follow a consistent verb_noun snake_case convention (discover_api, read_skills, list_instances, get_status, execute_code), making the pattern predictable.

Tool Count5/5

Five tools is well-scoped for an API execution server: discovery, guidance, instance listing, status check, and code execution. Each tool has a clear role.

Completeness4/5

The workflow from discovering guidance to executing code is covered. Minor gap: no explicit instance selection parameter on execute_code and no model lifecycle tools, but the API sandbox can handle those operations.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI platforms to control Autodesk Navisworks via natural language, supporting model analysis, selection, data extraction, and visual management.
    5
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-driven interaction with Tekla Structures through natural language commands, allowing users to select elements, insert components, and automate modeling workflows.
    10
    -
  • A
    license
    A
    quality
    B
    maintenance
    Connects AI assistants to CSI ETABS for structural engineering tasks, enabling model creation, analysis, design, and seismic checks via the COM API.
    69
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to interact with Autodesk Civil 3D through natural language, supporting tools for surfaces, alignments, profiles, corridors, pipe networks, COGO points, and AutoCAD geometry.
    9
    2
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/BentleySystems/openstaad-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server