Skip to main content
0.0.x

@netscript/mcp

The Model Context Protocol server for NetScript workspaces. This page describes the package's public surface and is maintained by hand; the authoritative, always-current symbol list is deno doc jsr:@netscript/mcp@0.0.8. For the full index of packages and plugins return to the reference overview.

@netscript/mcp publishes 22 token-bounded MCP tools that let a coding agent monitor a running app, debug a correlated execution, read framework-semantic telemetry, run the doctor, search the public documentation, discover first-party package exports, and trigger allowlisted CLI commands — over newline-delimited JSON-RPC on stdio, with no npm MCP SDK on the dependency graph.

Most consumers never import this package: netscript agent init installs it as an MCP server and netscript agent mcp runs it. See Agent tooling for the CLI × skills × MCP combo, and the package README for the mental model and recipes.

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 faithful retrieval of a known document or section; check mode and use full: true with nextCursor for exact retrieval of complete text.

Two entrypoints carry the surface:

  • @netscript/mcp — tool contracts, the registry, the protocol runner, ports, and default adapters.
  • @netscript/mcp/cli — the executable composition that binds the real telemetry, docs, doctor, and process adapters.

Server composition

Symbol Kind Summary
createMcpServer function Create the MCP server with initialize / tools/list / tools/call support.
createToolRegistry function Immutable, enumerable definitions of the 22 tools.
McpServer interface Callable server subset: handle(message) plus the registered tools.
McpServerOptions interface Composition seams: probe, environment, flows, truncation.
MCP_PROTOCOL_VERSION const The MCP protocol version the runner implements (2025-11-25).

Tool contracts

Symbol Kind Summary
TOOL_NAMES const The 22 tool names, in registry order.
TOOL_INPUT_SCHEMAS const Standard Schema input contract per tool.
TOOL_OUTPUT_SCHEMAS const Standard Schema output contract per tool.
validateSchema function Validate a value against a tool schema, throwing on drift.
ToolDefinition interface A tool's name, contracts, and flow.
ToolFlow type The function a tool executes; depends only on ports.
ToolName type Union of the 22 tool names.

Per-tool field overview

The table below is a top-level field overview — input names and result field names per tool, taken from the live tools/list. It is not the complete contract: types, enum values, numeric bounds, array maxima, nested shapes, and required-vs-optional result fields live in the published Standard Schema contracts (TOOL_INPUT_SCHEMAS / TOOL_OUTPUT_SCHEMAS), which every tools/list response returns in full. Bold inputs are required; every other input is optional. Every limit input caps the result count server-side before truncation applies.

Tool Inputs Result fields
get_app_status service, limit status, counts, domains
list_runs domain, status, service, sinceUnixMs, limit count, runs
get_run id id, summary, traceId, outcome, errorMessage, spans, logs
get_recent_errors service, domain, sinceUnixMs, limit count, groups
get_last_job_result jobId, jobName, service, sinceUnixMs found, jobName, jobId, status, outcome, exitCode, startUnixMs, completedUnixMs, durationMs, errorMessage, traceId
analyze_service_performance service, sinceUnixMs, limit service, sinceUnixMs, sampleCount, errorCount, errorRate, averageDurationMs, p50DurationMs, p95DurationMs, throughputPerMinute, topOperations
analyze_db_bottlenecks service, sinceUnixMs, limit sinceUnixMs, sampleCount, operations
doctor endpoint status, endpoint, counts, checks, families
search_docs query, limit count, matches
list_docs limit count, docs, and corpus (kind, resolved root, total documentCount)
get_doc slug, section, full, cursor contractVersion, mode, slug, title, section, content, outline, omitted, nextCursor, redirectedFrom
find_guidance intent, limit Bounded ordered section recommendations, cited code, related routes, confidence, fallback, and truncated
find_export symbol, limit Exact package / subpath / declaration-kind matches, total count, and truncated
list_package_exports package, offset, limit A stable declaration page grouped by subpath, total/returned counts, nextOffset, and truncated
get_export symbol, package, subpath One exact declaration signature and JSDoc with explicit truncated; ambiguity is refused with bounded candidates
search_exports query, package, kind, limit Ranked partial-name or declaration-shape matches with signatures, scores, totals, and truncated
list_commands filter, limit count, commands
execute_command command, args exitCode, durationMs, outputTail, truncated, timedOut
record_drift resource, summary, details recorded, resource, receipt
list_api_services — Service status, URLs, optional operation count, conflicts, and verbatim discovery source outcomes
list_service_operations service, filter, limit Bounded operation rows with optional access, plus truncated metadata
get_operation_schema service, operation, view Projected schema view, operation identity, optional access, access-aware curlExample, and authNote

