NOVUS / RESTAURANT

Documentation

The MCP server and what it will not do

Two addresses on one handler, why authentication runs before tools/list, the three read-only tools, and the protocol revisions it answers.

Last reviewed against the product on .

This site runs a Model Context Protocol server, so an assistant can read your market signals, supplier totals and provider health directly rather than being told about them second-hand. It is the only authenticated MCP server in the Novus estate, because it is the only one with a database behind it: the answer here depends on who is asking.

The address, and a ready-made client configuration block, are on the public MCP server page. This page explains how the endpoint behaves.

Two addresses, one server

The endpoint answers at /mcp and at /api/mcp. The second came first and is the address already published to clients configured earlier; the first is the path every Novus site uses, and the one the sibling sites point at. Rather than move a published URL, both paths call the same handler.

They also share one rate-limit budget. Two doors with a limit on only one of them is not a limit, and a caller alternating between them gets one allowance rather than two.

POST only

What each HTTP method answers
MethodAnswerWhy
POSTJSON-RPC over HTTPThe whole transport. Every method rides here.
GET405, with an Allow header naming POSTProtocol revision 2026-07-28 removed the server-sent stream. A client that opens one has to be told definitively, or it waits for an event that will never arrive.
DELETE405, with an Allow header naming POSTThe same revision removed protocol sessions. There is no session to tear down.

Measured from app/mcp/route.ts, app/api/mcp/route.ts and createMcpHandler in src/lib/mcp/core.ts.

Opening the endpoint in a browser is therefore expected to fail. That is why the human-readable MCP server page exists separately.

Authentication comes first

The server requires a bearer token, and the check runs before any method dispatches, including tools/list and server/discover. That ordering is the point: merely listing the tools of a private server tells an unauthenticated caller what data it holds. A caller without a valid token does not learn the tool names.

A failed check answers 401 with a WWW-Authenticate header naming the bearer scheme and an invalid_token error, which is what lets a client tell "your credential is wrong" apart from "this endpoint is not here". The credential is a personal access token; see personal access tokens for how to make one and what it is limited to.

The tools

Tools the server exposes
ToolWhat it returnsScoped to
market_summaryComparable market signals: item, data level, percent change, confidence, priority, when it was observed, and the source URL it came fromYour organization
supplier_summaryPurchasing totals per supplier, split by currency, with the number of purchase rows behind eachYour organization
source_healthThe latest health check for every public data provider the site ingests from, newest firstThe whole site

Measured from mcpServerDefinition in src/lib/mcp/server.ts.

source_health is deliberately not scoped to an organization, because it describes the ingestion pipeline rather than anyone's data. It stays behind authentication anyway, since it describes internal infrastructure.

Tools
3
all read-only
Market signals per call
25
a fixed cap; the tool does not page
Rate limit
120 per minute
per caller address, shared across both addresses
Server version
2.0.0
reported in the server info every client receives

Measured from src/lib/mcp/server.ts and RATE_POLICIES.mcp in src/lib/shared/rate-limit.ts.

The limit is the loosest of the three policies in this repo, because one assistant conversation legitimately makes many small tool calls in a row and throttling that makes the site look broken to exactly the audience the endpoint exists for. The real ceiling on abuse is credential issuance rather than this number, which is why the token endpoint is the one carrying a durable quota.

Protocol revisions

The server is dual-era: it answers the current stateless revision and the older handshake-based ones on the same endpoint, because clients in the wild speak both.

Protocol revisions this server answers
RevisionEraHow a client selects it
2026-07-28Modern, statelessVersion, client identity and capabilities ride in the request's own metadata. No handshake, no session.
2025-11-25, 2025-06-18, 2025-03-26LegacyAn initialize request, answered with the newest of these the client asked for.

Measured from MODERN_PROTOCOL_VERSION and LEGACY_PROTOCOL_VERSIONS in src/lib/mcp/core.ts.

A modern request may repeat its protocol version, method name or tool name in headers. If a header disagrees with the body, the request is refused with a 400 rather than resolved by guessing which one the client meant.

Origin

A request carrying an Origin header is accepted only when that origin is this site's own or one explicitly allowed; anything else is refused with 403. A request with no Origin header at all is accepted, because that is every non-browser client, which is what an MCP client normally is.

What this server will not do

The server also asks its callers to report provenance. Every market observation carries a source URL and an observation time, and an assistant reporting a figure should carry both, because the point of this dataset is that a number can be traced to the official source it came from. Checking source_health first matters for the same reason: a provider that is currently failing still returns its last successful observation, which looks exactly like a current one.

When the endpoint is switched off

MCP delivery sits behind an environment flag. When it is off, the endpoint answers 404, not 403, so a disabled server is indistinguishable from one that was never deployed. If a client reports the address as missing rather than unauthorised, that is the state to suspect before you start checking tokens.