Tools

Tool reference.

Every tool is a typed, stable interface to PLCs.ai. Names are stable, snake_case, and prefixed plcs_. Reads are safe; writes are consequential and may be billable — see Safety & billing.

19 toolsStreamable HTTP

Inputs below are the agent-visible parameters. The server manages transport details for you: model tools (plcs_interpret, plcs_generate_code) run synchronously and return one complete result; writes accept an optional idempotency_key (omit it and the server mints one per call); and file uploads take a file_path/file_inline/file_blob_url instead of raw multipart. For a large or locally-generated file, plcs_stage_upload returns a short-lived upload URL you PUT the bytes to — then pass it back as file_blob_url, so the file never streams through the model.

Connect & discover

plcs_health

Authenticated health check

GET/health
Read-onlyAny valid credential

Authenticated connectivity check for PLCs.ai. Returns the organization id resolved from your credential and the actor type. Use this first to confirm the connection works and which organization you are acting as. Requires only a valid credential — no extra permission.

Inputs

No inputs.

plcs_list_projects

List projects

GET/projects
Read-onlyAny valid credential

List the PLC projects this credential can see, most-recently-touched first. Returns identity metadata only (id, name, vendor, version, analysis status) — NOT the project source; read source with plcs_get_project_source. Results are filtered to the credential's project scope and paginated via an opaque cursor (pass cursor from a prior response to page). Requires only a valid credential — no extra permission.

Inputs

InputTypeDescription
team_idstringRestrict to a single team.
limitintegerPage size (default 50, max 200).
Default 50 · min 1, max 200
cursorstringOpaque cursor from a previous response's next_cursor.

plcs_get_project

Get a project

GET/projects/{id}
Read-onlyAny valid credential

Get one project's identity and current-version metadata plus a short analysis_status summary (not the full results blob). An unknown or out-of-scope id returns a not-found error. Requires only a valid credential.

Inputs

InputTypeDescription
id requiredstringThe project id.

Read source & live data

plcs_get_project_source

Read a project's source

GET/projects/{id}/source
Read-onlyRequires code_read

Read a project's source in one of four representations via format: parsed (default — vendor-neutral parsed structure as JSON), raw (the current committed version's L5X XML or Siemens ZIP, handed back as a file path or short-lived URL, never inline), scl (aggregated Structured Text), or ladder (aggregated ladder rungs). ALL formats reflect the LATEST committed version — including in-app edits saved on the platform, so raw never returns a stale originally-uploaded file. NOTE: parsed on a large project can exceed the inline size ceiling and fail with a too-large error — when that happens, retry with format=raw. Requires the code_read permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
formatstring enum
Values: parsed raw scl ladder · Default parsed

plcs_get_live_values

Latest live tag values

GET/projects/{id}/hmi/values
Read-onlyRequires hmi_view

Get the latest live tag values for a project, as streamed by a Desktop Companion App (DCA) session. This is PLCs.ai's most differentiated read: real values off the running plant. IMPORTANT: when no DCA is actively streaming, the response is a normal success with live: false and an empty tags object — this is the expected "no live session" state, NOT an error. Requires the hmi_view permission.

Inputs

InputTypeDescription
id requiredstringThe project id.

plcs_get_tag_history

Recent value history for a tag

GET/projects/{id}/hmi/history
Read-onlyRequires hmi_view

Get the recent, most-recent-first value history for a single tag (tag is required) from the current Desktop Companion App session. Returns an empty history when no live session has streamed that tag — a normal state, not an error. Requires the hmi_view permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
tag requiredstringThe tag name to fetch history for.
limitintegerMax entries (default 50, max 600).
Default 50 · min 1, max 600

Ground & interpret

plcs_search_context

Retrieve grounded context for a query

GET/projects/{id}/search-context
Read-onlyRequires code_read

