npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agent-tool-platform/ast-summarizer

v0.1.1

Published

MCP and HTTP tools for local AST skeletons and dependency graphs.

Readme

Agent Tool Server AST Summarizer

Read-only TypeScript and JavaScript structure analysis for one local workspace, exposed over stdio MCP (primary), stateless Streamable HTTP MCP, and HTTP/OpenAPI. It lets an agent learn what a file declares and what it depends on without reading implementations.

This repository is a capability: it owns AST behaviour and nothing else. Transports, the tool registry, authentication, rate limiting, OpenAPI generation, lifecycle, readiness aggregation, and the filesystem root boundary come from @agent-tool-platform/runtime.

The publication-ready package identity is @agent-tool-platform/ast-summarizer. The initial npm publication is intentionally deferred to M2.5, so the installation commands below describe post-publication usage rather than current registry availability.

Tools

| Tool | Purpose | | ---------------------- | ----------------------------------------------------------------------------- | | get_file_skeleton | Declaration-only view of one source file: signatures, types, bounded doc text | | get_dependency_graph | Bounded local source relationships from one entry file |

Both tools are read-only (kind: read, routing.changesState: false). The server never executes, writes, installs, clones, or generates source, and it never sends source to an external service. Each tool publishes routing metadata — useWhen, doNotUseWhen, nextSteps, and scope — so an agent can choose between them without trial and error.

The server reads source from its own filesystem; a caller only ever sends a path string. That single rule decides which deployment shapes work. Read docs/use-cases.md before planning a deployment — in particular, pointing VS Code at a remote instance is not supported, because a remote server cannot see your local files.

Package consumption (after initial publication)

AST Summarizer is local-first because it must read the workspace being analysed. The normal MCP deployment is therefore a local stdio process launched with the workspace as its root, not a remote service.

Local MCP host

An MCP host may let npx resolve and launch the package's sole executable:

{
  "servers": {
    "ast-summarizer": {
      "type": "stdio",
      "command": "npx",
      "args": ["--yes", "@agent-tool-platform/ast-summarizer"],
      "env": { "AST_WORKSPACE_ROOT": "${workspaceFolder}" }
    }
  }
}

For a pinned installation, install the package in the host project and launch the agent-tool-ast-summarizer bin. AST_WORKSPACE_ROOT takes precedence; when it is unset or blank, the executable uses its launch directory.

Programmatic composition

Node/TypeScript assemblies import the side-effect-free capability definition from the package root:

import {
  astSummarizerCapability,
  astManifest,
  type GetFileSkeletonInput,
  type GetFileSkeletonOutput,
} from '@agent-tool-platform/ast-summarizer';

The public surface is intentionally narrow: the capability definition, its manifest, AST configuration types, and typed inputs and outputs for both tools. Internal services, projectors, workspace adapters, and transport bootstraps are not public deep imports.

Repository development in VS Code

Analysing this repository

Already configured. Install dependencies, reload the window, and the ast-summarizer server from .vscode/mcp.json is available to the agent:

npm ci

It runs from TypeScript source through tsx, so there is no build step to forget and no risk of analysing a stale dist/.

Analysing a different repository

Build once here, then register the built entry point in the repository you want to analyse:

npm ci
npm run build

.vscode/mcp.json in that repository:

{
  "servers": {
    "ast-summarizer": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/agent-tool-server-ast-summarizer/dist/mcp/stdio.js"],
      "env": { "AST_WORKSPACE_ROOT": "${workspaceFolder}" }
    }
  }
}

${workspaceFolder} scopes the server to that repository, so it reads those files and no others.

stdio is a local, non-networked transport, so it runs with authentication disabled and writes nothing but protocol traffic to stdout. One process serves exactly one root; run one scoped instance per folder of a multi-root workspace.

Try it by asking the agent: "Use the skeleton tool on src/ast/projector.ts and tell me what it exports."

