Voyager's web-page sense: safe read-only observation of one live URL (structure, security, a11y).
Voyager's web-page sense. A safe, read-only observation of one live URL: its structure, forms, links, script origins, security posture (HTTPS / HSTS / CSP / mixed-content / cookies) and accessibility signals (lang, image alt coverage, heading order) — each with a described, never applied fix.
It parses static HTML — no JavaScript execution, no headless browser — so
it's honest about what it can and cannot see (it will not render a client-side
SPA's runtime state). Every piece of page text is returned framed as
untrusted. It is SSRF-gated: it refuses non-http(s) URLs and anything
resolving to private, loopback, or cloud-metadata addresses.
One sense in the Voyager family. Read-only, like all the senses — it never submits a form, clicks, or mutates anything.
npm i -g @dir-ai/voyager-browser
voyager-browser observe https://example.com
voyager-browser observe https://example.com --json
https://example.com/
https://example.com — 200; 3 finding(s), worst: medium. 0 form(s), 1 link(s).
title: Example Domain
security: https · a11y lang:yes alt:n/a
med HTTPS without HSTS
↳ add Strict-Transport-Security: max-age=63072000; includeSubDomains
med no Content-Security-Policy
↳ add a Content-Security-Policy to constrain scripts/resources
low no X-Content-Type-Options: nosniff
↳ add X-Content-Type-Options: nosniff
One tool, observe_page.
{ "command": "voyager-browser", "args": ["mcp"] }
import { observe } from '@dir-ai/voyager-browser'
const brief = await observe('https://example.com')
console.log(brief.summary)
console.log(brief.security) // { https, hsts, csp, mixedContent, thirdPartyScripts, … }
console.log(brief.forms) // insecure / cross-origin / sensitive flags
console.log(brief.findings) // severity + described fix
unsafe-inline/unsafe-eval/wildcard/no object-src/no base-uri); missing clickjacking protection (X-Frame-Options / frame-ancestors); missing nosniff, Referrer-Policy, Permissions-Policy; version-leaking Server/X-Powered-By; mixed content on an HTTPS page (origin-compared, not prefix); per-cookie Secure/HttpOnly; third-party scripts without Subresource Integrity.critical); a sensitive form (password/payment) posting cross-origin or over HTTP; a sensitive POST with no anti-CSRF token; sensitive data on GET.target="_blank" without rel="noopener" (reverse-tabnabbing).Set-Cookie, and same-origin bundles are decoded (header+payload, base64url, no signature verification, no secret cracking) and flagged for alg:none (critical), expired (exp in the past), or missing exp. Claim values are framed as untrusted.GETs to a short fixed list (/.git/config, /.env, /.svn/entries, /.DS_Store, /config.json, /wp-config.php~, /backup/, /uploads/), flagging only a confirmed body signature — never a bare 200. Pinned to the vetted IP; honours --authorized. Disable with --no-discovery.<html lang>, images without alt, skipped heading levels, unlabeled form fields.render: static | hybrid | client-heavy field: if a page's content is JavaScript-rendered, the brief says so and marks itself PARTIAL rather than reporting a shell as clean.@dir-ai/voyager / @dir-ai/voyager-net.http(s); a single URL (no lists/credentials). The host is resolved, every address is classified canonically (IPv4-mapped IPv6, unspecified, CGNAT, NAT64, link-local, private, loopback, metadata all refused), and the connection is pinned to the vetted IP so DNS rebinding cannot swap in an internal address between the check and the fetch. Every redirect hop is re-vetted and re-pinned.render field says exactly how much it saw.CognitiveClaim adapter so a page observation drops into a @dir-ai/voyager-agent mission (page → host → dependency chain).--render sandboxed headless pass (network-isolated, resource-capped) for true SPA/rendered-DOM coverage, always labeled as render-mode output; a stable finding-kind taxonomy and a full posture score.The line stays fixed: voyager-browser expands by reading more of what's already served, never by doing more to the server. Anything active (submitting, fuzzing, probing) belongs to a separate consent-gated organ.
| Package | Sense |
|---|---|
@dir-ai/voyager | web — verified-internet retrieval |
@dir-ai/voyager-browser | web page — observe one live URL |
@dir-ai/voyager-repo | code — orient in a repository |
@dir-ai/voyager-net | hosts — authorized host audit |
@dir-ai/voyager-contract | the cognitive contract the senses speak |
@dir-ai/voyager-agent | the one agent that composes them |
MIT © dir-ai
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @dir-ai/voyager-browserMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-dir-ai-voyager-browser": {
"command": "npx",
"args": [
"-y",
"@dir-ai/voyager-browser"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup reference@dir-ai/voyager-browsernpmio.github.dir-ai/voyager-browser works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.