{
  "markdown": "# Starfetch\n\n<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"assets/starfetch-logo-dark.svg\" />\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"assets/starfetch-logo-light.svg\" />\n    <img src=\"assets/starfetch-logo-light.svg\" width=\"420\" alt=\"Starfetch\" />\n  </picture>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/starfetch-js/starfetch/actions/workflows/ci.yml\"><img src=\"https://github.com/starfetch-js/starfetch/actions/workflows/ci.yml/badge.svg?branch=main&amp;event=push\" alt=\"CI\" /></a>\n  <a href=\"https://codecov.io/gh/starfetch-js/starfetch\"><img src=\"https://codecov.io/gh/starfetch-js/starfetch/graph/badge.svg?branch=main\" alt=\"Coverage\" /></a>\n  <a href=\"https://registry.modelcontextprotocol.io/?search=io.github.starfetch-js%2Fstarfetch\"><img src=\"https://img.shields.io/badge/MCP_Registry-listed-6f42c1\" alt=\"MCP Registry\" /></a>\n  <a href=\"https://www.skills.sh/starfetch-js/starfetch/starfetch\"><img src=\"https://img.shields.io/badge/skills.sh-starfetch-111827\" alt=\"skills.sh\" /></a>\n  <a href=\"https://www.npmjs.com/package/@starfetch-js/mcp\"><img src=\"https://img.shields.io/npm/v/@starfetch-js/mcp?label=npm\" alt=\"npm version\" /></a>\n</p>\n\nStarfetch gives AI agents safe, reproducible access to public astronomy\ncatalogs through the\n[Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro).\n\nAsk an astronomy question in natural language. A Starfetch-enabled agent can\nselect an appropriate service, inspect its live tables and columns, construct\na bounded ADQL query, execute it, and return the result with the exact service,\ntable, query, limit, units, and assumptions it used.\n\n<p align=\"center\">\n  <img src=\"assets/demo.gif\" width=\"900\" alt=\"A Starfetch-enabled agent inspecting Gaia metadata, ranking high-proper-motion sources near the Pleiades, and summarizing the results\" />\n</p>\n\n```text\nYou: Find the 10 Gaia DR3 sources with the highest proper motion within 0.5\n     degrees of the Pleiades center at RA 56.75°, Dec +24.12°. What stands out?\n\nAgent: selects Gaia → inspects metadata → runs bounded ADQL →\n       returns catalog rows, exact ADQL, units, and assumptions\n```\n\nRepresentative captured result:\n\n```text\nService: ESA Gaia Archive\nTable: gaiadr3.gaia_source\nRows returned: 10\nQuery limit: TOP 10 / MAXREC 10\n\nHighest returned proper motions:\n- Gaia DR3 66780900298410496: 244.48 mas/yr\n- Gaia DR3 66524409149512064: 184.50 mas/yr\n\nExact ADQL:\nSELECT TOP 10 source_id, ra, dec, pm, pmra, pmdec, parallax, parallax_error,\n  phot_g_mean_mag, bp_rp, ruwe\nFROM gaiadr3.gaia_source\nWHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 56.75, 24.12, 0.5)) = 1\n  AND pm IS NOT NULL\nORDER BY pm DESC\n```\n\nGaia, SIMBAD, VizieR, the NASA Exoplanet Archive, and IRSA are available as\nbuilt-in service presets. Agents can also discover and query other public TAP\nservices by URL. Starfetch remains TAP-native and keeps ADQL visible, so the\nagent workflow is convenient without becoming a scientific black box.\n\n## Start here\n\n- [Connect an agent](#connect-an-agent)\n- [What the agent does](#what-the-agent-does)\n- [Why Starfetch?](#why-starfetch)\n- [Reliability without hidden assumptions](#reliability-without-hidden-assumptions)\n- [Optional Starfetch skill](#optional-starfetch-skill)\n- [Supported scope](#supported-scope)\n- [CLI and TypeScript](#cli-and-typescript)\n- [Run the Gaia proper-motion demo](#run-the-gaia-proper-motion-demo)\n- [Development](#development)\n\n## Connect an agent\n\nThe local npm server is Starfetch's stable public connection path. It runs on\nyour computer and can be registered with any compatible MCP client.\n\n### Local npm server\n\nRegister Starfetch with the agent client that will launch it. Running the MCP\npackage by itself only starts a stdio server; it does not connect that server to\nan agent. Starfetch is also discoverable through the\n[official MCP Registry](https://registry.modelcontextprotocol.io/?search=io.github.starfetch-js%2Fstarfetch).\n\n#### Codex\n\nRegister Starfetch for the Codex CLI, IDE extension, and ChatGPT desktop app:\n\n```sh\ncodex mcp add starfetch -- npx -y @starfetch-js/mcp\ncodex mcp list\n```\n\nThese Codex surfaces share MCP configuration. See the\n[official Codex MCP documentation](https://developers.openai.com/codex/mcp).\n\n#### Claude Code\n\nRegister Starfetch in user scope:\n\n```sh\nclaude mcp add --scope user --transport stdio starfetch -- npx -y @starfetch-js/mcp\nclaude mcp get starfetch\n```\n\nSee the\n[official Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp).\n\n#### Cursor\n\nAdd this server entry to `~/.cursor/mcp.json` for global use or\n`.cursor/mcp.json` for one project:\n\n```json\n{\n  \"mcpServers\": {\n    \"starfetch\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@starfetch-js/mcp\"]\n    }\n  }\n}\n```\n\nSee the\n[official Cursor MCP documentation](https://docs.cursor.com/context/model-context-protocol).\n\nOther MCP clients can use the same stdio command and arguments through their\nown server-registration interface:\n\n```text\ncommand: npx\nargs: -y @starfetch-js/mcp\n```\n\nRestart or reload the client after registration, then ask a normal astronomy\nquestion. You should not need to write ADQL or name Starfetch tools in the\nprompt. Starfetch requires Node.js 22 or newer.\n\n### Remote MCP\n\nA remote MCP service runs on the internet and accepts MCP connections over\nHTTPS. No Starfetch package has to be installed or launched on the user's\ncomputer. Compatible clients can connect to the production endpoint:\n\n```text\nhttps://starfetch-mcp-app-production-wumkqeiqaa-ew.a.run.app/mcp\n```\n\nThe remote service is public, unauthenticated, bounded, and best effort. Do\nnot send credentials, private archive URLs, sensitive personal data, or\nunbounded workloads. The local npm server remains the default when you want\nlocal control or when a client does not support remote Streamable HTTP MCP.\n\nSee the remote service's [overview](apps/mcp-app/README.md),\n[privacy notice](apps/mcp-app/PRIVACY.md),\n[support](apps/mcp-app/SUPPORT.md), and\n[terms of use](apps/mcp-app/TERMS.md).\n\n## What the agent does\n\nFor a service-specific catalog question, Starfetch guidance teaches the agent\nto:\n\n1. choose an explicit service preset or public TAP URL;\n2. check service availability when appropriate;\n3. inspect relevant tables and the selected table's columns;\n4. construct ADQL only from discovered schema information;\n5. bound exploratory work with ADQL `TOP`, TAP `MAXREC`, or both;\n6. execute the smallest useful query;\n7. return the service, table, exact ADQL, effective limit, format, units, and\n   relevant assumptions;\n8. return to metadata after a schema or syntax failure instead of guessing.\n\nThe agent should never present a timeout, availability failure, parse error, or\nquery error as an empty scientific result. A successful zero-row result and a\nfailed request are different outcomes.\n\nStarfetch exposes tools for the complete workflow:\n\n```text\nstarfetch_list_presets\nstarfetch_registry_search\nstarfetch_tap_availability\nstarfetch_tap_capabilities\nstarfetch_tap_tables\nstarfetch_tap_columns\nstarfetch_tap_query\nstarfetch_tap_submit_job\nstarfetch_tap_job_status\nstarfetch_tap_job_wait\nstarfetch_tap_job_fetch\nstarfetch_tap_job_delete\n```\n\nQuery tools return result data separately from diagnostics. They preserve the\nexact submitted ADQL and effective row limit for reproduction and review.\nSynchronous queries and async submissions send TAP `MAXREC=100` when `maxrec`\nis omitted.\n\nThe remote HTTP service returns an opaque `jobCapability` with each async\nsubmission. Supply that value unchanged to every remote status, wait, fetch,\nor delete call. The capability remains usable while the remote job exists and\nthe service signing secret is unchanged. Remote deletion is marked destructive\nso MCP clients can obtain user approval. The stdio MCP server and CLI keep\ntheir existing job-reference behavior and do not advertise remote-only fields.\n\n## Why Starfetch?\n\nStarfetch is a useful middle layer when an agent needs live public catalog data\nwithout turning the workflow into a black box:\n\n- it inspects live schemas instead of guessing table and column names;\n- it bounds public-service queries by default and preserves service failures;\n- it returns exact ADQL, limits, units, and assumptions for reproduction;\n- it provides one metadata-first interface across several TAP services; and\n- its CLI and TypeScript library can reproduce an agent's query outside the\n  agent client.\n\nUse an archive's own interface, PyVO/Astropy, or local analysis tools instead\nwhen you need authenticated/private archives, extensive local analysis, image\ndata processing, or authoritative astrophysical interpretation.\n\n## Reliability without hidden assumptions\n\nThe MCP server works without installing a filesystem skill. Starfetch carries\nthe same canonical guidance through three overlapping layers:\n\n| Layer                     | Role                                                                            |\n| ------------------------- | ------------------------------------------------------------------------------- |\n| MCP tool descriptions     | Minimum metadata-first and bounded-query contract available to every MCP client |\n| MCP prompts and resources | Discoverable workflows, ADQL guidance, service notes, and examples              |\n| Optional Starfetch skill  | Rich multi-step behavior across longer agent interactions                       |\n\nThe server exposes the retrievable prompts `query_astronomy_catalog`,\n`explore_service`, `run_cone_search`, and `troubleshoot_adql`. Canonical\nMarkdown resources are available under `starfetch://guides/`,\n`starfetch://services/`, and `starfetch://examples/`.\n\nPrompt and resource support depends on the MCP client. Tool descriptions remain\nself-sufficient for basic safe operation when a client exposes tools only. The\noptional skill contains the full workflow, service references, and examples.\n\n## Optional Starfetch skill\n\nInstall the skill when the agent client supports filesystem skills and you want\nthe strongest multi-interaction behavior. The skill is recommended, not\nrequired by the MCP server.\n\nInstall the canonical skill directly from GitHub through skills.sh:\n\n```sh\nnpx skills add https://github.com/starfetch-js/starfetch/tree/main/packages/skill/skill/starfetch\n```\n\nInspect or install the packaged skill:\n\n```sh\nnpx -y @starfetch-js/cli skill print\nnpx -y @starfetch-js/cli skill install --target codex\nnpx -y @starfetch-js/cli skill install --target claude-code --scope project\nnpx -y @starfetch-js/cli skill install --target cursor\n```\n\nInstall into a custom final skill directory with:\n\n```sh\nnpx -y @starfetch-js/cli skill install --path ./starfetch-skill\n```\n\nUse `--dry-run` to preview file actions. Default destinations are:\n\n- Codex user scope: `~/.codex/skills/starfetch`\n- Claude Code user scope: `~/.claude/skills/starfetch`\n- Codex project scope: `.codex/skills/starfetch`\n- Claude Code project scope: `.claude/skills/starfetch`\n- Cursor project scope: `.cursor/rules/starfetch.mdc`\n\nCodex and Claude Code default to user scope. Cursor defaults to project scope\nbecause its rules are project files.\n\n## Supported scope\n\nStarfetch is designed for public astronomical Table Access Protocol services.\nIt currently provides:\n\n- built-in presets for `gaia`, `simbad`, `vizier`, `exoplanetarchive`, and\n  `irsa`;\n- VO registry search for additional TAP endpoints;\n- VOSI availability, capabilities, table, and column metadata;\n- bounded synchronous ADQL queries;\n- explicit TAP/UWS async job submission, status, wait, fetch, and deletion;\n- VOTable, CSV, and TSV requests, plus safe JSON and JSONL conversion;\n- exact query and limit diagnostics.\n\nStarfetch does not accept credentials or implement authenticated TAP workflows.\nThe MCP server does not execute shell commands or write local result files.\nStarfetch retrieves catalog data; it does not validate astrophysical\ninterpretations or reconcile scientific differences between catalogs.\n\nVOTable TABLEDATA and inline base64 BINARY/BINARY2 rows can be converted.\nVOTable FITS rows, remote streams, and compressed streams remain pass-through\nor unsupported for local row conversion.\n\n## CLI and TypeScript\n\nMCP is the primary agent interface. The CLI is useful for scripting, inspecting\na query outside an agent, and reproducing the exact request an agent reported.\nThe TypeScript library supports applications and custom adapters.\n\n### CLI quickstart\n\nInstall or run the CLI once:\n\n```sh\nnpm install -g @starfetch-js/cli\nnpx -y @starfetch-js/cli tap tables --service gaia\n```\n\nInspect metadata before writing service-specific ADQL:\n\n```sh\nstarfetch tap availability --service gaia\nstarfetch tap tables --service gaia\nstarfetch tap columns --service gaia --table gaiadr3.gaia_source\n```\n\nRun a bounded query:\n\n```sh\nstarfetch tap query \\\n  --service gaia \\\n  --query \"SELECT TOP 5 source_id, ra, dec FROM gaiadr3.gaia_source\" \\\n  --format json\n```\n\nADQL can come from `--query`, a file, or stdin. Result data can be written with\n`--out`:\n\n```sh\nstarfetch tap query --service gaia --file query.sql --format csv --out result.csv\ncat query.sql | starfetch tap query --service gaia --format jsonl\n```\n\nUse `--service` for a preset or `--url` for an explicit TAP base URL. If both\nare supplied, `--url` selects the endpoint and the service name remains as\ndiagnostic context.\n\nDiscover additional services through the VO registry:\n\n```sh\nstarfetch tap registry search gaia --maxrec 5 --format json\n```\n\n### Async jobs\n\nUse explicit async jobs for larger justified queries:\n\n```sh\nstarfetch tap jobs submit \\\n  --service gaia \\\n  --query \"SELECT TOP 10 source_id, ra, dec FROM gaiadr3.gaia_source\" \\\n  --maxrec 10\n\nstarfetch tap jobs status <job-url>\nstarfetch tap jobs wait --interval 2000 --timeout 120000 <job-url>\nstarfetch tap jobs fetch <job-url> --format votable --out result.xml\nstarfetch tap jobs delete <job-url>\n```\n\nAbsolute job URLs are sufficient for follow-up commands. Bare job IDs require\n`--service` or `--url` so Starfetch can resolve the TAP `/async` endpoint.\n\n### TypeScript API\n\nInstall `@starfetch-js/core` when a script, app, or custom agent adapter needs\ndirect TAP access:\n\n```sh\nnpm install @starfetch-js/core\n```\n\n```ts\nimport { registry, tap } from \"@starfetch-js/core\";\n\nconst client = tap(\"gaia\");\nconst columns = await client.columns(\"gaiadr3.gaia_source\");\nconst result = await client.query(\n  \"SELECT TOP 5 source_id, ra, dec FROM gaiadr3.gaia_source\",\n  { format: \"votable\", maxrec: 5 },\n);\n\nconsole.log(columns.length);\nconsole.log(await result.fields());\nconsole.log(await result.overflow());\nconsole.log(await result.json());\n\nconst services = await registry().searchTapServices({\n  query: \"gaia\",\n  maxrec: 5,\n});\nconsole.log(services[0]?.accessUrl);\n```\n\n`tap(target)` accepts a known preset, a TAP base URL, or an object containing a\nservice and/or URL. Metadata methods read TAP `/availability`, `/capabilities`,\nand `/tables`; sync queries use `/sync`, and explicit jobs use `/async`.\n\n## Run the Gaia proper-motion demo\n\nReproduce the demo's metadata-first Gaia query and print the exact ADQL,\neffective limit, and returned rows:\n\n```sh\ngit clone https://github.com/starfetch-js/starfetch.git\ncd starfetch\nnpm ci\nnpm run build\nnode examples/quickstart/run.mjs\n```\n\nThis command queries the public Gaia TAP service. For more CLI, TypeScript API,\nlive TAP, and MCP Inspector workflows, see\n[starfetch-js/examples](https://github.com/starfetch-js/examples). Each example\nincludes its exact ADQL, expected columns, and a cross-platform Node.js runner.\n\n```sh\ngit clone https://github.com/starfetch-js/examples.git\ncd examples\nnpm ci\nnode 01-gaia-nearby-stars/run.mjs\n```\n\nLaunch MCP Inspector from that repository with:\n\n```sh\nnpm run inspect:mcp\n```\n\n## Packages\n\n- `@starfetch-js/mcp`: primary stdio MCP server and packaged agent guidance.\n- `@starfetch-js/skill`: optional distributable Starfetch agent skill.\n- `@starfetch-js/cli`: scripting, TAP inspection, query, async job, and skill\n  installation commands.\n- `@starfetch-js/core`: reusable TAP, VOSI, UWS, VOTable, registry, and output\n  conversion primitives.\n\n## Development\n\nInstall dependencies with the committed lockfile:\n\n```sh\nnpm ci\n```\n\nRun the private Streamable HTTP development app with:\n\n```sh\nnpm run dev:http\n```\n\nIt serves MCP at `http://127.0.0.1:3000/mcp` and process health at\n`http://127.0.0.1:3000/health`. Each MCP request gets a fresh stateless\n`@starfetch-js/mcp` server. The HTTP surface keeps the 12 canonical Starfetch\ntools unchanged and adds two UI-linked tools through the immutable\n`ui://starfetch/table/v1` MCP Apps resource. `starfetch_render_table` presents\nan existing table view without submitting a TAP request.\n`starfetch_query_table` runs a synchronous JSON query for the interactive\nscientific table; its full loaded table is widget-only while the model receives\na 20-row preview. Ordinary MCP clients can continue using the canonical text\nand structured results without loading the widget. Configuration is\nenvironment-only:\n\n- `HOST` defaults to `127.0.0.1`; set `0.0.0.0` explicitly for all interfaces.\n- `PORT` defaults to `3000`.\n- `ALLOWED_ORIGINS` is a comma-separated list of exact browser origins and\n  defaults to none.\n- `SHUTDOWN_GRACE_MS` defaults to `10000` and accepts `1` through `60000`.\n- `STARFETCH_JOB_CAPABILITY_SECRET` is a base64url secret of at least 32 bytes.\n  It is required when `HOST` is not loopback; loopback development uses an\n  ephemeral per-process secret when omitted.\n\nThe anonymous HTTP policy is a fixed, tested product profile rather than a\nset of independently tunable environment variables. It caps MCP requests at 2\nMiB, TAP responses at 8 MiB, inline uploads at 1 MiB, `MAXREC` at 10,000,\nredirects at 3, outbound requests at 4 concurrent operations, and tools at 60\nseconds. Canonical synchronous queries still default to `MAXREC=100`; the\ninteractive table query defaults to `MAXREC=1000` and caps its widget payload\nat 6 MiB.\nJob waits default to 30 seconds, cap at 45 seconds, and poll between 1 and 10\nseconds. The process admits 100 MCP requests per minute globally; deployments\nthat need per-client limits should enforce them at a trusted HTTPS ingress.\n\nThe HTTP host accepts only credential-free HTTPS TAP targets whose complete\nDNS result is public, pins validated addresses for each request hop, keeps\nredirects same-origin, never automatically follows write redirects, and\nrejects remote-URI TAP uploads. These restrictions apply to the anonymous HTTP\napp, not the local stdio MCP, CLI, or TypeScript API.\n\nTo verify the protocol surface without opening the widget, start the app and\nrun MCP Inspector's CLI in another shell:\n\n```sh\nnpx -y @modelcontextprotocol/inspector@latest --cli http://127.0.0.1:3000/mcp --transport http --method tools/list\nnpx -y @modelcontextprotocol/inspector@latest --cli http://127.0.0.1:3000/mcp --transport http --method tools/call --tool-name starfetch_list_presets\n```\n\nTo render the widget in MCP Inspector's Apps tab:\n\n1. Keep `npm run dev:http` running, then start the Inspector UI without a stdio\n   server command:\n\n   ```sh\n   npx -y @modelcontextprotocol/inspector@latest\n   ```\n\n2. In Inspector, select **Via Proxy**, choose **Streamable HTTP**, enter\n   `http://127.0.0.1:3000/mcp`, leave authentication empty, and connect.\n3. Open **Apps**, select **Refresh Apps**, and choose\n   `starfetch_render_table`. The Apps tab lists UI-linked tools rather than the\n   server name.\n4. Paste a valid bounded table view into **App Input** and select **Open App**.\n   This minimal preset view exercises the widget without making a live TAP\n   request:\n\n   ```json\n   {\n     \"contractVersion\": 1,\n     \"resultKind\": \"presets\",\n     \"title\": \"TAP service presets\",\n     \"columns\": [\n       { \"key\": \"name\", \"label\": \"Name\" },\n       { \"key\": \"url\", \"label\": \"TAP URL\" }\n     ],\n     \"rows\": [\n       {\n         \"name\": \"gaia\",\n         \"url\": \"https://gea.esac.esa.int/tap-server/tap\"\n       }\n     ],\n     \"source\": { \"tool\": \"starfetch_list_presets\" },\n     \"state\": \"populated\",\n     \"clipping\": {\n       \"reasons\": [],\n       \"sourceRows\": 1,\n       \"sourceColumns\": 2\n     }\n   }\n   ```\n\nThe Apps tab requires the Streamable HTTP endpoint; the canonical stdio\nserver exposes the core Starfetch tools without UI resources. Inspector's\n**Via Proxy** mode works with the default origin policy. To use **Direct** mode,\nallow Inspector's browser origins explicitly when starting the app:\n\n```sh\nALLOWED_ORIGINS=http://localhost:6274,http://127.0.0.1:6274 npm run dev:http\n```\n\nThe widget uses the standard MCP Apps host bridge for tool results, theme\nvariables, display-mode requests, model-context updates, and file downloads.\nIt also reads ChatGPT's initial tool globals when present and uses ChatGPT's\nfile APIs only as a download fallback. Its React UI uses semantic table markup,\nglobal TanStack Table sorting, page-scoped row selection, 100-row desktop pages,\n10-row mobile pages, and fine-grained Shiki SQL highlighting for exact ADQL.\nDesktop tables use a capped two-axis scroll viewport; mobile tables expand to\nthe page height and retain horizontal scrolling for wide results. An icon-only control in\nthe action toolbar requests fullscreen or inline display mode. Another action\ncan expose selected rows or the current page to the model for the next\nturn; it does not expose the whole loaded table. The action remains available,\nand each press replaces the previously pending model-context snapshot. The\nresource declares no network or static-resource domains and requests only\nclipboard-write permission.\n\nRun its unit, single-file build, and browser-host acceptance checks with:\n\n```sh\nnpm --workspace @starfetch-js/mcp-app run check\nnpm --workspace @starfetch-js/mcp-app run test:browser\n```\n\nBuild and smoke-test the production Linux container with Docker:\n\n```sh\nnpm run smoke:container\n```\n\nThe image workflow publishes immutable containers to\n`ghcr.io/starfetch-js/starfetch-mcp-app`.\n\nFor ChatGPT Developer Mode or another remote MCP Apps host, expose the local MCP\nendpoint through HTTPS, add the resulting `/mcp` URL to the host, call a\nmetadata tool to inspect the target, then call `starfetch_query_table`. Verify\nlight and dark themes, fullscreen and inline modes, horizontal scrolling,\nsorting, paging, highlighted ADQL and copying, current-page model context, and\nTSV, CSV, and JSON copy and download actions. Host-specific visual differences\nshould be handled through the bridge theme variables rather than a second\ncomponent implementation.\n\nFor a temporary remote URL, the development machine can run:\n\n```sh\ncloudflared tunnel --url http://127.0.0.1:3000 --http-host-header 127.0.0.1:3000\n```\n\nThe HTTP app has no authentication. It applies a coarse, per-process fixed window limit of 100 MCP requests per minute, not per-client abuse protection. A quick tunnel is public and temporary: use only non-sensitive test traffic and stop it immediately after testing. This development app is not production deployment infrastructure.\n\nThe workspace requires Node.js `>=22.13.0`. Run:\n\n```sh\nnpm run format:check\nnpm run lint\nnpm run typecheck\nnpm test\nnpm run coverage\nnpm run build\nnpm run smoke:cli\n```\n\nRelease-sensitive agent surface checks are:\n\n```sh\nnpm --workspace packages/mcp run typecheck\nnpm --workspace packages/mcp run test\nnpm --workspace packages/mcp run build\nnpm --workspace packages/mcp run smoke\n\nnpm --workspace @starfetch-js/mcp-app run check\n\nnpm --workspace packages/skill run typecheck\nnpm --workspace packages/skill run test\nnpm --workspace packages/skill run build\n```\n\nDefault tests use local fixtures and mocks only. Optional live TAP checks are\nexplicit:\n\n```sh\nnpm run test:live:tap\n```\n\n## License\n\nMIT\n",
  "bytes": 23833,
  "sha": "ab1d6175af150035eb6f25fbe914ae98606f1914ff45a39cd4992783264cfa4e",
  "repo_slug": "starfetch-js/starfetch",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_starfetch_js_starfetch_d7eefe7d/readme"
}