npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@anyshift/mcp-proxy

v0.3.5

Published

Generic MCP proxy that adds truncation, file writing, and JQ capabilities to any MCP server

Readme

@anyshift/mcp-proxy

Universal MCP Proxy - Add truncation, file writing, and JQ capabilities to ANY Model Context Protocol (MCP) server.

Features

🔄 100% MCP-Agnostic: Works with any MCP server through environment variable contract ✂️ Response Truncation: Auto-truncate large responses to token limits 💾 Automatic File Writing: Save large responses to disk 🔍 JQ Tool: Query saved JSON files with JQ syntax 🎯 Zero Configuration: No config files, just environment variables

Why Use This?

MCP servers often return very large responses (dashboards, metrics, logs) that:

  • Exceed AI model context windows (causing truncation or errors)
  • Make it hard for AI to synthesize information
  • Cannot be easily queried or analyzed

This proxy solves these problems by:

  1. Truncating responses to configurable token limits
  2. Saving full responses to disk automatically
  3. Adding a JQ tool to query saved JSON files

Environment Variable Contract

The proxy uses a namespace convention to separate its configuration from the child MCP server's configuration:

Proxy Configuration (MCP_PROXY_* prefix)

These variables control the proxy's behavior:

# REQUIRED: Child MCP specification
MCP_PROXY_CHILD_COMMAND="mcp-grafana"           # Command to spawn child MCP

# OPTIONAL: Child command arguments
MCP_PROXY_CHILD_ARGS="arg1,arg2"                # Comma-separated arguments

# OPTIONAL: Truncation settings (defaults shown)
MCP_PROXY_MAX_TOKENS=10000                      # Max tokens before truncation
MCP_PROXY_CHARS_PER_TOKEN=4                     # Chars per token calculation

# OPTIONAL: File writing settings
MCP_PROXY_WRITE_TO_FILE=true                    # Enable file writing (default: false)
MCP_PROXY_OUTPUT_PATH=/tmp/mcp-results          # REQUIRED if WRITE_TO_FILE=true
MCP_PROXY_MIN_CHARS_FOR_WRITE=1000              # Min size to save (default: 1000)

# OPTIONAL: JQ tool settings
MCP_PROXY_ENABLE_JQ=true                        # Enable JQ tool (default: true)
MCP_PROXY_JQ_TIMEOUT_MS=30000                   # JQ timeout (default: 30000)

# OPTIONAL: Debug logging
MCP_PROXY_ENABLE_LOGGING=true                   # Enable debug logs (default: false)

Pass-Through Variables (NO prefix)

All other environment variables are passed directly to the child MCP:

# Grafana example
GRAFANA_URL=https://your-instance.grafana.net
GRAFANA_SERVICE_ACCOUNT_TOKEN=glsa_...

# Datadog example
DATADOG_API_KEY=...
DATADOG_APP_KEY=...

# Anyshift example
API_TOKEN=...
API_BASE_URL=...

# Any other env vars your MCP needs
CUSTOM_VAR=value

Key Design Principle: The proxy knows nothing about specific MCP servers. It simply:

  1. Reads MCP_PROXY_* vars for its own config
  2. Passes everything else to the child MCP

Quick Start Examples

Example 1: Wrap Grafana MCP

# Proxy configuration
export MCP_PROXY_CHILD_COMMAND="mcp-grafana"
export MCP_PROXY_MAX_TOKENS=10000
export MCP_PROXY_WRITE_TO_FILE=true
export MCP_PROXY_OUTPUT_PATH=/tmp/grafana-results

# Grafana credentials (passed through to child)
export GRAFANA_URL=https://your-instance.grafana.net
export GRAFANA_SERVICE_ACCOUNT_TOKEN=glsa_your_token

# Run proxy
npx @anyshift/mcp-proxy

Example 2: Wrap Anyshift MCP

# Proxy configuration
export MCP_PROXY_CHILD_COMMAND="npx"
export MCP_PROXY_CHILD_ARGS="-y,@anyshift/anyshift-mcp-server"
export MCP_PROXY_WRITE_TO_FILE=true
export MCP_PROXY_OUTPUT_PATH=/tmp/anyshift-results

# Anyshift credentials (passed through)
export API_TOKEN=your_token
export API_BASE_URL=https://api.anyshift.io

# Run proxy
npx @anyshift/mcp-proxy

Example 3: Wrap Custom MCP

# Proxy configuration
export MCP_PROXY_CHILD_COMMAND="node"
export MCP_PROXY_CHILD_ARGS="/path/to/your/mcp-server.js"
export MCP_PROXY_MAX_TOKENS=5000

# Your MCP's credentials (passed through)
export YOUR_API_KEY=...
export YOUR_API_URL=...

# Run proxy
npx @anyshift/mcp-proxy

How It Works

graph TB
    AI[🤖 AI Agent<br/>Claude]

    AI -->|MCP Protocol| Proxy

    subgraph Proxy["@anyshift/mcp-proxy"]
        Start[Receive tool call]
        CheckJQ{JQ tool?}
        ExecuteJQ[Execute JQ locally]
        Forward[Forward to child MCP]
        GetResponse[Get response from child]
        CheckSize{Size ≥ 1000 chars?}
        WriteFile[📄 Write FULL data to file]
        ReturnFile[Return file reference]
        CheckTrunc{Size > 40K chars?}
        Truncate[Truncate with notice]
        ReturnDirect[Return response]

        Start --> CheckJQ
        CheckJQ -->|Yes| ExecuteJQ
        CheckJQ -->|No| Forward
        Forward --> GetResponse
        ExecuteJQ --> CheckTrunc
        GetResponse --> CheckSize
        CheckSize -->|Yes| WriteFile
        WriteFile --> ReturnFile
        CheckSize -->|No| CheckTrunc
        CheckTrunc -->|Yes| Truncate
        CheckTrunc -->|No| ReturnDirect

        ReturnFile -.->|📄 Small reference| AI
        Truncate -.->|Truncated text| AI
        ReturnDirect -.->|Full response| AI
    end

    Proxy -->|stdio + env vars| Child[Child MCP<br/>anyshift/datadog/grafana]
    Child -.->|Response| Proxy

    style AI fill:#e1f5ff
    style Proxy fill:#fff4e1
    style Child fill:#e8f5e9
    style WriteFile fill:#c8e6c9
    style ReturnFile fill:#c8e6c9