Faithful documentation retrieval

get_doc reports contractVersion: 2 and mode on every successful response. Documents and sections whose JSON-escaped UTF-8 content fits 12 KiB return mode: "verbatim" with exact text. Larger inputs return mode: "extract": title, description, a whole-document navigation outline (heading, slug, character count), selected source blocks, and verbatim sentences. Selection uses four tiers: whole fences, command lines and config-key lines first (cheapest first); heading lines second; sentences containing links or inline code third; plain first sentences last. Selected spans are emitted in source order. A fence or sentence that cannot fit is omitted whole. The omitted.blocks count includes partially omitted paragraphs, and omitted.characters counts source characters not retained. The extract never paraphrases or cuts a snippet. Section-scoped extracts restrict content to that section but intentionally retain the whole-document outline to navigate to other sections; outline sizes describe the indexed section bodies.

For complete text, call get_doc with full: true. It returns mode: "full", one exact source page, and nextCursor when more text remains. Pass that value as cursor with the same slug, section (if selected), and full: true until nextCursor is absent. Concatenating content reconstructs the original document body byte for byte, including line endings and whitespace. YAML front matter is metadata and is excluded; section retrieval keeps the existing trimmed section-body convention. Full pages may divide fences, but preserve every character and never split a Unicode surrogate pair. Read the assembled text before using a multi-page snippet.

Cursors are versioned and bound to canonical slug, section, and SHA-256 source digest. Malformed, mismatched, or stale cursors return invalid_doc_cursor; restart without a cursor after a change. cursor requires full: true. Default results are cached per indexed document/section. The source admission ceiling is 4 Mi UTF-16 characters. Oversized sources are skipped during indexing; retrieving one returns doc_too_large naming its slug, while list, search and guidance remain available for accepted documents. Sources are never silently truncated. Outline/metadata exceeding the 64 KiB response ceiling produces an explicit transport error directing the caller to full mode.

The offline benchmark runs with deno task --cwd packages/mcp benchmark:docs over public docs site sources, or append --embedded for the shipped release fallback. It compares lexical token proxies including response metadata, independently inventoried fence/command/config/link retention, missing-material fallback proxies, and cold retrieval latency against the previous 2,000-character truncation. It reports both all-document and extract-mode-only aggregates and checks exact full reconstruction for every document. The fallback proxy measures missing source material; observed filesystem reads require a separate agent-run receipt. No inference model is used; model summarization is tracked in #2112.

Operation access summary

list_service_operations and get_operation_schema share the same optional access result shape:

{
  "authentication": "required",
  "securitySchemes": ["bearerAuth"],
  "scopes": ["catalog:read"],
  "roles": ["reader"]
}

This bounded OperationAccessSummary reports declared access facts only. authentication is none, optional, or required; each list allows at most 50 non-empty strings, and each string is bounded to 2,000 characters. It never contains a principal, token, cookie, secret, or credential value.

Retained OpenAPI operation Tool result
No own security property access is absent, preserving the undeclared state
security: [] authentication: 'none'; schemes and scopes are empty
security: [{}, { bearerAuth: [] }] authentication: 'optional'; bearerAuth is listed
security: [{ bearerAuth: ['catalog:read'] }] authentication: 'required'; scheme and scopes are listed
Required operation with x-netscript-roles Roles are copied into the bounded roles list

The root and ./cli entrypoints export the read-tool result types together with the types they reference, so typed consumers never meet a private type:

Symbol Kind Summary
ServiceOperationSummary interface One bounded list_service_operations row.
ListServiceOperationsResult interface Successful list_service_operations value.
GetOperationSchemaResult interface Successful get_operation_schema value.
OperationAccessSummary interface Declared access facts; also exported by ./openapi-projection.
SchemaViewName type Projection view name; also exported by ./openapi-projection.

get_operation_schema produces different credential-free guidance for undeclared, public, optional, and required operations. Only the required template includes the literal placeholder Authorization: Bearer <credential>; no real credential is requested or echoed.

