1. Conduid
  2. Browser
  3. Dynamic MCP
MCP server · Browser

Dynamic MCP

MCP proxy server that reduces LLM context overhead with on-demand tool loading from multiple upstream servers.

Unclaimed MIT last commit 6 months ago aillmmcpmodel-context-protocolproxy
39Low

Scored 4 days ago · breakdown

About Dynamic MCP

Dynamic MCP is an MCP server published by asyrjasalo in the Browser category: mCP proxy server that reduces LLM context overhead with on-demand tool loading from multiple upstream servers.

The repository has 12 stars and 7 forks, with the last commit 6 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.

Install

From source
git clone https://github.com/asyrjasalo/dynamic-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Dynamic MCP

Powered by Claude · Grounded in docs

I know everything about Dynamic MCP. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 2 days ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.

1 check has not been run yet.

Releases

v1.5.0Release v1.5.0 · 13 Feb 2026Added Per-Server Timeout Configuration - Custom timeouts per server for tools, resources, and prompts Add `"timeout": { "tools": "30s", "resources": "30s", "prompts": "30s" }` to any server config Supports formats: `30s`, `1min`, `1m`,…
v1.4.0Release v1.4.0 · 12 Jan 2026Added Per-Server Enable/Disable Control - Optional `enabled` field to disable specific MCP servers Add `"enabled": false` to any server config to skip connection Defaults to `true` when omitted (all servers enabled by default) Clean way to…
v1.3.0Release v1.3.0 · 9 Jan 2026Added Per-Server Feature Flags - Control which MCP APIs are exposed per server Optional `features` field in server config (tools, resources, prompts) Opt-out design: all features enabled by default for backward compatibility Clear error…
v1.2.0Release v1.2.0 · 8 Jan 2026Added Multi-Tool Import Support - Automatically import configs from 10 AI coding tools Cursor, OpenCode, Claude Desktop, Claude Code CLI, VS Code Cline, KiloCode, Codex CLI, Gemini CLI, Google Antigravity Enhanced CLI - `--global` flag for…
v1.1.0Release v1.1.0 · 7 Jan 2026Added Python package distribution via PyPI with maturin bindings Windows ARM64 platform support in release binaries CHANGELOG.md included in GitHub release notes Changed Binary renamed from `dynamic-mcp` to `dmcp` for consistency with…

README

dynamic-mcp

MCP proxy server that reduces LLM context overhead by grouping tools from multiple upstream MCP servers and loading tool schemas on-demand.

Instead of requiring you to expose all MCP servers upfront (which can consume thousands of tokens), dynamic-mcp exposes only two MCP tools initially.

It supports tools, resources, and prompts from upstream MCP servers with stdio, HTTP, and SSE transports, handles OAuth, and automatically retries failed connections.

Quick Start

Installation

Option 1: Python package

Use uvx to run the PyPI package in your agent's MCP settings:

{
  "mcpServers": {
    "dynamic-mcp": {
      "command": "uvx",
      "args": ["dmcp", "/path/to/your/dynamic-mcp.json"]
    }
  }
}

You can set the DYNAMIC_MCP_CONFIG environment variable and omit the config path.

Option 2: Native binary

Download a release for your operating system and put dmcp in your PATH:

{
  "mcpServers": {
    "dynamic-mcp": {
      "command": "dmcp"
    }
  }
}

Set the DYNAMIC_MCP_CONFIG environment variable and omit the args altogether.

Option 3: Compile from source

Install from crates.io:

cargo install dynamic-mcp

The binary is then available at ~/.cargo/bin/dmcp ($CARGO_HOME/bin/dmcp).

Import from AI Coding Tools

Dynamic-mcp can automatically import MCP server configurations from popular AI coding tools.

Supported Tools (<tool-name>):

  • Cursor (cursor)
  • OpenCode (opencode)
  • Claude Desktop (claude-desktop)
  • Claude Code CLI (claude)
  • Visual Studio Code (vscode)
  • Cline (cline)
  • KiloCode (kilocode)
  • Codex CLI (codex)
  • Gemini CLI (gemini)
  • Google Antigravity (antigravity)

Quick Start

Import from project config (run in project directory):