Response Handling Examples

Small responses (< 1,000 chars):

Child: 500 chars → Proxy: Return directly → AI: 500 chars ✓

Medium responses (1,000 - 40,000 chars):

Child: 5,000 chars → Proxy: Write to file → AI: "📄 File: path/to/file.json" ✓

Large responses (> 40,000 chars):

Child: 100,000 chars → Proxy: Write FULL 100K to file → AI: "📄 File: ..." ✓
Note: File contains complete data, not truncated!

JQ tool queries:

AI: JQ query → Proxy: Execute locally → AI: Result (truncated if > 40K) ✓

Key Design Principle

File writing happens BEFORE truncation. This ensures:

  • Files always contain complete, untruncated data
  • Large responses are accessible via file references
  • AI receives small, manageable responses
  • No data loss due to context limits

Integration Examples

AI-Workbench Integration

// In ai-workbench builder.go
func WrapWithProxy(baseMCPConfig MCPConfig, ...) MCPConfig {
    proxyEnv := map[string]string{
        "MCP_PROXY_CHILD_COMMAND": baseMCPConfig.Command,
        "MCP_PROXY_MAX_TOKENS":    "10000",
        "MCP_PROXY_WRITE_TO_FILE": "true",
        "MCP_PROXY_OUTPUT_PATH":   outputPath,
    }

    // Merge child's env vars (pass-through)
    for key, value := range baseMCPConfig.Env {
        proxyEnv[key] = value
    }

    return MCPConfig{
        Command: "npx",
        Args:    []string{"-y", "@anyshift/mcp-proxy"},
        Env:     proxyEnv,
    }
}

Claude Desktop Integration

{
  "mcpServers": {
    "grafana": {
      "command": "npx",
      "args": ["-y", "@anyshift/mcp-proxy"],
      "env": {
        "MCP_PROXY_CHILD_COMMAND": "mcp-grafana",
        "MCP_PROXY_MAX_TOKENS": "10000",
        "MCP_PROXY_WRITE_TO_FILE": "true",
        "MCP_PROXY_OUTPUT_PATH": "/tmp/grafana-results",
        "GRAFANA_URL": "https://your-instance.grafana.net",
        "GRAFANA_SERVICE_ACCOUNT_TOKEN": "glsa_..."
      }
    }
  }
}

Environment Variable Reference

MCP_PROXY_CHILD_COMMAND (REQUIRED)

The command to spawn as the child MCP server.

Examples:

  • "mcp-grafana" - Direct binary
  • "npx" - Use with MCP_PROXY_CHILD_ARGS="-y,@anyshift/anyshift-mcp-server"
  • "node" - Use with MCP_PROXY_CHILD_ARGS="/path/to/server.js"

MCP_PROXY_CHILD_ARGS (OPTIONAL)

Comma-separated arguments to pass to the child command.

Example: "arg1,arg2,--verbose" becomes ["arg1", "arg2", "--verbose"]

MCP_PROXY_MAX_TOKENS (OPTIONAL, default: 10000)

Maximum tokens before truncating responses.

Calculation: maxTokens × charsPerToken = max characters Default: 10000 × 4 = 40,000 characters

MCP_PROXY_WRITE_TO_FILE (OPTIONAL, default: false)

Enable automatic file writing for responses above MIN_CHARS_FOR_WRITE.

When to enable:

  • Responses frequently exceed token limits
  • Need full data for later analysis
  • Want to use JQ tool to query responses

MCP_PROXY_OUTPUT_PATH (REQUIRED if WRITE_TO_FILE=true)

Directory where response files are saved.

File naming: {timestamp}_{tool_name}_{short_id}.json

MCP_PROXY_ENABLE_JQ (OPTIONAL, default: true)

Add the execute_jq_query tool for querying saved JSON files.

Disable when:

  • Child MCP already provides JQ tool
  • Don't need file querying capability

MCP_PROXY_ENABLE_LOGGING (OPTIONAL, default: false)

Enable debug logging to stderr.

Logs include:

  • Configuration summary
  • Tool discovery count
  • Truncation events
  • File writing operations

Development

# Clone and install
cd mcp-proxy
pnpm install

# Build
pnpm build

# Test with Grafana
export MCP_PROXY_CHILD_COMMAND="mcp-grafana"
export GRAFANA_URL=...
export GRAFANA_SERVICE_ACCOUNT_TOKEN=...
node dist/index.js

# Test with custom MCP
export MCP_PROXY_CHILD_COMMAND="node"
export MCP_PROXY_CHILD_ARGS="/path/to/my-mcp.js"
export MY_API_KEY=...
node dist/index.js

Benefits

Zero configuration files - Pure environment variables ✅ Truly MCP-agnostic - Works with ANY MCP server ✅ Simple integration - Just wrap the command with env vars ✅ Clean separation - Proxy config vs child config ✅ Pass-through design - Child gets exactly what it needs

License

MIT

Related Projects