Content
# cursor-mcp-response-proxy
Local MCP stdio response proxy for Cursor. The proxy entry point is fixed to stdio, and the upstream can be:
- Local stdio MCP server
- Traditional SSE MCP server
- Streamable HTTP MCP server
When a single upstream response exceeds the security threshold, the proxy saves the complete JSON-RPC message and returns a shorter preview and file path to Cursor, avoiding the body being discarded.
## Background
Cursor has a size limit for MCP tool results. If the returned content exceeds the limit too much, Cursor may directly discard the entire result instead of truncating the body, and it will not automatically save the complete content to a file and provide the file path to the Agent. At this point, although the upstream MCP tool has successfully executed, the Agent still cannot read the result and does not know where to obtain the complete content.
In the Cursor environment, it has been measured that a single MCP tool result can return up to about `12000` ASCII characters, and truncation starts from the `12001`st character. Considering that the actual response also contains JSON-RPC packaging, field information, and may use multi-byte characters, this project sets the default security threshold to `10000` characters, leaving room for these extra contents and different Cursor version behaviors.
This project is used to handle this problem before the response reaches Cursor: the proxy detects the size of a single JSON-RPC response, and when it exceeds the security threshold, it first saves the complete response to a local file, and then returns a shorter preview, the original character count, and the file path to Cursor. This way, the Agent can continue to use the preview and read the complete file when needed.
```text
Cursor (stdio)
<-> cursor-mcp-response-proxy
<-> stdio | SSE | Streamable HTTP upstream
```
## Installation
### Linux / macOS
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
pip install pytest
```
### Windows PowerShell
```powershell
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .
python -m pip install pytest
```
Verification:
```bash
PYTHONPATH=src pytest
cursor-mcp-response-proxy --help
```
In Windows PowerShell:
```powershell
python -m pytest
.\.venv\Scripts\cursor-mcp-response-proxy.exe --help
```
## Platform Support
- Linux: Development and end-to-end verification have been completed.
- Windows: Using UTF-8 stdio and standard Windows `file:///C:/...` URI; the upstream subprocess is responsible for starting and terminating by the official MCP Python SDK's Windows implementation.
- macOS: Using the same POSIX path as Linux, the transport layer is provided by the official MCP Python SDK.
Automated tests verify Windows path URI and UTF-8 standard stream configuration. It is still recommended to perform an actual Cursor MCP smoke test on the target Windows and macOS versions before release.
## Default Response Protection
| Configuration | Default Value |
| ---------------------- | ------------------------------------ |
| `--max-response-chars` | `10000` |
| `--preview-chars` | `4000` |
| `--output-dir` | `~/.cache/cursor-mcp-response-proxy` |
The threshold is calculated by the character count of the entire compact JSON-RPC message. When exceeding the threshold:
1. The complete original message is saved as a JSON file.
2. `tools/call`, `resources/read`, `prompts/get` return previews that comply with their respective protocol structures.
3. Proxy information is placed in the standard `_meta._cursor_mcp_response_proxy` field.
4. Other unknown responses return JSON-RPC errors with the complete file path.
## Cursor Configuration
The following example assumes the project is located at `/path/to/cursor-mcp-response-proxy`.
### Streamable HTTP
Anysearch example:
```json
{
"mcpServers": {
"anysearch": {
"command": "/path/to/cursor-mcp-response-proxy/.venv/bin/cursor-mcp-response-proxy",
"args": [
"streamable-http",
"--url",
"https://api.anysearch.com/mcp",
"--header",
"Authorization=Bearer ${ANYSEARCH_API_KEY}"
],
"env": {
"ANYSEARCH_API_KEY": "your_API_KEY"
}
}
}
}
```
`${ANYSEARCH_API_KEY}` is expanded by the proxy at startup. Do not write the real key into the repository.
In Windows, change the `command` to the actual virtual environment path. Backslashes in JSON strings need to be written as `\\`:
```json
{
"mcpServers": {
"anysearch": {
"command": "C:\\path\\to\\cursor-mcp-response-proxy\\.venv\\Scripts\\cursor-mcp-response-proxy.exe",
"args": [
"streamable-http",
"--url",
"https://api.anysearch.com/mcp",
"--header",
"Authorization=Bearer ${ANYSEARCH_API_KEY}"
],
"env": {
"ANYSEARCH_API_KEY": "your_API_KEY"
}
}
}
}
```
### SSE
```json
{
"mcpServers": {
"legacy-sse": {
"command": "/path/to/cursor-mcp-response-proxy/.venv/bin/cursor-mcp-response-proxy",
"args": [
"sse",
"--url",
"https://example.com/sse",
"--header",
"Authorization=Bearer ${MCP_TOKEN}"
],
"env": {
"MCP_TOKEN": "your_token"
}
}
}
}
```
### stdio
The upstream command is placed after `--`:
```json
{
"mcpServers": {
"local-server": {
"command": "/path/to/cursor-mcp-response-proxy/.venv/bin/cursor-mcp-response-proxy",
"args": [
"stdio",
"--",
"python",
"-m",
"example_mcp_server"
]
}
}
}
```
Environment variables can be passed by repeating `--env NAME=VALUE`. The proxy only passes these variables and the SDK's secure default environment variables to the upstream subprocess.
## Command Line
```bash
cursor-mcp-response-proxy stdio [common parameters] [--env NAME=VALUE] -- COMMAND [ARGS...]
cursor-mcp-response-proxy sse [common parameters] --url URL [--header NAME=VALUE]
cursor-mcp-response-proxy streamable-http [common parameters] --url URL [--header NAME=VALUE]
```
HTTP parameters:
- `--header NAME=VALUE`: repeatable, value supports `${ENV_VAR}`.
- `--timeout`: regular HTTP operation timeout, default 120 seconds.
- `--sse-read-timeout`: timeout for waiting for new SSE events, default 300 seconds.
Common environment variables:
| Variable | Description |
| ---------------------------------------------------- | --------- |
| `CURSOR_MCP_RESPONSE_PROXY_MAX_RESPONSE_CHARS` | Response protection threshold |
| `CURSOR_MCP_RESPONSE_PROXY_PREVIEW_CHARS` | Preview character count |
| `CURSOR_MCP_RESPONSE_PROXY_OUTPUT_DIR` | Complete response directory |
| `CURSOR_MCP_RESPONSE_PROXY_TIMEOUT_SECONDS` | HTTP operation timeout |
| `CURSOR_MCP_RESPONSE_PROXY_SSE_READ_TIMEOUT_SECONDS` | SSE read timeout |
## Implementation Boundary
- Three upstream transports are provided by the official MCP Python SDK 1.x.
- The proxy does not create a business-level `ClientSession`; control messages, notifications, and server requests are transparently forwarded, and the response is rewritten according to the protocol structure when the content type response exceeds the limit.
- The transport layer does not handle response size, and the response processing layer does not send network requests.
- Logs are only written to stderr, and stdout only writes a single line of MCP JSON-RPC message.
## Directory
```text
src/cursor_mcp_response_proxy/
__main__.py # Command entry
config.py # Subcommands, request headers, and environment variable configuration
proxy.py # Cursor stdio bidirectional proxy and request association
transports.py # stdio, SSE, Streamable HTTP upstream adaptation
response_handler.py # Volume judgment and protocol-compatible rewriting
storage.py # Complete response file writing
tests/
fixtures/ # Test-specific MCP upstream
```