@se-studio/site-mcp 0.0.0-next16-20260822103555
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 +200 -0
- package/README.md +117 -0
- package/dist/create-server.d.ts +8 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +121 -0
- package/dist/create-server.js.map +1 -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/fetch-text.d.ts +23 -0
- package/dist/fetch-text.d.ts.map +1 -0
- package/dist/fetch-text.js +56 -0
- package/dist/fetch-text.js.map +1 -0
- package/dist/generated/version.d.ts +3 -0
- package/dist/generated/version.d.ts.map +1 -0
- package/dist/generated/version.js +4 -0
- package/dist/generated/version.js.map +1 -0
- package/dist/handler.d.ts +20 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +59 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/path.d.ts +26 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +44 -0
- package/dist/path.js.map +1 -0
- package/dist/server-card.d.ts +15 -0
- package/dist/server-card.d.ts.map +1 -0
- package/dist/server-card.js +42 -0
- package/dist/server-card.js.map +1 -0
- package/dist/types.d.ts +94 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/llms.md +86 -0
- package/package.json +48 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# @se-studio/site-mcp
|
|
2
|
+
|
|
3
|
+
## 0.0.0-next16-20260822103555
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [eeed547]
|
|
8
|
+
- @se-studio/core-ui@0.0.0-next16-20260822103555
|
|
9
|
+
|
|
10
|
+
## 0.3.23
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [f8a2ec2]
|
|
15
|
+
- @se-studio/core-ui@1.24.7
|
|
16
|
+
|
|
17
|
+
## 0.3.22
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [b6434f7]
|
|
22
|
+
- @se-studio/core-ui@1.24.6
|
|
23
|
+
|
|
24
|
+
## 0.3.21
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [dbfb662]
|
|
29
|
+
- @se-studio/core-ui@1.24.5
|
|
30
|
+
|
|
31
|
+
## 0.3.20
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies [2c479e7]
|
|
36
|
+
- @se-studio/core-ui@1.24.4
|
|
37
|
+
|
|
38
|
+
## 0.3.19
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- @se-studio/core-ui@1.24.3
|
|
43
|
+
|
|
44
|
+
## 0.3.18
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- Updated dependencies
|
|
49
|
+
- @se-studio/core-ui@1.24.2
|
|
50
|
+
|
|
51
|
+
## 0.3.17
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Updated dependencies
|
|
56
|
+
- @se-studio/core-ui@1.24.1
|
|
57
|
+
|
|
58
|
+
## 0.3.16
|
|
59
|
+
|
|
60
|
+
### Patch Changes
|
|
61
|
+
|
|
62
|
+
- Updated dependencies [50d02a0]
|
|
63
|
+
- @se-studio/core-ui@1.24.0
|
|
64
|
+
|
|
65
|
+
## 0.3.15
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- @se-studio/core-ui@1.23.2
|
|
70
|
+
|
|
71
|
+
## 0.3.14
|
|
72
|
+
|
|
73
|
+
### Patch Changes
|
|
74
|
+
|
|
75
|
+
- Updated dependencies
|
|
76
|
+
- @se-studio/core-ui@1.23.1
|
|
77
|
+
|
|
78
|
+
## 0.3.13
|
|
79
|
+
|
|
80
|
+
### Patch Changes
|
|
81
|
+
|
|
82
|
+
- Updated dependencies
|
|
83
|
+
- @se-studio/core-ui@1.23.0
|
|
84
|
+
|
|
85
|
+
## 0.3.12
|
|
86
|
+
|
|
87
|
+
### Patch Changes
|
|
88
|
+
|
|
89
|
+
- Updated dependencies [5b69ac6]
|
|
90
|
+
- @se-studio/core-ui@1.22.1
|
|
91
|
+
|
|
92
|
+
## 0.3.11
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- Updated dependencies [760c9c4]
|
|
97
|
+
- @se-studio/core-ui@1.22.0
|
|
98
|
+
|
|
99
|
+
## 0.3.10
|
|
100
|
+
|
|
101
|
+
### Patch Changes
|
|
102
|
+
|
|
103
|
+
- Updated dependencies
|
|
104
|
+
- @se-studio/core-ui@1.21.0
|
|
105
|
+
|
|
106
|
+
## 0.3.9
|
|
107
|
+
|
|
108
|
+
### Patch Changes
|
|
109
|
+
|
|
110
|
+
- Updated dependencies [928562f]
|
|
111
|
+
- @se-studio/core-ui@1.20.0
|
|
112
|
+
|
|
113
|
+
## 0.3.8
|
|
114
|
+
|
|
115
|
+
### Patch Changes
|
|
116
|
+
|
|
117
|
+
- Updated dependencies
|
|
118
|
+
- @se-studio/core-ui@1.19.10
|
|
119
|
+
|
|
120
|
+
## 0.3.7
|
|
121
|
+
|
|
122
|
+
### Patch Changes
|
|
123
|
+
|
|
124
|
+
- Updated dependencies
|
|
125
|
+
- @se-studio/core-ui@1.19.9
|
|
126
|
+
|
|
127
|
+
## 0.3.6
|
|
128
|
+
|
|
129
|
+
### Patch Changes
|
|
130
|
+
|
|
131
|
+
- @se-studio/core-ui@1.19.8
|
|
132
|
+
|
|
133
|
+
## 0.3.5
|
|
134
|
+
|
|
135
|
+
### Patch Changes
|
|
136
|
+
|
|
137
|
+
- @se-studio/core-ui@1.19.7
|
|
138
|
+
|
|
139
|
+
## 0.3.4
|
|
140
|
+
|
|
141
|
+
### Patch Changes
|
|
142
|
+
|
|
143
|
+
- @se-studio/core-ui@1.19.6
|
|
144
|
+
|
|
145
|
+
## 0.3.3
|
|
146
|
+
|
|
147
|
+
### Patch Changes
|
|
148
|
+
|
|
149
|
+
- @se-studio/core-ui@1.19.5
|
|
150
|
+
|
|
151
|
+
## 0.3.2
|
|
152
|
+
|
|
153
|
+
### Patch Changes
|
|
154
|
+
|
|
155
|
+
- @se-studio/core-ui@1.19.4
|
|
156
|
+
|
|
157
|
+
## 0.3.1
|
|
158
|
+
|
|
159
|
+
### Patch Changes
|
|
160
|
+
|
|
161
|
+
- 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.
|
|
162
|
+
- Updated dependencies
|
|
163
|
+
- @se-studio/core-ui@1.19.3
|
|
164
|
+
|
|
165
|
+
## 0.3.0
|
|
166
|
+
|
|
167
|
+
### Minor Changes
|
|
168
|
+
|
|
169
|
+
- 14aeb6d: Agent discovery helpers: API catalog, A2A agent card, skills index builders; Link header options for api-catalog, agent-card, and agent-skills.
|
|
170
|
+
|
|
171
|
+
### Patch Changes
|
|
172
|
+
|
|
173
|
+
- Updated dependencies [14aeb6d]
|
|
174
|
+
- @se-studio/core-ui@1.19.2
|
|
175
|
+
|
|
176
|
+
## 0.2.2
|
|
177
|
+
|
|
178
|
+
### Patch Changes
|
|
179
|
+
|
|
180
|
+
- 6573a6b: Rate-limit public Upstash search (default 10/min per IP) on `/api/search` and MCP `search_site` via optional `checkRateLimit` inject.
|
|
181
|
+
|
|
182
|
+
## 0.2.1
|
|
183
|
+
|
|
184
|
+
### Patch Changes
|
|
185
|
+
|
|
186
|
+
- Updated dependencies [d9ddfa0]
|
|
187
|
+
- @se-studio/core-ui@1.19.1
|
|
188
|
+
|
|
189
|
+
## 0.2.0
|
|
190
|
+
|
|
191
|
+
### Minor Changes
|
|
192
|
+
|
|
193
|
+
- e716d0e: Public site MCP (Band B): new `@se-studio/site-mcp` for stateless read-only agent tools (`get_markdown`, `get_site_info`, `search_site`). Server-card `endpointPath` is configurable (default `/api/mcp`); the App Router mount is the routing source of truth.
|
|
194
|
+
|
|
195
|
+
`@se-studio/core-ui`: opt-in MCP server-card Link headers (`mcpServerCard`), robots `allowExtra`, hardened `htmlPathToMarkdownPath` (encoded traversal + length), and `./agent-ready` subpath export for pure helpers shared with site-mcp.
|
|
196
|
+
|
|
197
|
+
### Patch Changes
|
|
198
|
+
|
|
199
|
+
- Updated dependencies [e716d0e]
|
|
200
|
+
- @se-studio/core-ui@1.19.0
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @se-studio/site-mcp
|
|
2
|
+
|
|
3
|
+
Public, **read-only**, **stateless** MCP for SE Studio marketing sites.
|
|
4
|
+
|
|
5
|
+
Agents use tools instead of scraping HTML:
|
|
6
|
+
|
|
7
|
+
| Tool | Purpose |
|
|
8
|
+
|------|---------|
|
|
9
|
+
| `search_site` | Hybrid search (injected; typically `@se-studio/search`) |
|
|
10
|
+
| `get_markdown` | Fetch `/{path}.md` export |
|
|
11
|
+
| `get_site_info` | Fetch `/site-info.md` |
|
|
12
|
+
|
|
13
|
+
This is **not** cms-edit. No OAuth, no draft writes. Runs on the marketing origin.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @se-studio/site-mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Endpoint path
|
|
22
|
+
|
|
23
|
+
The **Next.js route file path** is the mount point (e.g. `app/api/mcp/route.ts` → `/api/mcp`).
|
|
24
|
+
`createSiteMcpHandler` does **not** take a path — routing is owned by App Router.
|
|
25
|
+
|
|
26
|
+
**Trailing slash:** SE Studio sites use `trailingSlash: true`. Advertise **`/api/mcp` without a trailing slash** (server card, catalog, agent card). Also set **`skipTrailingSlashRedirect: true`** — Next’s built-in slash 308 runs before middleware and ignores rewrites. Then in middleware call `apiPathNeedingTrailingSlash` + `NextResponse.rewrite` for bare `/api/*`, and 308 HTML paths to the slashed form yourself if you still want page trailing slashes.
|
|
27
|
+
|
|
28
|
+
Use `endpointPath` only on **`buildMcpServerCard`** so the well-known card advertises the same URL agents should call:
|
|
29
|
+
|
|
30
|
+
| Site shape | Example `endpointPath` (server card) |
|
|
31
|
+
|------------|--------------------------------------|
|
|
32
|
+
| Standard SE Studio | `/api/mcp` |
|
|
33
|
+
| Top-level | `/mcp` |
|
|
34
|
+
| Point.me-style API prefix | `/marketing-api/mcp` |
|
|
35
|
+
|
|
36
|
+
When under `/api/`, update robots with `allowExtra` from `@se-studio/core-ui`:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
createRobotsTxtResponse({
|
|
40
|
+
isProduction,
|
|
41
|
+
baseUrl,
|
|
42
|
+
allowExtra: ['/api/mcp', '/api/search'],
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Some crawlers treat `Allow` loosely; discovery is primarily via `Link: rel="mcp-server-card"` and the well-known card.
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// app/api/mcp/route.ts
|
|
52
|
+
import { createSiteMcpHandler } from '@se-studio/site-mcp';
|
|
53
|
+
import { baseUrl } from '@/lib/server-config';
|
|
54
|
+
|
|
55
|
+
const handler = createSiteMcpHandler({
|
|
56
|
+
identity: {
|
|
57
|
+
name: 'se-studio',
|
|
58
|
+
title: 'Something Else',
|
|
59
|
+
websiteUrl: baseUrl,
|
|
60
|
+
},
|
|
61
|
+
tools: {
|
|
62
|
+
getMarkdown: {},
|
|
63
|
+
getSiteInfo: {},
|
|
64
|
+
// search: { search: async ({ query, limit, type }) => { … } },
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export const GET = handler;
|
|
69
|
+
export const POST = handler;
|
|
70
|
+
export const DELETE = handler;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Server card
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// app/.well-known/mcp/server-card.json/route.ts
|
|
77
|
+
import { buildMcpServerCard } from '@se-studio/site-mcp';
|
|
78
|
+
import { baseUrl } from '@/lib/server-config';
|
|
79
|
+
|
|
80
|
+
export function GET() {
|
|
81
|
+
const card = buildMcpServerCard({
|
|
82
|
+
identity: {
|
|
83
|
+
name: 'se-studio',
|
|
84
|
+
title: 'Something Else',
|
|
85
|
+
websiteUrl: baseUrl,
|
|
86
|
+
},
|
|
87
|
+
endpointPath: '/api/mcp', // must match the App Router mount
|
|
88
|
+
tools: { getMarkdown: {}, getSiteInfo: {} },
|
|
89
|
+
});
|
|
90
|
+
return Response.json(card, {
|
|
91
|
+
headers: {
|
|
92
|
+
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Discovery Link header
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
appendAgentDiscoveryLinkHeaders(response.headers, pathname, { mcpServerCard: true });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Path mapping
|
|
105
|
+
|
|
106
|
+
Markdown paths use **`@se-studio/core-ui/agent-ready`** (`htmlPathToMarkdownPath`) — the same Band A helper as middleware content negotiation — so rules do not drift.
|
|
107
|
+
|
|
108
|
+
## Safety defaults
|
|
109
|
+
|
|
110
|
+
- Fetch timeout: 10s (override `fetchTimeoutMs`)
|
|
111
|
+
- Max body: 512 KiB (override `maxBodyBytes`)
|
|
112
|
+
- Encoded path traversal rejected
|
|
113
|
+
- Tool failures set MCP `isError: true`
|
|
114
|
+
|
|
115
|
+
## LLM reference
|
|
116
|
+
|
|
117
|
+
See [docs/llms.md](./docs/llms.md).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { SiteMcpHandlerConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create an MCP server instance with tools based on config.
|
|
5
|
+
* Fresh per request (stateless serverless).
|
|
6
|
+
*/
|
|
7
|
+
export declare function createSiteMcpServer(config: SiteMcpHandlerConfig): McpServer;
|
|
8
|
+
//# sourceMappingURL=create-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAgBvD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CA+H3E"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { fetchTextLimited } from './fetch-text.js';
|
|
4
|
+
import { joinUrl, resolveMarkdownRequestPath } from './path.js';
|
|
5
|
+
import { listEnabledToolNames } from './server-card.js';
|
|
6
|
+
import { SITE_MCP_VERSION } from './version.js';
|
|
7
|
+
function toolText(text) {
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: 'text', text }],
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function toolError(message) {
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: 'text', text: message }],
|
|
15
|
+
isError: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create an MCP server instance with tools based on config.
|
|
20
|
+
* Fresh per request (stateless serverless).
|
|
21
|
+
*/
|
|
22
|
+
export function createSiteMcpServer(config) {
|
|
23
|
+
const version = config.identity.version ?? SITE_MCP_VERSION;
|
|
24
|
+
const websiteUrl = config.identity.websiteUrl.replace(/\/+$/, '');
|
|
25
|
+
const fetchImpl = config.fetch ?? fetch;
|
|
26
|
+
const tools = config.tools ?? {};
|
|
27
|
+
const fetchTimeoutMs = config.fetchTimeoutMs;
|
|
28
|
+
const maxBodyBytes = config.maxBodyBytes;
|
|
29
|
+
const server = new McpServer({
|
|
30
|
+
name: config.identity.name,
|
|
31
|
+
version,
|
|
32
|
+
});
|
|
33
|
+
const enabled = listEnabledToolNames(tools);
|
|
34
|
+
if (enabled.includes('get_markdown')) {
|
|
35
|
+
server.tool('get_markdown', `Fetch a page or article from ${config.identity.title} as clean Markdown (frontmatter + body). ` +
|
|
36
|
+
'Use public paths like "/", "/about", or article paths (not .md suffix). Prefer this over scraping HTML.', {
|
|
37
|
+
path: z.string().describe('Public page path, e.g. "/", "/about", "/work/case-study"'),
|
|
38
|
+
}, async ({ path }) => {
|
|
39
|
+
const mdPath = resolveMarkdownRequestPath(path);
|
|
40
|
+
if (!mdPath) {
|
|
41
|
+
return toolError(`Invalid or disallowed path: ${path}`);
|
|
42
|
+
}
|
|
43
|
+
const url = joinUrl(websiteUrl, mdPath);
|
|
44
|
+
const result = await fetchTextLimited(url, {
|
|
45
|
+
fetchImpl,
|
|
46
|
+
timeoutMs: fetchTimeoutMs,
|
|
47
|
+
maxBytes: maxBodyBytes,
|
|
48
|
+
headers: { Accept: 'text/markdown, text/plain, */*' },
|
|
49
|
+
});
|
|
50
|
+
if (!result.ok) {
|
|
51
|
+
return toolError(`${result.error} (${url})`);
|
|
52
|
+
}
|
|
53
|
+
// Raw markdown on success — agents can use it directly
|
|
54
|
+
return toolText(result.text);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (enabled.includes('get_site_info')) {
|
|
58
|
+
server.tool('get_site_info', `Fetch the factual site-info document for ${config.identity.title} (counts, lists, summary for assistants).`, {}, async () => {
|
|
59
|
+
const url = joinUrl(websiteUrl, '/site-info.md');
|
|
60
|
+
const result = await fetchTextLimited(url, {
|
|
61
|
+
fetchImpl,
|
|
62
|
+
timeoutMs: fetchTimeoutMs,
|
|
63
|
+
maxBytes: maxBodyBytes,
|
|
64
|
+
headers: { Accept: 'text/markdown, text/plain, */*' },
|
|
65
|
+
});
|
|
66
|
+
if (!result.ok) {
|
|
67
|
+
return toolError(`${result.error} (${url})`);
|
|
68
|
+
}
|
|
69
|
+
return toolText(result.text);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (enabled.includes('search_site') && tools.search) {
|
|
73
|
+
const searchFn = tools.search.search;
|
|
74
|
+
const checkRateLimit = tools.search.checkRateLimit;
|
|
75
|
+
const request = config.request;
|
|
76
|
+
server.tool('search_site', `Search published content on ${config.identity.title}. Returns titles, hrefs, and short snippets. ` +
|
|
77
|
+
'Use get_markdown on a result href/path for full page content.', {
|
|
78
|
+
query: z.string().min(1).describe('Search query'),
|
|
79
|
+
limit: z
|
|
80
|
+
.number()
|
|
81
|
+
.int()
|
|
82
|
+
.min(1)
|
|
83
|
+
.max(20)
|
|
84
|
+
.optional()
|
|
85
|
+
.describe('Max results (1–20, default 10)'),
|
|
86
|
+
type: z
|
|
87
|
+
.string()
|
|
88
|
+
.optional()
|
|
89
|
+
.describe('Optional content type filter, e.g. page, article, person'),
|
|
90
|
+
}, async ({ query, limit, type }) => {
|
|
91
|
+
const capped = Math.min(limit ?? 10, 20);
|
|
92
|
+
try {
|
|
93
|
+
if (checkRateLimit && request) {
|
|
94
|
+
const rate = await checkRateLimit(request);
|
|
95
|
+
if (!rate.allowed) {
|
|
96
|
+
const retry = rate.retryAfterSeconds != null && rate.retryAfterSeconds > 0
|
|
97
|
+
? ` Try again in ${rate.retryAfterSeconds} seconds.`
|
|
98
|
+
: '';
|
|
99
|
+
return toolError(rate.message ?? `Rate limited: too many search requests.${retry}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const result = await searchFn({
|
|
103
|
+
query: query.trim(),
|
|
104
|
+
limit: capped,
|
|
105
|
+
type,
|
|
106
|
+
});
|
|
107
|
+
return toolText(JSON.stringify({
|
|
108
|
+
query: result.query,
|
|
109
|
+
totalCount: result.totalCount,
|
|
110
|
+
results: result.results,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
115
|
+
return toolError(`Search failed: ${message}`);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return server;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=create-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -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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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Default timeout for origin fetches (markdown / site-info). */
|
|
2
|
+
export declare const DEFAULT_FETCH_TIMEOUT_MS = 10000;
|
|
3
|
+
/** Default max body size (~512 KiB) for public tool responses. */
|
|
4
|
+
export declare const DEFAULT_MAX_BODY_BYTES: number;
|
|
5
|
+
export type FetchTextResult = {
|
|
6
|
+
ok: true;
|
|
7
|
+
text: string;
|
|
8
|
+
status: number;
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
error: string;
|
|
12
|
+
status?: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Fetch a URL as text with timeout and max body size.
|
|
16
|
+
*/
|
|
17
|
+
export declare function fetchTextLimited(url: string, options?: {
|
|
18
|
+
fetchImpl?: typeof fetch;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
maxBytes?: number;
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
}): Promise<FetchTextResult>;
|
|
23
|
+
//# sourceMappingURL=fetch-text.d.ts.map
|