Skip to content

Commit 13b6086

Browse files
release: 12.8.0 (#612)
* feat(mcp): expose client options in `streamableHTTPApp` * fix(mcp): avoid importing unsupported libraries on non-node environments * feat(mcp): allow setting logging level * chore: add server.json to publish to Github's MCP registry (#613) * chore: add server.json to publish to Github's MCP registry * reference mcp registry name in package.json and preemptively bump version in server.json * newline on server.json * release: 12.8.0 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: Justin Sanford <[email protected]>
1 parent 01d6535 commit 13b6086

File tree

10 files changed

+143
-42
lines changed

10 files changed

+143
-42
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-
".": "12.7.0"
2+
".": "12.8.0"
33
}

CHANGELOG.md

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

3+
## 12.8.0 (2025-09-18)
4+
5+
Full Changelog: [v12.7.0...v12.8.0](https://github.com/muxinc/mux-node-sdk/compare/v12.7.0...v12.8.0)
6+
7+
### Features
8+
9+
* **mcp:** allow setting logging level ([cf8ef79](https://github.com/muxinc/mux-node-sdk/commit/cf8ef795cd13ac0505f84f87dcc98698c26d6e5b))
10+
* **mcp:** expose client options in `streamableHTTPApp` ([2321073](https://github.com/muxinc/mux-node-sdk/commit/23210734b3ea348d6d8e18fa43e050928a743912))
11+
12+
13+
### Bug Fixes
14+
15+
* **mcp:** avoid importing unsupported libraries on non-node environments ([6e3db76](https://github.com/muxinc/mux-node-sdk/commit/6e3db76730719347ad239075c7293a989d8571d5))
16+
17+
18+
### Chores
19+
20+
* add server.json to publish to Github's MCP registry ([#613](https://github.com/muxinc/mux-node-sdk/issues/613)) ([fd07791](https://github.com/muxinc/mux-node-sdk/commit/fd0779160400d828c16c1dca6f0db1eb30c06e69))
21+
322
## 12.7.0 (2025-08-27)
423

524
Full Changelog: [v12.6.1...v12.7.0](https://github.com/muxinc/mux-node-sdk/compare/v12.6.1...v12.7.0)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mux/mux-node",
3-
"version": "12.7.0",
3+
"version": "12.8.0",
44
"description": "The official TypeScript library for the Mux API",
55
"author": "Mux <[email protected]>",
66
"types": "dist/index.d.ts",

packages/mcp-server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mux/mcp",
3-
"version": "12.7.0",
3+
"version": "12.8.0",
44
"description": "The official MCP Server for the Mux API",
55
"author": "Mux <[email protected]>",
66
"types": "dist/index.d.ts",
@@ -14,6 +14,7 @@
1414
"homepage": "https://github.com/muxinc/mux-node-sdk/tree/main/packages/mcp-server#readme",
1515
"license": "Apache-2.0",
1616
"packageManager": "[email protected]",
17+
"mcpName": "com.mux/mcp",
1718
"private": false,
1819
"publishConfig": {
1920
"access": "public"

packages/mcp-server/server.json

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
3+
"name": "com.mux/mcp",
4+
"description": "The official MCP Server for the Mux API",
5+
"status": "active",
6+
"repository": {
7+
"url": "https://github.com/muxinc/mux-node-sdk",
8+
"source": "github",
9+
"subfolder": "packages/mcp-server"
10+
},
11+
"version": "12.8.0",
12+
"packages": [
13+
{
14+
"registry_type": "npm",
15+
"registry_base_url": "https://registry.npmjs.org",
16+
"identifier": "@mux/mcp",
17+
"version": "12.8.0",
18+
"transport": {
19+
"type": "stdio"
20+
},
21+
"environment_variables": [
22+
{
23+
"description": "Your Mux access token ID",
24+
"is_required": true,
25+
"format": "string",
26+
"is_secret": true,
27+
"name": "MUX_TOKEN_ID"
28+
},
29+
{
30+
"description": "Your Mux access token secret",
31+
"is_required": true,
32+
"format": "string",
33+
"is_secret": true,
34+
"name": "MUX_TOKEN_SECRET"
35+
},
36+
{
37+
"description": "Your JWT signing key ID, for use with signed playback IDs",
38+
"is_required": false,
39+
"format": "string",
40+
"is_secret": true,
41+
"name": "MUX_SIGNING_KEY"
42+
},
43+
{
44+
"description": "Your JWT private key, for use with signed playback IDs",
45+
"is_required": false,
46+
"format": "string",
47+
"is_secret": true,
48+
"name": "MUX_PRIVATE_KEY"
49+
}
50+
]
51+
}
52+
],
53+
"remotes": [
54+
{
55+
"type": "streamable-http",
56+
"url": "https://mcp.mux.com",
57+
"headers": [
58+
{
59+
"name": "Authorization",
60+
"description": "Optional basic authorization header you can include, combining your Access Token and Secret using HTTP Basic Auth. If not provided, authorization will be handled via OAuth.",
61+
"is_required": false,
62+
"is_secret": true
63+
}
64+
]
65+
}
66+
]
67+
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import { Endpoint, ContentBlock, Metadata } from './tools/types';
77

88
import { Tool } from '@modelcontextprotocol/sdk/types.js';
99

10-
import { newDenoHTTPWorker } from '@valtown/deno-http-worker';
1110
import { WorkerInput, WorkerError, WorkerSuccess } from './code-tool-types';
12-
import { workerPath } from './code-tool-paths.cjs';
1311

1412
/**
1513
* A tool that runs code against a copy of the SDK.
@@ -20,7 +18,7 @@ import { workerPath } from './code-tool-paths.cjs';
2018
*
2119
* @param endpoints - The endpoints to include in the list.
2220
*/
23-
export function codeTool(): Endpoint {
21+
export async function codeTool(): Promise<Endpoint> {
2422
const metadata: Metadata = { resource: 'all', operation: 'write', tags: [] };
2523
const tool: Tool = {
2624
name: 'execute',
@@ -29,6 +27,10 @@ export function codeTool(): Endpoint {
2927
inputSchema: { type: 'object', properties: { code: { type: 'string' } } },
3028
};
3129

30+
// Import dynamically to avoid failing at import time in cases where the environment is not well-supported.
31+
const { newDenoHTTPWorker } = await import('@valtown/deno-http-worker');
32+
const { workerPath } = await import('./code-tool-paths.cjs');
33+
3234
const handler = async (client: Mux, args: unknown) => {
3335
const baseURLHostname = new URL(client.baseURL).hostname;
3436
const { code } = args as { code: string };

packages/mcp-server/src/http.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,25 @@ import cors from 'cors';
77
import express from 'express';
88
import { fromError } from 'zod-validation-error/v3';
99
import { McpOptions, parseQueryOptions } from './options';
10-
import { initMcpServer, newMcpServer } from './server';
10+
import { ClientOptions, initMcpServer, newMcpServer } from './server';
1111
import { parseAuthHeaders } from './headers';
1212

1313
const oauthResourceIdentifier = (req: express.Request): string => {
1414
const protocol = req.headers['x-forwarded-proto'] ?? req.protocol;
1515
return `${protocol}://${req.get('host')}/`;
1616
};
1717

18-
const newServer = (
19-
defaultMcpOptions: McpOptions,
20-
req: express.Request,
21-
res: express.Response,
22-
): McpServer | null => {
18+
const newServer = ({
19+
clientOptions,
20+
mcpOptions: defaultMcpOptions,
21+
req,
22+
res,
23+
}: {
24+
clientOptions: ClientOptions;
25+
mcpOptions: McpOptions;
26+
req: express.Request;
27+
res: express.Response;
28+
}): McpServer | null => {
2329
const server = newMcpServer();
2430

2531
let mcpOptions: McpOptions;
@@ -41,10 +47,8 @@ const newServer = (
4147
initMcpServer({
4248
server: server,
4349
clientOptions: {
50+
...clientOptions,
4451
...authOptions,
45-
defaultHeaders: {
46-
'X-Stainless-MCP': 'true',
47-
},
4852
},
4953
mcpOptions,
5054
});
@@ -67,17 +71,19 @@ const newServer = (
6771
return server;
6872
};
6973

70-
const post = (defaultOptions: McpOptions) => async (req: express.Request, res: express.Response) => {
71-
const server = newServer(defaultOptions, req, res);
72-
// If we return null, we already set the authorization error.
73-
if (server === null) return;
74-
const transport = new StreamableHTTPServerTransport({
75-
// Stateless server
76-
sessionIdGenerator: undefined,
77-
});
78-
await server.connect(transport);
79-
await transport.handleRequest(req, res, req.body);
80-
};
74+
const post =
75+
(options: { clientOptions: ClientOptions; mcpOptions: McpOptions }) =>
76+
async (req: express.Request, res: express.Response) => {
77+
const server = newServer({ ...options, req, res });
78+
// If we return null, we already set the authorization error.
79+
if (server === null) return;
80+
const transport = new StreamableHTTPServerTransport({
81+
// Stateless server
82+
sessionIdGenerator: undefined,
83+
});
84+
await server.connect(transport);
85+
await transport.handleRequest(req, res, req.body);
86+
};
8187

8288
const get = async (req: express.Request, res: express.Response) => {
8389
if (req.headers['sec-fetch-dest'] === 'document') {
@@ -117,22 +123,28 @@ const oauthAuthorizationServer = (req: express.Request, res: express.Response) =
117123
res.redirect('https://auth.mux.com/.well-known/oauth-authorization-server');
118124
};
119125

120-
export const streamableHTTPApp = (options: McpOptions): express.Express => {
126+
export const streamableHTTPApp = ({
127+
clientOptions = {},
128+
mcpOptions = {},
129+
}: {
130+
clientOptions?: ClientOptions;
131+
mcpOptions?: McpOptions;
132+
}): express.Express => {
121133
const app = express();
122134
app.set('query parser', 'extended');
123135
app.use(express.json());
124136

125137
app.get('/.well-known/oauth-authorization-server', cors(), oauthAuthorizationServer);
126138
app.get('/.well-known/oauth-protected-resource', cors(), oauthMetadata);
127139
app.get('/', get);
128-
app.post('/', cors(), post(options));
140+
app.post('/', cors(), post({ clientOptions, mcpOptions }));
129141
app.delete('/', del);
130142

131143
return app;
132144
};
133145

134146
export const launchStreamableHTTPServer = async (options: McpOptions, port: number | string | undefined) => {
135-
const app = streamableHTTPApp(options);
147+
const app = streamableHTTPApp({ mcpOptions: options });
136148
const server = app.listen(port);
137149
const address = server.address();
138150

packages/mcp-server/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function main() {
1414
return;
1515
}
1616

17-
const selectedTools = selectToolsOrError(endpoints, options);
17+
const selectedTools = await selectToolsOrError(endpoints, options);
1818

1919
console.error(
2020
`MCP Server starting with ${selectedTools.length} tools:`,
@@ -47,9 +47,9 @@ function parseOptionsOrError() {
4747
}
4848
}
4949

50-
function selectToolsOrError(endpoints: Endpoint[], options: McpOptions): Endpoint[] {
50+
async function selectToolsOrError(endpoints: Endpoint[], options: McpOptions): Promise<Endpoint[]> {
5151
try {
52-
const includedTools = selectTools(endpoints, options);
52+
const includedTools = await selectTools(endpoints, options);
5353
if (includedTools.length === 0) {
5454
console.error('No tools match the provided filters.');
5555
process.exit(1);

packages/mcp-server/src/server.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
55
import { Endpoint, endpoints, HandlerFunction, query } from './tools';
66
import {
77
CallToolRequestSchema,
8-
Implementation,
98
ListToolsRequestSchema,
9+
Implementation,
1010
Tool,
1111
} from '@modelcontextprotocol/sdk/types.js';
1212
import { ClientOptions } from '@mux/mux-node';
@@ -32,7 +32,7 @@ export const newMcpServer = () =>
3232
new McpServer(
3333
{
3434
name: 'mux',
35-
version: '12.7.0',
35+
version: '12.8.0',
3636
},
3737
{ capabilities: { tools: {}, logging: {} } },
3838
);
@@ -55,7 +55,7 @@ export function initMcpServer(params: {
5555
let providedEndpoints: Endpoint[] | null = null;
5656
let endpointMap: Record<string, Endpoint> | null = null;
5757

58-
const initTools = (implementation?: Implementation) => {
58+
const initTools = async (implementation?: Implementation) => {
5959
if (implementation && (!mcpOptions.client || mcpOptions.client === 'infer')) {
6060
mcpOptions.client =
6161
implementation.name.toLowerCase().includes('claude') ? 'claude'
@@ -66,8 +66,8 @@ export function initMcpServer(params: {
6666
...mcpOptions.capabilities,
6767
};
6868
}
69-
providedEndpoints = selectTools(endpoints, mcpOptions);
70-
endpointMap = Object.fromEntries(providedEndpoints.map((endpoint) => [endpoint.tool.name, endpoint]));
69+
providedEndpoints ??= await selectTools(endpoints, mcpOptions);
70+
endpointMap ??= Object.fromEntries(providedEndpoints.map((endpoint) => [endpoint.tool.name, endpoint]));
7171
};
7272

7373
const client = new Mux({
@@ -80,7 +80,7 @@ export function initMcpServer(params: {
8080

8181
server.setRequestHandler(ListToolsRequestSchema, async () => {
8282
if (providedEndpoints === null) {
83-
initTools(server.getClientVersion());
83+
await initTools(server.getClientVersion());
8484
}
8585
return {
8686
tools: providedEndpoints!.map((endpoint) => endpoint.tool),
@@ -89,7 +89,7 @@ export function initMcpServer(params: {
8989

9090
server.setRequestHandler(CallToolRequestSchema, async (request) => {
9191
if (endpointMap === null) {
92-
initTools(server.getClientVersion());
92+
await initTools(server.getClientVersion());
9393
}
9494
const { name, arguments: args } = request.params;
9595
const endpoint = endpointMap![name];
@@ -104,7 +104,7 @@ export function initMcpServer(params: {
104104
/**
105105
* Selects the tools to include in the MCP Server based on the provided options.
106106
*/
107-
export function selectTools(endpoints: Endpoint[], options?: McpOptions): Endpoint[] {
107+
export async function selectTools(endpoints: Endpoint[], options?: McpOptions): Promise<Endpoint[]> {
108108
const filteredEndpoints = query(options?.filters ?? [], endpoints);
109109

110110
let includedTools = filteredEndpoints;
@@ -119,7 +119,7 @@ export function selectTools(endpoints: Endpoint[], options?: McpOptions): Endpoi
119119
} else if (options?.includeAllTools) {
120120
includedTools = endpoints;
121121
} else if (options?.includeCodeTools) {
122-
includedTools = [codeTool()];
122+
includedTools = [await codeTool()];
123123
} else {
124124
includedTools = endpoints;
125125
}

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const VERSION = '12.7.0'; // x-release-please-version
1+
export const VERSION = '12.8.0'; // x-release-please-version

0 commit comments

Comments
 (0)