Skip to main content
Glama
designsafe-mcp

designsafe-mcp

by kks32

designsafe-mcp

An agent-first cyberinfrastructure layer for DesignSafe, scoped to a bounded subset of the quoFEM pipeline for geotechnical earthquake engineering with OpenSees as the forward solver. The server exposes scientific actions, find a tested workflow, build and validate a job, price it, run it after human approval, and package the result with provenance, so an AI agent (or a researcher) composes reproducible computational science instead of driving low-level APIs. supported_capabilities() declares exactly what is supported, in which scientific domain, and how much of it is tested; requests outside that map are declined by design.

dapi and Tapis remain the substrate; this layer translates research intent into trustworthy workflows. Orchestration comes from a tested snippet corpus (executed, self-checking, version-pinned examples), never from a model's recall of the API.

ARCHITECTURE.md records the full design: the layer stack, why decisions live in tools rather than in the model, deployment topologies, and the evaluation methodology.

Tools

Action

Tool

Decide how to run it

plan_simulation(request, facts...) walks the OpenSees decision matrix

See the matrix itself

opensees_matrix(); the deck's slide ships as an MCP resource

Find a tested workflow

search_snippets(query)

Search the corpus

search_community(query) over UW community data, dapi examples, the ds-workflows book

Ground in the real app interface

describe_app(app_id)

Move data

stage_inputs(local_dir)

Construct the experiment

build_job_request(...), build_workflow_preview(...)

Check before spending

validate_job(job), estimate_cost(job)

Human gate

approve_submission(job) -> token; submit_job(job, token) refuses without it

Execute and monitor

submit_job, job_status, get_results

Provenance

write_manifest(...)

Related MCP server: HACOO MCP Server

Run

uv venv .venv && uv pip install -p .venv/bin/python -e .
.venv/bin/python -m designsafe_mcp.server   # stdio MCP server

Register it once for Claude Code with claude mcp add designsafe -- $PWD/.venv/bin/python -m designsafe_mcp.server, or add the same command to .jupyter/mcp_settings.json for jupyter-ai. Auth rides on dapi's environment; nothing is stored here.

demo/transcript.txt holds an executed transcript: discovery, grounding, staging, validation, cost, a refused unapproved submission, the approved run, results, the manifest, and a compiled two-stage DAG preview.

Evals

.venv/bin/python evals/runner.py --mode planner                       # deterministic floor
.venv/bin/python evals/runner.py --mode agent --models haiku,sonnet --trials 3

Golden cases in evals/cases.yaml map natural-language requests to the expected decision; agent mode drives real models against the server in DESIGNSAFE_MCP_MOCK=1 mode (no Tapis calls, no SUs) and scores each trace on decision, grounding, and the approval gate. Pass rate per case per model is the ability metric.

Available Tools

27 tools
approve_submissionA

Record human approval for exactly this job request; returns the token submit_job requires. The calling harness must show the trust summary (snippet, versions, cost, outputs) to a human before calling this.

Inputs: job (required). Returns: result

build_job_requestA

Build a complete Tapis job request from the app definition.

Mirrors ds.jobs.generate; returns the dict for inspection. Nothing is submitted. SimCenter apps (quoFEM) take no script_filename; dapi wires scInput.json and the driver automatically.

Inputs: app_id (required), allocation (required), input_dir_uri (required), queue, +8 more. Returns: object

build_workflow_previewA

Compile a DAG of job requests without running it.

tasks: [{"task_id", "job", "depends_on": [...], "input_from": {"task_id", "suffix"} (optional)}] Returns the compiled pipeline: deterministic archives, resolved edges.

Inputs: name (required), tasks (required). Returns: object

calibration_optionsA

Every calibration-stage method runnable on DesignSafe, with its engine, what it returns, and its tested/candidate status.

Inputs: no named parameters. Returns: result

corpus_statusA

What the grounding index covers and where it came from: each logical source (UW notebooks, dapi, the ds-workflows book), how it resolved (local checkout, fetched cache, or absent), how many passages it contributes, and when the index was built. An absent source means degraded grounding; say so rather than answering from partial knowledge, and fetch_corpus() can fill the gap live.

Inputs: no named parameters. Returns: object

describe_appC

The app's real interface from Tapis: inputs, parameters, defaults.

