@speakeasy-api/docs-mcp-server 0.1.0
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/LICENSE +661 -0
- package/README.md +46 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +283 -0
- package/dist/bin.js.map +1 -0
- package/dist/http.d.ts +13 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +191 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +4 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +53 -0
- package/dist/schema.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +156 -0
- package/dist/server.js.map +1 -0
- package/dist/stdio.d.ts +7 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +31 -0
- package/dist/stdio.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @speakeasy-api/docs-mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server runtime exposing hybrid search over documentation via HTTP and stdio transports.
|
|
4
|
+
|
|
5
|
+
**Beta.** Part of the [Speakeasy Docs MCP](https://github.com/speakeasy-api/docs-mcp) monorepo.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @speakeasy-api/docs-mcp-server
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## CLI Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# HTTP transport
|
|
17
|
+
docs-mcp-server --index-dir ./dist/.lancedb --transport http --port 20310
|
|
18
|
+
|
|
19
|
+
# Stdio transport (for MCP host integration)
|
|
20
|
+
docs-mcp-server --index-dir ./dist/.lancedb --transport stdio
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Programmatic Usage
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { McpDocsServer } from '@speakeasy-api/docs-mcp-server';
|
|
27
|
+
|
|
28
|
+
const server = new McpDocsServer({
|
|
29
|
+
dbPath: './dist/.lancedb',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
server.start();
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## MCP Tools
|
|
36
|
+
|
|
37
|
+
| Tool | Description |
|
|
38
|
+
|------|-------------|
|
|
39
|
+
| `search_docs` | Hybrid search with dynamically generated parameters and JSON Schema enum validation. Supports cursor pagination. |
|
|
40
|
+
| `get_doc` | Retrieve a specific chunk with optional neighboring context. |
|
|
41
|
+
|
|
42
|
+
Tool names, descriptions, and parameters are dynamically generated from the `metadata.json` produced during indexing.
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
[AGPL-3.0](https://github.com/speakeasy-api/docs-mcp/blob/main/LICENSE)
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile, stat } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { z } from "zod/v4";
|
|
7
|
+
import { DocsIndex, LanceDbSearchEngine, createEmbeddingProvider, normalizeMetadata } from "@speakeasy-api/docs-mcp-core";
|
|
8
|
+
import { McpDocsServer } from "./server.js";
|
|
9
|
+
import { startStdioServer } from "./stdio.js";
|
|
10
|
+
import { startHttpServer } from "./http.js";
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const { version: SERVER_VERSION } = require("../package.json");
|
|
13
|
+
const TaxonomyFieldSchema = z.object({
|
|
14
|
+
description: z.string().optional(),
|
|
15
|
+
values: z.array(z.string())
|
|
16
|
+
}).passthrough();
|
|
17
|
+
const MetadataDocumentSchema = z.object({
|
|
18
|
+
metadata_version: z.string(),
|
|
19
|
+
corpus_description: z.string(),
|
|
20
|
+
taxonomy: z.record(z.string(), TaxonomyFieldSchema),
|
|
21
|
+
stats: z.object({
|
|
22
|
+
total_chunks: z.number().int(),
|
|
23
|
+
total_files: z.number().int(),
|
|
24
|
+
indexed_at: z.string(),
|
|
25
|
+
source_commit: z.string().nullable().optional()
|
|
26
|
+
}).passthrough(),
|
|
27
|
+
embedding: z.object({
|
|
28
|
+
provider: z.string(),
|
|
29
|
+
model: z.string(),
|
|
30
|
+
dimensions: z.number().int()
|
|
31
|
+
}).nullable(),
|
|
32
|
+
index: z.object({
|
|
33
|
+
path: z.string(),
|
|
34
|
+
table: z.string()
|
|
35
|
+
}).optional()
|
|
36
|
+
}).passthrough();
|
|
37
|
+
const program = new Command();
|
|
38
|
+
program
|
|
39
|
+
.name("docs-mcp-server")
|
|
40
|
+
.description("Run @speakeasy-api/docs-mcp-server over MCP stdio transport")
|
|
41
|
+
.requiredOption("--index-dir <path>", "Directory containing chunks.json and metadata.json")
|
|
42
|
+
.option("--name <value>", "MCP server name", "@speakeasy-api/docs-mcp-server")
|
|
43
|
+
.option("--tool-prefix <value>", "Tool name prefix (e.g. 'acme' produces acme_search_docs)")
|
|
44
|
+
.option("--version <value>", "MCP server version", SERVER_VERSION)
|
|
45
|
+
.option("--query-embedding-provider <provider>", "Query embedding provider: auto | none | hash | openai", parseQueryEmbeddingProvider, "auto")
|
|
46
|
+
.option("--query-embedding-model <value>", "Query embedding model override")
|
|
47
|
+
.option("--query-embedding-dimensions <number>", "Query embedding dimensions", parseNumberOption)
|
|
48
|
+
.option("--query-embedding-api-key <value>", "Query embedding API key (or set OPENAI_API_KEY)")
|
|
49
|
+
.option("--query-embedding-base-url <value>", "Query embedding API base URL")
|
|
50
|
+
.option("--query-embedding-batch-size <number>", "Query embedding batch size", parseIntOption)
|
|
51
|
+
.option("--proximity-weight <number>", "Lexical phrase blend weight", parseNumberOption)
|
|
52
|
+
.option("--phrase-slop <number>", "Phrase query slop (0-5)", parseNumberOption)
|
|
53
|
+
.option("--vector-weight <number>", "Vector rank blend weight", parseNumberOption)
|
|
54
|
+
.option("--allow-chunks-fallback", "Allow fallback to chunks.json when .lancedb is missing", false)
|
|
55
|
+
.option("--transport <type>", "Transport type: stdio or http", "stdio")
|
|
56
|
+
.option("--port <number>", "HTTP server port (only used with --transport http)", parseIntOption, 20310)
|
|
57
|
+
.action(async (options) => {
|
|
58
|
+
const indexDir = path.resolve(options.indexDir);
|
|
59
|
+
const metadataPath = path.join(indexDir, "metadata.json");
|
|
60
|
+
const chunksPath = path.join(indexDir, "chunks.json");
|
|
61
|
+
const metadataRaw = await readFile(metadataPath, "utf8");
|
|
62
|
+
let metadataDocument;
|
|
63
|
+
try {
|
|
64
|
+
metadataDocument = MetadataDocumentSchema.parse(JSON.parse(metadataRaw));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const detail = error instanceof z.ZodError ? z.prettifyError(error) : String(error);
|
|
68
|
+
throw new Error(`Invalid metadata.json at '${metadataPath}':\n${detail}`, { cause: error });
|
|
69
|
+
}
|
|
70
|
+
const metadata = normalizeMetadata(metadataDocument);
|
|
71
|
+
const metadataKeys = Object.keys(metadata.taxonomy);
|
|
72
|
+
const indexConfig = parseIndexConfig(metadataDocument);
|
|
73
|
+
const queryEmbeddingProvider = resolveQueryEmbeddingProvider(options, metadata.embedding);
|
|
74
|
+
const loadInput = {
|
|
75
|
+
lancedbPath: path.resolve(indexDir, indexConfig.path),
|
|
76
|
+
tableName: indexConfig.table,
|
|
77
|
+
chunksPath,
|
|
78
|
+
metadataKeys,
|
|
79
|
+
allowChunksFallback: options.allowChunksFallback
|
|
80
|
+
};
|
|
81
|
+
if (queryEmbeddingProvider !== undefined) {
|
|
82
|
+
loadInput.queryEmbeddingProvider = queryEmbeddingProvider;
|
|
83
|
+
}
|
|
84
|
+
if (options.proximityWeight !== undefined) {
|
|
85
|
+
loadInput.proximityWeight = options.proximityWeight;
|
|
86
|
+
}
|
|
87
|
+
if (options.phraseSlop !== undefined) {
|
|
88
|
+
loadInput.phraseSlop = options.phraseSlop;
|
|
89
|
+
}
|
|
90
|
+
if (options.vectorWeight !== undefined) {
|
|
91
|
+
loadInput.vectorWeight = options.vectorWeight;
|
|
92
|
+
}
|
|
93
|
+
const index = await loadSearchEngine(loadInput);
|
|
94
|
+
const rrfWeights = parseRrfWeightsFromEnv();
|
|
95
|
+
const app = new McpDocsServer({
|
|
96
|
+
index,
|
|
97
|
+
metadata,
|
|
98
|
+
...(options.toolPrefix ? { toolPrefix: options.toolPrefix } : {}),
|
|
99
|
+
...(rrfWeights ? { rrfWeights } : {})
|
|
100
|
+
});
|
|
101
|
+
const serverName = options.name === "@speakeasy-api/docs-mcp-server" && options.toolPrefix
|
|
102
|
+
? `${options.toolPrefix}-docs-server`
|
|
103
|
+
: options.name;
|
|
104
|
+
if (options.transport === "http") {
|
|
105
|
+
await startHttpServer(app, {
|
|
106
|
+
name: serverName,
|
|
107
|
+
version: options.version,
|
|
108
|
+
port: options.port
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
await startStdioServer(app, {
|
|
113
|
+
name: serverName,
|
|
114
|
+
version: options.version
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
void program.parseAsync(process.argv);
|
|
119
|
+
async function loadSearchEngine(input) {
|
|
120
|
+
if (await exists(input.lancedbPath)) {
|
|
121
|
+
const openInput = {
|
|
122
|
+
dbPath: input.lancedbPath,
|
|
123
|
+
tableName: input.tableName,
|
|
124
|
+
metadataKeys: input.metadataKeys,
|
|
125
|
+
onWarning: (message) => console.warn(`warn: ${message}`)
|
|
126
|
+
};
|
|
127
|
+
if (input.queryEmbeddingProvider !== undefined) {
|
|
128
|
+
openInput.queryEmbeddingProvider = input.queryEmbeddingProvider;
|
|
129
|
+
}
|
|
130
|
+
if (input.proximityWeight !== undefined) {
|
|
131
|
+
openInput.proximityWeight = input.proximityWeight;
|
|
132
|
+
}
|
|
133
|
+
if (input.phraseSlop !== undefined) {
|
|
134
|
+
openInput.phraseSlop = input.phraseSlop;
|
|
135
|
+
}
|
|
136
|
+
if (input.vectorWeight !== undefined) {
|
|
137
|
+
openInput.vectorWeight = input.vectorWeight;
|
|
138
|
+
}
|
|
139
|
+
return LanceDbSearchEngine.open(openInput);
|
|
140
|
+
}
|
|
141
|
+
if (!input.allowChunksFallback) {
|
|
142
|
+
throw new Error(`LanceDB index not found at '${input.lancedbPath}'. Re-run docs-mcp build or pass --allow-chunks-fallback to use chunks.json fallback.`);
|
|
143
|
+
}
|
|
144
|
+
console.warn(`warn: LanceDB index not found at '${input.lancedbPath}'; falling back to chunks.json in-memory search`);
|
|
145
|
+
const chunksRaw = await readFile(input.chunksPath, "utf8");
|
|
146
|
+
const chunks = JSON.parse(chunksRaw);
|
|
147
|
+
return new DocsIndex(chunks);
|
|
148
|
+
}
|
|
149
|
+
function parseIndexConfig(metadata) {
|
|
150
|
+
const index = metadata.index;
|
|
151
|
+
if (!index || typeof index !== "object") {
|
|
152
|
+
return {
|
|
153
|
+
path: ".lancedb",
|
|
154
|
+
table: "chunks"
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const record = index;
|
|
158
|
+
return {
|
|
159
|
+
path: toNonEmptyString(record.path) ?? ".lancedb",
|
|
160
|
+
table: toNonEmptyString(record.table) ?? "chunks"
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function resolveQueryEmbeddingProvider(options, metadataEmbedding) {
|
|
164
|
+
const selectedProvider = selectEmbeddingProvider(options.queryEmbeddingProvider, metadataEmbedding);
|
|
165
|
+
if (!selectedProvider || selectedProvider === "none") {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
const input = {
|
|
169
|
+
provider: selectedProvider
|
|
170
|
+
};
|
|
171
|
+
const model = options.queryEmbeddingModel ?? metadataEmbedding?.model;
|
|
172
|
+
if (model !== undefined) {
|
|
173
|
+
input.model = model;
|
|
174
|
+
}
|
|
175
|
+
const dimensions = options.queryEmbeddingDimensions ?? metadataEmbedding?.dimensions;
|
|
176
|
+
if (dimensions !== undefined) {
|
|
177
|
+
input.dimensions = dimensions;
|
|
178
|
+
}
|
|
179
|
+
const apiKey = options.queryEmbeddingApiKey ?? process.env.OPENAI_API_KEY;
|
|
180
|
+
if (apiKey !== undefined) {
|
|
181
|
+
input.apiKey = apiKey;
|
|
182
|
+
}
|
|
183
|
+
if (options.queryEmbeddingBaseUrl !== undefined) {
|
|
184
|
+
input.baseUrl = options.queryEmbeddingBaseUrl;
|
|
185
|
+
}
|
|
186
|
+
if (options.queryEmbeddingBatchSize !== undefined) {
|
|
187
|
+
input.batchSize = options.queryEmbeddingBatchSize;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
return createEmbeddingProvider(input);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
194
|
+
console.warn(`warn: query embedding disabled: ${message}`);
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function selectEmbeddingProvider(option, metadataEmbedding) {
|
|
199
|
+
if (option !== "auto") {
|
|
200
|
+
return option;
|
|
201
|
+
}
|
|
202
|
+
const provider = metadataEmbedding?.provider?.trim().toLowerCase();
|
|
203
|
+
if (!provider || provider === "none") {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
if (provider === "hash" || provider === "openai") {
|
|
207
|
+
return provider;
|
|
208
|
+
}
|
|
209
|
+
console.warn(`warn: embedding provider '${metadataEmbedding?.provider}' is not supported at runtime; falling back to FTS-only search`);
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
function parseQueryEmbeddingProvider(value) {
|
|
213
|
+
const normalized = value.trim().toLowerCase();
|
|
214
|
+
if (normalized === "auto" ||
|
|
215
|
+
normalized === "none" ||
|
|
216
|
+
normalized === "hash" ||
|
|
217
|
+
normalized === "openai") {
|
|
218
|
+
return normalized;
|
|
219
|
+
}
|
|
220
|
+
throw new Error(`unsupported query embedding provider '${value}'. Expected one of: auto, none, hash, openai`);
|
|
221
|
+
}
|
|
222
|
+
function parseNumberOption(value) {
|
|
223
|
+
const parsed = Number(value);
|
|
224
|
+
if (!Number.isFinite(parsed)) {
|
|
225
|
+
throw new Error(`invalid numeric value '${value}'`);
|
|
226
|
+
}
|
|
227
|
+
return parsed;
|
|
228
|
+
}
|
|
229
|
+
function parseIntOption(value) {
|
|
230
|
+
const parsed = Number.parseInt(value, 10);
|
|
231
|
+
if (!Number.isFinite(parsed)) {
|
|
232
|
+
throw new Error(`invalid integer value '${value}'`);
|
|
233
|
+
}
|
|
234
|
+
return parsed;
|
|
235
|
+
}
|
|
236
|
+
function parseRrfWeightsFromEnv() {
|
|
237
|
+
const vector = parseOptionalEnvFloat("RRF_WEIGHT_VECTOR");
|
|
238
|
+
const match = parseOptionalEnvFloat("RRF_WEIGHT_MATCH");
|
|
239
|
+
const phrase = parseOptionalEnvFloat("RRF_WEIGHT_PHRASE");
|
|
240
|
+
if (vector === undefined && match === undefined && phrase === undefined) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
const weights = {};
|
|
244
|
+
if (vector !== undefined) {
|
|
245
|
+
weights.vector = vector;
|
|
246
|
+
}
|
|
247
|
+
if (match !== undefined) {
|
|
248
|
+
weights.match = match;
|
|
249
|
+
}
|
|
250
|
+
if (phrase !== undefined) {
|
|
251
|
+
weights.phrase = phrase;
|
|
252
|
+
}
|
|
253
|
+
return weights;
|
|
254
|
+
}
|
|
255
|
+
function parseOptionalEnvFloat(name) {
|
|
256
|
+
const raw = process.env[name];
|
|
257
|
+
if (raw === undefined || raw === "") {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
const parsed = Number(raw);
|
|
261
|
+
if (!Number.isFinite(parsed)) {
|
|
262
|
+
console.warn(`warn: ignoring invalid ${name} value '${raw}'`);
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
return parsed;
|
|
266
|
+
}
|
|
267
|
+
function toNonEmptyString(value) {
|
|
268
|
+
if (typeof value !== "string") {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
const trimmed = value.trim();
|
|
272
|
+
return trimmed ? trimmed : undefined;
|
|
273
|
+
}
|
|
274
|
+
async function exists(targetPath) {
|
|
275
|
+
try {
|
|
276
|
+
await stat(targetPath);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import type { McpDocsServer } from "./server.js";
|
|
3
|
+
export interface StartHttpServerOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
port?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface HttpServerHandle {
|
|
9
|
+
httpServer: http.Server;
|
|
10
|
+
port: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function startHttpServer(app: McpDocsServer, options?: StartHttpServerOptions): Promise<HttpServerHandle>;
|
|
13
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AA2CD,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CA2B3B"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const { version: PKG_VERSION } = require("../package.json");
|
|
8
|
+
/**
|
|
9
|
+
* Create a fresh MCP Server wired to the given app and return it connected to a
|
|
10
|
+
* new stateless StreamableHTTPServerTransport. In stateless mode every request
|
|
11
|
+
* gets its own server+transport pair (the SDK examples demonstrate this pattern
|
|
12
|
+
* in `simpleStatelessStreamableHttp.ts`).
|
|
13
|
+
*/
|
|
14
|
+
function createPerRequestServer(app, options) {
|
|
15
|
+
const server = new Server({
|
|
16
|
+
name: options.name ?? "@speakeasy-api/docs-mcp-server",
|
|
17
|
+
version: options.version ?? PKG_VERSION
|
|
18
|
+
}, {
|
|
19
|
+
capabilities: {
|
|
20
|
+
tools: {}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
24
|
+
const tools = app.getTools().map((tool) => ({
|
|
25
|
+
name: tool.name,
|
|
26
|
+
description: tool.description,
|
|
27
|
+
inputSchema: tool.inputSchema
|
|
28
|
+
}));
|
|
29
|
+
return { tools };
|
|
30
|
+
});
|
|
31
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
32
|
+
const result = await app.callTool(request.params.name, request.params.arguments ?? {});
|
|
33
|
+
return result;
|
|
34
|
+
});
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- exactOptionalPropertyTypes workaround
|
|
36
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
37
|
+
return { server, transport };
|
|
38
|
+
}
|
|
39
|
+
export async function startHttpServer(app, options = {}) {
|
|
40
|
+
const port = options.port ?? 20310;
|
|
41
|
+
const httpServer = http.createServer(async (req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
await handleRequest(req, res, app, options);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error("Unhandled error in request handler:", error);
|
|
47
|
+
if (!res.headersSent) {
|
|
48
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
49
|
+
res.end(JSON.stringify({
|
|
50
|
+
jsonrpc: "2.0",
|
|
51
|
+
error: { code: -32603, message: "Internal server error" },
|
|
52
|
+
id: null
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
else if (!res.writableEnded) {
|
|
56
|
+
res.end();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const actualPort = await listenOnAvailablePort(httpServer, port);
|
|
61
|
+
console.error(`MCP HTTP server listening on http://localhost:${actualPort}/mcp`);
|
|
62
|
+
return { httpServer, port: actualPort };
|
|
63
|
+
}
|
|
64
|
+
const CORS_HEADERS = {
|
|
65
|
+
"Access-Control-Allow-Origin": "*",
|
|
66
|
+
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
67
|
+
"Access-Control-Allow-Headers": "*",
|
|
68
|
+
"Access-Control-Max-Age": "86400"
|
|
69
|
+
};
|
|
70
|
+
function setCorsHeaders(res) {
|
|
71
|
+
for (const [key, value] of Object.entries(CORS_HEADERS)) {
|
|
72
|
+
res.setHeader(key, value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function handleRequest(req, res, app, options) {
|
|
76
|
+
// Only the pathname matters; the base URL is arbitrary.
|
|
77
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
78
|
+
if (url.pathname !== "/mcp") {
|
|
79
|
+
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
80
|
+
res.end("Method Not Allowed");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
setCorsHeaders(res);
|
|
84
|
+
if (req.method === "OPTIONS") {
|
|
85
|
+
res.writeHead(204);
|
|
86
|
+
res.end();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (req.method === "GET" || req.method === "DELETE") {
|
|
90
|
+
res.writeHead(405, { "Content-Type": "application/json" });
|
|
91
|
+
res.end(JSON.stringify({
|
|
92
|
+
jsonrpc: "2.0",
|
|
93
|
+
error: { code: -32000, message: "Method not allowed." },
|
|
94
|
+
id: null
|
|
95
|
+
}));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Parse JSON body before handing off to the transport
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
const body = await readBody(req);
|
|
102
|
+
parsed = JSON.parse(body);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
106
|
+
res.end(JSON.stringify({
|
|
107
|
+
jsonrpc: "2.0",
|
|
108
|
+
error: { code: -32700, message: "Parse error" },
|
|
109
|
+
id: null
|
|
110
|
+
}));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const { server, transport } = createPerRequestServer(app, options);
|
|
114
|
+
try {
|
|
115
|
+
await server.connect(transport);
|
|
116
|
+
await transport.handleRequest(req, res, parsed);
|
|
117
|
+
res.on("close", () => {
|
|
118
|
+
transport.close();
|
|
119
|
+
server.close();
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error("Error handling MCP request:", error);
|
|
124
|
+
if (!res.headersSent) {
|
|
125
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
126
|
+
res.end(JSON.stringify({
|
|
127
|
+
jsonrpc: "2.0",
|
|
128
|
+
error: { code: -32603, message: "Internal server error" },
|
|
129
|
+
id: null
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
transport.close();
|
|
133
|
+
server.close();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const MAX_PORT_ATTEMPTS = 10;
|
|
137
|
+
/**
|
|
138
|
+
* Try to listen on `startPort`. If the port is busy (EADDRINUSE), try
|
|
139
|
+
* startPort+1, startPort+2, etc. up to MAX_PORT_ATTEMPTS.
|
|
140
|
+
* Port 0 is passed through directly (OS picks an ephemeral port).
|
|
141
|
+
*/
|
|
142
|
+
function listenOnAvailablePort(server, startPort) {
|
|
143
|
+
if (startPort === 0) {
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
server.once("error", reject);
|
|
146
|
+
server.listen(0, () => {
|
|
147
|
+
server.removeListener("error", reject);
|
|
148
|
+
const addr = server.address();
|
|
149
|
+
resolve(typeof addr === "object" && addr ? addr.port : 0);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
let attempt = 0;
|
|
154
|
+
return new Promise((resolve, reject) => {
|
|
155
|
+
const tryPort = (port) => {
|
|
156
|
+
server.once("error", (err) => {
|
|
157
|
+
if (err.code === "EADDRINUSE" && attempt < MAX_PORT_ATTEMPTS) {
|
|
158
|
+
attempt++;
|
|
159
|
+
tryPort(port + 1);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
reject(err);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
server.listen(port, () => {
|
|
166
|
+
server.removeAllListeners("error");
|
|
167
|
+
resolve(port);
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
tryPort(startPort);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const MAX_BODY_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
174
|
+
function readBody(req) {
|
|
175
|
+
return new Promise((resolve, reject) => {
|
|
176
|
+
const chunks = [];
|
|
177
|
+
let totalLength = 0;
|
|
178
|
+
req.on("data", (chunk) => {
|
|
179
|
+
totalLength += chunk.length;
|
|
180
|
+
if (totalLength > MAX_BODY_BYTES) {
|
|
181
|
+
req.destroy();
|
|
182
|
+
reject(new Error("Request body too large"));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
chunks.push(chunk);
|
|
186
|
+
});
|
|
187
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString()));
|
|
188
|
+
req.on("error", reject);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CorpusMetadata } from "@speakeasy-api/docs-mcp-core";
|
|
2
|
+
export declare function buildSearchDocsSchema(metadata: CorpusMetadata): Record<string, unknown>;
|
|
3
|
+
export declare function buildGetDocSchema(): Record<string, unknown>;
|
|
4
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCvF;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqB3D"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function buildSearchDocsSchema(metadata) {
|
|
2
|
+
const properties = {
|
|
3
|
+
query: {
|
|
4
|
+
type: "string",
|
|
5
|
+
description: "The search query (e.g., 'how to paginate', 'RateLimitError')."
|
|
6
|
+
},
|
|
7
|
+
limit: {
|
|
8
|
+
type: "integer",
|
|
9
|
+
description: "Maximum number of results to return. Default is 10.",
|
|
10
|
+
minimum: 1,
|
|
11
|
+
maximum: 50,
|
|
12
|
+
default: 10
|
|
13
|
+
},
|
|
14
|
+
cursor: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "Opaque pagination token returned from a previous search. Omit for the first page."
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
for (const [key, field] of Object.entries(metadata.taxonomy)) {
|
|
20
|
+
properties[key] = {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: field.description ?? `Filter results by ${key}.`,
|
|
23
|
+
enum: field.values
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
type: "object",
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
properties,
|
|
30
|
+
required: ["query"]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function buildGetDocSchema() {
|
|
34
|
+
return {
|
|
35
|
+
type: "object",
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
properties: {
|
|
38
|
+
chunk_id: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "The exact ID of the chunk to retrieve, as returned by search_docs (e.g., 'guides/retries.md#backoff-strategy')."
|
|
41
|
+
},
|
|
42
|
+
context: {
|
|
43
|
+
type: "integer",
|
|
44
|
+
description: "Number of adjacent chunks to include before and after the target chunk. Default is 0.",
|
|
45
|
+
minimum: 0,
|
|
46
|
+
maximum: 5,
|
|
47
|
+
default: 0
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
required: ["chunk_id"]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=schema.js.map
|