mcp-filter


Namemcp-filter JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryMCP server proxy that exposes a filtered tool surface from upstream servers.
upload_time2025-10-11 06:08:29
maintainerNone
docs_urlNone
authorMCP Filter Contributors
requires_python>=3.10
licenseMIT
keywords filter mcp model-context-protocol proxy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">
  <img src="logo.png" alt="MCP Filter" width="300">
  <h1>MCP Filter</h1>
  <p>A proxy MCP (Model Context Protocol) server that filters the upstream tool surface to just the tools you need. Expose one or two critical tools (for example, <code>execute_sql</code> on Supabase) while filtering out the token-costly ones, without having to modify the upstream implementation.</p>
</div>

## Before & After

**Before:** Unfiltered MCP servers consumed ~50k tokens on a fresh Claude Code session

```
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁   claude-sonnet-4-5 · 112k/200k tokens (56%)
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁   ⛁ System: 2.3k tokens
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁   ⛁ System tools: 11.8k tokens
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁   ⛁ MCP tools: 50.1k tokens (25%)  ← Large!
⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛶ Free space: 88k (44%)
```

**After:** With mcp-filter, reduced to ~13.7k tokens (72% reduction) while keeping all necessary tools.

```
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛶ ⛶   claude-sonnet-4-5 · 80k/200k tokens (40%)
⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛶ ⛶ ⛶
⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ System: 2.3k tokens
⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ System tools: 11.8k tokens
⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ MCP tools: 13.7k tokens (6.9%)  ← Filtered!
⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛶ Free space: 120k (60%)  ← +32k gained
```

Filter only the tools you need, save context for longer sessions.

**To see your token usage:** Open Claude Code and run `/context` to view the breakdown.

## What & Why

- **Static allowlist** keeps the exposed tool list tiny, cutting context usage for clients that serialize tool schemas.
- **Drop-in proxy**: stands in front of any MCP server that speaks stdio or HTTP/SSE, forwarding calls transparently.
- **Safety guardrails**: optional regex-based deny list, optional prefix, and optional health tool for observability.

## Installation

Python 3.10+ is supported; 3.11 is recommended.

```bash
pip install mcp-filter
```

**From source (development):**

```bash
pyenv install 3.11.9
pyenv local 3.11.9
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
```

## Quick Start

```bash
mcp-filter run \
  -t stdio \
  --stdio-command npx \
  --stdio-arg "-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN" \
  -a "execute_sql,list_tables,get_project"
```

**Shorthand flags:** `-t` (transport), `-a` (allow-tool), `-d` (deny-pattern), `-p` (prefix)

**Note:** Both `--stdio-arg` and `-a` support flexible input - use repeatable flags or comma-separated strings, whichever is cleaner for your use case.

## How to Wrap Your MCP

### Concept

Transform any existing MCP server config by wrapping it with mcp-filter. The filter proxies your original command and only exposes the tools you specify with `-a`.

**Before (original Supabase config):**

```json
{
  "mcpServers": {
    "supabase": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase@latest",
        "--access-token",
        "YOUR_TOKEN"
      ]
    }
  }
}
```

This exposes all 29 tools (**~20.8k tokens**):

<details>
<summary>Show all tools</summary>

```
└ mcp__supabase__search_docs (supabase): 2.8k tokens
└ mcp__supabase__list_organizations (supabase): 582 tokens
└ mcp__supabase__get_organization (supabase): 604 tokens
└ mcp__supabase__list_projects (supabase): 600 tokens
└ mcp__supabase__get_project (supabase): 603 tokens
└ mcp__supabase__get_cost (supabase): 646 tokens
└ mcp__supabase__confirm_cost (supabase): 682 tokens
└ mcp__supabase__create_project (supabase): 832 tokens
└ mcp__supabase__pause_project (supabase): 599 tokens
└ mcp__supabase__restore_project (supabase): 599 tokens
└ mcp__supabase__list_tables (supabase): 640 tokens
└ mcp__supabase__list_extensions (supabase): 596 tokens
└ mcp__supabase__list_migrations (supabase): 596 tokens
└ mcp__supabase__apply_migration (supabase): 668 tokens
└ mcp__supabase__execute_sql (supabase): 657 tokens
└ mcp__supabase__get_logs (supabase): 677 tokens
└ mcp__supabase__get_advisors (supabase): 699 tokens
└ mcp__supabase__get_project_url (supabase): 599 tokens
└ mcp__supabase__get_anon_key (supabase): 601 tokens
└ mcp__supabase__generate_typescript_types (supabase): 600 tokens
└ mcp__supabase__list_edge_functions (supabase): 603 tokens
└ mcp__supabase__get_edge_function (supabase): 625 tokens
└ mcp__supabase__deploy_edge_function (supabase): 907 tokens
└ mcp__supabase__create_branch (supabase): 718 tokens
└ mcp__supabase__list_branches (supabase): 625 tokens
└ mcp__supabase__delete_branch (supabase): 596 tokens
└ mcp__supabase__merge_branch (supabase): 603 tokens
└ mcp__supabase__reset_branch (supabase): 636 tokens
└ mcp__supabase__rebase_branch (supabase): 617 tokens
```