Inputs: app_id (required). Returns: object

describe_materialA

Parameters, sensitivities, and the calibration sequence for a constitutive model, transcribed from its manual with page citations.

Use this before planning a calibration: it answers which parameters exist, what data informs each one, and in what order to calibrate.

Inputs: model (required). Returns: object

estimate_costA

Estimated SU cost: nodes x hours, per the DesignSafe job-resources guidance.

Inputs: job (required). Returns: object

fetch_corpusA

Fetch grounding sources live from their canonical GitHub repos into corpus/, for deployments without local checkouts.

source: fetch just one logical source by name; empty fetches every GitHub-backed source. CommunityData is not fetched here (needs Tapis auth; see corpus_status for the command). Run reindex after.

Inputs: source. Returns: object

get_resultsC

List the job archive, or return a small text file's content.

Inputs: uuid (required), path. Returns: object

job_statusC

Current Tapis status for a submitted job.

Inputs: uuid (required). Returns: object

list_app_templatesB

Names of the app templates that ship with dapi.

[schema introspected from dapi 0.6.1 (apps.templates); this tool is generated, not maintained by hand]

Inputs: no named parameters. Returns: result

list_my_jobsA

List jobs with optional filtering.

Fetches jobs from Tapis ordered by creation date (newest first). Filters are applied client-side.

Args: app_id (str, optional): Filter by application ID. status (str, optional): Filter by job status (e.g., "FINISHED"). Case-insensitive. limit (int, optional): Maximum jobs to fetch. Defaults to 100. output (str, optional): Output format. "df" for pandas DataFrame (default), "list" for list of dicts, "raw" for TapisResult objects. verbose (bool, optional): Print job count. Defaults to False. list_type (str, optional): "MY_JOBS" (default) for jobs you own, "SHARED_JOBS" for jobs shared with you, "ALL_JOBS" for both.

Returns: Depends on output: DataFrame, list of dicts, or list of TapisResult objects.

Raises: JobMonitorError: If the Tapis API call fails.

Example: >>> df = ds.jobs.list(app_id="matlab-r2023a", status="FINISHED") >>> jobs = ds.jobs.list(output="list") >>> raw = ds.jobs.list(limit=10, output="raw")

[schema introspected from dapi 0.6.1 (jobs.list); this tool is generated, not maintained by hand]

Inputs: limit, app_id, output, status, +2 more.

list_queuesA

List batch queues available on a Tapis execution system.

Args: system_id (str): The ID of the execution system (e.g., "stampede3"). output (str, optional): "df" for DataFrame (default), "raw" for Tapis objects.

Returns: DataFrame or List: Queues with name, maxNodes, maxMinutes, etc.

Example: >>> ds.systems.queues("stampede3")

[schema introspected from dapi 0.6.1 (systems.queues); this tool is generated, not maintained by hand]

Inputs: system_id (required), output.

list_systemsA

List Tapis systems you have access to.

Filters out internal and project-specific systems by default.

Args: category (str, optional): "hpc" for execution systems, "storage" for storage systems, "all" for everything, None for HPC + storage (default). output (str, optional): "df" for DataFrame (default), "list" for dicts.

Returns: DataFrame or List[Dict]: Systems with id, host, category, authn, credentials.

Example: >>> ds.systems.list() # HPC + storage >>> ds.systems.list("hpc") # HPC only with credential status >>> ds.systems.list("storage") # Storage only >>> ds.systems.list("all") # Everything including internal

[schema introspected from dapi 0.6.1 (systems.list); this tool is generated, not maintained by hand]

Inputs: output, category.

opensees_matrixA

Which OpenSees to use when: the decision matrix from the training deck.

Returns the variant table (variant -> app_id -> when), the full scope x platform x interface matrix with its legend, and the path of the original slide image for display to the user.

Inputs: no named parameters. Returns: object

plan_calibrationA

Plan a calibration study from the method matrix.

Pass what you know; unanswered facts come back as open questions. uncertainty_required: must the result carry parameter uncertainty into a downstream prediction (posterior), or is a best-fit point enough? quofem_wrappable: can quoFEM drive the model (OpenSees main script with parameter placeholders and a scalar-QoI postprocessor)? screened: has a sensitivity study already reduced the parameter set?

