Skip to main content
Glama
README.md
# domaintrack

domaintrack looks up what is publicly known about a domain:
its reputation snapshot, the AI crawler policy its robots.txt
sets, and the list of data sources those answers are built
from.

It is a forwarding client, not a data store. The answers live
in Domduck's public store and are served by its keyless public
endpoint; this package carries the endpoint's three-tool
surface, serves the tool list locally, and forwards each call
upstream, returning the upstream answer exactly as it arrives.
There is no account and no API key: the public endpoint is the
whole surface. Domduck's authenticated endpoint, with its
dated history series, is separate and is not touched here —
this client sends no credentials of any kind.

One behaviour is worth knowing before you automate against
it: asking about a domain nobody has looked up yet is not an
error. The snapshot comes back with `hasReading` set to
false, which is the store honestly saying it holds no reading
for that name yet.

## Tools

- `lookup_domain` — the stored reputation snapshot for one
  domain: Domain Rating, Tranco rank, OpenPageRank,
  registration date, TLS certificate state and AI crawler
  policy. Requires `domain`.
- `get_ai_crawler_policy` — for each of the eight tracked AI
  crawlers, whether the domain's robots.txt allows it, blocks
  it, or never mentions it, plus whether an llms.txt is
  published. Requires `domain`.
- `list_sources` — the catalogue of sources behind the other
  two tools and what each one means. No arguments; read it
  first if a snapshot field is unfamiliar.

## CLI

```bash
npx @reneturcios/domaintrack lookup_domain '{"domain":"example.com"}'
npx @reneturcios/domaintrack get_ai_crawler_policy '{"domain":"example.com"}'
npx @reneturcios/domaintrack list_sources
npx @reneturcios/domaintrack --version
```

Each tool subcommand forwards one call and prints the result
content as JSON. Exit codes: 0 on success, 1 when the
upstream call comes back as an error result, 2 on a usage
error (unknown subcommand, malformed JSON argument).

## MCP server

```bash
npx @reneturcios/domaintrack mcp
```

MCP client configuration:

```json
{
  "mcpServers": {
    "domaintrack": {
      "command": "npx",
      "args": ["-y", "@reneturcios/domaintrack", "mcp"]
    }
  }
}
```

The server answers `tools/list` itself and forwards every
`tools/call` to the public endpoint over a Streamable HTTP
session (initialize, then notifications/initialized, then the
call), reusing the session — and its `Mcp-Session-Id`, when
the endpoint issues one — for the life of the process.

Failures on the wire are reported in this package's own
words, as a text result starting with `domaintrack error:` —
a JSON-RPC error from upstream, a non-2xx HTTP status, an
unparseable response body, or a failed request each map to
that prefix followed by the detail.

## Docker

```bash
docker run -i ghcr.io/cloudcorprecords/domaintrack            # stdio MCP server
docker run --rm ghcr.io/cloudcorprecords/domaintrack lookup_domain '{"domain":"example.com"}'
```

## Configuration

- `DOMDUCK_MCP_URL` — overrides the upstream endpoint, which
  defaults to `https://domduck.com/api/mcp/public`. (This
  override is a reconstruction on our side; the endpoint
  itself is the pinned public one.)

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # node test runner via tsx; stubbed upstream, no network
npm run dev     # run the CLI from source
```

## License

MIT — see `LICENSE`.