script-connected-html-output — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited script-connected-html-output (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
When an HTML file displays data from integrations, use data scripts so the data refreshes every time the file is opened. Only hardcode data when the source is truly static (user-provided CSV, pasted text).
Refer to the gumloop-sdk skill for the client and tool-calling patterns.
For new script-connected HTML artifacts, start with:
python3 /home/user/skills/.tools/html_scaffold.py /home/user/myproject --script-connectedThen replace the generated data.py sample payload with the real Gumloop SDK call.
fetch('/gumloop/data/{key}') instead of hardcoding datasandbox_download(..., scripts={"key": "/home/user/script.py"}, server_ids=["server_id"])The platform intercepts /gumloop/ fetches and runs the matching script server-side.
Data script (/home/user/get_issues.py):
import json
from gumloop import Gumloop
client = Gumloop() # base URL + token from env; project resolved from the token
resp = client.mcp.execute("linear", "list_issues", {"max_limit": 50})
print(json.dumps(resp.results[0].decoded_content))HTML uses fetch to load that data and render it:
<script>
fetch('/gumloop/data/issues')
.then(function(r) { return r.json(); })
.then(function(data) {
var container = document.getElementById('content');
data.forEach(function(issue) {
var div = document.createElement('div');
div.textContent = issue.title;
container.appendChild(div);
});
});
</script>Export bundles both together:
sandbox_download(
sandbox_path="/home/user/dashboard.html",
scripts={"issues": "/home/user/get_issues.py"},
server_ids=["linear"]
)Keys in scripts and the fetch URLs must match. The tools each script may call are parsed from its source to scope the execute token — you don't list them. server_ids lists every server_id used by any script (enables connection checks when the artifact is shared).
For forms that write back to integrations, use /gumloop/action/{key} with POST. The request body is forwarded to the script as os.getenv("GUMLOOP_PAYLOAD").
import os, json
from gumloop import Gumloop
client = Gumloop() # base URL + token from env; project resolved from the token
payload = json.loads(os.getenv("GUMLOOP_PAYLOAD", "{}"))
resp = client.mcp.execute("linear", "create_issue", payload)
print(json.dumps(resp.results[0].decoded_content))print(json.dumps(...)) — stdout is the response bodyGumloop() directly (runs in a one-off sandbox)gumcp_server type servers (see server-discovery catalog). Do not use gumstack_server or mcp_server tools in data scripts — they will fail at execute timescripts from sandbox_download entirely for static HTML~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.