</details>

**After (wrapped with mcp-filter):**

```json
{
  "mcpServers": {
    "supabase": {
      "command": "mcp-filter",
      "args": [
        "run",
        "-t",
        "stdio",
        "--stdio-command",
        "npx",
        "--stdio-arg",
        "-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN",
        "-a",
        "execute_sql,list_tables,get_project"
      ]
    }
  }
}
```

This only exposes 3 tools we allowed (**~1.9k tokens** = 91% reduction!):

```
└ mcp__supabase__get_project (supabase): 605 tokens
└ mcp__supabase__list_tables (supabase): 642 tokens
└ mcp__supabase__execute_sql (supabase): 659 tokens
```

### Examples for Claude Code / Claude Desktop

`examples/mcp.json.sample` includes common setups. Add to your `mcp.json`:

**Supabase (stdio)** – wrap the official MCP binary:

```json
"supabase": {
  "command": "mcp-filter",
  "args": [
    "run",
    "-t", "stdio",
    "--stdio-command", "npx",
    "--stdio-arg", "-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN",
    "-a", "execute_sql,list_tables,get_project"
  ]
}
```

**Linear (stdio wrapping mcp-remote)** – preserves OAuth browser flow:

```json
"linear": {
  "command": "mcp-filter",
  "args": [
    "run",
    "-t", "stdio",
    "--stdio-command", "npx",
    "--stdio-arg", "-y mcp-remote https://mcp.linear.app/sse",
    "-a", "get_issue,list_issues,create_issue,update_issue,create_comment"
  ]
}
```

Adjust auth-tokens/headers to match your environment; the filter never logs or exposes them.

## Configuration Reference

Environment variables (prefixed with `MF_`) override CLI flags. See `.env.example` for a template.

- `MF_TRANSPORT` / `-t`: `stdio` (default) or `http`
- `MF_STDIO_COMMAND` / `MF_STDIO_ARGS`: upstream binary + args
- `MF_HTTP_URL` / `MF_HTTP_HEADERS`: SSE/HTTP endpoint and extra headers (`key=value;Another=Value`)
- `MF_ALLOW_TOOLS` / `-a`: exact tool names (repeatable, or comma-separated)
- `MF_ALLOW_PATTERNS`: regex patterns for tool names (repeatable, or comma-separated)
- `MF_DENY_PATTERNS` / `-d`: regex patterns to block (repeatable, or comma-separated)
- `MF_RENAME_PREFIX` / `-p` / `--prefix`: prefix exposed tool names (e.g., `supabase_`)
- `MF_INCLUDE_HEALTH_TOOL=1` / `--health`: enable built-in health tool (disabled by default)
- `MF_SHOW_TOKEN_ESTIMATES=1`: enable token estimate logging (disabled by default)

## FAQ

**Can I expose more than one tool?** Yes—pass multiple `--allow-tool` flags or use regex patterns. All exposed tools share the optional rename prefix.

**Are my credentials safe?** Yes. The filter never logs secrets passed as CLI arguments or headers.

**What if the upstream goes down?** Health checks surface the failure while the filter continues to reject new calls with a clear error.

**Can I merge config files?** Env + CLI merging is built in. For more complex setups, script the CLI invocation or add a thin wrapper that loads `mf.toml` and passes flags.

## Advanced

### Observability & Health

- Rich-based structured logging annotates server name, transport, and exposed tool count.
- Optional built-in health tool (disabled by default, ~500 tokens per server) returns upstream liveness and exposed tool names; output is safe JSON. Enable with `MF_INCLUDE_HEALTH_TOOL=1` or `--health`.

### Security Notes

