Stateless and Read-Only by Design

Why does statelessness matter for an MCP tool?

Statelessness matters because every sniff_domain call carries everything it needs and no call depends on the one before it. That makes calls safe to retry and cheap to scale across instances, and it means no key of yours. It is a claim about the request boundary, not about storage: your results are saved against your account.

Best move: treat every call as a self-contained investigation that reads only its arguments.

Why it works: with no server memory to resume, the tool becomes safe to retry, cheap to scale, and free of any key of yours.

Key takeaways

  • Stateless means each call is self-contained: it reads only its arguments, and no call depends on the one before it.
  • Owning the crawl is what keeps the tier free of any key of yours, because there is no upstream credential to replay.
  • Stateless describes the request boundary, not storage: your results are saved against your account.
  • Read-only plus stateless makes every call safe to retry: a dropped connection costs a repeat crawl, never corrupted state.
  • Any instance can serve any request, so the tool scales horizontally with no session affinity or sticky routing.
  • The cost is no memory across calls: cross-query correlation over time and long-running jobs are out of scope by design.

What does “stateless” mean here, and does MCP require it?

Stateless means no call depends on the one before it. Each sniff_domain request carries its own domain and profile, runs its own investigation, and returns the dossier. There is no session to resume and no stored profile that shapes what comes back. It is a claim about the request boundary, not about what gets saved: your results are stored against your account, and the privacy policy covers that.

MCP itself does not force this. The Streamable HTTP transport supports sessions: the server can issue a session ID and hold state across a run. Stateless is a choice we make on top of that. We run each call as a self-contained, read-only investigation and opt out of session state.

The distinction matters because “agentic” here means investigation inside one request, not a conversation the server remembers. When the tool decides to render JavaScript, follow a redirect, or fetch Wayback history on a deep profile, all of that happens within the single call and resolves before the response returns. Nothing is deferred to a later request. You get correlation across five layers because one call did the correlating, not because the server stitched together things it remembered from earlier.

How does statelessness keep the free tier keyless?

Most enrichment APIs hand you a key because they need to attach state to you: a quota counter, a billing record, a stored credential for the upstream services they proxy. Statelessness removes the reason for two of those. We own the crawl, so there is no upstream key to store on your behalf and no bring-your-own-key handshake to manage. The server fetches public signals directly.

That leaves rate limiting, which is what the sign-in is for: your daily allowance counts against the account you signed in as. An agent host connects to mcp.bassethound.ai/mcp, you approve one sign-in, and there is no secret for you to source or rotate. Paid plans raise depth and volume on the same connection.

Keyless is structural here, not a promotion. Because each call is self-contained and reads only public data, there is nothing per-user the server has to authenticate to do its job. A BYOK tool cannot make the same claim: it has to hold or receive your key to reach the data, which is state, which is a credential to protect. Owning the crawl is what lets us skip that.

What does statelessness give you at scale and under failure?

Two things: easy horizontal scale and safe retries. Because no call depends on server memory, any instance can serve any request. There is no session affinity, no coordination between nodes. To handle more load you add instances behind the endpoint and route freely. A crashed instance loses nothing, because it held nothing worth losing.

Read-only plus stateless also makes retries clean. sniff_domain is a safe operation in the HTTP sense: it reads public signals and changes nothing. If a connection drops mid-call, the agent can reissue the same request. Worst case you re-pay the crawl. There is no half-written session state to reconcile.

This matters most to the caller. An agent host planning a batch of lookups does not have to serialize them or track which session owns which query. It can fan out concurrent calls and treat each independently. Idempotent reads mean the failure story is “try again,” not “reconcile partial state.” That is the operational payoff of holding no state: the boring failure modes are the only failure modes.

What does statelessness cost you?

Honesty first: statelessness is a trade, not a free win. No call builds on the one before it, so there is nothing to resume and no server-side history you can query. Ask for the same domain twice outside the cache window and the second call investigates again from scratch. The model is “fresh crawl each call,” not “stored profile you subscribe to.”

That rules out some features by design. There is no watchlist that notifies you when a domain’s stack changes, no diff between last week’s dossier and today’s. On a deep profile, we fetch Wayback history live each time rather than maintaining a timeline for you. If you want change tracking, you store the dossiers and diff them yourself.

The static-crawl limit is separate but worth naming in the same breath. A fully server-side or proxied component can hide from a crawl plus optional JS render, and the dossier reports those gaps rather than guessing. Statelessness does not fix that, and it does not pretend to. What you get in return is a tool that is simple to reason about, cheap to scale, and safe to retry.

Bassethound perspective

Stateless is a feature, and the enrichment vendors are built to dispute that. Their model is the account: a stored profile of everyone you looked up, a dashboard, a history, a key that ties it all to you. That state is the product they sell back to you.

We took the other bet. Owning the crawl means the tool needs no key of yours, structurally rather than as a trial, and no credential of yours has to be stored for a call to do its job. Every call is self-contained and read-only, which is why an agent can fan out a hundred lookups without managing a single session. Your results are stored against your account, which is account management rather than a profile of you.

A competitor will say you lose watchlists and history. True. You lose them on our side and keep them on yours, where you already control storage and retention. The correlation you pay for is not across time, it is across layers: tech, infra, firmographics, AI-readiness, and security fused in one call. An agent cannot get that from five separate stateful MCPs cheaply. Fusion in a single stateless request is the moat. The queryable history you subscribe to is the thing we chose not to build.

Sources

Frequently asked questions

Does statelessness mean Bassethound cannot cache anything?

No. Results are cached, so a repeat call can return a cached dossier. Stateless refers to per-call independence, not a ban on caching.

Can I get change tracking on a domain?

Not from us directly. There is no watchlist and no server-side diff between one call and the next. Store the dossiers yourself and compare them, or poll on your own schedule.

Is sniff_domain safe to retry?

Yes. It is read-only and self-contained, so reissuing a request after a dropped connection just repeats the crawl. There is no partial state to corrupt.

Does the MCP spec require stateless servers?

No. Streamable HTTP supports sessions and server-held state. Bassethound opts out at the application layer and runs each call self-contained and read-only.

Why keyless instead of bring-your-own-key?

Because we own the crawl. There is no upstream credential to store for you, so you bring no key. The MCP endpoint requires a sign-in, and your daily allowance counts against that sign-in.

Sniff a domain.

Run sniff_domain on any site and read its five-layer dossier in one call.

Sniff a domain