Retrieve grounded context for a natural-language query from a project: returns the matching source chunks with similarity scores (highest-score first) and human-readable citations (e.g. program · routine, a block name, or a filename). This is RETRIEVAL, NOT GENERATION: there is no synthesized answer — YOU reason over the returned chunks yourself. Use it to ground your own reasoning in real source material before answering a question about the plant or code (distinct from any interpretation tool, which would return a model-written answer). A project with no searchable content returns an empty chunks array — a normal state, not an error. Optional limit caps the chunk count (default 8, max 25). Requires the code_read permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
query requiredstringThe natural-language query to retrieve context for.
limitintegerMax chunks to return (default 8, max 25). Alias top_k.
Default 8 · min 1, max 25

plcs_interpret

Interpret a prompt against a project

POST/projects/{id}/interpret
WriteIdempotent retryRequires ai_explain

Ask PLCs.ai's own PLC-specialized assistant to INTERPRET a project and get back a written, cited answer in one blocking call: { answer, citations, usage }. This is GENERATION, not retrieval: PLCs.ai produces a synthesized answer for you — distinct from plcs_search_context, which returns only raw source chunks for YOU to reason over, and from plcs_generate_code, which writes or modifies logic. Prefer this when the human EXPLICITLY asks for PLCs.ai's own interpretation/opinion of what the code does or why; otherwise ground your own reasoning with plcs_search_context instead. answer is the prose interpretation; citations are the source identifiers backing it (suppress them with include_citations: false). It reads only — it creates NO version and changes nothing in the project. If the organization is paused at its API spend limit the call fails with a spend-limit error — surface it to the human (they can raise the limit in Settings) and do not retry. Requires the ai_explain permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
prompt requiredstringThe question to ask about the project.
include_citationsbooleanWhether to include source citations in the response.
Default true
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.

Analyze

plcs_start_analysis

Start an async analysis job

POST/projects/{id}/analyses
WriteIdempotent retryRequires analysis_tab

Start an asynchronous analysis run on a project (dead code, missing handshakes, cycle-time, etc.) and get back a job id immediately — this does NOT block until the analysis finishes. Returns { analysisId, status }; then poll plcs_get_analysis with that analysisId until status is complete (or error). A queued/running status is normal progress, NOT a failure. If the organization is paused at its API spend limit the call fails with a spend-limit error — surface that to the human (they can raise the limit in Settings); do not retry automatically. Requires the analysis_tab permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.

plcs_get_analysis

Poll an analysis job

GET/analyses/{analysisId}
Read-onlyRequires analysis_tab

Poll the status of an analysis job started by plcs_start_analysis, by its analysisId. While the job is queued/running the response carries a message with poll guidance and no results yet — keep polling, this is normal, not an error. When status is complete the results are populated; when error, errors are populated. This is a read (no charge). Requires the analysis_tab permission.

Inputs

InputTypeDescription
analysisId requiredstringThe analysis job id returned by startAnalysis.

Generate & save

plcs_generate_code

Generate or modify PLC code (proposal)

POST/projects/{id}/generate
WriteIdempotent retryRequires ai_generate

Ask the assistant to PRODUCE or MODIFY PLC logic and get back a reviewable proposal in one blocking call: { generated_code, code_blocks, citations, usage }. generated_code is the full markdown proposal (prose + fenced ladder/st/scl blocks + inline insertion directives); code_blocks lifts those fenced blocks out for programmatic use. CRITICAL SAFETY PROPERTY — it PROPOSES, NEVER DEPLOYS: this creates NO version and changes nothing in the project. To persist a proposal you must take a separate, explicit step (plcs_save_version, which needs the code_write permission). If the organization is paused at its API spend limit the call fails with a spend-limit error — surface it to the human and do not retry. Requires the ai_generate permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
prompt requiredstringWhat to generate or change (e.g. "Add a 5-second start-up delay timer").
targetobjectOptional hint for which program/routine to target. Folded into the prompt as guidance; the assistant decides the final placement.
target.programstring
target.routinestring
include_citationsbooleanWhether to include source citations in the response.
Default true
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.

plcs_save_version

Commit a new version (Save project)

POST/projects/{id}/versions
WriteConsequentialIdempotent retryRequires code_write