Truncation semantics. After a flow succeeds, truncateResult recursively bounds the result using DEFAULT_TRUNCATION_POLICY — arrays are capped at 50 elements and strings at 2,000 UTF-16 code units — before the runner serializes it. get_doc is exempt from these recursive cuts; it uses the faithful retrieval budget below and checks the complete MCP response against 64 KiB. The analytics tools (analyze_service_performance, analyze_db_bottlenecks) additionally never return raw spans: their results are computed aggregates. execute_command returns only a bounded combined output tail (4,096 bytes by default) and flags truncated when output was cut. A failed flow returns a structured tool error (a stable code plus a message), not a truncated success.

Documentation resolves in this order: explicit --docs-root, NETSCRIPT_DOCS_ROOT, an indexable <projectRoot>/.netscript/docs, then a generated release-matched embedded fallback. An empty or redirect-only project probe falls back to embedded; an invalid explicit/environment root remains a structured error. list_docs.corpus.kind is filesystem or embedded, its root is the resolved filesystem path or null, and documentCount is the total before the requested list limit.

Record drift

record_drift is an evidence-gated mutating tool that appends structured architecture or runtime drift entries to .netscript/agent/drift.jsonl.

  • Required Evidence: Must be authorized by a fresh successful diagnostic receipt (created within 15 minutes, exitStatus: 0) for the target resource. Diagnostic receipts are automatically produced by doctor, telemetry tools, API introspection tools, or netscript plugin doctor --resource <resource>.
  • Target & Scope: resource identifies the target component (e.g. plugin name, service name, or 'project'). Receipts live at .netscript/agent/diagnostics/<resource>.json.
  • Mutation Behavior: Appends one JSON line to .netscript/agent/drift.jsonl containing timestamp, resource, summary, optional details, and the attached evidence receipt.
  • Failure Modes: If no receipt is found, if the receipt is older than 15 minutes, or if the receipt recorded a non-zero exit status, the tool fails with structured error code diagnostic_evidence_required.
  • Dry-run / Preview: Inspecting receipt files or invoking doctor previews diagnostic state without appending to drift.jsonl.

Output bounds

Every successful result is bounded server-side before the runner serializes it, so a tool can never flood the model's context.

Symbol Kind Summary
truncateResult function Recursively bound arrays and strings in a JSON-compatible result.
DEFAULT_TRUNCATION_POLICY const The default bounds: 50 array items, 2,000 UTF-16 code units per string.
TruncationPolicy interface maxItems and maxStringLength.

Command policy

execute_command is default-deny: a normalized command path must match an allow rule and no deny rule. Deny beats allow; anything unmatched is denied.

Symbol Kind Summary
decideCommand function Decide whether a normalized command path is allowed by a policy.
DEFAULT_COMMAND_POLICY const Conservative allowlist shipped with the server.
CommandPolicy interface Ordered allow / deny prefix rules.
CommandPolicyDecision type The decision returned for a command path.

The default policy allows db init|generate|migrate|seed|status|introspect, generate, contract, service list, plugin install|list|sync|doctor, and ui:add|ui:init|ui:list|ui:update; it denies deploy, init, marketplace, db reset, plugin remove, and ui:remove.

Ports

Every tool flow depends on a port, never on a concrete client — which is why this package can report on the CLI without depending on it. @netscript/cli implements the ports and injects them at its own composition root.

Symbol Kind Summary
TelemetryProbePort interface Telemetry endpoint reachability check.
DocsCorpusPort interface Public Markdown corpus: search, list, get.
ExportSurfaceCorpusPort interface Version-pinned normalized deno doc --json export data.
CommandCatalogPort interface Supplies the live CLI command tree to list_commands.
CommandExecutorPort interface Runs an allowed command, returning structured process data.
ProjectDoctorPort interface Typed project and plugin diagnostics.
DoctorCheckFamily interface One group of doctor checks aggregated into the verdict.

Generated export corpus

EmbeddedExportSurfaceCorpus is a separate corpus from public prose. Generation runs deno doc --json over every publishable first-party package export map, normalizes one record per exported declaration, and embeds deterministic gzip/base64 data. Runtime loading is lazy and mirror-free: it verifies the schema and framework versions, SHA-256, compressed and uncompressed byte sizes, and exact package/subpath/symbol counts before answering a query. get_export returns only the selected symbol's bounded signature and JSDoc; no tool places a whole generated file into model context.

