mcp-remote 0.1.21 → 0.1.22
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/README.md +18 -0
- package/dist/{chunk-BCWNEBAL.js → chunk-AVTRP4BV.js} +100 -5
- package/dist/client.js +1 -1
- package/dist/proxy.js +8 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -135,6 +135,24 @@ To bypass authentication, or to emit custom headers on all requests to your remo
|
|
|
135
135
|
]
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
* To ignore specific tools from the remote server, add the `--ignore-tool` flag. This will filter out tools matching the specified patterns from both `tools/list` responses and block `tools/call` requests. Supports wildcard patterns with `*`.
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
"args": [
|
|
142
|
+
"mcp-remote",
|
|
143
|
+
"https://remote.mcp.server/sse",
|
|
144
|
+
"--ignore-tool",
|
|
145
|
+
"delete*",
|
|
146
|
+
"--ignore-tool",
|
|
147
|
+
"remove*"
|
|
148
|
+
]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
You can specify multiple `--ignore-tool` flags to ignore different patterns. Examples:
|
|
152
|
+
- `delete*` - ignores all tools starting with "delete" (e.g., `deleteTask`, `deleteUser`)
|
|
153
|
+
- `*account` - ignores all tools ending with "account" (e.g., `getAccount`, `updateAccount`)
|
|
154
|
+
- `exactTool` - ignores only the tool named exactly "exactTool"
|
|
155
|
+
|
|
138
156
|
### Transport Strategies
|
|
139
157
|
|
|
140
158
|
MCP Remote supports different transport strategies when connecting to an MCP server. This allows you to control whether it uses Server-Sent Events (SSE) or HTTP transport, and in what order it tries them.
|
|
@@ -11872,7 +11872,7 @@ var Client = class extends Protocol {
|
|
|
11872
11872
|
};
|
|
11873
11873
|
|
|
11874
11874
|
// package.json
|
|
11875
|
-
var version = "0.1.
|
|
11875
|
+
var version = "0.1.22";
|
|
11876
11876
|
|
|
11877
11877
|
// node_modules/.pnpm/pkce-challenge@5.0.0/node_modules/pkce-challenge/dist/index.node.js
|
|
11878
11878
|
var crypto;
|
|
@@ -13679,11 +13679,75 @@ function log(str, ...rest) {
|
|
|
13679
13679
|
debugLog(str, ...rest);
|
|
13680
13680
|
}
|
|
13681
13681
|
}
|
|
13682
|
-
|
|
13682
|
+
var MESSAGE_BLOCKED = Symbol("MessageBlocked");
|
|
13683
|
+
var isMessageBlocked = (value) => value === MESSAGE_BLOCKED;
|
|
13684
|
+
function createMessageTransformer({
|
|
13685
|
+
transformRequestFunction,
|
|
13686
|
+
transformResponseFunction
|
|
13687
|
+
} = {}) {
|
|
13688
|
+
const pendingRequests = /* @__PURE__ */ new Map();
|
|
13689
|
+
const interceptRequest = (message) => {
|
|
13690
|
+
const messageId = message.id;
|
|
13691
|
+
if (!messageId) return message;
|
|
13692
|
+
pendingRequests.set(messageId, message);
|
|
13693
|
+
return transformRequestFunction?.(message) ?? message;
|
|
13694
|
+
};
|
|
13695
|
+
const interceptResponse = (message) => {
|
|
13696
|
+
const messageId = message.id;
|
|
13697
|
+
if (!messageId) return message;
|
|
13698
|
+
const originalRequest = pendingRequests.get(messageId);
|
|
13699
|
+
pendingRequests.delete(messageId);
|
|
13700
|
+
return transformResponseFunction?.(originalRequest, message) ?? message;
|
|
13701
|
+
};
|
|
13702
|
+
return {
|
|
13703
|
+
interceptRequest,
|
|
13704
|
+
interceptResponse
|
|
13705
|
+
};
|
|
13706
|
+
}
|
|
13707
|
+
function mcpProxy({
|
|
13708
|
+
transportToClient,
|
|
13709
|
+
transportToServer,
|
|
13710
|
+
ignoredTools = []
|
|
13711
|
+
}) {
|
|
13683
13712
|
let transportToClientClosed = false;
|
|
13684
13713
|
let transportToServerClosed = false;
|
|
13714
|
+
const messageTransformer = createMessageTransformer({
|
|
13715
|
+
transformRequestFunction: (request) => {
|
|
13716
|
+
if (request.method === "tools/call" && request.params?.name) {
|
|
13717
|
+
const toolName = request.params.name;
|
|
13718
|
+
if (!shouldIncludeTool(ignoredTools, toolName)) {
|
|
13719
|
+
const errorResponse = {
|
|
13720
|
+
jsonrpc: "2.0",
|
|
13721
|
+
id: request.id,
|
|
13722
|
+
error: {
|
|
13723
|
+
code: -32603,
|
|
13724
|
+
message: `Tool "${toolName}" is not available`
|
|
13725
|
+
}
|
|
13726
|
+
};
|
|
13727
|
+
transportToClient.send(errorResponse).catch(onClientError);
|
|
13728
|
+
return MESSAGE_BLOCKED;
|
|
13729
|
+
}
|
|
13730
|
+
}
|
|
13731
|
+
return request;
|
|
13732
|
+
},
|
|
13733
|
+
transformResponseFunction: (req, res) => {
|
|
13734
|
+
if (req.method === "tools/list") {
|
|
13735
|
+
return {
|
|
13736
|
+
...res,
|
|
13737
|
+
result: {
|
|
13738
|
+
...res.result,
|
|
13739
|
+
tools: res.result.tools.filter((tool) => shouldIncludeTool(ignoredTools, tool.name))
|
|
13740
|
+
}
|
|
13741
|
+
};
|
|
13742
|
+
}
|
|
13743
|
+
return res;
|
|
13744
|
+
}
|
|
13745
|
+
});
|
|
13685
13746
|
transportToClient.onmessage = (_message) => {
|
|
13686
|
-
const message = _message;
|
|
13747
|
+
const message = messageTransformer.interceptRequest(_message);
|
|
13748
|
+
if (isMessageBlocked(message)) {
|
|
13749
|
+
return;
|
|
13750
|
+
}
|
|
13687
13751
|
log("[Local\u2192Remote]", message.method || message.id);
|
|
13688
13752
|
if (DEBUG) {
|
|
13689
13753
|
debugLog("Local \u2192 Remote message", {
|
|
@@ -13703,7 +13767,7 @@ function mcpProxy({ transportToClient, transportToServer }) {
|
|
|
13703
13767
|
transportToServer.send(message).catch(onServerError);
|
|
13704
13768
|
};
|
|
13705
13769
|
transportToServer.onmessage = (_message) => {
|
|
13706
|
-
const message = _message;
|
|
13770
|
+
const message = messageTransformer.interceptResponse(_message);
|
|
13707
13771
|
log("[Remote\u2192Local]", message.method || message.id);
|
|
13708
13772
|
if (DEBUG) {
|
|
13709
13773
|
debugLog("Remote \u2192 Local message", {
|
|
@@ -14045,6 +14109,18 @@ async function parseCommandLineArgs(args, usage) {
|
|
|
14045
14109
|
authorizeResource = args[resourceIndex + 1];
|
|
14046
14110
|
log(`Using authorize resource: ${authorizeResource}`);
|
|
14047
14111
|
}
|
|
14112
|
+
const ignoredTools = [];
|
|
14113
|
+
let j = 0;
|
|
14114
|
+
while (j < args.length) {
|
|
14115
|
+
if (args[j] === "--ignore-tool" && j < args.length - 1) {
|
|
14116
|
+
const toolName = args[j + 1];
|
|
14117
|
+
ignoredTools.push(toolName);
|
|
14118
|
+
log(`Ignoring tool: ${toolName}`);
|
|
14119
|
+
args.splice(j, 2);
|
|
14120
|
+
continue;
|
|
14121
|
+
}
|
|
14122
|
+
j++;
|
|
14123
|
+
}
|
|
14048
14124
|
if (!serverUrl) {
|
|
14049
14125
|
log(usage);
|
|
14050
14126
|
process.exit(1);
|
|
@@ -14104,7 +14180,8 @@ async function parseCommandLineArgs(args, usage) {
|
|
|
14104
14180
|
debug,
|
|
14105
14181
|
staticOAuthClientMetadata,
|
|
14106
14182
|
staticOAuthClientInfo,
|
|
14107
|
-
authorizeResource
|
|
14183
|
+
authorizeResource,
|
|
14184
|
+
ignoredTools
|
|
14108
14185
|
};
|
|
14109
14186
|
}
|
|
14110
14187
|
function setupSignalHandlers(cleanup) {
|
|
@@ -14123,6 +14200,24 @@ function setupSignalHandlers(cleanup) {
|
|
|
14123
14200
|
function getServerUrlHash(serverUrl) {
|
|
14124
14201
|
return crypto2.createHash("md5").update(serverUrl).digest("hex");
|
|
14125
14202
|
}
|
|
14203
|
+
function patternToRegex(pattern) {
|
|
14204
|
+
const parts = pattern.split("*");
|
|
14205
|
+
const escapedParts = parts.map((part) => part.replace(/\W/g, "\\$&"));
|
|
14206
|
+
const regexPattern = escapedParts.join(".*");
|
|
14207
|
+
return new RegExp(`^${regexPattern}$`, "i");
|
|
14208
|
+
}
|
|
14209
|
+
function shouldIncludeTool(ignorePatterns, toolName) {
|
|
14210
|
+
if (!ignorePatterns || ignorePatterns.length === 0) {
|
|
14211
|
+
return true;
|
|
14212
|
+
}
|
|
14213
|
+
for (const pattern of ignorePatterns) {
|
|
14214
|
+
const regex = patternToRegex(pattern);
|
|
14215
|
+
if (regex.test(toolName)) {
|
|
14216
|
+
return false;
|
|
14217
|
+
}
|
|
14218
|
+
}
|
|
14219
|
+
return true;
|
|
14220
|
+
}
|
|
14126
14221
|
|
|
14127
14222
|
// src/lib/node-oauth-client-provider.ts
|
|
14128
14223
|
import open from "open";
|
package/dist/client.js
CHANGED
package/dist/proxy.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
mcpProxy,
|
|
10
10
|
parseCommandLineArgs,
|
|
11
11
|
setupSignalHandlers
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AVTRP4BV.js";
|
|
13
13
|
|
|
14
14
|
// src/proxy.ts
|
|
15
15
|
import { EventEmitter } from "events";
|
|
@@ -110,7 +110,7 @@ var StdioServerTransport = class {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/proxy.ts
|
|
113
|
-
async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "http-first", host, staticOAuthClientMetadata, staticOAuthClientInfo, authorizeResource) {
|
|
113
|
+
async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "http-first", host, staticOAuthClientMetadata, staticOAuthClientInfo, authorizeResource, ignoredTools) {
|
|
114
114
|
const events = new EventEmitter();
|
|
115
115
|
const serverUrlHash = getServerUrlHash(serverUrl);
|
|
116
116
|
const authCoordinator = createLazyAuthCoordinator(serverUrlHash, callbackPort, events);
|
|
@@ -141,7 +141,8 @@ async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "h
|
|
|
141
141
|
const remoteTransport = await connectToRemoteServer(null, serverUrl, authProvider, headers, authInitializer, transportStrategy);
|
|
142
142
|
mcpProxy({
|
|
143
143
|
transportToClient: localTransport,
|
|
144
|
-
transportToServer: remoteTransport
|
|
144
|
+
transportToServer: remoteTransport,
|
|
145
|
+
ignoredTools
|
|
145
146
|
});
|
|
146
147
|
await localTransport.start();
|
|
147
148
|
log("Local STDIO server running");
|
|
@@ -195,7 +196,8 @@ parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx proxy.ts <https://se
|
|
|
195
196
|
debug,
|
|
196
197
|
staticOAuthClientMetadata,
|
|
197
198
|
staticOAuthClientInfo,
|
|
198
|
-
authorizeResource
|
|
199
|
+
authorizeResource,
|
|
200
|
+
ignoredTools
|
|
199
201
|
}) => {
|
|
200
202
|
return runProxy(
|
|
201
203
|
serverUrl,
|
|
@@ -205,7 +207,8 @@ parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx proxy.ts <https://se
|
|
|
205
207
|
host,
|
|
206
208
|
staticOAuthClientMetadata,
|
|
207
209
|
staticOAuthClientInfo,
|
|
208
|
-
authorizeResource
|
|
210
|
+
authorizeResource,
|
|
211
|
+
ignoredTools
|
|
209
212
|
);
|
|
210
213
|
}
|
|
211
214
|
).catch((error) => {
|