Persist a NEW version of an existing project from an updated vendor file — the headless equivalent of "Save project". IRREVERSIBLE & CONSEQUENTIAL: a successful commit bumps the project's current version and re-runs analysis — so a client may ask you to confirm first. Provide the file ONE of three ways: file_path (a path on the machine running this server, read in on-prem/local mode), file_inline (base64-encoded bytes), or file_blob_url (a URL the API can fetch). The server picks inline-vs-large-file transport by size automatically — you do NOT base64 large files yourself. originalFilename is optional when using file_path (derived from the path). If you GENERATED/edited the file locally and this server is remote (no shared disk for file_path), do NOT use file_inline — base64 costs a token per byte. Instead call plcs_stage_upload first, PUT the bytes to the upload_url it returns, then pass its file_blob_url + originalFilename here (token-free). The uploaded file MUST be the same vendor as the project (an L5X stays L5X, a Siemens ZIP stays Siemens) — a mismatch returns a 400. Re-sending the exact current bytes is a safe no-op that returns 200 with resolution: identical_file and NO new version. This only persists what you give it — author a change first with plcs_generate_code, review it, THEN save. Requires the code_write permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
namestringOptional display name for the project.
acknowledge_billingbooleanAcknowledges the per-project charge for an enterprise per-project organization. Only consulted when this upload would create a NEW billable project; ignored for every other org type and for add-version / identical-file. When a new billable project is created without this set to true, the request is rejected with 402 billing_acknowledgement_required (carrying the projected cost); resend with true to confirm. Ignored on POST /projects/{id}/versions.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.
originalFilenamestringThe vendor file name (e.g. "Injection_Molding.L5X" or "Reference_Coiler.zip"). Optional when using file_path — derived from the path basename.
file_pathstringPath to the vendor file on the machine running this MCP server (on-prem/local mode). The server reads it and handles upload sizing.
file_inlinestringBase64-encoded file bytes — an alternative to file_path when the file is not on the server's filesystem. Large files are routed to the large-file flow automatically.
file_blob_urlstringA URL the PLCs.ai API can fetch the file bytes from (large-file escape hatch). Provide originalFilename alongside it.

plcs_stage_upload

Stage a file upload (token-free)

WriteMCP server toolAny valid credential

Stage a TOKEN-FREE file upload for a subsequent plcs_save_version or plcs_ingest_project. Use this whenever the file you want to save was generated or edited LOCALLY and this MCP server is remote — so file_path (which needs a shared disk) is unavailable and file_inline would cost a token for every byte of the file. It returns an upload_url: PUT the raw file bytes there over plain HTTP (e.g. curl -T <file> "<upload_url>") so the bytes never pass through the model. It also returns a file_blob_url that the PLCs.ai API fetches the bytes from. After uploading, call plcs_save_version / plcs_ingest_project with that file_blob_url and originalFilename. The links are short-lived. This creates NO project version on its own, is NOT billable, and makes no change to any project.

Inputs

InputTypeDescription
filename requiredstringThe vendor file name to stage, e.g. "PG_CM13.L5X" or "Reference_Coiler.zip".

Export

plcs_export_plc

Export the project to its vendor PLC file

POST/projects/{id}/exports/plc
WriteIdempotent retryRequires export_plc

Start an asynchronous export of a project's current committed version to its native vendor format (Rockwell .L5X or a Siemens TIA .zip) and get back a job id immediately — this does NOT block. Returns { exportId, status }; then poll plcs_get_export with that exportId until status is complete, and fetch the bytes with plcs_download_export. Exports the current version as-is (no edits). Requires the export_plc permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.

plcs_export_pdf

Render a PDF report for the project

POST/projects/{id}/exports/pdf
WriteIdempotent retryRequires export_pdf

Start an asynchronous render of a PDF documentation report for a project's current committed version (it does NOT include in-app chat history). Returns { exportId, status } immediately; poll plcs_get_export until complete, then fetch the bytes with plcs_download_export. Requires the export_pdf permission.

Inputs

InputTypeDescription
id requiredstringThe project id.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.

plcs_get_export

Poll an export job

GET/exports/{exportId}
Read-onlyRequires export_plc / export_pdf

