@se-studio/site-mcp 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +2 -0
- package/dist/discovery.d.ts +96 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +94 -0
- package/dist/discovery.js.map +1 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/docs/llms.md +24 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @se-studio/site-mcp
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add `apiPathNeedingTrailingSlash` for middleware: rewrite bare `/api/*` under Next `trailingSlash: true` so Streamable HTTP MCP POST is not 308’d. Document the pattern in site-mcp.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @se-studio/core-ui@1.19.3
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 14aeb6d: Agent discovery helpers: API catalog, A2A agent card, skills index builders; Link header options for api-catalog, agent-card, and agent-skills.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [14aeb6d]
|
|
20
|
+
- @se-studio/core-ui@1.19.2
|
|
21
|
+
|
|
3
22
|
## 0.2.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ pnpm add @se-studio/site-mcp
|
|
|
23
23
|
The **Next.js route file path** is the mount point (e.g. `app/api/mcp/route.ts` → `/api/mcp`).
|
|
24
24
|
`createSiteMcpHandler` does **not** take a path — routing is owned by App Router.
|
|
25
25
|
|
|
26
|
+
**Trailing slash:** SE Studio sites use `trailingSlash: true`. Advertise **`/api/mcp` without a trailing slash** (server card, catalog, agent card). In middleware, call `apiPathNeedingTrailingSlash` from `@se-studio/core-ui` and `NextResponse.rewrite` so bare `/api/*` hits the handler without a client-visible 308 (Streamable HTTP POST cannot rely on redirects).
|
|
27
|
+
|
|
26
28
|
Use `endpointPath` only on **`buildMcpServerCard`** so the well-known card advertises the same URL agents should call:
|
|
27
29
|
|
|
28
30
|
| Site shape | Example `endpointPath` (server card) |
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One API advertised in RFC 9727-style api-catalog linkset.
|
|
3
|
+
* Omit disabled/future endpoints (e.g. /api/ask) until they return 200.
|
|
4
|
+
*/
|
|
5
|
+
export interface ApiCatalogEntry {
|
|
6
|
+
/** Absolute or site-relative path of the API (e.g. `/api/mcp`). */
|
|
7
|
+
path: string;
|
|
8
|
+
/** Optional human docs URL (absolute or site-relative). */
|
|
9
|
+
serviceDoc?: string;
|
|
10
|
+
/** Optional schema.org type URL(s), e.g. SearchAction. */
|
|
11
|
+
type?: string | string[];
|
|
12
|
+
}
|
|
13
|
+
export interface BuildApiCatalogOptions {
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
apis: ApiCatalogEntry[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build `application/linkset+json` body for `/.well-known/api-catalog`.
|
|
19
|
+
* Shape matches what isitagentready validates (Joost-compatible).
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildApiCatalog(options: BuildApiCatalogOptions): {
|
|
22
|
+
linkset: Array<{
|
|
23
|
+
anchor: string;
|
|
24
|
+
'service-doc'?: Array<{
|
|
25
|
+
href: string;
|
|
26
|
+
}>;
|
|
27
|
+
type?: Array<{
|
|
28
|
+
href: string;
|
|
29
|
+
}>;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
/** Skill advertised on an A2A agent card (maps to MCP tools today; ask later). */
|
|
33
|
+
export interface A2AAgentSkill {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
inputModes?: string[];
|
|
38
|
+
outputModes?: string[];
|
|
39
|
+
examples?: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface A2ASupportedInterface {
|
|
42
|
+
url: string;
|
|
43
|
+
transport: string;
|
|
44
|
+
protocol: string;
|
|
45
|
+
}
|
|
46
|
+
export interface BuildA2AAgentCardOptions {
|
|
47
|
+
name: string;
|
|
48
|
+
version?: string;
|
|
49
|
+
description: string;
|
|
50
|
+
/** Organization / site URL (provider). */
|
|
51
|
+
websiteUrl: string;
|
|
52
|
+
organization?: string;
|
|
53
|
+
/** Primary agent URL (usually the MCP endpoint). */
|
|
54
|
+
url: string;
|
|
55
|
+
supportedInterfaces?: A2ASupportedInterface[];
|
|
56
|
+
skills: A2AAgentSkill[];
|
|
57
|
+
capabilities?: {
|
|
58
|
+
streaming?: boolean;
|
|
59
|
+
pushNotifications?: boolean;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build A2A Agent Card JSON for `/.well-known/agent-card.json`.
|
|
64
|
+
* v1 should describe live MCP tools only; add ask skill + /api/ask interface when Ask ships.
|
|
65
|
+
*/
|
|
66
|
+
export declare function buildA2AAgentCard(options: BuildA2AAgentCardOptions): Record<string, unknown>;
|
|
67
|
+
export interface AgentSkillsIndexEntry {
|
|
68
|
+
name: string;
|
|
69
|
+
type?: string;
|
|
70
|
+
description: string;
|
|
71
|
+
/** Absolute or site-relative URL to SKILL.md */
|
|
72
|
+
url: string;
|
|
73
|
+
digest?: string;
|
|
74
|
+
}
|
|
75
|
+
export interface BuildAgentSkillsIndexOptions {
|
|
76
|
+
baseUrl: string;
|
|
77
|
+
skills: AgentSkillsIndexEntry[];
|
|
78
|
+
schema?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Build Agent Skills discovery index for `/.well-known/agent-skills/index.json`.
|
|
82
|
+
* Only list real skills — do not pad empty entries for score.
|
|
83
|
+
*/
|
|
84
|
+
export declare function buildAgentSkillsIndex(options: BuildAgentSkillsIndexOptions): {
|
|
85
|
+
$schema: string;
|
|
86
|
+
skills: Array<{
|
|
87
|
+
name: string;
|
|
88
|
+
type: string;
|
|
89
|
+
description: string;
|
|
90
|
+
url: string;
|
|
91
|
+
digest?: string;
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
/** JSON response helpers for well-known routes. */
|
|
95
|
+
export declare function jsonDiscoveryResponse(body: unknown, contentType?: string): Response;
|
|
96
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,eAAe,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAChE,OAAO,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChC,CAAC,CAAC;CACJ,CA0BA;AAED,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC9C,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuC5F;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ,CAYA;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,EACb,WAAW,SAAoC,GAC9C,QAAQ,CASV"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { joinUrl } from './path.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build `application/linkset+json` body for `/.well-known/api-catalog`.
|
|
4
|
+
* Shape matches what isitagentready validates (Joost-compatible).
|
|
5
|
+
*/
|
|
6
|
+
export function buildApiCatalog(options) {
|
|
7
|
+
const base = options.baseUrl.replace(/\/+$/, '');
|
|
8
|
+
const linkset = options.apis.map((api) => {
|
|
9
|
+
const anchor = api.path.startsWith('http') ? api.path : joinUrl(base, api.path);
|
|
10
|
+
const entry = { anchor };
|
|
11
|
+
if (api.serviceDoc) {
|
|
12
|
+
const doc = api.serviceDoc.startsWith('http')
|
|
13
|
+
? api.serviceDoc
|
|
14
|
+
: joinUrl(base, api.serviceDoc);
|
|
15
|
+
entry['service-doc'] = [{ href: doc }];
|
|
16
|
+
}
|
|
17
|
+
if (api.type) {
|
|
18
|
+
const types = Array.isArray(api.type) ? api.type : [api.type];
|
|
19
|
+
entry.type = types.map((href) => ({ href }));
|
|
20
|
+
}
|
|
21
|
+
return entry;
|
|
22
|
+
});
|
|
23
|
+
return { linkset };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build A2A Agent Card JSON for `/.well-known/agent-card.json`.
|
|
27
|
+
* v1 should describe live MCP tools only; add ask skill + /api/ask interface when Ask ships.
|
|
28
|
+
*/
|
|
29
|
+
export function buildA2AAgentCard(options) {
|
|
30
|
+
const websiteUrl = options.websiteUrl.replace(/\/+$/, '');
|
|
31
|
+
const primaryUrl = options.url.startsWith('http')
|
|
32
|
+
? options.url
|
|
33
|
+
: joinUrl(websiteUrl, options.url);
|
|
34
|
+
const interfaces = options.supportedInterfaces ??
|
|
35
|
+
[
|
|
36
|
+
{
|
|
37
|
+
url: primaryUrl,
|
|
38
|
+
transport: 'http',
|
|
39
|
+
protocol: 'MCP/2025-11-25',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
return {
|
|
43
|
+
name: options.name,
|
|
44
|
+
version: options.version ?? '1.0.0',
|
|
45
|
+
description: options.description,
|
|
46
|
+
url: primaryUrl,
|
|
47
|
+
provider: {
|
|
48
|
+
organization: options.organization ?? options.name,
|
|
49
|
+
url: websiteUrl,
|
|
50
|
+
},
|
|
51
|
+
supportedInterfaces: interfaces,
|
|
52
|
+
capabilities: {
|
|
53
|
+
streaming: options.capabilities?.streaming ?? true,
|
|
54
|
+
pushNotifications: options.capabilities?.pushNotifications ?? false,
|
|
55
|
+
},
|
|
56
|
+
skills: options.skills.map((s) => ({
|
|
57
|
+
id: s.id,
|
|
58
|
+
name: s.name,
|
|
59
|
+
description: s.description,
|
|
60
|
+
inputModes: s.inputModes ?? ['text'],
|
|
61
|
+
outputModes: s.outputModes ?? ['text'],
|
|
62
|
+
...(s.examples?.length ? { examples: s.examples } : {}),
|
|
63
|
+
})),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build Agent Skills discovery index for `/.well-known/agent-skills/index.json`.
|
|
68
|
+
* Only list real skills — do not pad empty entries for score.
|
|
69
|
+
*/
|
|
70
|
+
export function buildAgentSkillsIndex(options) {
|
|
71
|
+
const base = options.baseUrl.replace(/\/+$/, '');
|
|
72
|
+
return {
|
|
73
|
+
$schema: options.schema ?? 'https://agentskills.io/schema/index.json',
|
|
74
|
+
skills: options.skills.map((s) => ({
|
|
75
|
+
name: s.name,
|
|
76
|
+
type: s.type ?? 'skill-md',
|
|
77
|
+
description: s.description,
|
|
78
|
+
url: s.url.startsWith('http') ? s.url : joinUrl(base, s.url),
|
|
79
|
+
...(s.digest ? { digest: s.digest } : {}),
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** JSON response helpers for well-known routes. */
|
|
84
|
+
export function jsonDiscoveryResponse(body, contentType = 'application/json; charset=utf-8') {
|
|
85
|
+
return new Response(JSON.stringify(body, null, 2), {
|
|
86
|
+
status: 200,
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': contentType,
|
|
89
|
+
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
|
|
90
|
+
'Access-Control-Allow-Origin': '*',
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createSiteMcpServer } from './create-server.js';
|
|
2
|
+
export type { A2AAgentSkill, A2ASupportedInterface, AgentSkillsIndexEntry, ApiCatalogEntry, BuildA2AAgentCardOptions, BuildAgentSkillsIndexOptions, BuildApiCatalogOptions, } from './discovery.js';
|
|
3
|
+
export { buildA2AAgentCard, buildAgentSkillsIndex, buildApiCatalog, jsonDiscoveryResponse, } from './discovery.js';
|
|
2
4
|
export type { FetchTextResult } from './fetch-text.js';
|
|
3
5
|
export { DEFAULT_FETCH_TIMEOUT_MS, DEFAULT_MAX_BODY_BYTES, fetchTextLimited, } from './fetch-text.js';
|
|
4
6
|
export { createSiteMcpHandler } from './handler.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,OAAO,EACP,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,EACxB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,OAAO,EACP,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createSiteMcpServer } from './create-server.js';
|
|
2
|
+
export { buildA2AAgentCard, buildAgentSkillsIndex, buildApiCatalog, jsonDiscoveryResponse, } from './discovery.js';
|
|
2
3
|
export { DEFAULT_FETCH_TIMEOUT_MS, DEFAULT_MAX_BODY_BYTES, fetchTextLimited, } from './fetch-text.js';
|
|
3
4
|
export { createSiteMcpHandler } from './handler.js';
|
|
4
5
|
export { htmlPathToMarkdownPath, joinUrl, MAX_MARKDOWN_PATH_INPUT, normalizeEndpointPath, resolveMarkdownRequestPath, } from './path.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAUzD,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,OAAO,EACP,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAU5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/docs/llms.md
CHANGED
|
@@ -58,6 +58,29 @@ buildMcpServerCard({
|
|
|
58
58
|
## Paths
|
|
59
59
|
|
|
60
60
|
- Mount via Next route (e.g. `/api/mcp`)
|
|
61
|
-
- Card `endpointPath` must match mount
|
|
61
|
+
- Card `endpointPath` must match mount (**no** trailing slash)
|
|
62
|
+
- Sites with `trailingSlash: true`: middleware rewrite bare `/api/*` via `apiPathNeedingTrailingSlash` from `@se-studio/core-ui` (avoids 308 on MCP POST)
|
|
62
63
|
- Markdown mapping: `@se-studio/core-ui/agent-ready` (shared with Band A middleware)
|
|
63
64
|
- Robots: `allowExtra: ['/api/mcp', '/api/search']` when under `Disallow: /api/`
|
|
65
|
+
|
|
66
|
+
## Discovery builders (well-known)
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
buildApiCatalog,
|
|
71
|
+
buildA2AAgentCard,
|
|
72
|
+
buildAgentSkillsIndex,
|
|
73
|
+
jsonDiscoveryResponse,
|
|
74
|
+
} from '@se-studio/site-mcp';
|
|
75
|
+
|
|
76
|
+
// GET /.well-known/api-catalog
|
|
77
|
+
jsonDiscoveryResponse(buildApiCatalog({ baseUrl, apis: [{ path: '/api/mcp' }, { path: '/api/search', type: 'https://schema.org/SearchAction' }] }), 'application/linkset+json')
|
|
78
|
+
|
|
79
|
+
// GET /.well-known/agent-card.json — MCP skills now; add ask skill when /api/ask exists
|
|
80
|
+
buildA2AAgentCard({ name, description, websiteUrl: baseUrl, url: '/api/mcp', skills: [...] })
|
|
81
|
+
|
|
82
|
+
// GET /.well-known/agent-skills/index.json — only real skills
|
|
83
|
+
buildAgentSkillsIndex({ baseUrl, skills: [{ name, description, url: '/.well-known/agent-skills/.../SKILL.md' }] })
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Link headers (core-ui): `appendAgentDiscoveryLinkHeaders(headers, pathname, { mcpServerCard, apiCatalog, agentCard, agentSkills })`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/site-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Public, read-only, stateless MCP for SE Studio marketing sites (search, markdown, site-info)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@se-studio/core-ui": "1.19.
|
|
31
|
+
"@se-studio/core-ui": "1.19.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@biomejs/biome": "^2.5.5",
|