Table of contents
Lovable builds two kinds of project, and an MCP server card lives in a different place in each. Get the template wrong and you either edit a file that never ships or create a route that answers 404. This guide covers the card for check P2 on both templates. I built a TanStack Start app and a React + Vite app, and every response below was captured from a running server.
The card is the JSON document at /.well-known/mcp/server-card.json that tells an agent where your MCP server lives. Its schema is still a draft, so read Publish an MCP Server Card So Agents Can Find Your Tools first. This post is only the Lovable mechanics for check P2, which AIScan grades.
Quick summary
| If your Lovable project is on... | Do this | Time |
|---|---|---|
| React + Vite (older projects) | Add public/.well-known/mcp/server-card.json and publish | 5 min |
| TanStack Start (new apps since 13 May 2026), fixed card | Same file in public/ | 5 min |
| TanStack Start, card with CORS and cache headers | Add the route file src/routes/[.]well-known.mcp.server-card[.]json.ts | 10 min |
Either, still on a preview or lovable.app workspace URL | Connect a custom domain before judging the result | varies |
Check first: run npx aiscan-cli yoursite.com and read check P2 in the Capabilities group.
Which Lovable template are you on?
According to Lovable's SEO and AI search docs, apps created from 13 May 2026 use TanStack Start with server-side rendering, and older apps use React + Vite. Look for routeTree.gen.ts under src/: if it exists, you are on TanStack Start. A plain index.html at the project root with a src/main.tsx means React + Vite. Lovable also documents an upgrade path to TanStack Start.
Option 1: a file in public/
This works on both templates. Ask the Lovable agent in the project chat to create public/.well-known/mcp/server-card.json with your card:
{
"serverInfo": { "name": "example-mcp", "version": "1.0.0" },
"description": "Search the example catalog",
"transport": { "type": "streamable-http", "url": "https://example.com/mcp" },
"tools": [{ "name": "search", "description": "Search the catalog" }]
}
Replace the example values with your real server name, endpoint and tools. The field names follow the shape in AIScan's own P2 guidance and are a convention, not a ratified schema.
On a React + Vite build, vite build copied the file untouched to dist/.well-known/mcp/server-card.json, and vite preview answered with 200 and application/json. On TanStack Start the dev server served the same file as application/json with Cache-Control: no-cache. You cannot set other headers on a plain file from the project code.
Option 2: a TanStack Start server route
Use this when the card needs CORS headers for browser-based clients. The folder trick from other frameworks does not work here. TanStack Router reads a . in a file name as a path separator, so each literal dot has to be escaped. Per the file naming conventions, square brackets escape special characters, and script[.]js.tsx becomes /script.js.
Create src/routes/[.]well-known.mcp.server-card[.]json.ts:
import { createFileRoute } from '@tanstack/react-router'
const card = {
serverInfo: { name: 'example-mcp', version: '1.0.0' },
description: 'Search the example catalog',
transport: { type: 'streamable-http', url: 'https://example.com/mcp' },
}
export const Route = createFileRoute('/.well-known/mcp/server-card.json')({
server: {
handlers: {
GET: () =>
Response.json(card, {
headers: {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'public, max-age=3600',
},
}),
},
},
})
I tested this on @tanstack/react-start 1.168.60, @tanstack/react-router 1.170.41 and Vite 8.3.3. The generated route tree listed the path /.well-known/mcp/server-card.json, and the endpoint returned 200, application/json, access-control-allow-origin: * and cache-control: public, max-age=3600. A request with a trailing slash also returned 200.
The one-character mistake
Leave the second dot unescaped and you get a different URL. I renamed the file to [.]well-known.mcp.server-card.json.ts and the route tree registered /.well-known/mcp/server-card/json. That path returned 200. The path AIScan checks, /.well-known/mcp/server-card.json, returned 404. Nothing errors at build time, so the file looks right and the card is missing. Open routeTree.gen.ts and read the path: line for your route.
Publish, then test the live domain
A preview is not the live site. Lovable's docs say branded workspace URLs are never indexable, and that you should connect a custom domain to build search presence. Publish the project, then test the domain agents will use. How hosting serves files to crawlers is described on Lovable's hosting page.
Verify the card
Run AIScan first:
npx aiscan-cli yoursite.com
Find P2 · MCP Server Card in the Capabilities group. It should pass. By hand, one request does the same job:
curl -si https://yoursite.com/.well-known/mcp/server-card.json
Expected output for the route version, trimmed:
HTTP/2 200
content-type: application/json
access-control-allow-origin: *
cache-control: public, max-age=3600
{"serverInfo":{"name":"example-mcp","version":"1.0.0"}, ...}
For the public/ file you will see 200 and application/json without the two custom headers.
When the card still fails
- 404 on the route version. The file name has an unescaped dot, or the dev server has not regenerated
routeTree.gen.ts. Check thepath:line. - 200 with an HTML body. A React + Vite single-page app answers unknown paths with the app shell. In
vite preview, a misspelledserver-card.jsnreturned200withtext/html. Look atcontent-typeand the first bytes of the body, never only the status code. I did not test Lovable's own host for this behavior, so check it withcurl. - Works on the preview, fails on your domain. The project was edited but not published again.
Where to go next
Run npx aiscan-cli yoursite.com, confirm check P2, then browse the other fixes in the AIScan guides. The capabilities checks reference lists P1 to P4 and E2. If your project also lacks a feed, the RSS guide for Lovable covers the same template split, and the Lovable page lists every guide for the platform. The Next.js version of this guide covers the same check on another framework.
Frequently asked questions
Where does the MCP server card go in a Lovable project?
Put it at public/.well-known/mcp/server-card.json on either template, or on TanStack Start add a server route file named [.]well-known.mcp.server-card[.]json.ts under src/routes. Both serve /.well-known/mcp/server-card.json.
How do I know whether my Lovable project is on TanStack Start or React + Vite?
Lovable's docs say apps created from 13 May 2026 use TanStack Start and older apps use React + Vite. A routeTree.gen.ts file under src/ means TanStack Start.
Why does my card return 404 after I added a TanStack route file?
The file name probably has an unescaped dot. server-card.json.ts registers /server-card/json, not /server-card.json. Write server-card[.]json.ts and read the path line in routeTree.gen.ts.
Why does the card URL return 200 but AIScan still fails check P2?
A single-page app can answer any unknown path with its HTML shell and a 200 status. Check that content-type is application/json and that the body starts with a JSON object.
Why does the card work in preview but not on my domain?
The latest edit was probably not published. Publish the project again, then request the card on the custom domain agents will use.
Do I need the TanStack route, or is a file in public/ enough?
A file in public/ is enough to pass a presence check. Use the route when you want to send CORS and cache headers from your own code, which a plain file cannot do.
Does the server card replace server/discover or the MCP Registry?
No. They answer different questions. The card is a static document a crawler reads over plain HTTP, and the registry is a separate listing. The linked server card guide explains both.
Which fields should the card contain?
The shape in AIScan's P2 guidance uses serverInfo, description, transport and tools. The schema is still a draft, so treat the field names as a convention and keep the card small and accurate.
Related guides
How to return a real 404 with a recoverable body on Lovable
Lovable can return a real 404 or a soft 200 for the same missing URL, and which one you get depends on the stack your project was built on. AIScan check E1 Correct 404 handling grades both the status…
UCP profiles: Shopify serves one, most other stores don't
Shopify stores answer on /.wellknown/ucp. Almost nobody else does. We checked 238 commerceactive sites in the AIScan corpus on 10 October 2026: 12 of 17 Shopify catalogue stores pass check M1 the…
How to publish /.well-known/mcp/server-card.json on Docusaurus
Docusaurus serves anything in static/ asis, so the MCP server card needs one file and no plugin. This guide covers check P2 on Docusaurus. I built a site on Docusaurus 3.10.2 and ran the dev server…
How to publish /.well-known/mcp/server-card.json on Hugo
Hugo has two ways to put an MCP server card at /.wellknown/mcp/servercard.json, and one of them can build cleanly while writing the file to the wrong place. This guide covers the card for check P2 on…