- Only tools explicitly allowlisted or matching an allow regex are exposed.
- Deny-patterns apply last to ensure sensitive tools stay hidden.
- Optional rename prefix avoids tool collisions when multiple filtered proxies run side-by-side.
- Health payload (when enabled) avoids secrets—only structural metadata is emitted.
- **Credentials & secrets**: Arguments and headers passed via CLI flags are never logged. For production deployments, prefer environment variables (e.g., `MF_STDIO_ARGS`) to avoid exposing credentials in process lists.

### Requirements

- Python 3.10+ (3.11 recommended)
- `mcp>=1.0.0` and `fastmcp>=0.3.0` (installed automatically)
- Upstream tool list is fixed per session; mid-run changes require restart
- HTTP transport requires SSE-compatible upstream servers

## Roadmap

### v0.2.0 (Planned)

**Schema Pruning** — Additional 30-60% token reduction

- Add `--prune-schema [off|safe|aggressive]` to strip non-essential schema fields
- Safe mode: remove `title`, `description`, `examples`, `default` while preserving contract
- Aggressive mode: strip all descriptions except top-level (≤140 chars)

**Enhanced Error Handling**

- Return proper JSON-RPC error codes (e.g., `-32602` for blocked tools)
- Include helpful error details: `{"public_tools": [...], "tool_requested": "...", "reason": "not_allowlisted"}`

**Collision-Safe Naming**

- Replace collision failures with deterministic suffixes (`tool_name_{hash[:4]}`)
- Log warnings but continue operation

**Full JSON Schema Validation**

- Validate tool arguments locally before forwarding upstream
- Provide clear, early error messages for invalid calls
- Compile schemas at startup for performance

**Structured Logging & Monitoring**

- Add `--log-format [pretty|json]` for production-friendly JSON lines
- Add `--redact-keys` to automatically redact sensitive field names
- Expose metrics for blocked calls, latency, and tool usage

**Operational Controls**

- Add `--timeout-ms` (default: 120000) for per-call timeouts
- Add `--max-concurrency` (default: 8) to limit parallel upstream calls

**Resources & Prompts Filtering**

- Add `--allow-resources` and `--allow-prompts` (off by default)
- Apply same pattern-based filtering as tools

### Future Considerations

- Multi-upstream mode: `--upstream NAME=cmd...` for managing multiple filtered servers
- Compressor mode: meta-tools with on-demand forwarding (separate from filter mode)
- Built-in deny presets: `--deny-dangerous-verbs` to block destructive operations by default

## Testing

```bash
source .venv/bin/activate
python -m pytest
```

