Skip to main content
0.0.x

Agent tooling

The rest of this pillar is about the AI you build into your app — the engine, the MCP client stack, durable chat. This page is the mirror image: what NetScript gives the coding agents (and the humans pairing with them) that build your app. One vocabulary across three surfaces:

  • the netscript CLI performs direct, scriptable operations;
  • installed skills explain which NetScript workflow to use and when to hand off to the CLI;
  • the MCP server returns compact framework-aware diagnostics, telemetry summaries, and public docs.

There is a fourth surface that is easy to miss: this documentation site is itself built to be read by agents — every page has a Markdown twin, and the whole corpus is published behind llms.txt. We cover that below.

Prefer the CLI when a command already expresses the operation — it is easier to reproduce in a terminal or CI job, and the CLI reference is the task-oriented map of what exists. Use MCP for interactive investigation, especially when one framework-aware tool replaces several telemetry queries or when an agent needs to discover a document before reading it.

Install into a project

netscript agent init

Host detection selects which host integrations are added. Use --host claude, --host vscode, --host opencode, or --host all (all three) to select an agent host explicitly. Without the flag, hosts resolve in this order, and the first source that yields a host decides:

  1. Project markers — an existing .claude directory (Claude Code), .vscode directory (VS Code), or opencode.json, opencode.jsonc, or .opencode (OpenCode).
  2. The invoking environment — CLAUDECODE (Claude Code), OPENCODE or any OPENCODE_* variable (OpenCode), and a VS Code-family terminal (TERM_PROGRAM=vscode, VSCODE_*, or CURSOR_*).
  3. The default — Claude Code.

The command prints the decision, for example Agent hosts: opencode (from environment: OPENCODE)., followed by the editor decision. Only variable names are printed, never their values.

Editor configuration is a separate, shared target: --editor none|zed|vscode applies the same Deno editor setup available during netscript init to an existing project and adds native MCP wiring. When omitted, one existing .zed or .vscode directory is honoured; if both exist, select explicitly. With neither directory, the editor whose integrated terminal launched the command is used: TERM_PROGRAM first, because each terminal rewrites it, then ZED_TERM (Zed), then VSCODE_* or CURSOR_* (VS Code). Unsupported editor names fail with the supported list and instructions to use --editor none plus a manual MCP configuration.

If network lookup is unavailable or the framework is unfamiliar, add --with-docs. This opt-in expands a several-megabyte local corpus containing the release-built prose and task router plus deno doc output for every export subpath of each exact NetScript package version found in the project. Version disagreement or a failed documentation command aborts before the local docs tree is written; without the flag, no offline corpus is installed. When the bundle is installed, every generated host command receives the same absolute --docs-root <project>/.netscript/docs pair.

Every host receives the canonical NetScript skill bundle under .agents/skills/ and a marked NetScript section in AGENTS.md. Host and editor targets add only their own integration files:

Host or editor target Additional files written
Claude Code host .mcp.json, the single discovery bridge .claude/skills/repo-skills/SKILL.md, and CLAUDE.md with an @AGENTS.md import
VS Code editor .vscode/mcp.json, .netscript/schema/config-file.v1.json, .vscode/settings.json, .vscode/extensions.json, .vscode/launch.json, .vscode/tasks.json
Zed editor .zed/settings.json with context_servers, .zed/debug.json, .zed/tasks.json, .netscript/schema/config-file.v1.json
OpenCode host opencode.json (or an existing opencode.jsonc) with netscript and aspire local MCP servers, the deno lsp language server, and the deno fmt formatter

OpenCode reads opencode.json from the project root and never reads .mcp.json, so it gets its own writer. Each MCP server entry carries an explicit timeout (180 s for netscript, 120 s for aspire) because OpenCode's 5-second default does not cover a cold-cache JSR resolve. OpenCode leaves language servers and formatters off when lsp and formatter are omitted, and ships no Deno formatter, so the file also declares lsp.deno and formatter.deno. An existing deno entry and an explicit false are kept, including one inherited from opencode.json when the wiring goes into opencode.jsonc. OpenCode discovers .agents/skills/ itself, so no extra skill tree is written for it.

Both project files are read as JSONC and edited in place, so comments, trailing commas, and unrelated settings survive. OpenCode merges both files and lets opencode.jsonc override opencode.json, so an existing opencode.jsonc receives the full wiring. A netscript or aspire server already declared in opencode.json is refreshed too, which keeps the effective command current. A malformed file stops agent init before it writes anything.

