@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 bydoctor, telemetry tools, API introspection tools, ornetscript plugin doctor --resource <resource>. - Target & Scope:
resourceidentifies 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.jsonlcontainingtimestamp,resource,summary, optionaldetails, 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
doctorpreviews diagnostic state without appending todrift.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.