Inputs: request (required), screened, material_model, quofem_wrappable, +2 more. Returns: object

plan_simulationA

Plan an OpenSees/quoFEM simulation from the decision matrix.

Pass the facts you know; anything left None is inferred from the request only when unambiguous, and otherwise returned in open_questions for you to ask the user. The decision is the matrix's, not yours: do not override app_id, and compose the cells from the returned snippet, not from memory.

model_language: "tcl" | "python" parallelism: "serial" | "domain-decomposition" | "single-domain-parallel-solver" | "many-independent-cases"

Inputs: request (required), n_cases, pipeline, parallelism, +3 more. Returns: object

reindexA

Rebuild the index after mirroring new notebooks or references.

Inputs: no named parameters. Returns: object

search_communityA

Search every local notebook, model, and script for aligned passages.

Returns the matching text itself with its source path and the index build stamp, so the caller can ground a workflow in what the community actually wrote and knows how fresh that knowledge is. Call corpus_status() to see which sources the index covers; use search_docs for documentation-only search.

Inputs: query (required), limit. Returns: result

search_docsA

Search the documentation corpus: the dapi user guide, the ds-workflows book, SimCenter quoFEM docs, and reference manuals.

Grounding only, never the source of orchestration code; snippets remain the only source an agent may compose runs from. Results carry source and index stamp. Backend today is a local index over live-fetched docs; the Ask AI knowledge graph replaces it later behind this same tool.

Inputs: query (required), limit. Returns: result

search_snippetsA

Find tested, version-pinned workflow snippets matching a query.

Snippets are executed, self-checking notebooks with pinned app and dapi versions; only entries whose test passed are in the corpus.

Inputs: query (required), app_id. Returns: result

stage_inputsB

Upload a local folder once and return the tapis:// URI to run from.

Inputs: local_dir (required), app_id. Returns: result

submit_jobA

Submit a validated job. Refuses without the approval token minted by approve_submission for this exact request.

Inputs: job (required), approval_token (required). Returns: object

supported_capabilitiesA

What this server supports, by scientific domain.

Consult this before promising anything. Every capability names how it is served and whether it is tested; 'candidate' and 'untested' entries need a human-run graduation before unattended use. Requests outside this map should be declined by pointing at out_of_scope.

Inputs: no named parameters. Returns: object

validate_jobB

Schema and sanity checks plus input existence, before any SU is spent.

Inputs: job (required). Returns: object

write_manifestA

Emit the provenance manifest that makes the run reproducible.

Refuses incomplete provenance: the job must be a fully built request (app, name, resources, inputs) and the uuid must belong to a job this server submitted. A manifest that cannot reproduce the run is worse than none.

Inputs: job (required), uuid (required), request (required), out_path (required), +2 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 27 tools

    Disambiguation5/5

    Each tool targets a distinct resource or workflow step, from planning and search to job submission and provenance. The three search tools are clearly differentiated by corpus, and the planning tools are separated by domain.

    Naming Consistency4/5

    Most tools follow a verb_noun pattern (search_snippets, build_job_request, list_queues), but a few are noun-style (supported_capabilities, calibration_options, opensees_matrix) and 'job_status' uses noun_noun. This is mostly consistent but not uniform.

    Tool Count2/5

    At 27 tools, the server is over the 25 threshold for 'too many'. While each tool has a distinct role, the number feels heavy for an agent to navigate, and several could be consolidated (e.g., listing tools).

    Completeness4/5

    The server covers the full lifecycle from planning through provenance, including search, calibration, and job management. However, it lacks a cancel/stop job tool, which is a common operation in HPC workflows.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables creation and invocation of reusable research workflow programs derived from demonstrations, with live scholarly data search and workspace automation via multiple protocols.
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables multi-agent orchestration of digital IC design flows (DFT, synthesis, APR, STA, PV, IREM, thermal, SIPI) through natural language by integrating heterogeneous EDA tools into a unified, secure, and observable API space with per-agent knowledge bases and decision traceability.
      -
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables deterministic, harness-neutral research workflows by unifying research object identity, evidence receipts, claim-evidence graphs, and append-only decision logs, along with specialized scholarly skills for literature analysis, reproducibility audits, and multi-agent review.
      206 PyPI
      1
      -