dmcp import <tool-name>

Import from global/user config:

dmcp import --global <tool-name>

Force overwrite (skip confirmation prompt):

dmcp import <tool-name> --force

The command will:

  1. Detect your tool's config location
  2. Parse the existing MCP servers
  3. Interactively prompt for descriptions
  4. Interactively prompt for feature selection (tools, resources, prompts)
  5. Normalize environment variable formats
  6. Generate dynamic-mcp.json

Example Import

$ dmcp import cursor

🔄 Starting import from cursor to dynamic-mcp format
📖 Reading config from: .cursor/mcp.json

✅ Found 2 MCP server(s) to import

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Server: filesystem
Type: stdio

Config details:
  command: "npx"
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

💬 Enter description for 'filesystem' (what this server does): File operations on /tmp directory

🔧 Keep all features (tools, resources, prompts) for 'filesystem'? [Y/n]:
(press Enter to keep all features, or 'n' to customize)

[... prompts for other servers ...]

✅ Import complete!
📝 Output saved to: dynamic-mcp.json

Feature Selection: During import, you can customize which MCP features are enabled per server:

  • Press Enter (or Y) to keep all features (tools, resources, prompts)
  • Type 'n' to selectively enable/disable individual features
  • This allows fine-grained control without manually editing the config file

Example of custom feature selection:

🔧 Keep all features (tools, resources, prompts) for 'server'? [Y/n]: n

  Select features to enable (press Enter to accept default):
  Enable tools? [Y/n]: y
  Enable resources? [Y/n]: n
  Enable prompts? [Y/n]: n

Tool-Specific Notes

  • Cursor: Supports both .cursor/mcp.json (project) and ~/.cursor/mcp.json (global)
  • Claude Desktop: Global config only, location varies by OS:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json
    • Linux: ~/.config/Claude/claude_desktop_config.json
  • Claude Code CLI: Supports both .mcp.json (project root) and ~/.claude.json (user/global)
  • Gemini CLI: Supports both .gemini/settings.json (project) and ~/.gemini/settings.json (global)
  • VS Code: Supports both .vscode/mcp.json (project) and user-level config (OS-specific paths)
  • OpenCode: Supports both JSON and JSONC formats (JSON with comments)
  • Codex CLI: Global only - uses TOML format (~/.codex/config.toml)
  • Antigravity: Global only - ~/.gemini/antigravity/mcp_config.json

Environment Variable Conversion

The import command automatically normalizes environment variables to dynamic-mcp's ${VAR} format:

Tool Original Format Converted To
Cursor ${env:GITHUB_TOKEN} ${GITHUB_TOKEN}
Claude Desktop ${GITHUB_TOKEN} ${GITHUB_TOKEN}
Claude Code CLI ${GITHUB_TOKEN} ${GITHUB_TOKEN}
VS Code ${env:GITHUB_TOKEN} ${GITHUB_TOKEN}
Codex "${GITHUB_TOKEN}" ${GITHUB_TOKEN}

Note: VS Code's ${input:ID} secure prompts cannot be automatically converted. You'll need to manually configure these after import.

See docs/IMPORT.md for detailed tool-specific import guides.

Dynamic MCP format

Calling upstream servers on demand

Create a dynamic-mcp.json file with a description field for each server:

{
  "mcpServers": {
    "filesystem": {
      "description": "Use when you need to read, write, or search files.",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    }
  }
}

Environment Variables

It supports the ${VAR} syntax for environment variable interpolation:

{
  "mcpServers": {
    "example": {
      "description": "Example with env vars",
      "command": "node",
      "args": ["${HOME}/.local/bin/server.js"],
      "env": {
        "API_KEY": "${MY_API_KEY}"
      }
    }
  }
}

Server Types

It supports all standard MCP transport mechanisms.

Note: The type field is optional when url is present. If omitted, the server automatically uses HTTP transport with SSE detection per the MCP spec. This maintains backwards compatibility with tools like OpenCode.

stdio (Default)

{
  "description": "Server description for LLM",
  "command": "npx",
  "args": ["-y", "package-name"],
  "env": {
    "KEY": "value"
  }
}

http

