https://raw.githubusercontent.com/cyanheads/attack-surface-mcp-server/HEAD/AGENTS.md
− **Version:** 0.5.0− **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `0.13.18`− **Engines:** Bun ≥1.4.0, Node ≥24.0.0− This is a defensive external-attack-surface-mapping (EASM) server. It is **passive and non-intrusive by mandate**: it reads public records (Certificate Transparency, DNS, RDAP/WHOIS) and each target's *own* published surface (one TLS handshake, one HTTP GET per host). It does **not** port-scan, exploit, brute-force, fuzz, or probe for vulnerabilities — that capability is excluded from the surface by design, never gated behind a flag. Output is descriptive (what exists, what the posture is), neve− - **The SSRF guard is the security spine.** Every outbound connection to a user-supplied target (DNS, TLS, HTTP) must pass `assertSafeDomain` / `assertSafeUrl` / `assertSafeResolverIp` (`src/utils/ssrf-guard.ts`) before connecting. It rejects private, loopback, link-local, cloud-metadata, and reserved ranges. Never route a new outbound path around it.− | `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |− `npm run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. `mcpb pack` reads `.mcpbignore`, not `.gitignore`, so every root path the bundle must not ship — source, tests, docs, caches, logs, agent docs, plugin manifests, gitignored local files — needs a root-anchored line there (`/docs/`, never `docs/`, which also strips `node_modules/*/docs/`); `lint:packaging` names each missing or unanchored line. Root `skills/` ships on purpose. The pack step is followed by+ **Version:** 0.6.0+ **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.22`+ **Engines:** Bun ≥1.4.4, Node ≥24.0.0+ This is a defensive external-attack-surface-mapping (EASM) server. It is **passive and non-intrusive by mandate**: it reads public records (Certificate Transparency, DNS, RDAP/WHOIS) and each target's *own* published surface (TLS handshakes and HTTP GETs). It does **not** port-scan, exploit, brute-force, fuzz, or probe for vulnerabilities — that capability is excluded from the surface by design, never gated behind a flag. Output is descriptive (what exists, what the posture is), never an exploit+ - **The SSRF guard is the security spine.** TLS, HTTP and registration connections pass `assertSafeDomain` / `assertSafeUrl` / `resolveSafeHost` (`src/utils/ssrf-guard.ts`) before connecting. Guarded hostnames require public A/AAAA evidence from the first configured resolver and validated system answers; resolved addresses never appear in rejection text. DNS-only evidence uses explicit configured resolvers validated by `assertSafeResolverIp`, without connecting to the queried host. Private DNS a+ | `bun run lint:packaging` | Check environment variable parity, `.mcpbignore` coverage, plugin manifests, and published skills (run by devcheck) |+ `bun run bundle` produces a stdio `.mcpb` bundle for Claude Desktop. Put every repository-only path in `.mcpbignore` with a root-anchored pattern such as `/docs/`. Root `skills/` ships with the server. After packing, `scripts/clean-mcpb.ts` prunes development dependencies, removes agent docs at each installed dependency's root and dependency `SKILL.md` files at any depth, and retains runtime modules such as the SDK's `dist/ext/skills/`. It also removes platform-specific bindings, node-gyp build