The suite exercises filtering precedence, rename collisions, schema validation, health handling, and call forwarding against a fake upstream server.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "mcp-filter",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "filter, mcp, model-context-protocol, proxy",
    "author": "MCP Filter Contributors",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/41/a6/6de00a67249b1fc0d14d5df2daf2bb574b78688eed0a8c26225515f1add5/mcp_filter-0.1.0.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n  <img src=\"logo.png\" alt=\"MCP Filter\" width=\"300\">\n  <h1>MCP Filter</h1>\n  <p>A proxy MCP (Model Context Protocol) server that filters the upstream tool surface to just the tools you need. Expose one or two critical tools (for example, <code>execute_sql</code> on Supabase) while filtering out the token-costly ones, without having to modify the upstream implementation.</p>\n</div>\n\n## Before & After\n\n**Before:** Unfiltered MCP servers consumed ~50k tokens on a fresh Claude Code session\n\n```\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1   claude-sonnet-4-5 \u00b7 112k/200k tokens (56%)\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1   \u26c1 System: 2.3k tokens\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1   \u26c1 System tools: 11.8k tokens\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1   \u26c1 MCP tools: 50.1k tokens (25%)  \u2190 Large!\n\u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6   \u26f6 Free space: 88k (44%)\n```\n\n**After:** With mcp-filter, reduced to ~13.7k tokens (72% reduction) while keeping all necessary tools.\n\n```\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26f6 \u26f6   claude-sonnet-4-5 \u00b7 80k/200k tokens (40%)\n\u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26c1 \u26f6 \u26f6 \u26f6\n\u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6   \u26c1 System: 2.3k tokens\n\u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6   \u26c1 System tools: 11.8k tokens\n\u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6   \u26c1 MCP tools: 13.7k tokens (6.9%)  \u2190 Filtered!\n\u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6 \u26f6   \u26f6 Free space: 120k (60%)  \u2190 +32k gained\n```\n\nFilter only the tools you need, save context for longer sessions.\n\n**To see your token usage:** Open Claude Code and run `/context` to view the breakdown.\n\n## What & Why\n\n- **Static allowlist** keeps the exposed tool list tiny, cutting context usage for clients that serialize tool schemas.\n- **Drop-in proxy**: stands in front of any MCP server that speaks stdio or HTTP/SSE, forwarding calls transparently.\n- **Safety guardrails**: optional regex-based deny list, optional prefix, and optional health tool for observability.\n\n## Installation\n\nPython 3.10+ is supported; 3.11 is recommended.\n\n```bash\npip install mcp-filter\n```\n\n**From source (development):**\n\n```bash\npyenv install 3.11.9\npyenv local 3.11.9\npython -m venv .venv\nsource .venv/bin/activate\npip install -e '.[dev]'\n```\n\n## Quick Start\n\n```bash\nmcp-filter run \\\n  -t stdio \\\n  --stdio-command npx \\\n  --stdio-arg \"-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN\" \\\n  -a \"execute_sql,list_tables,get_project\"\n```\n\n**Shorthand flags:** `-t` (transport), `-a` (allow-tool), `-d` (deny-pattern), `-p` (prefix)\n\n**Note:** Both `--stdio-arg` and `-a` support flexible input - use repeatable flags or comma-separated strings, whichever is cleaner for your use case.\n\n## How to Wrap Your MCP\n\n### Concept\n\nTransform any existing MCP server config by wrapping it with mcp-filter. The filter proxies your original command and only exposes the tools you specify with `-a`.\n\n**Before (original Supabase config):**\n\n```json\n{\n  \"mcpServers\": {\n    \"supabase\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"@supabase/mcp-server-supabase@latest\",\n        \"--access-token\",\n        \"YOUR_TOKEN\"\n      ]\n    }\n  }\n}\n```\n\nThis exposes all 29 tools (**~20.8k tokens**):\n\n<details>\n<summary>Show all tools</summary>\n\n```\n\u2514 mcp__supabase__search_docs (supabase): 2.8k tokens\n\u2514 mcp__supabase__list_organizations (supabase): 582 tokens\n\u2514 mcp__supabase__get_organization (supabase): 604 tokens\n\u2514 mcp__supabase__list_projects (supabase): 600 tokens\n\u2514 mcp__supabase__get_project (supabase): 603 tokens\n\u2514 mcp__supabase__get_cost (supabase): 646 tokens\n\u2514 mcp__supabase__confirm_cost (supabase): 682 tokens\n\u2514 mcp__supabase__create_project (supabase): 832 tokens\n\u2514 mcp__supabase__pause_project (supabase): 599 tokens\n\u2514 mcp__supabase__restore_project (supabase): 599 tokens\n\u2514 mcp__supabase__list_tables (supabase): 640 tokens\n\u2514 mcp__supabase__list_extensions (supabase): 596 tokens\n\u2514 mcp__supabase__list_migrations (supabase): 596 tokens\n\u2514 mcp__supabase__apply_migration (supabase): 668 tokens\n\u2514 mcp__supabase__execute_sql (supabase): 657 tokens\n\u2514 mcp__supabase__get_logs (supabase): 677 tokens\n\u2514 mcp__supabase__get_advisors (supabase): 699 tokens\n\u2514 mcp__supabase__get_project_url (supabase): 599 tokens\n\u2514 mcp__supabase__get_anon_key (supabase): 601 tokens\n\u2514 mcp__supabase__generate_typescript_types (supabase): 600 tokens\n\u2514 mcp__supabase__list_edge_functions (supabase): 603 tokens\n\u2514 mcp__supabase__get_edge_function (supabase): 625 tokens\n\u2514 mcp__supabase__deploy_edge_function (supabase): 907 tokens\n\u2514 mcp__supabase__create_branch (supabase): 718 tokens\n\u2514 mcp__supabase__list_branches (supabase): 625 tokens\n\u2514 mcp__supabase__delete_branch (supabase): 596 tokens\n\u2514 mcp__supabase__merge_branch (supabase): 603 tokens\n\u2514 mcp__supabase__reset_branch (supabase): 636 tokens\n\u2514 mcp__supabase__rebase_branch (supabase): 617 tokens\n```\n\n</details>\n\n**After (wrapped with mcp-filter):**\n\n```json\n{\n  \"mcpServers\": {\n    \"supabase\": {\n      \"command\": \"mcp-filter\",\n      \"args\": [\n        \"run\",\n        \"-t\",\n        \"stdio\",\n        \"--stdio-command\",\n        \"npx\",\n        \"--stdio-arg\",\n        \"-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN\",\n        \"-a\",\n        \"execute_sql,list_tables,get_project\"\n      ]\n    }\n  }\n}\n```\n\nThis only exposes 3 tools we allowed (**~1.9k tokens** = 91% reduction!):\n\n```\n\u2514 mcp__supabase__get_project (supabase): 605 tokens\n\u2514 mcp__supabase__list_tables (supabase): 642 tokens\n\u2514 mcp__supabase__execute_sql (supabase): 659 tokens\n```\n\n### Examples for Claude Code / Claude Desktop\n\n`examples/mcp.json.sample` includes common setups. Add to your `mcp.json`:\n\n**Supabase (stdio)** \u2013 wrap the official MCP binary:\n\n```json\n\"supabase\": {\n  \"command\": \"mcp-filter\",\n  \"args\": [\n    \"run\",\n    \"-t\", \"stdio\",\n    \"--stdio-command\", \"npx\",\n    \"--stdio-arg\", \"-y @supabase/mcp-server-supabase@latest --access-token YOUR_TOKEN\",\n    \"-a\", \"execute_sql,list_tables,get_project\"\n  ]\n}\n```\n\n**Linear (stdio wrapping mcp-remote)** \u2013 preserves OAuth browser flow:\n\n```json\n\"linear\": {\n  \"command\": \"mcp-filter\",\n  \"args\": [\n    \"run\",\n    \"-t\", \"stdio\",\n    \"--stdio-command\", \"npx\",\n    \"--stdio-arg\", \"-y mcp-remote https://mcp.linear.app/sse\",\n    \"-a\", \"get_issue,list_issues,create_issue,update_issue,create_comment\"\n  ]\n}\n```\n\nAdjust auth-tokens/headers to match your environment; the filter never logs or exposes them.\n\n## Configuration Reference\n\nEnvironment variables (prefixed with `MF_`) override CLI flags. See `.env.example` for a template.\n\n- `MF_TRANSPORT` / `-t`: `stdio` (default) or `http`\n- `MF_STDIO_COMMAND` / `MF_STDIO_ARGS`: upstream binary + args\n- `MF_HTTP_URL` / `MF_HTTP_HEADERS`: SSE/HTTP endpoint and extra headers (`key=value;Another=Value`)\n- `MF_ALLOW_TOOLS` / `-a`: exact tool names (repeatable, or comma-separated)\n- `MF_ALLOW_PATTERNS`: regex patterns for tool names (repeatable, or comma-separated)\n- `MF_DENY_PATTERNS` / `-d`: regex patterns to block (repeatable, or comma-separated)\n- `MF_RENAME_PREFIX` / `-p` / `--prefix`: prefix exposed tool names (e.g., `supabase_`)\n- `MF_INCLUDE_HEALTH_TOOL=1` / `--health`: enable built-in health tool (disabled by default)\n- `MF_SHOW_TOKEN_ESTIMATES=1`: enable token estimate logging (disabled by default)\n\n## FAQ\n\n**Can I expose more than one tool?** Yes\u2014pass multiple `--allow-tool` flags or use regex patterns. All exposed tools share the optional rename prefix.\n\n**Are my credentials safe?** Yes. The filter never logs secrets passed as CLI arguments or headers.\n\n**What if the upstream goes down?** Health checks surface the failure while the filter continues to reject new calls with a clear error.\n\n**Can I merge config files?** Env + CLI merging is built in. For more complex setups, script the CLI invocation or add a thin wrapper that loads `mf.toml` and passes flags.\n\n## Advanced\n\n### Observability & Health\n\n- Rich-based structured logging annotates server name, transport, and exposed tool count.\n- Optional built-in health tool (disabled by default, ~500 tokens per server) returns upstream liveness and exposed tool names; output is safe JSON. Enable with `MF_INCLUDE_HEALTH_TOOL=1` or `--health`.\n\n### Security Notes\n\n- Only tools explicitly allowlisted or matching an allow regex are exposed.\n- Deny-patterns apply last to ensure sensitive tools stay hidden.\n- Optional rename prefix avoids tool collisions when multiple filtered proxies run side-by-side.\n- Health payload (when enabled) avoids secrets\u2014only structural metadata is emitted.\n- **Credentials & secrets**: Arguments and headers passed via CLI flags are never logged. For production deployments, prefer environment variables (e.g., `MF_STDIO_ARGS`) to avoid exposing credentials in process lists.\n\n### Requirements\n\n- Python 3.10+ (3.11 recommended)\n- `mcp>=1.0.0` and `fastmcp>=0.3.0` (installed automatically)\n- Upstream tool list is fixed per session; mid-run changes require restart\n- HTTP transport requires SSE-compatible upstream servers\n\n## Roadmap\n\n### v0.2.0 (Planned)\n\n**Schema Pruning** \u2014 Additional 30-60% token reduction\n\n- Add `--prune-schema [off|safe|aggressive]` to strip non-essential schema fields\n- Safe mode: remove `title`, `description`, `examples`, `default` while preserving contract\n- Aggressive mode: strip all descriptions except top-level (\u2264140 chars)\n\n**Enhanced Error Handling**\n\n- Return proper JSON-RPC error codes (e.g., `-32602` for blocked tools)\n- Include helpful error details: `{\"public_tools\": [...], \"tool_requested\": \"...\", \"reason\": \"not_allowlisted\"}`\n\n**Collision-Safe Naming**\n\n- Replace collision failures with deterministic suffixes (`tool_name_{hash[:4]}`)\n- Log warnings but continue operation\n\n**Full JSON Schema Validation**\n\n- Validate tool arguments locally before forwarding upstream\n- Provide clear, early error messages for invalid calls\n- Compile schemas at startup for performance\n\n**Structured Logging & Monitoring**\n\n- Add `--log-format [pretty|json]` for production-friendly JSON lines\n- Add `--redact-keys` to automatically redact sensitive field names\n- Expose metrics for blocked calls, latency, and tool usage\n\n**Operational Controls**\n\n- Add `--timeout-ms` (default: 120000) for per-call timeouts\n- Add `--max-concurrency` (default: 8) to limit parallel upstream calls\n\n**Resources & Prompts Filtering**\n\n- Add `--allow-resources` and `--allow-prompts` (off by default)\n- Apply same pattern-based filtering as tools\n\n### Future Considerations\n\n- Multi-upstream mode: `--upstream NAME=cmd...` for managing multiple filtered servers\n- Compressor mode: meta-tools with on-demand forwarding (separate from filter mode)\n- Built-in deny presets: `--deny-dangerous-verbs` to block destructive operations by default\n\n## Testing\n\n```bash\nsource .venv/bin/activate\npython -m pytest\n```\n\nThe suite exercises filtering precedence, rename collisions, schema validation, health handling, and call forwarding against a fake upstream server.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "MCP server proxy that exposes a filtered tool surface from upstream servers.",
    "version": "0.1.0",
    "project_urls": null,
    "split_keywords": [
        "filter",
        " mcp",
        " model-context-protocol",
        " proxy"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9268cbd6a72bcdae79d82c51fe0d88b18b6d2b110563a34e88316d0ae401093a",
                "md5": "483e7e0693fd44772cdd63e082805224",
                "sha256": "d2175206ec4f7e7d4374abfc5f92234d3ecf7e398de80c103aa52fbc13db2d0f"
            },
            "downloads": -1,
            "filename": "mcp_filter-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "483e7e0693fd44772cdd63e082805224",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 18464,
            "upload_time": "2025-10-11T06:08:22",
            "upload_time_iso_8601": "2025-10-11T06:08:22.430861Z",
            "url": "https://files.pythonhosted.org/packages/92/68/cbd6a72bcdae79d82c51fe0d88b18b6d2b110563a34e88316d0ae401093a/mcp_filter-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "41a66de00a67249b1fc0d14d5df2daf2bb574b78688eed0a8c26225515f1add5",
                "md5": "6343286c66ed753b4b7d5df13f41edf9",
                "sha256": "62c8c84fa1db1359e126cca3ff3fc1f42c934fbaec4125a799a6dfce3ac1f1eb"
            },
            "downloads": -1,
            "filename": "mcp_filter-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "6343286c66ed753b4b7d5df13f41edf9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 3259577,
            "upload_time": "2025-10-11T06:08:29",
            "upload_time_iso_8601": "2025-10-11T06:08:29.966214Z",
            "url": "https://files.pythonhosted.org/packages/41/a6/6de00a67249b1fc0d14d5df2daf2bb574b78688eed0a8c26225515f1add5/mcp_filter-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-11 06:08:29",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "mcp-filter"
}
        
Elapsed time: 1.10157s