staad-core — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited staad-core (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
staad, input_data, json, mathimport statements, dir(), getattr(), ... are BLOCKED — use skills for discovery, only use pre-injected names in codestaad is already connected and ready — do NOT call any initialization functioninput_data is injected if input_data_path is provided in execute_code params — use it to feed large datasets into the sandbox without hardcodinggeo = staad.Geometry, prop = staad.Property, sup = staad.Support, load = staad.Load, cmd = staad.Command, out = staad.Output, design = staad.Designoutput_data_path is provided, write the result variable to that file path instead of returning it in the context (use for large/tabular data). The execute_code return value will contain a summary of the result content instead (e.g. number of rows, columns and a sample of rows).input_data_path and output_data_path 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.Before writing any script:
discover_api → lists available skills and usage guidanceread_skills with skill names → detailed instructions for that domainNever guess or invent function names — only use names from the skill documentation.
list_instances to see all running STAAD.Pro instances (lightweight ROT scan)get_status(instance) to verify a specific instance is reachableinstance (alias like staadPro1) to execute_code when multiple instances are runningThe MCP is built against a single bundled openstaadpy wrapper, identical for every connected instance — so the wrapper is never something to gate on. What does vary is the STAAD.Pro version of each running instance. Two consequences:
Assign* methods return bool andraise on failure instead of returning a negative int code (see staad-steel-design, staad-properties, staad-supports). Use try/except; do not check if result < 0 for those methods.
GetAnalysisErrorMessages,GetAnalysisWarningMessages). On an older connected STAAD they do not exist and raise a clear "update STAAD.Pro" error.
Gate STAAD-v26-only functions using the version you already have — do NOT add a check inside the script:
list_instances → each row includes a version field; orget_status(instance) → returns staad_version. This is the STAAD.Pro version, not the wrapper version.
execute_code call using thev26-only function.
STAAD.Pro v26.
Functions marked (Requires STAAD.Pro v26+) in the skills need a connected STAAD of that version or newer.
execute_code:staad.GetBaseUnit() → "English" or "Metric"staad.Geometry.IsZUp() → True if Z is upstaad.GetInputUnitForLength() / staad.GetInputUnitForForce() → current input unit stringsEnglish = inches + KIP; Metric = meters + kNstaad.SetInputUnits(lengthUnit, forceUnit) → change input units (integer codes)SetSilentMode(True) MUST be called before these operations (they trigger UI dialogs that block automation):
UpdateStructure, SaveModelAnalyzeModel, AnalyzeExAlways restore with SetSilentMode(False) at the end of the script.
UpdateStructure() = reload from disk — it discards all in-memory AddNode/AddBeam state that has not yet been written to disk. If you call it after adding geometry in the same script, all that geometry is lost.SaveModel(True) = write current in-memory state to disk without reloading — use this to flush geometry before assigning supports/loads in the same script session.SaveModel(True) — not UpdateStructure().UpdateStructure is only safe to call when the current in-memory state already matches what is on disk.AddNode/AddBeam just to query geometry — COM geometry APIs read from the in-memory buffer immediately.SaveModel() casually — only when:.std file from disk), orAlways work on the currently open model. If the user says "create a model", that means add geometry/properties to the current open model — not create a new file.
staad and all sub-objects remain valid — do NOT reinitializestaad.GetSTAADFile() to get the current model pathstaad.GetSTAADFileFolder() returns the folder path#### Opening, Creating & Saving Files
The following functions are available but path-validated by the sandbox:
staad.OpenSTAADFile(filePath) — open an existing STAAD model filestaad.NewSTAADFile(filePath, envCode, unitCode) — create a new STAAD model filestaad.SaveAs(filePath) — save the current model to a new file pathstaad.CloseSTAADFile() — close the currently open modelPath rules (enforced automatically — violations raise an error):
"C:\\Users\\me\\models\\bridge.std")\\\\server\\share\\...) are blockedWindows, Program Files, ProgramData) are blocked..) is blocked# Open an existing model
staad.OpenSTAADFile("C:\\Projects\\Bridge\\bridge_v2.std")
# Create a new model (envCode=1 for general, unitCode depends on unit system)
staad.NewSTAADFile("C:\\Projects\\NewModel\\frame.std", 1, 0)
# Save a copy
staad.SaveAs("C:\\Projects\\Bridge\\bridge_backup.std")
# Close the current model
staad.CloseSTAADFile()staad.ShowApplication() — show the STAAD.Pro windowstaad.GetApplicationVersion() → version stringstaad.IsPhysicalModel() → True if physical model modestaad.Quit() — close the application (use with caution)staad.AnalyzeEx(silentMode, hiddenMode, waitTillComplete) → status code2 = OK, 3 = warnings, 4 = errors, -1 = terminatedsilentMode=1, waitTillComplete=1 for automationstaad.AnalyzeModel() — simplified, no return valueimport, dir(), getattr(), ... are blocked — only staad, input_data, json, math are availableinput_data_path is provided, input_data is injected as an immutable variable — use it to feed large datasets into the sandbox without hardcodingoutput_data_path is provided, write the result variable to that file path instead of returning it in the context (use for large/tabular data). The execute_code return value will contain a summary of the result content instead (e.g. number of rows, columns and a sample of rows).input_data_path and output_data_path 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.staad.GetSTAADFile() to get the current model path after a file switchUpdateStructure/AnalyzeModel/AnalyzeEx/SaveModel inside SetSilentMode(True/False)SaveModel without explicit user instructionUpdateStructure discards in-memory geometry not yet on disk — use SaveModel(True) instead when you need to flush before support/load assignmentAnalyzeEx runs both analysis AND design; AnalyzeModel runs analysis only~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.