-
Notifications
You must be signed in to change notification settings - Fork 2
0.34.0
Two things landed together: making it obvious that a plain REST/HTTP API is a first-class connector (no MCP server required), and closing a spot where secrets could leak into shell child processes.
Upgrade impact: none (additive), with one security tightening — see "Do I need to change anything?" below.
If you've been assuming you need to stand up an MCP server just to let a skill call your HTTP API — you don't. McpConnector is the dispatch contract for $ connector.tool ops, and "MCP" names the verb, not the wire. A connector fronting a plain REST endpoint is a first-class citizen; MCP JSON-RPC framing is just one implementation (HttpMcpConnector).
There's now a complete, runnable worked example — examples/connectors/RestConnector/ — that fronts a REST API: an ENDPOINTS table maps each tool to method + path, call() does path-templating, query-vs-body routing, auth-header injection, and timeout; staticTools() gives lint a closed tool set; describeTools() surfaces the endpoints. Not a throws TODO skeleton — copy it and adapt.
MCP and REST connectors coexist in one registry. A single skill body can mix them freely:
run:
$ gmail.send_message to="${WHO}" subject="Done" -> SENT # an MCP connector
$ tickets.create title="${SUMMARY}" priority="high" -> TICKET # a REST connector
New in this release for connector authors: McpToolDescriptor is re-exported from skillscript-runtime/connectors (you need the named type to write describeTools()), and docs/connector-contract-reference.md gained a full McpConnector section.
Before: a shell(...) op's child process inherited the runtime's whole environment — including your SKILLSCRIPT_SECRET_* values. Now those are scrubbed from shell children, on both the structured (command=/argv=) and the unsafe=true bash path.
Why it's safe to scrub: the runtime resolves a {{secret.NAME}} marker and splices the value straight into the spawn argv at the sink, so a shell child never needed the raw secret in its ambient environment in the first place. Scrubbing makes your # Requires: declaration authoritative (least-privilege enforced) rather than advisory.
Egress vars are preserved — HTTPS_PROXY, NODE_EXTRA_CA_CERTS, CURL_CA_BUNDLE, SSL_CERT_FILE still pass through, so the outbound-proxy / credential-free-egress pattern is unaffected.
Almost certainly no. The one case affected: a skill that read an undeclared secret straight out of a shell child's environment (e.g. curl picking up $SOME_SECRET implicitly). That never was a supported pattern — the supported way a secret reaches a command is a {{secret.NAME}} marker with a matching # Requires: secret.NAME. If you had a skill relying on the implicit-env behavior, declare the secret and place the marker:
# Requires: secret.API_KEY
run:
shell(command="curl -H 'Authorization: Bearer {{secret.API_KEY}}' https://api...") -> R
Everything else is backward-compatible — no config edits, no re-approval.