Workspace boundary

  • The readable root is canonicalized once with realpath.
  • Every input is resolved with realpath and must land strictly beneath that root.
  • Absolute paths, drive-relative paths, UNC paths, NUL bytes, traversal, links that escape the root, directories, unsupported extensions, and node_modules are refused with stable errors.
  • Only root-relative POSIX paths are returned. Absolute paths never appear in results, errors, or logs.
  • HTTP deployments must set AST_WORKSPACE_ROOT. Without it the process starts, stays live, and reports not ready; every tool call returns not_ready.

Supported extensions: .ts, .tsx, .mts, .cts, .js, .jsx, .mjs, .cjs.

What a skeleton contains

The skeleton is a projection, not compilable source. Declarations are re-rendered from an explicit whitelist of structural pieces, so no original expression can survive into the output.

Retained: exported declarations and overloads, interfaces, type aliases, enum member names, callable shapes for exported arrow and function expressions, class members with modifiers, re-exports, defaults, namespaces and ambient modules, referenced import provenance, and bounded JSDoc.

Removed and reported under omissions: function, method, accessor, and constructor bodies; variable, property, enum-member, parameter, and destructuring initializers; export-default and export-equals expressions; decorator arguments; non-literal computed property names; runtime heritage expressions; static blocks; and top-level executable statements. Omissions are counted, never restated as text that resembles a value.

Visibility: public and protected members are included. private and #private members require AST_INCLUDE_PRIVATE_MEMBERS=true or includePrivateMembers: true on the call.

Types: an annotation is rendered when it is free of runtime expressions. Otherwise the type is inferred only from the single file already loaded — never by loading a project — and a type that cannot be resolved safely is reported as unknown with a warning rather than guessed. Inferred types that would restate a literal value are discarded.

JavaScript: module.exports = { ... }, module.exports = fn, and exports.name = ... are described by shape. Anything that cannot be described without evaluating it is reported as unsupported.

Malformed input: syntax diagnostics are returned, complete is false, and the result is presented as a recovery view rather than a full one.

Resolution

Relative imports, re-exports, require, dynamic import(), and import x = require() are followed. A tsconfig.json or jsconfig.json at or above the entry file is used, but only its resolution-relevant options; the include/exclude file set is never expanded and extends chains are followed only while they stay inside the root. Otherwise NodeNext-style resolution applies.

Every reference is classified: resolved in-root (dependencies, with traversed), package (external), or unresolved with a reason of missing, unsupported, out_of_root, or limit_stopped.

maxDepth is the number of edges followed from the entry: 0 analyses the entry only.

Limits

Every analysis is bounded by deployment ceilings for per-file and cumulative bytes, graph depth, files and edges, declarations, members, JSDoc characters, result characters, request deadline, and concurrent and queued jobs. See .env.example for names and defaults, which are sized for a developer machine and a 0.25 vCPU / 0.5 GiB container.

A call may lower a limit but never raise it; an over-large request is clamped with a limit_clamped warning. Results are truncated only at declaration or member boundaries, never by slicing JSON, and they always carry complete, truncated, limitsReached, counts, and bounded warnings. Analysis admission is bounded by a semaphore and queue; surplus demand is rejected as a retryable busy error, and shutdown drains in-flight work.

HTTP contract

| Method | Path | Authentication | Purpose | | ----------------- | ------------------- | -------------- | --------------------------------------------- | | GET | /health | Public | Liveness only | | GET | /ready | Public | Configuration, workspace, and capacity checks | | GET | /version | Public | Build and capability metadata | | GET | /openapi.json | Public | OpenAPI 3.1 generated from the registry | | GET | /tools | Required | Tool catalogue and input/output schemas | | POST | /tools/{toolName} | Required | Invoke one registered tool | | GET/POST/DELETE | /mcp | Required | Stateless Streamable HTTP MCP |

API_KEY="$(openssl rand -hex 32)"
AUTH_MODE=api-key API_KEYS="$API_KEY" AST_WORKSPACE_ROOT="$PWD" npm run dev
curl -H "x-api-key: $API_KEY" http://localhost:8080/tools