Default adapters

Symbol Kind Summary
EmbeddedDocsCorpus class In-memory DocsCorpusPort used for package and outer-CLI Markdown assets.
EmbeddedExportSurfaceCorpus class Lazy mirror-free ExportSurfaceCorpusPort with version, hash, size, and count verification.
FilesystemDocsCorpus class DocsCorpusPort over an explicit, environment, or project-probed Markdown root.
SpawnCommandExecutor class CommandExecutorPort that spawns the netscript binary.
StaticCommandCatalog class CommandCatalogPort used when no live catalog is injected.
PluginDoctorFamily class Plugin diagnostics as a doctor check family.
slugifyDocsHeading function Normalize a Markdown heading into a get_doc section slug.

Sub-path exports

Export Path
@netscript/mcp ./mod.ts
@netscript/mcp/cli ./cli.ts
@netscript/mcp/openapi-projection ./openapi-projection.ts

@netscript/mcp/cli

The executable composition. It binds the real telemetry query, filesystem docs corpus, Aspire / project-wiring / plugin doctor families, and the process executor, and runs them over stdio.

Symbol Kind Summary
runMcpStdioServer function Run the server on Deno standard input and output.
createMcpCliServer function Compose the server with optional outer CLI adapters.
resolveDocsRoot function Resolve docs by flag, environment, then an indexable .netscript/docs project probe.
McpCliOptions interface Composition seams including exportSurfaceCorpus, docs, telemetry, doctor, commands, and project root.

Telemetry endpoint discovery is ordered: an explicit endpoint option, then NETSCRIPT_TELEMETRY_ENDPOINT, then ASPIRE_DASHBOARD_PORT, then http://localhost:18888. Only http: and https: endpoints are accepted, and an unreachable endpoint yields a structured warning rather than a crash.

Data boundary

The server reads telemetry, project metadata, generated registries, public documentation, and its package-embedded public export corpus. It never returns project source, environment-variable values, credentials, or secrets. Stdio is process-local; the only outbound traffic is the telemetry probe to the resolved endpoint.


Back to the reference overview.

Declared plugin runtime health

The CLI-hosted MCP doctor and get_app_status tools consume the plugin doctor's shared runtime aggregation. Status polling reads fresh declared resources through ProjectDoctorPort's runtime-health operation without repeating static module validation. Both tools use the same @netscript/plugin/health verdict. A healthy API with an unhealthy or missing declared child yields degraded, with monitoring severity fail. get_app_status returns healthStatus and bounded pluginHealth reports; each report includes API and child names, verdicts, and lifecycle states including crash-looping. Filtering an API retains its declared children. A standalone MCP process without the CLI project adapter, or a CLI project with no runtime declarations, retains the telemetry verdict and omits runtime health fields. Runtime inspection failures preserve telemetry counts/domains, report healthStatus: unknown, and include a bounded failed runtimeChecks finding. Declared runtimes with an absent/unavailable AppHost report an inspection failure rather than being mistaken for a no-plugin project. Each Aspire inspection command has a five-second deadline.

These inspection failures are intentional fail verdicts even when polling a stopped development app. Legacy adapters without a runtime-health operation use static doctor findings; their failures also remain visible when a service filter is supplied.

Runtime ownership follows the generated child/API reference links described in the plugin health reference, with optional InstalledFrom overrides. Installation metadata is not required. Invalid health-capable child entries produce named warning checks in both tools; get_app_status includes those warnings in runtimeChecks and reports warn while retaining telemetry. Failed findings take priority within the bounded checks list. Static-only adapter warnings retain their existing telemetry verdict; standalone MCP's unwired diagnostic warning remains visible in doctor.

A dead child remains degraded when a declared API has disabled health probes. A child-only plugin with a dead child is unhealthy. Cross-plugin precedence comes from summarizePluginHealth in the same shared package, so other consumers can use the identical roll-up.

The package forwards PluginHealthDeclaration, PluginHealthStatus, PluginHealthSummary, and PluginResourceHealth to document the types used by DoctorCheck.runtimeHealth. Their contract and aggregation implementation remain owned by @netscript/plugin/health.