The generated MCP configuration runs netscript agent mcp for the current project. Re-running agent init is idempotent: unchanged files are left alone, and existing host configuration is preserved alongside the netscript server entry.

Claude's bridge directs the agent to read skills from the authoritative .agents/skills/ tree and resolve bundled references there. A new CLAUDE.md starts with @AGENTS.md; an existing file receives the import and Claude-specific named-skill routing line once, preserving its content. Upstream Aspire workflow skills are installed only in the standard .agents/skills/ location, so initialization creates no skill mirrors. Existing legacy mirrors and custom Claude skills are left in place. Initialization warns when known legacy skill directories are present because they are no longer refreshed; automatic removal of identical legacy mirrors and divergent-file reporting remain follow-up work.

The marked AGENTS.md section states that MCP is the default surface for NetScript work. When no netscript MCP tools are listed, it tells the agent to call MCP doctor if the server is up, or otherwise run netscript plugin doctor from the shell (there is no bare netscript doctor). The agent then re-runs netscript agent init --host <host> and restarts its host. Skills are named by their registered name ("call the netscript skill"). Hosts that register those names load them through their skill tool. On Claude Code, call the repo-skills bridge with the requested skill name; the bridge permits reading .agents/skills/<name>/SKILL.md and its bundled references.

Before unfamiliar NetScript API or architecture work, call find_guidance with the task you intend to complete and follow its ordered citations. Use search_docs for literal lookup and get_doc for exact retrieval of a known document or section.

Zed project MCP configuration runs only after the worktree is trusted; review the generated commands before enabling project settings. Re-running with the same editor is idempotent and keeps unrelated MCP servers/settings alongside the NetScript entries.

The host command includes the absolute project deno.json path. Deno 2.9 normally holds newly published registry versions behind a 24-hour minimum dependency age; the generated JSR workspace keeps that policy while excluding only exact-version packages in the matching NetScript release train. Loading the project configuration explicitly lets a newly released @netscript/cli MCP server start immediately without changing the age policy for third-party dependencies.

Run the server

The generated host configuration runs netscript agent mcp, which starts the MCP server over standard input/output. An MCP client launches this command and communicates over stdin/stdout; do not run it by hand. When stdin is an interactive terminal, the command exits after showing copyable Zed and VS Code configuration. When stdin is piped, it writes no human-facing output that could corrupt the JSON-RPC stream. Its flags:

Flag Purpose
--project-root <path> NetScript project root used for execution and doctor flows. agent init writes this for you.
--endpoint <url> Telemetry endpoint URL; overrides discovery (below). Only http: and https: are accepted.
--docs-root <path> Public documentation root for the docs tools; overrides the default corpus (below).

What the server exposes

Twenty-two tools, every one returning a bounded structured result. Grouped by what an agent is trying to do:

  • Read the running app — seven telemetry read models: get_app_status, list_runs, get_run, get_recent_errors, get_last_job_result, analyze_service_performance, and analyze_db_bottlenecks. Each replaces a handful of raw telemetry queries with one aggregate answer.
  • Diagnose the project — doctor aggregates telemetry reachability, Aspire markers, project wiring, and plugin diagnostics into one verdict; the plugin slice has a direct twin in netscript plugin doctor.
  • Use the docs — find_guidance returns ordered section-level guidance and cited code for a natural-language task; search_docs, list_docs, and get_doc retain the literal search-to-get funnel over the documentation corpus (next section).
  • Discover exports — find_export, list_package_exports, get_export, and search_exports locate package subpaths, page through package surfaces, return one bounded signature/JSDoc block, and find related helpers by partial name or declaration shape.
  • Bridge to the CLI — list_commands discovers the current command tree (the machine-readable twin of netscript --help), and execute_command runs an allowlisted netscript … command with policy checking, timeout handling, and a bounded output tail.
  • Record drift — record_drift appends an evidence-gated entry to the project drift log (.netscript/agent/drift.jsonl) when authorized by a fresh successful diagnostic receipt.
  • Inspect service APIs — list_api_services, list_service_operations, and get_operation_schema expose live OpenAPI contracts before an agent guesses with curl.

We keep the per-tool schemas, output bounds, and the full execute_command policy in the @netscript/mcp reference rather than restating them here; for the commands themselves, the CLI reference is the cheat-sheet.

Documentation corpus

Documentation selection is deterministic: explicit --docs-root <path>, then NETSCRIPT_DOCS_ROOT, then an indexable <project>/.netscript/docs bundle, then the generated release-matched embedded corpus. The embedded fallback contains the bounded quickstart, contract-to-page, service, builder, and route golden paths plus the MCP README and CLI help. An empty, redirect-only, or otherwise non-indexable project bundle falls back to embedded; an invalid explicit or environment root returns docs_corpus_not_found instead of hiding the operator error.

