Skip to content

Commit f8d21bb

Browse files
authored
Merge pull request #32 from stainless-api/release-please--branches--main--changes--next--components--sdk
release: 0.2.0
2 parents 9bf0b1c + dd2618e commit f8d21bb

22 files changed

+181
-134
lines changed

.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.1.0"
2+
".": "0.2.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 22
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-bced6b6177fa276293bb8c54df90e10340f1b5dd92189225c53551d3952c091a.yml
3-
openapi_spec_hash: ad0459eb77d77055a261721e087ed5da
4-
config_hash: c3e64d6d69fcc4fb22a312bc13bcb67a
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-c05bce23f6a3478a1803494b2c627e0bbf73917a849756eddc42f4607e167c6b.yml
3+
openapi_spec_hash: b9eb999620220d15b176f815f21a67ba
4+
config_hash: 977c436868252591d86546b2127ab8ce

CHANGELOG.md

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

3+
## 0.2.0 (2026-02-20)
4+
5+
Full Changelog: [v0.1.0...v0.2.0](https://github.com/stainless-api/stainless-api-typescript/compare/v0.1.0...v0.2.0)
6+
7+
### Features
8+
9+
* **api:** manual updates ([79e1b0f](https://github.com/stainless-api/stainless-api-typescript/commit/79e1b0f2cdc37955766d09304b51017ed6dde8d7))
10+
* **api:** populate integrated_stats ([d197453](https://github.com/stainless-api/stainless-api-typescript/commit/d197453190c3f44ad746e7b3f83c6060d59e2dbb))
11+
12+
13+
### Bug Fixes
14+
15+
* **mcp:** initialize SDK lazily to avoid failing the connection on init errors ([f07516c](https://github.com/stainless-api/stainless-api-typescript/commit/f07516c5bc6719099b64f2a4ef693377d87b8ddc))
16+
17+
18+
### Chores
19+
20+
* **internal:** remove mock server code ([47f0521](https://github.com/stainless-api/stainless-api-typescript/commit/47f0521a21a0e3ae9bcd690e1c4802153d21dc55))
21+
* **mcp:** correctly update version in sync with sdk ([c5227ab](https://github.com/stainless-api/stainless-api-typescript/commit/c5227abb38834153889b213c0e666bb06ffd6464))
22+
* update mock server docs ([39315f6](https://github.com/stainless-api/stainless-api-typescript/commit/39315f6bc3defb8d426178475222568c9d79c138))
23+
324
## 0.1.0 (2026-02-19)
425

526
Full Changelog: [v0.1.0-alpha.27...v0.1.0](https://github.com/stainless-api/stainless-api-typescript/compare/v0.1.0-alpha.27...v0.1.0)

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ $ pnpm link -—global @stainless-api/sdk
6868
Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
6969

7070
```sh
71-
$ npx prism mock path/to/your/openapi.yml
71+
$ ./scripts/mock
7272
```
7373

7474
```sh

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stainless-api/sdk",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "The official TypeScript library for the Stainless API",
55
"author": "Stainless <support@stainless.com>",
66
"types": "dist/index.d.ts",

packages/mcp-server/manifest.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"dxt_version": "0.2",
33
"name": "@stainless-api/mcp",
4-
"version": "0.1.0-alpha.11",
4+
"version": "0.2.0",
55
"description": "The official MCP Server for the Stainless API",
66
"author": {
77
"name": "Stainless",
@@ -18,7 +18,9 @@
1818
"entry_point": "index.js",
1919
"mcp_config": {
2020
"command": "node",
21-
"args": ["${__dirname}/index.js"],
21+
"args": [
22+
"${__dirname}/index.js"
23+
],
2224
"env": {
2325
"STAINLESS_API_KEY": "${user_config.STAINLESS_API_KEY}",
2426
"STAINLESS_PROJECT": "${user_config.STAINLESS_PROJECT}"
@@ -46,5 +48,7 @@
4648
"node": ">=18.0.0"
4749
}
4850
},
49-
"keywords": ["api"]
51+
"keywords": [
52+
"api"
53+
]
5054
}

packages/mcp-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stainless-api/mcp",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "The official MCP Server for the Stainless API",
55
"author": "Stainless <support@stainless.com>",
66
"types": "dist/index.d.ts",

packages/mcp-server/src/http.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,17 @@ const newServer = async ({
2424
const stainlessApiKey = getStainlessApiKey(req, mcpOptions);
2525
const server = await newMcpServer(stainlessApiKey);
2626

27-
try {
28-
const authOptions = parseClientAuthHeaders(req, false);
27+
const authOptions = parseClientAuthHeaders(req, false);
2928

30-
await initMcpServer({
31-
server: server,
32-
mcpOptions: mcpOptions,
33-
clientOptions: {
34-
...clientOptions,
35-
...authOptions,
36-
},
37-
stainlessApiKey: stainlessApiKey,
38-
});
39-
} catch (error) {
40-
res.status(401).json({
41-
jsonrpc: '2.0',
42-
error: {
43-
code: -32000,
44-
message: `Unauthorized: ${error instanceof Error ? error.message : error}`,
45-
},
46-
});
47-
return null;
48-
}
29+
await initMcpServer({
30+
server: server,
31+
mcpOptions: mcpOptions,
32+
clientOptions: {
33+
...clientOptions,
34+
...authOptions,
35+
},
36+
stainlessApiKey: stainlessApiKey,
37+
});
4938

5039
return server;
5140
};

packages/mcp-server/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async function main() {
2424
await launchStreamableHTTPServer({
2525
mcpOptions: options,
2626
debug: options.debug,
27-
port: options.port ?? options.socket,
27+
port: options.socket ?? options.port,
2828
});
2929
break;
3030
}

packages/mcp-server/src/server.ts

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const newMcpServer = async (stainlessApiKey: string | undefined) =>
2121
new McpServer(
2222
{
2323
name: 'stainless_api_sdk_api',
24-
version: '0.1.0',
24+
version: '0.2.0',
2525
},
2626
{
2727
instructions: await getInstructions(stainlessApiKey),
@@ -56,18 +56,36 @@ export async function initMcpServer(params: {
5656
error: logAtLevel('error'),
5757
};
5858

59-
let client = new Stainless({
60-
...{
61-
project: readEnv('STAINLESS_PROJECT'),
62-
environment: (readEnv('STAINLESS_ENVIRONMENT') || undefined) as any,
63-
},
64-
logger,
65-
...params.clientOptions,
66-
defaultHeaders: {
67-
...params.clientOptions?.defaultHeaders,
68-
'X-Stainless-MCP': 'true',
69-
},
70-
});
59+
let _client: Stainless | undefined;
60+
let _clientError: Error | undefined;
61+
let _logLevel: 'debug' | 'info' | 'warn' | 'error' | 'off' | undefined;
62+
63+
const getClient = (): Stainless => {
64+
if (_clientError) throw _clientError;
65+
if (!_client) {
66+
try {
67+
_client = new Stainless({
68+
...{
69+
project: readEnv('STAINLESS_PROJECT'),
70+
environment: (readEnv('STAINLESS_ENVIRONMENT') || undefined) as any,
71+
},
72+
logger,
73+
...params.clientOptions,
74+
defaultHeaders: {
75+
...params.clientOptions?.defaultHeaders,
76+
'X-Stainless-MCP': 'true',
77+
},
78+
});
79+
if (_logLevel) {
80+
_client = _client.withOptions({ logLevel: _logLevel });
81+
}
82+
} catch (e) {
83+
_clientError = e instanceof Error ? e : new Error(String(e));
84+
throw _clientError;
85+
}
86+
}
87+
return _client;
88+
};
7189

7290
const providedTools = selectTools(params.mcpOptions);
7391
const toolMap = Object.fromEntries(providedTools.map((mcpTool) => [mcpTool.tool.name, mcpTool]));
@@ -85,6 +103,21 @@ export async function initMcpServer(params: {
85103
throw new Error(`Unknown tool: ${name}`);
86104
}
87105

106+
let client: Stainless;
107+
try {
108+
client = getClient();
109+
} catch (error) {
110+
return {
111+
content: [
112+
{
113+
type: 'text' as const,
114+
text: `Failed to initialize client: ${error instanceof Error ? error.message : String(error)}`,
115+
},
116+
],
117+
isError: true,
118+
};
119+
}
120+
88121
return executeHandler({
89122
handler: mcpTool.handler,
90123
reqContext: {
@@ -97,24 +130,29 @@ export async function initMcpServer(params: {
97130

98131
server.setRequestHandler(SetLevelRequestSchema, async (request) => {
99132
const { level } = request.params;
133+
let logLevel: 'debug' | 'info' | 'warn' | 'error' | 'off';
100134
switch (level) {
101135
case 'debug':
102-
client = client.withOptions({ logLevel: 'debug' });
136+
logLevel = 'debug';
103137
break;
104138
case 'info':
105-
client = client.withOptions({ logLevel: 'info' });
139+
logLevel = 'info';
106140
break;
107141
case 'notice':
108142
case 'warning':
109-
client = client.withOptions({ logLevel: 'warn' });
143+
logLevel = 'warn';
110144
break;
111145
case 'error':
112-
client = client.withOptions({ logLevel: 'error' });
146+
logLevel = 'error';
113147
break;
114148
default:
115-
client = client.withOptions({ logLevel: 'off' });
149+
logLevel = 'off';
116150
break;
117151
}
152+
_logLevel = logLevel;
153+
if (_client) {
154+
_client = _client.withOptions({ logLevel });
155+
}
118156
return {};
119157
});
120158
}

0 commit comments

Comments
 (0)