{
  "description": "HTTP server (type is optional)",
  "url": "https://api.example.com",
  "headers": {
    "Authorization": "Bearer ${TOKEN}"
  }
}

Or with explicit type:

{
  "type": "http",
  "description": "HTTP server with explicit type",
  "url": "https://api.example.com",
  "headers": {
    "Authorization": "Bearer ${TOKEN}"
  }
}

sse

SSE servers are automatically detected when the server responds with Content-Type: text/event-stream. You can also explicitly specify type: "sse" if the server only supports SSE:

{
  "type": "sse",
  "description": "SSE server (explicit type required only if server doesn't auto-detect)",
  "url": "https://api.example.com/sse",
  "headers": {
    "Authorization": "Bearer ${TOKEN}"
  }
}

OAuth Authentication (HTTP/SSE)

{
  "description": "OAuth-protected MCP server (type is optional)",
  "url": "https://api.example.com/mcp",
  "oauth_client_id": "your-client-id",
  "oauth_scopes": ["read", "write"]
}

OAuth Flow:

  • On first connection, a browser opens for authorization
  • Access tokens are stored in ~/.dynamic-mcp/oauth-servers/<server-name>.json
  • Automatic token refresh before expiry (with RFC 6749 token rotation support)
  • The token is injected as an Authorization: Bearer <token> header

Feature Flags

Control which MCP features are exposed per server using the optional features field. By default, all features (tools, resources, prompts) are enabled. You can selectively disable features:

{
  "mcpServers": {
    "server-with-tools-only": {
      "description": "Server that only exposes tools",
      "command": "npx",
      "args": ["-y", "some-mcp-server"],
      "features": {
        "resources": false,
        "prompts": false
      }
    },
    "server-without-prompts": {
      "description": "HTTP server without prompt templates (type is optional)",
      "url": "https://api.example.com",
      "features": {
        "prompts": false
      }
    }
  }
}

Behavior:

  • If features is omitted, all features are enabled (opt-out design)
  • If features is specified, unmentioned features default to true (enabled)
  • Disabled features return an error if accessed via the proxy
  • Example: If resources: false, calling resources/list returns an error

Disabling Servers

Use the optional enabled field to disable a specific server without removing it from the config:

{
  "mcpServers": {
    "filesystem": {
      "description": "File operations",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    },
    "disabled-server": {
      "description": "This server won't connect",
      "command": "some-command",
      "enabled": false
    }
  }
}

Behavior:

  • If enabled is omitted, the server is enabled (default behavior)
  • If enabled: false, the server is skipped during connection and won't appear in available groups
  • Useful for temporarily disabling servers during testing or maintenance without editing config structure
  • See examples/config.features.example.json for a complete example

Timeout Configuration

Configure custom timeouts for tool, resource, and prompt calls per server using the optional timeout field. By default:

  • Tool calls: 30 seconds
  • Resource calls: 10 seconds
  • Prompt calls: 10 seconds

You can customize these for servers that need more time:

{
  "mcpServers": {
    "slow-server": {
      "description": "Server with slow operations",
      "command": "npx",
      "args": ["-y", "some-slow-mcp-server"],
      "timeout": {
        "tools": "1min",
        "resources": "30s",
        "prompts": "30s"
      }
    }
  }
}

Supported duration formats:

Format Example Description
Seconds "30s", "5s" Simple seconds
Minutes "1min", "2m" Minutes (abbreviated or full)
Milliseconds "3000ms", "500ms" Milliseconds
Plain number 30 Seconds (plain number)

Behavior:

  • If timeout is omitted, defaults are used (tools: 30s, resources: 10s, prompts: 10s)
  • Individual timeout fields default to their respective defaults if not specified
  • Applies only to tool/resource/prompt call operations, not to connection or initialization
  • Useful for servers with long-running operations (database queries, file processing, etc.)

Troubleshooting

Server Connection Issues

Problem: ❌ Failed to connect to <server>