list_docs reports the selected corpus as { kind, root, documentCount } alongside its bounded docs rows. A filesystem selection reports the resolved root; embedded reports root: null, so an agent or measured run can see that it is using the fallback instead of inferring degradation from search results.

The export tools use a different, package-embedded corpus generated from Deno 2.9 deno doc --json. It is version- and hash-pinned, needs no project docs/ directory, and returns only bounded symbol records rather than generated files. Start with find_export when you know the exact symbol, list_package_exports when exploring a package, get_export for one declaration, or search_exports when you only know part of the helper name or its shape.

Token-efficient use

Tool inputs cap result counts, and the server truncates oversized results and command output. Start with the narrowest filter that answers the question. For documentation, use the search-to-get funnel: call search_docs, choose a slug, then call get_doc for that document or section.

Data boundary

The MCP server reads NetScript telemetry, project metadata and generated registries used for diagnostics, public documentation, and the package-embedded public export corpus. It does not return project source code, environment-variable values, credentials, or secrets.

Telemetry requests go only to the resolved dashboard endpoint. Discovery uses, in order, the --endpoint option, NETSCRIPT_TELEMETRY_ENDPOINT, ASPIRE_DASHBOARD_PORT, and the local default http://localhost:18888.

execute_command is default-deny. Explicit rules allow selected database, generation, contract, service-read, plugin, and UI commands. Deny rules take priority; deployment, project initialization, marketplace operations, database reset, plugin removal, and every unmatched command are rejected with a structured denial before a process is started. The rule-by-rule policy lives in the @netscript/mcp reference.

Troubleshooting

Start with the doctor tool: it aggregates four check families — telemetry, aspire, project, and plugins — into one verdict. Each check carries a pass, warn, or fail status, and warnings and failures may include a suggested fix. Reading the result:

  • telemetry warns or fails — no reachable telemetry endpoint. Verify the app is running, then check the discovery chain: --endpoint, NETSCRIPT_TELEMETRY_ENDPOINT, ASPIRE_DASHBOARD_PORT, and the local default http://localhost:18888. Telemetry tools still respond while the endpoint is down — nothing crashes: get_app_status reports status: "warn" with zero counts, the list and analytics tools (list_runs, get_recent_errors, analyze_service_performance, analyze_db_bottlenecks, …) return their ordinary empty or zero-valued results, and get_run returns a structured run_not_found error.
  • aspire or project warns — the project root is wrong or the workspace is missing expected markers. Confirm the --project-root written into your host configuration points at the project (re-run netscript agent init after moving a project).
  • plugins warns or fails — plugin diagnostics found an issue; the equivalent direct command is netscript plugin doctor.
  • Docs tools return docs_corpus_not_found — the configured --docs-root / NETSCRIPT_DOCS_ROOT path does not exist; fix the path or remove the override to fall back to the packaged corpus.
  • execute_command returns a denial — the command did not match the allowlist (see the data boundary above); run it directly in a terminal instead.

Reading these docs as an agent

The site you are reading ships its own agent affordances, no MCP server required:

  • Every page has a Markdown twin. The "View as Markdown" link near the top of each page points at clean Markdown distilled from the rendered page — component markup already resolved, links absolute — so an agent reads source-quality text instead of parsing HTML chrome. The twin lives at the page URL plus index.md: this page's twin is /ai/agent-tooling/index.md, and the same suffix works on any page.
  • A tiered llms.txt. /llms.txt is the index tier: it starts with a task router that maps your goal to the recommended reading order (manual → generated scaffold → deno doc symbol lookup), followed by every real page as an absolute canonical link with a one-line summary, grouped by section, plus a short note telling agents how to reach the twins. /llms-full.txt is the full tier: every page's Markdown twin concatenated into one corpus for bulk ingestion.

The ladder, cheapest first: start at llms.txt, fetch the twin of the one page you need, and reach for llms-full.txt only when you genuinely want everything. And the two halves meet: point the MCP server's --docs-root at a checkout of this site and search_docs runs over the same corpus.

Run the protocol smoke

deno test --allow-all packages/cli/e2e/tests/agent/agent-mcp-stdio_test.ts

The smoke starts the public CLI binary, initializes MCP over stdio, verifies the 21-tool catalog, and checks docs, exports, diagnostics, unreachable telemetry, and command denial behavior.

Where to go next