Skip to content

Commit 17dd04e

Browse files
authored
Merge pull request #9 from context-dot-dev/release-please--branches--main--changes--next--components--context.dev
release: 1.2.0
2 parents 646e717 + cb42e6d commit 17dd04e

16 files changed

Lines changed: 937 additions & 306 deletions

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.1.0"
2+
".": "1.2.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 20
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev%2Fcontext.dev-2ddb6d73ec8831eee4cb4352b85843a1f6f444e48d8be837cfcd118eddd2a63e.yml
3-
openapi_spec_hash: 1163122fba27e56fa5879bc98d32ee14
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev%2Fcontext.dev-56a21db16ac3a797f86daca01a2ea115a0365db4b2f9d8accdec4f4d3ee2eb83.yml
3+
openapi_spec_hash: bfcef090896da96023c4485a3d69e350
44
config_hash: 38268bb88fc4dcbb8f2f94dd138b5910

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## 1.2.0 (2026-04-03)
4+
5+
Full Changelog: [v1.1.0...v1.2.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v1.1.0...v1.2.0)
6+
7+
### Features
8+
9+
* **api:** api update ([c931051](https://github.com/context-dot-dev/context-typescript-sdk/commit/c931051a1454a44794d666b7a2695d2683cacc09))
10+
11+
12+
### Chores
13+
14+
* **internal:** fix MCP docker image builds in yarn projects ([d7023c7](https://github.com/context-dot-dev/context-typescript-sdk/commit/d7023c786b668d3afc62d151698bd05d0ab35f56))
15+
* **internal:** improve local docs search for MCP servers ([2a5884c](https://github.com/context-dot-dev/context-typescript-sdk/commit/2a5884cf913182d4cb05e5cc3a9a86f9a74aea47))
16+
* **internal:** improve local docs search for MCP servers ([6c0fe3f](https://github.com/context-dot-dev/context-typescript-sdk/commit/6c0fe3fb873609517518ce1b0b5d5a9c1a788d62))
17+
* **internal:** support type annotations when running MCP in local execution mode ([1b6f120](https://github.com/context-dot-dev/context-typescript-sdk/commit/1b6f1206b80413ac77ab7be9b471525323cb3efc))
18+
* **internal:** use link instead of file in MCP server package.json files ([dbabdac](https://github.com/context-dot-dev/context-typescript-sdk/commit/dbabdac818620983c0d464313aea3f8efa854772))
19+
* **mcp-server:** add support for session id, forward client info ([bb8cffe](https://github.com/context-dot-dev/context-typescript-sdk/commit/bb8cffe6ec501635c5c90206e2578f626ae11949))
20+
* **mcp-server:** log client info ([ae415f7](https://github.com/context-dot-dev/context-typescript-sdk/commit/ae415f745c8e24bc82b42ade8be3b5d43925422f))
21+
322
## 1.1.0 (2026-03-28)
423

524
Full Changelog: [v1.0.1...v1.1.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v1.0.1...v1.1.0)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "context.dev",
3-
"version": "1.1.0",
3+
"version": "1.2.0",
44
"description": "The official TypeScript library for the Context Dev API",
55
"author": "Context Dev <hello@context.dev>",
66
"types": "dist/index.d.ts",

packages/mcp-server/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ COPY . .
3535

3636
# Install all dependencies and build everything
3737
RUN yarn install --frozen-lockfile && \
38-
yarn build
38+
yarn build && \
39+
# Remove the symlink to the SDK so it doesn't interfere with the explicit COPY below
40+
rm -Rf packages/mcp-server/node_modules/context.dev
3941

4042
FROM denoland/deno:alpine-2.7.1
4143

packages/mcp-server/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"dxt_version": "0.2",
33
"name": "context.dev-mcp",
4-
"version": "1.1.0",
4+
"version": "1.2.0",
55
"description": "The official MCP Server for the Context Dev API",
66
"author": {
77
"name": "Context Dev",

packages/mcp-server/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "context.dev-mcp",
3-
"version": "1.1.0",
3+
"version": "1.2.0",
44
"description": "The official MCP Server for the Context Dev API",
55
"author": "Context Dev <hello@context.dev>",
66
"types": "dist/index.d.ts",
@@ -30,7 +30,7 @@
3030
"fix": "eslint --fix ."
3131
},
3232
"dependencies": {
33-
"context.dev": "file:../../dist/",
33+
"context.dev": "link:../../dist/",
3434
"ajv": "^8.18.0",
3535
"@cloudflare/cabidela": "^0.2.4",
3636
"@hono/node-server": "^1.19.10",

packages/mcp-server/src/code-tool-worker.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import ts from 'typescript';
77
import { WorkerOutput } from './code-tool-types';
88
import { ContextDev, ClientOptions } from 'context.dev';
99

10+
async function tseval(code: string) {
11+
return import('data:application/typescript;charset=utf-8;base64,' + Buffer.from(code).toString('base64'));
12+
}
13+
1014
function getRunFunctionSource(code: string): {
1115
type: 'declaration' | 'expression';
1216
client: string | undefined;
@@ -256,7 +260,9 @@ const fetch = async (req: Request): Promise<Response> => {
256260

257261
const log_lines: string[] = [];
258262
const err_lines: string[] = [];
259-
const console = {
263+
const originalConsole = globalThis.console;
264+
globalThis.console = {
265+
...originalConsole,
260266
log: (...args: unknown[]) => {
261267
log_lines.push(util.format(...args));
262268
},
@@ -266,7 +272,7 @@ const fetch = async (req: Request): Promise<Response> => {
266272
};
267273
try {
268274
let run_ = async (client: any) => {};
269-
eval(`${code}\nrun_ = run;`);
275+
run_ = (await tseval(`${code}\nexport default run;`)).default;
270276
const result = await run_(makeSdkProxy(client, { path: ['client'] }));
271277
return Response.json({
272278
is_error: false,
@@ -284,6 +290,8 @@ const fetch = async (req: Request): Promise<Response> => {
284290
} satisfies WorkerOutput,
285291
{ status: 400, statusText: 'Code execution error' },
286292
);
293+
} finally {
294+
globalThis.console = originalConsole;
287295
}
288296
};
289297

packages/mcp-server/src/docs-search-tool.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,43 +50,35 @@ export function setLocalSearch(search: LocalDocsSearch): void {
5050
_localSearch = search;
5151
}
5252

53-
const SUPPORTED_LANGUAGES = new Set(['http', 'typescript', 'javascript']);
54-
5553
async function searchLocal(args: Record<string, unknown>): Promise<unknown> {
5654
if (!_localSearch) {
5755
throw new Error('Local search not initialized');
5856
}
5957

6058
const query = (args['query'] as string) ?? '';
6159
const language = (args['language'] as string) ?? 'typescript';
62-
const detail = (args['detail'] as string) ?? 'verbose';
63-
64-
if (!SUPPORTED_LANGUAGES.has(language)) {
65-
throw new Error(
66-
`Local docs search only supports HTTP, TypeScript, and JavaScript. Got language="${language}". ` +
67-
`Use --docs-search-mode stainless-api for other languages, or set language to "http", "typescript", or "javascript".`,
68-
);
69-
}
60+
const detail = (args['detail'] as string) ?? 'default';
7061

7162
return _localSearch.search({
7263
query,
7364
language,
7465
detail,
75-
maxResults: 10,
66+
maxResults: 5,
7667
}).results;
7768
}
7869

79-
async function searchRemote(
80-
args: Record<string, unknown>,
81-
stainlessApiKey: string | undefined,
82-
): Promise<unknown> {
70+
async function searchRemote(args: Record<string, unknown>, reqContext: McpRequestContext): Promise<unknown> {
8371
const body = args as any;
8472
const query = new URLSearchParams(body).toString();
8573

8674
const startTime = Date.now();
8775
const result = await fetch(`${docsSearchURL}?${query}`, {
8876
headers: {
89-
...(stainlessApiKey && { Authorization: stainlessApiKey }),
77+
...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }),
78+
...(reqContext.mcpSessionId && { 'x-stainless-mcp-session-id': reqContext.mcpSessionId }),
79+
...(reqContext.mcpClientInfo && {
80+
'x-stainless-mcp-client-info': JSON.stringify(reqContext.mcpClientInfo),
81+
}),
9082
},
9183
});
9284

@@ -105,7 +97,7 @@ async function searchRemote(
10597
'Got error response from docs search tool',
10698
);
10799

108-
if (result.status === 404 && !stainlessApiKey) {
100+
if (result.status === 404 && !reqContext.stainlessApiKey) {
109101
throw new Error(
110102
'Could not find docs for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.',
111103
);
@@ -140,7 +132,7 @@ export const handler = async ({
140132
return asTextContentResult(await searchLocal(body));
141133
}
142134

143-
return asTextContentResult(await searchRemote(body, reqContext.stainlessApiKey));
135+
return asTextContentResult(await searchRemote(body, reqContext));
144136
};
145137

146138
export default { metadata, tool, handler };

packages/mcp-server/src/http.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ const newServer = async ({
6969
}
7070
}
7171

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+
7277
await initMcpServer({
7378
server: server,
7479
mcpOptions: effectiveMcpOptions,
@@ -78,8 +83,14 @@ const newServer = async ({
7883
},
7984
stainlessApiKey: stainlessApiKey,
8085
upstreamClientEnvs,
86+
mcpSessionId: (req as any).mcpSessionId,
87+
mcpClientInfo,
8188
});
8289

90+
if (mcpClientInfo) {
91+
getLogger().info({ mcpSessionId: (req as any).mcpSessionId, mcpClientInfo }, 'MCP client connected');
92+
}
93+
8394
return server;
8495
};
8596

@@ -135,9 +146,23 @@ export const streamableHTTPApp = ({
135146
const app = express();
136147
app.set('query parser', 'extended');
137148
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+
});
138160
app.use(
139161
pinoHttp({
140162
logger: getLogger(),
163+
customProps: (req) => ({
164+
mcpSessionId: (req as any).mcpSessionId,
165+
}),
141166
customLogLevel: (req, res) => {
142167
if (res.statusCode >= 500) {
143168
return 'error';

0 commit comments

Comments
 (0)