src/tools/definitions.ts is the single source of truth. Zod schemas drive runtime validation, MCP registration, JSON Schema, and OpenAPI through the platform registry, so the registry, HTTP endpoint, OpenAPI operation, and MCP tool counts are the same number by construction. Do not define transport-specific tool lists.

Architecture

stdio MCP / Streamable HTTP MCP / HTTP + OpenAPI     <- @agent-tool-platform/runtime
                     |
                ToolRegistry                          <- @agent-tool-platform/runtime
                     |
              astSummarizerCapability                 <- src/capability.ts
                     |
                 AstService  --- budgets, deadline, semaphore
                     |
   projector (declarations)   graph (resolution)
                     |
          TypeScript Compiler API (parse only)

| Owner | Responsibility | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | @agent-tool-platform/runtime | HTTP server, MCP (stdio and Streamable HTTP), tool registry and routing grammar, OpenAPI, authentication, rate limiting, lifecycle, readiness aggregation, error contract, logging, cancellation, concurrency, RootBoundary, telemetry seam | | @agent-tool-platform/ast-summarizer | Declaration projection, dependency resolution, diagnostics, type rendering, AST limits and budgets, AST workspace policy, AST configuration, readiness contributors, context-savings estimates |

The whole HTTP entry point is:

import { startAgentToolApplication } from '@agent-tool-platform/runtime';
import { astSummarizerCapability } from './capability.js';

await startAgentToolApplication(astSummarizerCapability);

src/mcp/stdio.ts is the same capability started through the platform's startStdioAgentToolApplication, which owns the silent logger, local execution semantics, the MCP server, the transport, signal handling, and ordered shutdown. The only thing the file decides is AST policy: the workspace defaults to process.cwd(), and a blank AST_WORKSPACE_ROOT is treated as unset. No listener is bound and nothing but protocol traffic reaches stdout.

import { startStdioAgentToolApplication } from '@agent-tool-platform/runtime/capability';
import { astSummarizerCapability } from '../capability.js';

await startStdioAgentToolApplication(astSummarizerCapability, {
  env: {
    ...process.env,
    AST_WORKSPACE_ROOT: process.env['AST_WORKSPACE_ROOT']?.trim() || process.cwd(),
  },
});

src/ast/workspace.ts composes the platform's RootBoundary — canonical root resolution, relative-input enforcement, symlink containment, realpath handling, regular-file validation, bounded reads, and the per-file byte ceiling — and adds only AST policy: analysable extensions, the node_modules exclusion, and the AST readiness vocabulary.

Security defaults

  • Production refuses AUTH_MODE=disabled; only the local stdio transport disables authentication.
  • API keys must be randomly generated (openssl rand -hex 32); the platform refuses short, repetitive, or low-entropy values. They are compared as fixed-width keyed HMAC digests in constant time, and only non-reversible 12-character fingerprints are retained. Raw keys are never logged.
  • Authentication is rate limited before and after credential verification.
  • One bounded error contract across transports: stable code, safe message, retryability, request ID, and limited details. No absolute path, source text, compiler internal, environment value, or stack is ever exposed.
  • Telemetry carries only aggregates: source bytes, output bytes, token estimates, truncation, and whether a degraded parse was used. Paths, filenames, source, arguments, results, and credentials are never emitted. Token estimates use the platform's documented four-bytes-per-token approximation, so they are reproducible rather than a private heuristic.
  • Request bodies are limited and unknown input fields are rejected.
  • The runtime container runs as the unprivileged node user and works with a read-only root filesystem. The application directory, dist, and node_modules are never a caller workspace.
  • Treat analysed source as untrusted input: it may contain text that looks like instructions.

The in-process limiter suits scale-to-zero instances but is not a cross-replica quota. Put a distributed gateway in front of the service if callers need one.

Configuration