Solutions:

  • Connection timeout: Each server has 10-second timeout for transport creation, initialization, and tool listing
  • Automatic retry: Failed servers are retried up to 3 times with exponential backoff (2s, 4s, 8s)
  • Periodic retry: Failed servers are retried every 30 seconds in the background
  • Slow HTTP servers: If remote HTTP/SSE servers are slow, they'll timeout and be retried automatically
  • Stdio servers: Verify command exists (which <command>)
  • HTTP/SSE servers: Check that the server is running and the URL is correct
  • Environment variables: Ensure all ${VAR} references are defined
  • OAuth servers: Complete OAuth flow when prompted

Logging:

By default, errors and warnings are logged to the terminal. For more verbose output:

# Debug mode (all logs including debug-level details)
RUST_LOG=debug uvx dmcp config.json

# Info mode (includes informational messages)
RUST_LOG=info uvx dmcp config.json

# Default mode (errors and warnings only, no RUST_LOG needed)
uvx dmcp config.json

OAuth Authentication Problems

Problem: The browser doesn't open for OAuth

Solutions:

  • Manually open the URL shown in the console
  • Check that the firewall allows localhost connections
  • Verify oauth_client_id is correct for the server

Problem: Token refresh fails

Solutions:

  • Delete cached token: rm ~/.dynamic-mcp/oauth-servers/<server-name>.json
  • Re-authenticate on next connection

Environment Variable Not Substituted

Problem: Config shows ${VAR} instead of value

Solutions:

  • Use ${VAR} syntax, not $VAR
  • Export variable: export VAR=value
  • Variable names are case-sensitive
  • Check for typos in variable name

Configuration Errors

Problem: Server missing 'description' field

Solutions:

  • Every MCP server in your config must have a description field

  • The description explains what the server does to the LLM

  • Example:

    {
      "description": "File system access - read, write, and search files",
      "command": "npx",
      "args": ["@modelcontextprotocol/server-filesystem"]
    }
    

Problem: Invalid JSON in config file

Solutions:

  • Validate JSON syntax (use jq . config.json)
  • Check for trailing commas
  • Ensure all required fields are present (description is always required; type is required only for http/sse servers)

Problem: Unknown field in config (e.g., unknown field \typo_field``)

Solutions:

  • dynamic-mcp uses strict JSON schema validation that only allows defined fields
  • Check for typos in field names: description, command, url, type, args, env, headers, oauth_client_id, oauth_scopes, features, enabled, timeout
  • Remove any extra or misspelled fields from your config
  • Refer to the schema examples above to see valid fields for each server type

Problem: Failed to resolve config path

Solutions:

  • Use an absolute path or a path relative to the working directory
  • Check that the file exists and has read permissions
  • Try: ls -la <config-path>

Tool Call Failures

Problem: Tool call returns error

Debugging:

  1. Test the tool directly with the upstream server
  2. Check that the tool name and arguments match the schema
  3. Verify the group name is correct
  4. Enable debug logging to see JSON-RPC messages

Performance Issues

Problem: Slow startup

Solutions:

  • Parallel connections already enabled
  • Check network latency for HTTP/SSE servers
  • Some servers may be slow to initialize (normal)

Problem: High memory usage

Solutions:

  • Tools are cached in memory (expected)
  • Failed groups use minimal memory
  • Large tool schemas contribute to memory usage

Building from source

Rust Binary

To build the Rust binary directly:

git clone https://github.com/asyrjasalo/dynamic-mcp.git
cd dynamic-mcp
cargo build --release

The binary is then available at ./target/release/dmcp.

Python Package

To build the Python package (wheel):

# Build wheel
uvx maturin build --release

# Install locally
pip install target/wheels/dmcp-*.whl

The Python package uses maturin with bindings = "bin" to compile the Rust binary directly into the wheel.

Contributing

For instructions on development setup, testing, and contributing, see CONTRIBUTING.md.

Release History

See CHANGELOG.md for version history and release notes.

Acknowledgments

README fetched from the repository 2 days ago. The original is authoritative.

Questions

About Dynamic MCP

How do I install Dynamic MCP?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Dynamic MCP safe to use with an AI agent?

Its trust score is 39 out of 100 (low). It passes 5 of the 5 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Dynamic MCP still maintained?

The last commit was 6 months ago and 4 open issues. That's long enough that you should check whether the maintainer is responding to issues before depending on it.