context.dev-mcp 1.0.1 → 1.2.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/code-tool-worker.d.mts.map +1 -1
- package/code-tool-worker.d.ts.map +1 -1
- package/code-tool-worker.js +43 -2
- package/code-tool-worker.js.map +1 -1
- package/code-tool-worker.mjs +10 -2
- package/code-tool-worker.mjs.map +1 -1
- package/docs-search-tool.d.mts +2 -0
- package/docs-search-tool.d.mts.map +1 -1
- package/docs-search-tool.d.ts +2 -0
- package/docs-search-tool.d.ts.map +1 -1
- package/docs-search-tool.js +32 -2
- package/docs-search-tool.js.map +1 -1
- package/docs-search-tool.mjs +31 -2
- package/docs-search-tool.mjs.map +1 -1
- package/http.d.mts.map +1 -1
- package/http.d.ts.map +1 -1
- package/http.js +24 -1
- package/http.js.map +1 -1
- package/http.mjs +24 -1
- package/http.mjs.map +1 -1
- package/instructions.d.mts +4 -1
- package/instructions.d.mts.map +1 -1
- package/instructions.d.ts +4 -1
- package/instructions.d.ts.map +1 -1
- package/instructions.js +23 -4
- package/instructions.js.map +1 -1
- package/instructions.mjs +20 -4
- package/instructions.mjs.map +1 -1
- package/local-docs-search.d.mts +28 -0
- package/local-docs-search.d.mts.map +1 -0
- package/local-docs-search.d.ts +28 -0
- package/local-docs-search.d.ts.map +1 -0
- package/local-docs-search.js +940 -0
- package/local-docs-search.js.map +1 -0
- package/local-docs-search.mjs +900 -0
- package/local-docs-search.mjs.map +1 -0
- package/options.d.mts +3 -0
- package/options.d.mts.map +1 -1
- package/options.d.ts +3 -0
- package/options.d.ts.map +1 -1
- package/options.js +19 -0
- package/options.js.map +1 -1
- package/options.mjs +19 -0
- package/options.mjs.map +1 -1
- package/package.json +13 -2
- package/server.d.mts +9 -1
- package/server.d.mts.map +1 -1
- package/server.d.ts +9 -1
- package/server.d.ts.map +1 -1
- package/server.js +12 -3
- package/server.js.map +1 -1
- package/server.mjs +12 -3
- package/server.mjs.map +1 -1
- package/src/code-tool-worker.ts +10 -2
- package/src/docs-search-tool.ts +46 -8
- package/src/http.ts +27 -1
- package/src/instructions.ts +27 -4
- package/src/local-docs-search.ts +1096 -0
- package/src/options.ts +24 -0
- package/src/server.ts +21 -3
- package/src/stdio.ts +4 -1
- package/src/types.ts +2 -0
- package/stdio.d.mts.map +1 -1
- package/stdio.d.ts.map +1 -1
- package/stdio.js +4 -1
- package/stdio.js.map +1 -1
- package/stdio.mjs +4 -1
- package/stdio.mjs.map +1 -1
- package/types.d.mts +5 -0
- package/types.d.mts.map +1 -1
- package/types.d.ts +5 -0
- package/types.d.ts.map +1 -1
- package/types.js.map +1 -1
- package/types.mjs.map +1 -1
package/src/http.ts
CHANGED
|
@@ -23,7 +23,8 @@ const newServer = async ({
|
|
|
23
23
|
res: express.Response;
|
|
24
24
|
}): Promise<McpServer | null> => {
|
|
25
25
|
const stainlessApiKey = getStainlessApiKey(req, mcpOptions);
|
|
26
|
-
const
|
|
26
|
+
const customInstructionsPath = mcpOptions.customInstructionsPath;
|
|
27
|
+
const server = await newMcpServer({ stainlessApiKey, customInstructionsPath });
|
|
27
28
|
|
|
28
29
|
const authOptions = parseClientAuthHeaders(req, false);
|
|
29
30
|
|
|
@@ -68,6 +69,11 @@ const newServer = async ({
|
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
const mcpClientInfo =
|
|
73
|
+
typeof req.body?.params?.clientInfo?.name === 'string' ?
|
|
74
|
+
{ name: req.body.params.clientInfo.name, version: String(req.body.params.clientInfo.version ?? '') }
|
|
75
|
+
: undefined;
|
|
76
|
+
|
|
71
77
|
await initMcpServer({
|
|
72
78
|
server: server,
|
|
73
79
|
mcpOptions: effectiveMcpOptions,
|
|
@@ -77,8 +83,14 @@ const newServer = async ({
|
|
|
77
83
|
},
|
|
78
84
|
stainlessApiKey: stainlessApiKey,
|
|
79
85
|
upstreamClientEnvs,
|
|
86
|
+
mcpSessionId: (req as any).mcpSessionId,
|
|
87
|
+
mcpClientInfo,
|
|
80
88
|
});
|
|
81
89
|
|
|
90
|
+
if (mcpClientInfo) {
|
|
91
|
+
getLogger().info({ mcpSessionId: (req as any).mcpSessionId, mcpClientInfo }, 'MCP client connected');
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
return server;
|
|
83
95
|
};
|
|
84
96
|
|
|
@@ -134,9 +146,23 @@ export const streamableHTTPApp = ({
|
|
|
134
146
|
const app = express();
|
|
135
147
|
app.set('query parser', 'extended');
|
|
136
148
|
app.use(express.json());
|
|
149
|
+
app.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
150
|
+
const existing = req.headers['mcp-session-id'];
|
|
151
|
+
const sessionId = (Array.isArray(existing) ? existing[0] : existing) || crypto.randomUUID();
|
|
152
|
+
(req as any).mcpSessionId = sessionId;
|
|
153
|
+
const origWriteHead = res.writeHead.bind(res);
|
|
154
|
+
res.writeHead = function (statusCode: number, ...rest: any[]) {
|
|
155
|
+
res.setHeader('mcp-session-id', sessionId);
|
|
156
|
+
return origWriteHead(statusCode, ...rest);
|
|
157
|
+
} as typeof res.writeHead;
|
|
158
|
+
next();
|
|
159
|
+
});
|
|
137
160
|
app.use(
|
|
138
161
|
pinoHttp({
|
|
139
162
|
logger: getLogger(),
|
|
163
|
+
customProps: (req) => ({
|
|
164
|
+
mcpSessionId: (req as any).mcpSessionId,
|
|
165
|
+
}),
|
|
140
166
|
customLogLevel: (req, res) => {
|
|
141
167
|
if (res.statusCode >= 500) {
|
|
142
168
|
return 'error';
|
package/src/instructions.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
+
import fs from 'fs/promises';
|
|
3
4
|
import { readEnv } from './util';
|
|
4
5
|
import { getLogger } from './logger';
|
|
5
6
|
|
|
@@ -12,9 +13,15 @@ interface InstructionsCacheEntry {
|
|
|
12
13
|
|
|
13
14
|
const instructionsCache = new Map<string, InstructionsCacheEntry>();
|
|
14
15
|
|
|
15
|
-
export async function getInstructions(
|
|
16
|
+
export async function getInstructions({
|
|
17
|
+
stainlessApiKey,
|
|
18
|
+
customInstructionsPath,
|
|
19
|
+
}: {
|
|
20
|
+
stainlessApiKey?: string | undefined;
|
|
21
|
+
customInstructionsPath?: string | undefined;
|
|
22
|
+
}): Promise<string> {
|
|
16
23
|
const now = Date.now();
|
|
17
|
-
const cacheKey = stainlessApiKey ?? '';
|
|
24
|
+
const cacheKey = customInstructionsPath ?? stainlessApiKey ?? '';
|
|
18
25
|
const cached = instructionsCache.get(cacheKey);
|
|
19
26
|
|
|
20
27
|
if (cached && now - cached.fetchedAt <= INSTRUCTIONS_CACHE_TTL_MS) {
|
|
@@ -28,12 +35,28 @@ export async function getInstructions(stainlessApiKey: string | undefined): Prom
|
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
let fetchedInstructions: string;
|
|
39
|
+
|
|
40
|
+
if (customInstructionsPath) {
|
|
41
|
+
fetchedInstructions = await fetchLatestInstructionsFromFile(customInstructionsPath);
|
|
42
|
+
} else {
|
|
43
|
+
fetchedInstructions = await fetchLatestInstructionsFromApi(stainlessApiKey);
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
instructionsCache.set(cacheKey, { fetchedInstructions, fetchedAt: now });
|
|
33
47
|
return fetchedInstructions;
|
|
34
48
|
}
|
|
35
49
|
|
|
36
|
-
async function
|
|
50
|
+
async function fetchLatestInstructionsFromFile(path: string): Promise<string> {
|
|
51
|
+
try {
|
|
52
|
+
return await fs.readFile(path, 'utf-8');
|
|
53
|
+
} catch (error) {
|
|
54
|
+
getLogger().error({ error, path }, 'Error fetching instructions from file');
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function fetchLatestInstructionsFromApi(stainlessApiKey: string | undefined): Promise<string> {
|
|
37
60
|
// Setting the stainless API key is optional, but may be required
|
|
38
61
|
// to authenticate requests to the Stainless API.
|
|
39
62
|
const response = await fetch(
|