Agent Discovery & MCP Compliance
aihu is designed from the ground up for the agentic web. Every aihu application automatically exposes standard discovery endpoints that let AI agents find, understand, and call your components as tools — with no manual configuration.
How AI agents discover aihu apps
Aihu apps expose four discovery endpoints that agents and crawlers check:
| Endpoint | Purpose |
|---|---|
/llms.txt |
Human-readable index of docs and links in llmstxt.org format |
/llms-full.txt |
Extended index with full package list, examples, and spec links |
/.well-known/mcp/server-card.json |
Machine-readable MCP server card (SEP-1649) |
/robots.txt |
Agent-friendly crawl directives (RFC 9309) |
All four are generated automatically by @aihu-plugin/agent-readiness from a single config object. The minimum viable setup is:
import { createAgentReadinessRoutes } from '@aihu-plugin/agent-readiness'
import { createRequestRouter, defineRoute } from '@aihu/server'
const ar = createAgentReadinessRoutes({
name: 'My App',
endpoint: 'https://myapp.workers.dev/mcp',
summary: 'A aihu-powered app.',
})
const router = createRequestRouter({
routes: [
defineRoute('/llms.txt', ar.llmsTxt),
defineRoute('/.well-known/mcp/server-card.json', ar.mcpServerCard),
defineRoute('/robots.txt', ar.robotsTxt),
],
})This works on Cloudflare Workers, Bun, and Deno — anywhere with a fetch-API request handler.
The MCP Server Card
The MCP Server Card is a machine-readable JSON document at /.well-known/mcp/server-card.json that describes your application's agent capabilities per the SEP-1649 schema.
A minimal server card looks like:
{
"schema_version": "1.0",
"name": "My App",
"summary": "A aihu-powered app.",
"mcp_endpoint": "https://myapp.workers.dev/mcp",
"skills": [
{
"id": "my-counter",
"name": "Live Counter",
"description": "Read and increment a counter"
}
]
}The skills array is auto-populated from the agent-exposed props and actions in your SFCs — the compiler emits an MCP tool schema alongside each compiled component, and @aihu-plugin/agent-readiness aggregates them at build time.
To configure the server card, pass AgentReadinessConfig to createAgentReadinessRoutes:
const ar = createAgentReadinessRoutes({
name: 'My App',
version: '1.0.0',
summary: 'A aihu-powered app.',
endpoint: 'https://myapp.workers.dev/mcp',
// Optional: declare skills explicitly (merged with auto-derived from @state)
skills: [
{ id: 'counter', name: 'Counter', description: 'Read and set counter value' },
],
})Auth configuration (opt-in)
By default the MCP endpoint is public (no-auth, Option A). To require OAuth 2.0 (Option C per RFC 9728):
const ar = createAgentReadinessRoutes({
name: 'My App',
endpoint: 'https://myapp.workers.dev/mcp',
auth: {
type: 'oauth2',
authorizationUrl: 'https://auth.myapp.com/authorize',
tokenUrl: 'https://auth.myapp.com/token',
scopes: ['mcp:read', 'mcp:write'],
},
})llms.txt
The llms.txt file at the app root follows the llmstxt.org specification. It gives AI coding assistants a structured map of your app's documentation and endpoints.
Format
The file uses a small Markdown subset:
- First line:
# <Name>(H1 heading — the app name) - Optional second non-blank line:
> <tagline>(blockquote summary) - Sections:
## <Section Title>(H2 headings) - Links:
- Titleor- Title: Optional description - An optional
## Optionalsection at the end (for supplementary links)
The llms-full.txt variant follows the same format but uses ## More instead of ## Optional for the trailing section, and typically includes more links (all packages, examples, spec files).
LlmsTxtConfig type
@aihu-plugin/agent-readiness generates both files from LlmsTxtConfig:
interface LlmsTxtLink {
readonly title: string
readonly url: string
readonly description?: string
}
interface LlmsTxtSection {
readonly title: string
readonly links: ReadonlyArray<LlmsTxtLink>
}
interface LlmsTxtConfig {
readonly name: string
readonly summary?: string
readonly sections: ReadonlyArray<LlmsTxtSection>
readonly optional?: ReadonlyArray<LlmsTxtLink>
}To generate the files programmatically:
import { generateLlmsTxt, generateLlmsFullTxt } from '@aihu-plugin/agent-readiness'
const config: LlmsTxtConfig = {
name: 'My App',
summary: 'A aihu-powered app.',
sections: [
{
title: 'Getting Started',
links: [
{ title: 'Installation', url: 'https://myapp.com/docs/install' },
{ title: 'Quickstart', url: 'https://myapp.com/docs/quickstart' },
],
},
],
optional: [
{ title: 'Contributing', url: 'https://github.com/org/myapp/blob/main/CONTRIBUTING.md' },
],
}
const llmsTxt = generateLlmsTxt(config) // uses "## Optional"
const llmsFullTxt = generateLlmsFullTxt(config) // uses "## More"The llmsSections and llmsOptional fields on AgentReadinessConfig feed directly into these generators, so you can customize the content without calling the generators manually.
robots.txt
Aihu generates an agent-friendly robots.txt per RFC 9309. The default (aiAgents: 'allow-all') produces directives that permit all compliant AI agents to crawl your app:
User-agent: *
Allow: /
User-agent: GPTBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: anthropic-ai
Allow: /To restrict AI agent access, set aiAgents: 'disallow-all' or aiAgents: 'allow-verified'. You can also add custom rules for specific bots via standardBots:
const ar = createAgentReadinessRoutes({
name: 'My App',
endpoint: 'https://myapp.workers.dev/mcp',
aiAgents: 'allow-all',
standardBots: [
{ userAgent: 'Googlebot', allow: ['/'], disallow: ['/admin'] },
],
sitemap: 'https://myapp.com/sitemap.xml',
})Calling aihu components as MCP tools
Agent-callable components are the core proposition of aihu. Here is the end-to-end flow:
Step 1 — Declare an agent surface in @state
Expose a prop and an action with describe/expose metadata — no separate block needed for per-name agent visibility:
@state {
let count = prop<number>({ default: 0, expose: 'read' })
const increment = action(
{ describe: 'Increment the counter by one', expose: 'write' },
() => { count++ },
)
}Step 2 — Compiler emits .mcp.json
When the Rust SFC compiler processes this file with BuildTarget.Server or BuildTarget.Universal, it emits a .mcp.json sidecar describing the exposed tools:
{
"tools": [
{
"name": "increment",
"description": "Increment the counter by one",
"inputSchema": { "type": "object", "properties": {} }
}
],
"resources": [
{ "name": "count", "description": "Current counter value", "type": "number" }
]
}Note: with BuildTarget.Client, agent-exposed state is fully elided — no manifest JSON is emitted and no agent code reaches the browser bundle.
Step 3 — @aihu/agent-service exposes via aihu mcp serve
The @aihu/agent-service package reads the aggregated tool schemas and exposes them over the MCP protocol. Run:
aihu mcp serveThis starts an MCP-compatible server that AI agents (Claude, GPT, Gemini, etc.) can connect to and call your component actions as tools.
Step 4 — Live-binding connects tools to the running component
When an AI agent calls the increment tool, @aihu/agent-service uses the live-binding registry (RFC APPROVED) to find the running component instance and call the action against its actual signal graph — the UI updates in real time.
Testing compliance
All compliance checks are backed by vitest test suites that run as part of bun run test. The test files serve as the executable specification:
| Suite | File | Tests |
|---|---|---|
| llms.txt format | packages/plugin-agent-readiness/tests/compliance/llms-txt-spec.test.ts |
9 |
| MCP Server Card (SEP-1649) | packages/plugin-agent-readiness/tests/compliance/mcp-server-card-schema.test.ts |
14 |
| robots.txt (RFC 9309) | packages/plugin-agent-readiness/tests/compliance/robots-rfc9309.test.ts |
7 |
| isitagentready.com checklist | packages/plugin-agent-readiness/tests/compliance/isitagentready.test.ts |
7 |
| SSR output structure | packages/server/tests/compliance/ssr-output.test.ts |
12 |
Run all compliance checks:
bun run test # TS + Rust unit, integration, and compliance suites
bun run test:quality # Lighthouse gate (≥ 90 on perf/a11y/best-practices/seo)isitagentready.com
Aihu passes all 7 checks on isitagentready.com. The checks are exercised by the compliance test suite at packages/plugin-agent-readiness/tests/compliance/isitagentready.test.ts. The seven gates are:
llms.txtpresent at rootllms.txtfirst line is# <Name>/.well-known/mcp/server-card.jsonreturns valid JSON- MCP server card contains
mcp_endpoint robots.txtpresent and allows AI agents- App sets
X-Agent-Friendly: trueresponse header - MCP endpoint responds to
POSTwith a valid tool-list response