Skip to content

Commit a411993

Browse files
authored
Merge pull request #66 from isaacus-dev/release-please--branches--main--changes--next--components--isaacus
release: 0.22.2
2 parents 2c3d0a1 + d4a8abb commit a411993

23 files changed

Lines changed: 265 additions & 61 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-
".": "0.22.1"
2+
".": "0.22.2"
33
}

CHANGELOG.md

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

3+
## 0.22.2 (2026-04-13)
4+
5+
Full Changelog: [v0.22.1...v0.22.2](https://github.com/isaacus-dev/isaacus-typescript/compare/v0.22.1...v0.22.2)
6+
7+
### Chores
8+
9+
* **internal:** codegen related update ([cd5ec86](https://github.com/isaacus-dev/isaacus-typescript/commit/cd5ec86a820fbac4520158b5fae003a6599fefc0))
10+
* **internal:** codegen related update ([e862e90](https://github.com/isaacus-dev/isaacus-typescript/commit/e862e90b1f033b392912960f942d40fc383ce105))
11+
* **internal:** fix MCP docker image builds in yarn projects ([1bae689](https://github.com/isaacus-dev/isaacus-typescript/commit/1bae68900a33b2493aab475da4ab3b2b29df7107))
12+
* **internal:** fix MCP server import ordering ([f6e97bb](https://github.com/isaacus-dev/isaacus-typescript/commit/f6e97bbf7d651a7de7144059598e81bd625fb592))
13+
* **internal:** improve local docs search for MCP servers ([a75ecde](https://github.com/isaacus-dev/isaacus-typescript/commit/a75ecdeaa324f978296b0bff15dd1cb025826cea))
14+
* **internal:** improve local docs search for MCP servers ([04d3e6d](https://github.com/isaacus-dev/isaacus-typescript/commit/04d3e6d50fb40450008b888f47c0337a964bee83))
15+
* **internal:** show error causes in MCP servers when running in local mode ([fa77f22](https://github.com/isaacus-dev/isaacus-typescript/commit/fa77f220e93b435a3b7ad0ad37b9f5158e4e7bba))
16+
* **internal:** support type annotations when running MCP in local execution mode ([54d9001](https://github.com/isaacus-dev/isaacus-typescript/commit/54d90010c7f02e93aebbbb0d577d47f8557f5933))
17+
* **internal:** use link instead of file in MCP server package.json files ([670add9](https://github.com/isaacus-dev/isaacus-typescript/commit/670add93de484bd49d49dcd03c3d5bc3581d2021))
18+
* **mcp-server:** add support for session id, forward client info ([113e23c](https://github.com/isaacus-dev/isaacus-typescript/commit/113e23c3565fd8f4c39dc54e5ccb77216b3230f5))
19+
* **mcp-server:** increase local docs search result count from 5 to 10 ([2e69ea0](https://github.com/isaacus-dev/isaacus-typescript/commit/2e69ea055862bde72ba63d47eb769a9a7750e079))
20+
* **mcp-server:** log client info ([823adba](https://github.com/isaacus-dev/isaacus-typescript/commit/823adbac413f484a67e00354e5284e89479b71da))
21+
22+
23+
### Documentation
24+
25+
* update examples ([e668eb8](https://github.com/isaacus-dev/isaacus-typescript/commit/e668eb823f4bcd59c96bc62a232f1d608a7ff9f3))
26+
327
## 0.22.1 (2026-03-28)
428

529
Full Changelog: [v0.22.0...v0.22.1](https://github.com/isaacus-dev/isaacus-typescript/compare/v0.22.0...v0.22.1)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "isaacus",
3-
"version": "0.22.1",
3+
"version": "0.22.2",
44
"description": "The official TypeScript library for the Isaacus API",
55
"author": "Isaacus <support@isaacus.com>",
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/isaacus
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": "isaacus-mcp",
4-
"version": "0.22.1",
4+
"version": "0.22.2",
55
"description": "The official MCP Server for the Isaacus API",
66
"author": {
77
"name": "Isaacus",

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": "isaacus-mcp",
3-
"version": "0.22.1",
3+
"version": "0.22.2",
44
"description": "The official MCP Server for the Isaacus API",
55
"author": "Isaacus <support@isaacus.com>",
66
"types": "dist/index.d.ts",
@@ -30,7 +30,7 @@
3030
"fix": "eslint --fix ."
3131
},
3232
"dependencies": {
33-
"isaacus": "file:../../dist/",
33+
"isaacus": "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: 12 additions & 3 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 { Isaacus, ClientOptions } from 'isaacus';
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;
@@ -185,7 +189,8 @@ function makeSdkProxy<T extends object>(obj: T, { path, isBelievedBad = false }:
185189

186190
function parseError(code: string, error: unknown): string | undefined {
187191
if (!(error instanceof Error)) return;
188-
const message = error.name ? `${error.name}: ${error.message}` : error.message;
192+
const cause = error.cause instanceof Error ? `: ${error.cause.message}` : '';
193+
const message = error.name ? `${error.name}: ${error.message}${cause}` : `${error.message}${cause}`;
189194
try {
190195
// Deno uses V8; the first "<anonymous>:LINE:COLUMN" is the top of stack.
191196
const lineNumber = error.stack?.match(/<anonymous>:([0-9]+):[0-9]+/)?.[1];
@@ -241,7 +246,9 @@ const fetch = async (req: Request): Promise<Response> => {
241246

242247
const log_lines: string[] = [];
243248
const err_lines: string[] = [];
244-
const console = {
249+
const originalConsole = globalThis.console;
250+
globalThis.console = {
251+
...originalConsole,
245252
log: (...args: unknown[]) => {
246253
log_lines.push(util.format(...args));
247254
},
@@ -251,7 +258,7 @@ const fetch = async (req: Request): Promise<Response> => {
251258
};
252259
try {
253260
let run_ = async (client: any) => {};
254-
eval(`${code}\nrun_ = run;`);
261+
run_ = (await tseval(`${code}\nexport default run;`)).default;
255262
const result = await run_(makeSdkProxy(client, { path: ['client'] }));
256263
return Response.json({
257264
is_error: false,
@@ -269,6 +276,8 @@ const fetch = async (req: Request): Promise<Response> => {
269276
} satisfies WorkerOutput,
270277
{ status: 400, statusText: 'Code execution error' },
271278
);
279+
} finally {
280+
globalThis.console = originalConsole;
272281
}
273282
};
274283

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

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,14 @@ 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,
@@ -76,17 +67,18 @@ async function searchLocal(args: Record<string, unknown>): Promise<unknown> {
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';

packages/mcp-server/src/instructions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
import fs from 'fs/promises';
4-
import { readEnv } from './util';
54
import { getLogger } from './logger';
5+
import { readEnv } from './util';
66

77
const INSTRUCTIONS_CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes
88

0 commit comments

Comments
 (0)