Tools¶
Artek-MCP groups its tools into providers, one per area of the gateway. A key sees the tools of every enabled provider that its tool profile allows. The authoritative list for your gateway and your key is the artek-mcp://tools resource (every tool you can call, grouped by provider, with its risk level and whether it changes anything), or your client's tool list.
Tools marked mutating are refused while readOnly is on (the default) and are then limited by the mutation allowlist. Every mutating tool accepts dryRun: true.
Tool profiles¶
A profile is a named subset of the tools, bound to an API key. Its main purpose is context cost: an MCP client loads the whole tool list when it connects and carries it in the model's context on every request, so a key that sees only the tools its job needs keeps every question cheaper.
The profile is a property of the credential, not the request: it comes from the authenticated key, so nothing a client sends can widen it. The tool list hides what the profile excludes, and a call to an excluded tool is refused by name, so a profile is a real gate rather than a display filter. A key with no profile is not narrowed.
{
"auth": {
"keys": [
{ "name": "ops-tablet", "token": "...", "profile": "ops" },
{ "name": "admin", "token": "..." }
]
},
"profiles": {
"line-3": {
"description": "Line 3 operators",
"tools": ["alarms:*", "tags:tag_read", "gateway_info"]
}
}
}
Patterns use the same provider:tool form as the mutation allowlist:
| Pattern | Matches |
|---|---|
* |
every registered tool |
provider:* |
every tool of that provider (alarms:*) |
provider:tool |
one tool, qualified (tags:tag_read) |
tool |
one tool by bare name, whichever provider registered it |
An empty pattern list denies every tool, the same as an empty db.connections or mutation.allowlist.
Built-in profiles need no configuration:
| Profile | For |
|---|---|
ops |
alarms, tag reads, gateway health, plus redundancy_status |
dev |
projects, Perspective, development tools, deploys |
diag |
gateway health, logs, audit, store-and-forward; includes every gateway tool |
All three include diagnostics:*. Defining a profile with a built-in's name replaces the built-in. Edit profiles on the settings page: the API-keys table has a Profile column, and the Tool profiles card lists the built-ins and edits custom ones.
Profiles also gate resources and prompts. resources/list, resources/read, prompts/list and prompts/get apply the key's profile. A prompt sits in the tool position under its provider, and a resource sits there as its full URI, so diagnostics:* reaches that provider's tools, resources and prompts alike. A custom profile naming only individual tools reaches no resources or prompts; add diagnostics:* to grant the diagnose_gateway prompt and the artek-mcp://status resource.
Write resource patterns in full
A pattern is split at its first colon, and a resource URI contains one. The bare form artek-mcp://status therefore matches nothing. Write provider:* or the fully qualified diagnostics:artek-mcp://status.
Two safety behaviors.
- A key naming a profile that does not exist fails closed: every tool, resource and prompt is refused, and the refusal names the missing profile.
-
At startup, each profile logs how many capabilities it can reach, with a WARN for each pattern that matches nothing, so a mistyped profile does not look like a working one. For example:
Artek-MCP profile 'ops': 17 of 100 tools reachable, 23 of 110 capabilities overall (5 resources, 5 prompts registered)The totals depend on your configuration (each declared script endpoint is its own tool). Counts are against registered tools; providers that are disabled are further removed from what a client sees.
Providers and tools¶
gateway¶
Gateway health and inspection.
| Tool | Purpose |
|---|---|
gateway_info |
gateway identity and version |
modules_list |
installed modules |
database_connections |
database connections and their status |
opc_connections_list |
OPC connection name, type, state and fault (no endpoint URLs) |
system_metrics |
JVM heap, threads, CPU and GC snapshot |
gateway_logs |
bounded, filtered log query (see gateway_logs) |
loggers_list |
which loggers exist and at what level |
logger_level_set |
mutating: set one logger's level, runtime only |
redundancy_status |
role, activity level, peer status and recovery mode |
modules_quarantined |
modules the gateway quarantined |
licenses_list |
license state, including unlicensed or expired trials |
Resources: ignition://gateway/info, ignition://gateway/connections (database and OPC connections in one read). Prompt: triage_gateway_errors.
projects¶
| Tool | Purpose |
|---|---|
projects_list |
the gateway's projects |
project_resources |
a project's resources |
project_resource_read |
one resource's files or content |
project_resource_write |
mutating: create or modify one resource file, validated before writing |
project_resource_delete |
mutating: delete a whole resource (requires name echo) |
Resource: ignition://gateway/projects (every project with its inheritance: parent, inheritable, enabled, mutable; a project with no parent reports inherits:false). Prompt: review_project_changes.
config¶
Gateway configuration through the 8.3 config resource collection.
| Tool | Purpose |
|---|---|
config_types |
registered resource types (category, singleton, extension point) |
config_resources |
resources by module and type, with collection and enabled state |
config_resource_read |
file list, attributes or content; secret fields are always redacted, binary files report size only |
config_manifest |
per-resource SHA-256 digests for configuration drift checks |
config_resource_write |
mutating: create or modify one file; applies hot or after restart as the resource type requires; refuses content containing the redaction marker |
config_resource_delete |
mutating: delete a whole resource (requires name echo) |
Mutation targets are config/<moduleId>/<typeId>/<path>. Both mutating tools refuse the module's own settings (com.artek.mcp/*); those change only through the settings page.
tags¶
| Tool | Purpose |
|---|---|
tag_providers_list |
tag providers |
tag_browse |
browse a folder (up to 500 nodes) |
tag_read |
read values (up to 100 paths) |
tag_config_read |
tag configuration, not values (up to 50 paths, recursive, localPropsOnly) |
udt_types_list |
UDT definitions in a provider's _types_ tree (up to 200) |
udt_definition_read |
one UDT definition's members and parameters |
tag_write |
mutating: up to 50 path and value pairs, with a quality result per path |
Prompt: trace_tag.
alarms¶
| Tool | Purpose |
|---|---|
alarms_active |
active alarms, filtered by state and minimum priority |
alarm_journals_list |
alarm journals |
alarm_history |
time-bounded journal query |
alarm_acknowledge |
mutating: acknowledge up to 100 events by UUID, with optional notes |
alarm_shelve and alarm_unshelve are also mutating alarm tools. Prompt: investigate_alarm.
historian¶
| Tool | Purpose |
|---|---|
history_providers_list |
history providers |
history_browse |
browse historical paths (returns histprov: qualified paths) |
tag_history |
raw or aggregated history (up to 20 paths, up to 5000 windows) |
tag_history takes historian paths, not tag paths: each entry must carry the histprov component (histprov:<provider>:/drv:<driver>:/tag:<path>). A [provider]Folder/Tag path is refused, pointing you at history_browse, which returns the right form. history_provider_edit and history_provider_delete (name echo) are mutating tools for historian providers.
gatewaynetwork¶
Read-only Gateway Network topology: gan_overview (local server id, redundancy level, known servers and their state) and gan_connections_list (status, direction, ping, rates and last error per connection, up to 200).
deployment¶
Read-only views for comparing gateways and git baselines.
| Tool | Purpose |
|---|---|
project_manifest |
per-resource SHA-256 digests for drift checks between gateways or against a git baseline (up to 2000 resources) |
project_export |
the project as a base64 zip plus its SHA-256 (4 MiB default cap, 16 MiB maximum) |
devtools¶
| Tool | Purpose |
|---|---|
project_dependency_graph |
whole-project reference graph (see Dependency graph) |
view_dependency_graph |
view embedding graph, a projection of the same engine |
Deploy and search tools¶
These tools are part of the development surface (the built-in dev profile covers projects, Perspective, development tools and deploys). Check artek-mcp://tools for the provider each one is registered under.
| Tool | Purpose |
|---|---|
deploy_export_for_git |
export what a project defines (inherited resources excluded and counted as inheritedExcluded, with inheritsFrom, also recorded in the zip's deploy-manifest.json) |
deploy_diff |
compare a baseline with the live project |
deploy_apply |
mutating: apply a deploy zip, with rollback on failure |
ref_search, ref_usages |
text searches across project resources |
view_patch |
mutating: patch a view's JSON |
deploy_diff compares a baseline carrying inheritedExcluded against the project's own resources only, and any other baseline against the merged set, and reports which as liveSideOwnResourcesOnly. deploy_apply accepts an optional sha256 of the zip and refuses on mismatch rather than half-applying; the response carries integrityChecked, plus an integrityNote when no digest was given. This detects a damaged zip; it does not repair one.
view_patch keeps null-valued keys, because a view stores an unset param as an explicit null and dropping it would silently break the bindings that read it.
perspective¶
view_bindings analyzes a view.json statically: params and their direction, bindings with type, detail and transforms, embedded-view dependencies, and broken embedded-view references.
perspective-runtime¶
Registered only when the Perspective module is installed.
| Tool | Purpose |
|---|---|
list_perspective_sessions |
active sessions: id, project, username, client address and user agent, uptime, active pages (project filter, up to 200, default 50) |
get_session_details |
one session: authentication summary (username, roles, IdP; never tokens or raw IdP attributes), locale and time zone, page, view, component and binding counts |
close_session |
mutating, high risk: close a session (the native system.perspective.closeSession), and report the outcome |
send_session_message |
mutating, high risk: send a message to a session (the native system.perspective.sendMessage), scope session or page, optional pageId |
Mutation targets are perspective/session/<sessionId>.
vision¶
Disabled by default, and registered only when the Vision module is installed: vision_windows_list (window and template inventory), vision_window_read (components, bindings attributed to component and property, event scripts, navigation targets) and vision_window_xml (the serialization XML, up to 2 MiB). They read both native Vision resources and resources converted from 7.9, without constructing any Swing components on the gateway, and they can read components from other installed modules. A window using a component whose module is not installed fails, naming the class and its module.
Warning
Vision read results are returned as-is, not redacted. A window stores the last evaluated value of its bindings, so it can carry live data such as a logged-in username. Treat these tools like tag_browse.
Other providers¶
The tool surface also includes users and roles (for example user_remove, role_remove), store-and-forward (storeforward_quarantine_delete), alarm notification rosters, EAM (status tools and eam_task_update), the audit log, export_diagnostics_bundle, and three providers covered on their own pages:
db: Database access (disabled by default)scripting: Script endpoints (disabled by default)api: Gateway REST API bridge
The federation provider (disabled by default) routes calls to other gateways on the Gateway Network through federation_call and federation_call_mutating; see Configuration for how a key's scope applies to them.
diagnostics¶
| Tool | Purpose |
|---|---|
mcp_status |
provider inventory, policy and keys, narrowed to what the calling key's profile can reach; also caller.rate, caller.nameEcho, caller.readScopeCoverage and the node block |
policy_explain |
the authorization chain, gate by gate, for a call you describe with tool and arguments |
Resources: artek-mcp://status, artek-mcp://tools. Prompt: diagnose_gateway. The settings page's own diagnostics (for a gateway operator) are not narrowed.
gateway_logs¶
gateway_logs is a bounded log query, not a live tail. For streaming, use the gateway's own log console or container log.
| Argument | Effect |
|---|---|
minLevel, loggerName, contains |
filters |
sinceMinutes |
look back a relative distance |
startTime, endTime |
an absolute, inclusive window: an ISO-8601 instant, an offset date-time, a local date-time or date with no zone (read in the gateway's time zone), or epoch milliseconds |
limit |
up to 200, default 50 |
cursor |
continue from a previous page |
Messages are capped at 2000 characters; stack traces are off by default and capped at 20 frames.
Paging. A substring-filtered page scans the newest 5000 events that match the level and time filters. The response returns nextCursor and hasMore; pass the cursor back to reach older events. A filter matching nothing on one page still returns a cursor while the scan was truncated, so "no matches anywhere" and "no matches yet" look different. The response also echoes the resolved window, zone and filters as query.
- The cursor is stable. It freezes the window's end, so new events arriving do not shift your pages. Filters and the window travel inside the cursor, and any filter or time argument passed alongside a cursor is refused.
- Ties are handled. Several events often share one millisecond; the cursor records how many at that instant were already returned, and every page makes progress.
Before concluding a log search found nothing
Run loggers_list first. An empty search can mean "no such event" or "that logger is below the threshold". loggers_list hides loggers that only inherit their level (most of them); pass configuredOnly=false with a contains filter to search the rest.
Gateway inspection¶
| Tool | Use it when |
|---|---|
loggers_list |
you need to know which loggers exist and at what level |
logger_level_set |
you want one logger at DEBUG while reproducing a fault; set level=INHERIT afterwards to clear it |
redundancy_status |
you need to know whether the pair failed over, and to what |
modules_quarantined |
a module you installed does not appear: a quarantined module shows up as a missing feature, not a broken one |
licenses_list |
an installed capability refuses at the point of use: unlicensed, or trial expired |
- A logger level is runtime only. A gateway restart reverts it, and the tool reports
persisted: false. Its allowlist target islogger/<name>. It refuses any change that would stop theArtekMCP.Auditlogger writing at INFO (WARN or above onArtekMCP.Audit,ArtekMCPorROOT), and undoes a change found afterwards to have switched it off. modules_quarantinedanswers three ways.supported: falsemeans nothing could be inspected, and is not the same as an empty list.- A
peerblock does not mean there is a peer. A standalone gateway returns one with activity levelUndecidedand no version or address. Readpeer.connectedand the accompanyingpeerNote.
Writing project resources¶
Content is validated before it is written¶
project_resource_write checks the content, not only the arguments. A *.py file is parsed by this gateway's own Jython 2.7, and a *.json file is parsed strictly. A file that fails is refused with the parser's message and position, instead of being written and failing later at scan time. Valid Jython 2 syntax such as except (A, B), e: is accepted, and lenient JSON (unquoted keys, single quotes, trailing commas) is rejected, because the platform rejects it later.
| Argument | Effect |
|---|---|
| (none) | validate, and refuse on failure (default) |
validateOnly: true |
report the verdict and write nothing; refuses a file type no validator understands, so a clean result always means a validator ran |
skipValidation: true |
write anyway; the result carries validationOverridden: true |
Only *.py and *.json are validated. Other files (.sql, .css, binary) are written without validation and report checked: false and valid: false, so "nothing checked it" is never read as "it is fine".
deploy_apply does not validate content
A deploy zip's files are written as they are, so a script with a syntax error or a malformed view.json still lands and fails later at scan time. If you rely on validation, write through project_resource_write.
Root resources¶
page-config, stylesheet and session-props are single root resources of their type, and project_resource_write can modify them. Two guards apply: creating a root resource is refused (a type must have exactly one), and a folder root is refused. See the allowlist warning in Mutation policy.
Inherited resources are protected¶
A child project also sees the resources it inherits from its parent. Without a guard, a write addressed to the child could land on the parent. Every project-resource change is therefore checked for ownership, before any dryRun result:
project_resource_write,project_resource_deleteandview_patchrefuse an inherited target, naming the project that defines it.deploy_applycreate and modify refuse an inherited resource that differs. An unchanged inherited resource stays in theunchangedbucket, so a normal export and apply round trip on a child project still works.deploy_applywithmode:"sync"skips inherited resources during its delete pass and reports them asskippedInherited, each withdefinedBy, instead of refusing the whole call.
A child that overrides a resource locally can write its own copy; the refusal fires only when every match is inherited.
deploy_apply rolls back a failed push¶
Before pushing, deploy_apply snapshots the live content of every resource the plan touches. If the push fails, each resource is restored from the snapshot and re-read to confirm it matches, and the error reports the outcome resource by resource, including any that could not be restored and why. Created resources are deleted, modified ones restored, and deleted ones (mode=sync) recreated with their original bytes.
- Read
rollbackArmedin the response. If the live content exceeds the snapshot limit, it reportsrollbackArmed: falsewith the reason, rather than protecting only part of the set. - Pass
rollback: falseto skip the snapshot. - A timeout does not roll back. An unfinished push is not a failed one, and restoring over it would race it; it is reported as "not confirmed".
- The platform already validates every operation before applying any, so most failures (a stale signature, an illegal modify, a conflict) abort with nothing applied. Rollback covers a failure partway through a deploy that spans more than one resource type.
Dependency graph¶
project_dependency_graph builds a project's reference graph inside the gateway from the parsed resources, so it finds references a text search misses (in a view.json, scripts are stored with escaped newlines and quotes). view_dependency_graph is a view-only projection of the same engine.
| Question | Where the answer is |
|---|---|
| Does a resource reference something that does not exist? | findings.brokenReferences: every static reference whose target view, named query, page route, dock id, database connection or (with resolveTags) tag does not resolve, with the via that carries it and a hint when the target exists with different case |
| Is a resource referenced by anything? | findings.orphans, or node=<path> for one resource's inbound and outbound edges |
| Do views embed each other in a cycle? | findings.cycles |
| Do two resources of one type differ only by case? | findings.duplicateNames |
Every run reports stats.resourcesParsed, parsedByType and findingCounts, so a run that examined nothing never reads as clean. findings.unresolved lists references it could see but not resolve (for example a named query with a blank database and no project default).
| Argument | Effect |
|---|---|
project |
required |
includeDescendants |
also scan projects that inherit from this one as referrers (default true) |
resolveTags |
check static tag paths against their provider, a live read capped at 2000 distinct paths (default false) |
node |
focus on one node id (perspective-view:Folder/View) or bare path; returns focus.inbound and focus.outbound |
nodeType |
restrict nodes, edges and focus to one type |
nodes, edges |
include the raw lists (default false; edges capped by limit, default 2000, maximum 20000) |
What it reads. Perspective views (embedded views through props.path and every viewPath key, declarative popup, navigation and dock actions, tag, query and history bindings, tags inside expressions, and script calls), page configuration (routes and docks), session properties, session scripts and form submission handlers, named queries (their database), script modules and gateway event scripts.
What it does not claim.
- A reference built at runtime (a bound path, an indirect tag binding, a formatted string) has no static target. It is recorded as
dynamic: trueand excluded from every finding. - Tags are checked only with
resolveTags: true. Only a not-found result counts as missing; folders and UDT types exist. - Orphans are judged only for resources the project itself defines. Inherited resources may be referenced by sibling projects the scan never opened, and are counted under
orphanScope.inheritedExcluded. - Vision, WebDev and Reporting resources are counted as skipped (
stats.skippedByType). Named-query SQL is not parsed for table names, and UDT instance-to-type edges are not built.
view_dependency_graph returns project, viewCount, truncated and views[], following viewPath as well as props.path. For inbound references, cycles, orphans and broken references, use project_dependency_graph.
Refusals and remediation¶
Every refusal the module raises carries a remediation string naming the setting, allowlist entry or argument that would permit the call. It is structured data: error.data.remediation over HTTP, a remediation field on a federated error, and a remediation key on each denying row of policy_explain.
A remediation never describes what other keys can reach, and never hands back a value the caller was supposed to supply itself.
Unknown arguments are refused, not ignored. A call carrying a top-level argument the tool does not declare fails, naming the argument, the one you probably meant (for example search or filter on gateway_logs suggests contains) and what the tool takes. _meta is allowed, and the contents of declared object arguments (such as api_call's query and body) are not checked. policy_explain reports this as the arguments gate, takes only tool and arguments, and returns argumentsEvaluated so you can see exactly which call it explained.
Name echo on destructive tools¶
Six tools refuse unless the caller repeats the target's own name in a confirmName argument:
project_resource_deleteconfig_resource_deleteuser_removerole_removestoreforward_quarantine_delete(the echo is the engine name, not the ids)history_provider_delete
Every other gate asks whether a target is permitted; the name echo asks whether it is the one the caller meant. It protects against a wrong target, such as a path built from the wrong variable or a name carried over from a previous call. It does not replace dryRun, and dry runs are not exempt: a dry run naming the wrong target would report a plan for the wrong resource.
A tool whose target cannot be determined from its arguments is refused. The refusal names the confirmName argument and the rule, never the expected value. mutation.requireNameEcho: false turns the check off gateway-wide; it defaults to on. mcp_status reports its state and the guarded tools under caller.nameEcho.