|
8 | 8 | * When the api_catalog feature is enabled and not in passthrough mode, |
9 | 9 | * additionally advertises rel="api-catalog" (IANA-registered, RFC 9727) |
10 | 10 | * so generic crawlers that scan for standard rels can find the catalog. |
| 11 | + * |
| 12 | + * Each entry carries an optional `title="..."` parameter (RFC 8288 sec 3.4.1), |
| 13 | + * human-readable metadata for the link target. No protocol impact: parsers |
| 14 | + * that don't care simply ignore it. The describedby title matches the |
| 15 | + * wording used by specification.website (Joost de Valk) for the same target, |
| 16 | + * for free interop with peer publishers. |
11 | 17 | */ |
12 | 18 |
|
13 | 19 | import type { Config } from "./config-types"; |
14 | 20 |
|
15 | 21 | export function buildLinkHeader(config: Config): string { |
16 | 22 | const base = config.site.public_url ?? `https://${config.site.domain}`; |
17 | | - const entries: string[] = [`<${base}${config.manifest.path}>; rel="webmcp"`]; |
| 23 | + const entries: string[] = [ |
| 24 | + `<${base}${config.manifest.path}>; rel="webmcp"; title="WebMCP tool catalogue"`, |
| 25 | + ]; |
18 | 26 | if (config.features.api_catalog && config.api_catalog.mode !== "passthrough") { |
19 | | - entries.push(`<${base}${config.api_catalog.path}>; rel="api-catalog"`); |
| 27 | + entries.push( |
| 28 | + `<${base}${config.api_catalog.path}>; rel="api-catalog"; title="API catalogue (RFC 9727 Linkset)"`, |
| 29 | + ); |
20 | 30 | } |
21 | 31 | if (config.features.agent_skills && config.agent_skills.mode !== "passthrough") { |
22 | 32 | // Not (yet) IANA-registered; matches the convention used in Anthropic's |
23 | 33 | // Agent Skills format. Same pattern as our existing private rel="webmcp". |
24 | | - entries.push(`<${base}${config.agent_skills.path}>; rel="agent-skills"`); |
| 34 | + entries.push( |
| 35 | + `<${base}${config.agent_skills.path}>; rel="agent-skills"; title="Agent Skill (SKILL.md)"`, |
| 36 | + ); |
25 | 37 | } |
26 | 38 | if (config.features.llms_txt && config.llms_txt.mode !== "passthrough") { |
27 | 39 | // IANA-registered general "describedby" relation (RFC 8288). Points at |
28 | 40 | // /llms.txt - a publisher description in markdown. Generic agent-aware |
29 | 41 | // scanners that anchor on registered rel-types only (not our private |
30 | 42 | // rel="webmcp") find a description of the site through this entry. |
31 | | - entries.push(`<${base}${config.llms_txt.path}>; rel="describedby"; type="text/markdown"`); |
| 43 | + entries.push( |
| 44 | + `<${base}${config.llms_txt.path}>; rel="describedby"; type="text/markdown"; title="Site index for LLMs"`, |
| 45 | + ); |
32 | 46 | } |
33 | 47 | return entries.join(", "); |
34 | 48 | } |
|
0 commit comments