Script endpoints¶
Script endpoints let you expose chosen project library functions to an AI agent. Each function you declare becomes its own MCP tool, with its own description and argument schema. There is no way to run arbitrary code: an agent can call only the functions you declared, with the arguments you declared, in the project you chose.
The scripting provider ships disabled. Set providers.scripting to true to enable it; an absent key means disabled.
Declaring an endpoint¶
"scripting": {
"endpoints": [
{"name": "get_heat_analysis", "project": "MyProject", "function": "pkg.module.fn",
"description": "Return the heat's melt chemistry and cycle times. Reads only.",
"readOnly": true, "timeoutSeconds": 10,
"providerId": "heat",
"inputSchema": {"type": "object", "required": ["heatId"],
"properties": {"heatId": {"type": "string"}}}}
]
}
The tool is named exactly as name. Its arguments are the function's keyword arguments, plus a reserved dryRun.
| Field | Required | Meaning |
|---|---|---|
name |
yes | the MCP tool name. Unique across the gateway, and a valid tool name: a letter or _ first, then letters, digits, _ or -, up to 64 characters |
project |
yes | the project that owns the function |
function |
yes | the function's module.function path in that project's script library |
description |
yes | the description the agent sees. An endpoint without one is not registered |
readOnly |
no (default false) |
a read-only endpoint runs while the server is read-only, and skips the mutation allowlist |
providerId |
no (default: the project) | the namespace that profile patterns and provider:tool allowlist keys match this tool under |
inputSchema |
no | advertised as written, with dryRun added. It may not declare dryRun itself |
timeoutSeconds |
no (default 30) | how long one run may take |
Write a description that tells the agent what the function returns and whether it changes anything. It is the only guidance the agent has for choosing the tool.
A write endpoint runs with the gateway's authority
An endpoint with readOnly: false is a mutating tool: it is refused while the server is read-only and is limited by the mutation allowlist. Whatever the function does, it does in the project's Gateway scope. Declare an endpoint read-only only if the function truly changes nothing.
Registration happens at startup¶
Endpoints are registered when the gateway starts. After adding or changing an endpoint: save, restart the gateway, then reconnect your MCP client. A client keeps the tool list it received when it connected, and the server does not push list changes.
Running an endpoint, by contrast, reads the configuration live. This is deliberate and errs on the safe side: removing an endpoint stops it working immediately, while adding one takes a restart.
Registration refusals¶
An endpoint that cannot register is refused with a reason, while every other tool still comes up, so a typo in one endpoint cannot take the whole server down. Each refusal is logged as an ERROR, listed in mcp_status under scripting, and shown on the settings page. The script_endpoints_list tool reports every declared endpoint with its registered flag and registrationError.
An endpoint is refused when:
- it has no
description(add one, then restart); - its
namerepeats another endpoint's name, collides with a built-in tool, or is not a valid tool name; - its
providerIdequals another registered provider's id.
How a run executes¶
- Each run executes on its own thread in the owning project's Gateway scripting context.
- The return value comes back JSON-encoded.
- A run that exceeds
timeoutSecondsis abandoned and reported. Cancellation is best-effort, so write long-running functions to respond to interruption. - If the endpoint declares an
inputSchema, arguments the schema does not list are refused. An endpoint without a schema accepts any keyword argument. - On a redundant pair, script endpoints count as Runtime writes: see Redundant pairs.
Allowlist targets¶
The mutation-allowlist target of an endpoint is:
scripting/<project>/<name>
- To allow every endpoint of a project, use
scripting/<project>/(with the trailing slash). - An entry
scripting:script_runmatches nothing; there is noscript_runtool. - The older spelling
scripting/<name>is still honored in the gateway-wide allowlist, as an exact match for that one endpoint only. It never scopes a project named<name>. Per-key allowlists do not accept the older spelling.
Report schedules and other features without a dedicated tool can be reached through a declared endpoint's own tool, or through the REST API bridge.