Poll the status of an export job started by plcs_export_plc / plcs_export_pdf, by its exportId. While pending/running the response carries a message with poll guidance and no artifact yet — keep polling, this is normal, not an error. When status is complete, download_url (a relative path) and filename are populated — but prefer plcs_download_export to actually retrieve the bytes. When error, error carries a short reason. This is a read (no charge). Gated on the export's matching permission (export_plc / export_pdf).

Inputs

InputTypeDescription
exportId requiredstringThe export job id returned by startPlcExport / startPdfExport.

plcs_download_export

Download a completed export artifact

GET/exports/{exportId}/download
Read-onlyRequires export_plc / export_pdf

Retrieve the finished artifact (L5X / Siemens ZIP / PDF) of a complete export job by its exportId. The bytes are handed back as a local file path (on-prem) or a short-lived signed URL (cloud) — NEVER inlined into the response, so a large ZIP/PDF never floods the conversation. Read the artifact from the returned path/URL. Call plcs_get_export first and only download once status is complete. Gated on the export's matching permission.

Inputs

InputTypeDescription
exportId requiredstringThe export job id returned by startPlcExport / startPdfExport.

Ingest & embed

plcs_ingest_project

Ingest an L5X / Siemens export

POST/projects
WriteConsequentialIdempotent retryRequires project_upload

Upload an L5X (Rockwell) or Siemens TIA ZIP export to create or update a project (billed identically to a UI upload). CONSEQUENTIAL — a client may ask you to confirm first. Provide the file ONE of three ways: file_path (a path on the machine running this server, read in on-prem/local mode), file_inline (base64-encoded bytes), or file_blob_url (a URL the API can fetch); the server picks inline-vs-large-file transport by size automatically. If you GENERATED the file locally and this server is remote (no shared disk for file_path), do NOT use file_inline — base64 costs a token per byte; call plcs_stage_upload first, PUT the bytes to its upload_url, then pass its file_blob_url + originalFilename here (token-free). BILLING CONSENT: for an enterprise per-project organization, creating a NEW billable project returns 402 billing_acknowledgement_required with a projected-cost block (price_per_project_cents, currency, billed_count_after). DISCLOSE that cost to the human and only resend with acknowledge_billing: true on an EXPLICIT human go-ahead — NEVER acknowledge billing on your own. A 402 billing_setup_required means billing is not set up yet — the human must set it up in the desktop app, then retry. Note: a project-scoped key may only ADD a version to an in-scope identity; it can never create a NEW identity (use an unscoped key for that). Requires the project_upload permission.

Inputs

InputTypeDescription
namestringOptional display name for the project.
acknowledge_billingbooleanAcknowledges the per-project charge for an enterprise per-project organization. Only consulted when this upload would create a NEW billable project; ignored for every other org type and for add-version / identical-file. When a new billable project is created without this set to true, the request is rejected with 402 billing_acknowledgement_required (carrying the projected cost); resend with true to confirm. Ignored on POST /projects/{id}/versions.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.
originalFilenamestringThe vendor file name (e.g. "Injection_Molding.L5X" or "Reference_Coiler.zip"). Optional when using file_path — derived from the path basename.
file_pathstringPath to the vendor file on the machine running this MCP server (on-prem/local mode). The server reads it and handles upload sizing.
file_inlinestringBase64-encoded file bytes — an alternative to file_path when the file is not on the server's filesystem. Large files are routed to the large-file flow automatically.
file_blob_urlstringA URL the PLCs.ai API can fetch the file bytes from (large-file escape hatch). Provide originalFilename alongside it.

plcs_mint_embed_token

Mint a read-only embed token

POST/embed-tokens
WriteIdempotent retryRequires ai_explain

Mint a short-lived, project-scoped, read-only token for the embeddable assistant iframe. Regardless of your key's scope the token is intersected down to read-only (ai_explain + hmi_view) — a browser-delivered token can never carry a write scope. Returns { token, expires_at, permissions, project_id }. The minting key must itself have at least ai_explain.

Inputs

InputTypeDescription
project_id requiredstringThe project the embed token may access.
idempotency_keystringOptional idempotency key (e.g. a UUID). Normally omit it — the server generates one per call. Pass the SAME key to safely retry this write without double-billing: a replay returns the original result.