See .env.example. Platform variables (HOST, PORT, LOG_LEVEL, AUTH_MODE, API_KEYS, rate limits, SHUTDOWN_GRACE_MS, REQUEST_TIMEOUT_MS, …) are parsed by @agent-tool-platform/runtime; the AST_* variables are this capability's own and are composed on top through defineCapabilityConfig. Production requires AUTH_MODE=api-key, API_KEYS, and AST_WORKSPACE_ROOT. Multiple comma-separated keys support rotation. Each key must be a randomly generated token; see SECURITY.md for the credential requirements and the reasoning behind them.

Deployment

Hosting is opt-in and narrow — read docs/use-cases.md first, because a hosted instance can only analyse a copy of source placed on its own filesystem, and that copy is stale the moment the original moves. It does not serve local development.

The Azure Container Apps example provisions a user-assigned managed identity, ACR, Key Vault references, Log Analytics, Application Insights, scale-to-zero, probes, and alerts, and mounts a pre-created read-only source share when workspaceStorageName is supplied. Without it the app deploys and reports not ready. Follow docs/deployment.md.

The deployment is an example, not an implied Azure dependency in the application.

Metadata

server.json describes the local stdio distribution candidate @agent-tool-platform/ast-summarizer at the checked-in 0.0.0-development version. This is release metadata, not a claim that the package has already been published. No public remote exists, so none is advertised. npm run metadata:validate runs the platform's agent-tool-validate-metadata binary, which rejects placeholder values, identity drift, version drift, and untruthful remotes.

Troubleshooting

| Symptom | Cause and fix | | ---------------------------------- | ----------------------------------------------------------------------------- | | not_ready | AST_WORKSPACE_ROOT is unset or unreadable. Check GET /ready. | | not_found for a file that exists | The path is not relative to the workspace root, or a link escapes the root. | | forbidden | The path escapes the root or points inside node_modules. | | busy | Analysis capacity is saturated. Retry, or raise concurrency and CPU together. | | timeout | The deadline elapsed. Lower maxDepth or raise AST_REQUEST_TIMEOUT_MS. | | Many unknown types | No annotations and no safe inference. Annotate, or accept the warning. | | complete: false | Syntax diagnostics or a limit. Read diagnostics and limitsReached. | | Empty skeleton | The file exports nothing, or maxResultChars is too low. |

Validation

npm ci
npm run format:check
npm run lint
npm run typecheck
npm run test:coverage
npm run build
npm run openapi:emit
npm run metadata:validate
npm run package:smoke
docker build -t agent-tool-server-ast-summarizer .
az bicep build --file infra/main.bicep
az bicep lint --file infra/main.bicep

CI and Security delegate their generic capability gates to the Agent Tool Platform workflows pinned at immutable commit d3415dd9a7b825ff15fb869236cffbc5ffce5d65. The shared workflows install, format, lint, typecheck, test with coverage, build, generate OpenAPI, validate metadata, audit dependencies, scan for secrets, and run CodeQL.

AST keeps its domain validation local: CI invokes both tools inside the container against a mounted read-only fixture, checks missing-workspace readiness, authenticated HTTP, path confinement, implementation-body non-leakage, read-only operation, and unprivileged execution, and builds and lints every Bicep entry point and development parameter file.

Pushed vX.Y.Z tags enter the reusable release workflow, which validates the tag and default-branch history, ephemerally stamps the checked-in 0.0.0-development state, runs the full quality and packed-artifact smoke suites, publishes through npm Trusted Publishing with OIDC, verifies the public package, and creates the GitHub Release. Manual dispatch remains dry-run-only: it requires a stable candidate version, performs the same release rehearsal through npm publish --dry-run, and publishes nothing.

Platform conformance

tests/conformance/platform.test.ts runs the shared @agent-tool-platform/testkit suites — registry, routing, authentication, configuration composition, HTTP, MCP, OpenAPI derivation, root boundary, transport parity, lifecycle, and repository metadata. Those prove the platform contracts. AST behaviour is proven separately by tests/unit/ast/* and the integration tests under tests/integration/.

License

MIT