diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..cbcaa67c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# Claude Project Conventions + +This file contains conventions that Claude should follow when working on this project. + +- **Formatting:** Always format Python code with `ruff`. +- **Dependency Management:** Use `uv` for all Python dependency management. +- **Committing:** Always double-check with the user before committing changes to git. \ No newline at end of file diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 00000000..a09c4ac8 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,7 @@ +# Gemini Project Conventions + +This file contains conventions that Gemini should follow when working on this project. + +- **Formatting:** Always format Python code with `ruff`. +- **Dependency Management:** Use `uv` for all Python dependency management. +- **Committing:** Always double-check with the user before committing changes to git. \ No newline at end of file diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md new file mode 100644 index 00000000..69d1b5c7 --- /dev/null +++ b/MIGRATION_GUIDE.md @@ -0,0 +1,270 @@ +# MCPM v2.0 Migration Guide + +This guide helps existing MCPM v1 users transition to the new simplified global configuration model. + +## What's New in v2.0 + +### Simplified Architecture +- **Global Server Configuration**: All servers managed in a single global configuration +- **Virtual Profiles**: Profiles are now tags on servers, not separate configurations +- **Direct Execution**: Run servers directly without complex router setup +- **Beautiful CLI**: Enhanced interface with rich formatting and better organization +- **Client Integration**: Manage multiple MCP clients from one place + +### Key Improvements +- **Faster Startup**: No daemon dependencies, direct stdio execution +- **Better Performance**: Direct execution eliminates router complexity +- **Enhanced Usability**: Centralized server management, easy profile organization +- **Developer Tools**: Built-in inspector, HTTP testing, public sharing +- **Usage Analytics**: Track and analyze server usage patterns + +## Automatic Migration + +MCPM v2.0 includes an automatic migration system that detects v1 configurations and guides you through the upgrade process. + +### Migration Process + +When you run any MCPM command with v1 configuration present, you'll see: + +1. **Welcome Screen**: Introduction to v2.0 with migration options +2. **Configuration Analysis**: Review of your current v1 setup +3. **v2.0 Features**: Overview of new capabilities and improvements +4. **Breaking Changes**: Important changes that affect your workflow +5. **Migration Choice**: Three options for proceeding + +### Migration Options + +#### Option 1: Migrate (Recommended) +``` +Y - Migrate to v2 (recommended) +``` +- Converts your v1 profiles to v2 virtual profiles +- Migrates all servers to global configuration +- Preserves your existing setup while upgrading to v2 +- Creates backup of v1 configuration files + +#### Option 2: Start Fresh +``` +N - Start fresh with v2 (backup v1 configs) +``` +- Backs up your v1 configuration safely +- Starts with a clean v2 installation +- Removes v1 files after backup +- Good option if you want to reorganize from scratch + +#### Option 3: Ignore for Now +``` +I - Ignore for now (continue with current command) +``` +- Continues with your current command +- Keeps v1 configuration unchanged +- Can migrate later with `mcpm migrate` +- Some v2 features may not work properly + +### Manual Migration + +You can also trigger migration manually: + +```bash +mcpm migrate +``` + +This shows the same migration assistant as the automatic detection. + +## Command Changes + +### Main Commands + +| **v1 Command** | **v2 Command** | **Notes** | +|----------------|----------------|-----------| +| `mcpm add SERVER` | `mcpm install SERVER` | Cleaner naming | +| `mcpm rm SERVER` | `mcpm uninstall SERVER` | Cleaner naming | +| `mcpm ls` | `mcpm ls` | Same command, enhanced output | +| `mcpm target set` | *Removed* | No longer needed | +| `mcpm router start` | `mcpm run --http` | Direct HTTP execution | +| `mcpm share` | `mcpm share` | Simplified sharing | + +### Profile Commands + +| **v1 Command** | **v2 Command** | **Notes** | +|----------------|----------------|-----------| +| `mcpm target create %profile` | `mcpm profile create PROFILE` | Virtual profiles | +| `mcpm add SERVER --target %profile` | `mcpm profile edit PROFILE` | Interactive management | +| `mcpm target use %profile` | `mcpm profile run PROFILE` | Execute profile servers | +| `N/A` | `mcpm profile share PROFILE` | New: Share entire profiles | + +### New Commands + +| **Command** | **Description** | +|------------|----------------| +| `mcpm doctor` | System health check and diagnostics | +| `mcpm usage` | Comprehensive analytics and usage data | +| `mcpm inspect SERVER` | Launch MCP Inspector for server testing | +| `mcpm client ls` | List and manage MCP clients | +| `mcpm client edit CLIENT` | Configure client server selections | +| `mcpm client import CLIENT` | Import configurations from clients | +| `mcpm config` | Manage MCPM configuration settings | + +## Migration Examples + +### Before v2.0 (v1 workflow) +```bash +# Complex target-based workflow +mcpm target create @cursor +mcpm target set @cursor +mcpm add mcp-server-browse +mcpm add mcp-server-git + +mcpm target create %web-dev +mcpm add mcp-server-browse --target %web-dev +mcpm add mcp-server-git --target %web-dev + +mcpm router start +mcpm share mcp-server-browse +``` + +### After v2.0 (simplified workflow) +```bash +# Simple global configuration +mcpm install mcp-server-browse +mcpm install mcp-server-git + +# Create and organize with profiles +mcpm profile create web-dev +mcpm profile edit web-dev # Interactive server selection + +# Direct execution and sharing +mcpm run mcp-server-browse +mcpm share mcp-server-browse +mcpm profile run web-dev +mcpm profile share web-dev +``` + +## Client Integration + +### Before: Complex Router Setup +```json +{ + "mcpServers": { + "mcpm-router": { + "command": ["mcpm", "router", "run"], + "args": ["--port", "3000"] + } + } +} +``` + +### After: Direct Execution +```json +{ + "mcpServers": { + "browse": { + "command": ["mcpm", "run", "mcp-server-browse"] + }, + "git": { + "command": ["mcpm", "run", "mcp-server-git"] + } + } +} +``` + +Or use MCPM's client management: +```bash +mcpm client edit claude-desktop # Interactive configuration +mcpm client edit cursor # Select servers for Cursor +``` + +## Post-Migration Workflow + +### 1. Verify Migration +```bash +mcpm ls # See all migrated servers +mcpm profile ls # See migrated profiles +mcpm run SERVER-NAME # Test server execution +``` + +### 2. Explore New Features +```bash +mcpm client ls # See detected MCP clients +mcpm doctor # Check system health +mcpm usage # View usage analytics +mcpm inspect SERVER # Debug server with inspector +``` + +### 3. Organize with Profiles +```bash +mcpm profile create frontend +mcpm profile create backend +mcpm profile create ai-tools + +# Use interactive editor to assign servers +mcpm profile edit frontend +``` + +### 4. Client Integration +```bash +# Configure clients interactively +mcpm client edit claude-desktop +mcpm client edit cursor + +# Or import existing configurations +mcpm client import claude-desktop +``` + +## Troubleshooting + +### Migration Issues + +**Migration fails with profile errors** +- Check that profile servers exist in global config +- Verify server configurations are valid +- Run `mcpm doctor` for diagnostic information + +**"No v1 config found" when you have v1 files** +- Ensure files are in `~/.config/mcpm/` +- Check file permissions and format +- Try `mcpm migrate` to trigger manual migration + +**Stashed servers not migrated** +- Migration asks what to do with stashed servers +- Choose "restore" to add them to global config +- Choose "document" to save them for manual review + +### Post-Migration Issues + +**Servers not working in clients** +- Update client configurations to use `mcpm run SERVER` +- Use `mcpm client edit CLIENT` for interactive setup +- Check server status with `mcpm ls` + +**Profile commands not working** +- Profiles are now virtual tags, not separate configurations +- Use `mcpm profile edit PROFILE` to manage server assignments +- Check profile status with `mcpm profile ls` + +**Command not found errors** +- Some v1 commands have been removed or renamed +- Use `mcpm --help` to see all available commands +- Check this guide for command equivalents + +## Getting Help + +- **Health Check**: `mcpm doctor` - Diagnose system issues +- **Command Help**: `mcpm COMMAND --help` - Detailed command information +- **Migration Help**: `mcpm migrate --help` - Migration-specific options +- **Support**: https://github.com/pathintegral-institute/mcpm.sh/issues + +## Backup Information + +During migration, MCPM creates comprehensive backups: + +- **Location**: `~/.config/mcpm/backups/` +- **Contents**: Original v1 `config.json` and `profiles.json` +- **README**: Detailed backup information and recovery instructions +- **Timestamp**: Each backup includes creation timestamp + +Your original v1 configuration is never modified until you confirm migration. + +--- + +*MCPM v2.0 provides a cleaner, more powerful interface while preserving all your existing functionality. The migration process is designed to be safe and reversible.* \ No newline at end of file diff --git a/README.md b/README.md index a56fdcdf..0c400687 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Built with ❤️ by Path Integral Institute # 🌟 MCPM - Model Context Protocol Manager -MCPM is an open source service and a CLI package management tool for MCP servers. It simplifies managing server configurations across various supported clients, allows grouping servers into profiles, helps discover new servers via a registry, and includes a powerful router that aggregates multiple MCP servers behind a single endpoint with shared sessions. +MCPM is an open source CLI tool for managing MCP servers. It provides a simplified global configuration approach where you install servers once and organize them with profiles, then integrate them into any MCP client. Features include server discovery through a central registry, direct execution, sharing capabilities, and client integration tools. ![Demo of MCPM in action](.github/readme/demo.gif) @@ -37,15 +37,18 @@ Or choose [other installation methods](#-other-installation-methods) like `brew` ## 🔎 Overview -MCPM simplifies the installation, configuration, and management of Model Context Protocol servers and their configurations across different applications (clients). Key features include: +MCPM v2.0 provides a simplified approach to managing MCP servers with a global configuration model. Key features include: -- ✨ Easy addition and removal of MCP server configurations for supported clients. -- 📋 Centralized management using profiles: group server configurations together and add/remove them to client easily. -- 🔍 Discovery of available MCP servers through a central registry. -- 🔌 MCPM Router for aggregating multiple MCP servers behind a single endpoint with shared sessions. -- 💻 A command-line interface (CLI) for all management tasks. +- ✨ **Global Server Management**: Install servers once, use everywhere +- 📋 **Virtual Profiles**: Organize servers with tags for different workflows +- 🔍 **Server Discovery**: Browse and install from the MCP Registry +- 🚀 **Direct Execution**: Run servers over stdio or HTTP for testing +- 🌐 **Public Sharing**: Share servers through secure tunnels +- 🎛️ **Client Integration**: Manage configurations for Claude Desktop, Cursor, Windsurf, and more +- 💻 **Beautiful CLI**: Rich formatting and interactive interfaces +- 📊 **Usage Analytics**: Monitor server usage and performance -See [Advanced Features](docs/advanced_features.md) for more capabilities like shared server sessions and the MCPM Router. +MCPM v2.0 eliminates the complexity of v1's target-based system in favor of a clean global workspace model. ## 🖥️ Supported MCP Clients @@ -64,9 +67,7 @@ MCPM will support managing MCP servers for the following clients: ## 🔥 Command Line Interface (CLI) -MCPM provides a comprehensive CLI built with Python's Click framework. Commands generally operate on the currently **active client**. You can view/set the active client using `mcpm client`. Many commands also support scope modifiers like `@CLIENT_NAME/SERVER_NAME` or `%PROFILE_NAME/SERVER_NAME` to target specific clients or profiles directly. - -Below are the available commands, grouped by functionality: +MCPM provides a comprehensive CLI with a clean, organized interface. The v2.0 architecture uses a global configuration model where servers are installed once and can be organized with profiles, then integrated into specific MCP clients as needed. ### ℹ️ General @@ -75,109 +76,68 @@ mcpm --help # Display help information and available commands mcpm --version # Display the current version of MCPM ``` -### 🖥️ Client Management (`client`) - -```bash -mcpm client ls # List all supported MCP clients, detect installed ones, and show active client -mcpm client edit # Open the active client's MCP configuration file in an external editor -``` - -### 🌐 Server Management (`server`) +### 🌐 Server Management -These commands operate on the active client unless a specific scope (`@CLIENT` or `%PROFILE`) is provided. +Global server installation and management commands: ```bash -# 🔍 Search and Add -mcpm search [QUERY] # Search the MCP Registry for available servers -mcpm add SERVER_URL # Add an MCP server configuration (from URL or registry name) -mcpm add SERVER_URL --alias ALIAS # Add with a custom alias - -# 🛠️ Add custom server -mcpm import stdio SERVER_NAME --command COMMAND --args ARGS --env ENV # Add a stdio MCP server to a client -mcpm import remote SERVER_NAME --url URL # Add a remote MCP server to a client -mcpm import interact # Add a server by configuring it interactively - -# 📋 List and Remove -mcpm ls # List server configurations for the active client/profile -mcpm rm SERVER_NAME # Remove a server configuration - -# 🔄 Modify and Organize -mcpm cp SOURCE TARGET # Copy a server config (e.g., @client1/serverA %profileB) -mcpm mv SOURCE TARGET # Move a server config (e.g., %profileA/serverX @client2) - -# 📦 Stashing (Temporarily disable/enable) -mcpm stash SERVER_NAME # Temporarily disable/store a server configuration aside -mcpm pop [SERVER_NAME] # Restore the last stashed server, or a specific one by name +# 🔍 Search and Install +mcpm search [QUERY] # Search the MCP Registry for available servers +mcpm info SERVER_NAME # Display detailed information about a server +mcpm install SERVER_NAME # Install a server from registry to global configuration +mcpm uninstall SERVER_NAME # Remove a server from global configuration + +# 📋 List and Inspect +mcpm ls # List all installed servers and their profile assignments +mcpm edit SERVER_NAME # Edit a server configuration +mcpm inspect SERVER_NAME # Launch MCP Inspector to test/debug a server ``` -### 📂 Profile Management (`profile`) - -Profiles are named collections of server configurations. They allow you to easily switch between different sets of MCP servers. For example, you might have a `work` profile and a `personal` profile, each containing different servers. Or you might have a `production` profile and a `development` profile, each containing different configurations for the same servers. +### 🚀 Server Execution -The currently *active* profile's servers are typically used by features like the MCPM Router. Use `mcpm target set %profile_name` to set the active profile. +Execute servers directly for testing or integration: ```bash -# 🔄 Profile Lifecycle -mcpm profile ls # List all available MCPM profiles -mcpm profile add PROFILE_NAME # Add a new, empty profile -mcpm profile rm PROFILE_NAME # Remove a profile (does not delete servers within it) -mcpm profile rename OLD_NAME NEW_NAME # Rename a profile -mcpm add %profile_name # Add a profile to the active client +mcpm run SERVER_NAME # Execute a server directly over stdio +mcpm run SERVER_NAME --http # Execute a server over HTTP for testing +mcpm share SERVER_NAME # Share a server through secure tunnel for remote access +mcpm usage # Display comprehensive analytics and usage data ``` -### 🔌 Router Management (`router`) +### 📂 Profile Management -The MCPM Router runs as a background daemon process, acting as a stable endpoint (e.g., `http://localhost:6276`) that intelligently routes incoming MCP requests to the appropriate server based on the currently **active profile**. - -This allows you to change the underlying servers (by switching profiles with `mcpm target set %profile_name`) without reconfiguring your client applications. They can always point to the MCPM Router's address. - -The Router also maintains persistent connections to MCP servers, enabling multiple clients to share these server sessions. This eliminates the need to start separate server instances for each client, significantly reducing resource usage and startup time. Learn more about these advanced capabilities in [Advanced Features](docs/advanced_features.md). - -For more technical details on the router's implementation and namespacing, see [`docs/router_tech_design.md`](docs/router_tech_design.md). - -The Router can be shared in public network by `mcpm router share`. Be aware that the share link will be exposed to the public, make sure the generated secret is secure and only share to trusted users. See [MCPM Router Share](docs/router_share.md) for more details about how it works. +Profiles are virtual tags that organize servers into logical groups for different workflows: ```bash -mcpm router status # Check if the router daemon is running -mcpm router on # Start the MCP router daemon -mcpm router off # Stop the MCP router daemon -mcpm router set --host HOST --port PORT --address ADDRESS # Set the MCP router daemon's host port and the remote share address -mcpm router share # Share the router to public -mcpm router unshare # Unshare the router +# 🔄 Profile Operations +mcpm profile ls # List all profiles and their tagged servers +mcpm profile create PROFILE # Create a new profile +mcpm profile rm PROFILE # Remove a profile (servers remain installed) +mcpm profile edit PROFILE # Interactive server selection for profile + +# 🚀 Profile Execution +mcpm profile run PROFILE # Execute all servers in a profile over stdio or HTTP +mcpm profile share PROFILE # Share all servers in a profile through secure tunnel +mcpm profile inspect PROFILE # Launch MCP Inspector for all servers in profile ``` -### 🤝 Share Management (`share`) - -The `mcpm share` command allows you to take any shell command that starts an MCP server and instantly expose it as an SSE (Server-Sent Events) server. It uses `mcp-proxy` to handle the server transformation and then creates a secure tunnel for remote access, making your local MCP server accessible from anywhere. +### 🖥️ Client Integration -This is particularly useful for quickly sharing a development server, a custom MCP server, or even a standard server with specific configurations without needing to deploy it publicly. +Manage MCP client configurations (Claude Desktop, Cursor, Windsurf, etc.): ```bash -# 🚀 Share a local MCP server -mcpm share "COMMAND" # Replace COMMAND with your actual server start command - -# ⚙️ Options -# COMMAND: The shell command that starts your MCP server (e.g., "uvx mcp-server-fetch", "npx mcp-server"). This must be enclosed in quotes if it contains spaces. -# --port PORT: Specify a local port for the mcp-proxy to listen on. Defaults to a random available port. -# --address ADDRESS: Specify a public address for the tunnel (e.g., yourdomain.com:7000). If not provided, a random tunnel URL will be generated. -# --http: If set, the tunnel will use HTTP instead of HTTPS. Use with caution. -# --timeout TIMEOUT: Timeout in seconds for the mcp-proxy to wait for the server to start. Defaults to 60. -# --retry RETRY: Number of times to retry starting the server if it fails. Defaults to 0. - -# 💡 Usage Examples -mcpm share "uvx mcp-server-fetch" -mcpm share "npx mcp-server" --port 5000 -mcpm share "uv run my-mcp-server" --address myserver.com:7000 -mcpm share "npx -y @modelcontextprotocol/server-everything" --retry 3 +mcpm client ls # List all supported MCP clients and their status +mcpm client edit CLIENT_NAME # Interactive server enable/disable for a client +mcpm client edit CLIENT_NAME -e # Open client config in external editor +mcpm client import CLIENT_NAME # Import server configurations from a client ``` -### 🛠️ Utilities (`util`) +### 🛠️ System & Configuration ```bash -mcpm config clear-cache # Clear MCPM's registry cache. Cache defaults to refresh every 1 hour. -mcpm config set # Set global MCPM configuration, currently only support node_executable -mcpm config get # Get global MCPM configuration -mcpm inspector # Launch the MCPM Inspector UI to examine server configs +mcpm doctor # Check system health and server status +mcpm config # Manage MCPM configuration and settings +mcpm migrate # Migrate from v1 to v2 configuration ``` ### 📚 Registry @@ -186,20 +146,20 @@ The MCP Registry is a central repository of available MCP servers that can be in ## 🗺️ Roadmap -- [x] Landing page setup (`mcpm.sh`) -- [x] Core CLI foundation (Click) -- [x] Client detection and management (`mcpm client`) -- [x] Basic server management (`mcpm add`, `mcpm ls`, `mcpm rm`) -- [x] Registry integration (`mcpm search`, adding by name) -- [x] Router functionality (`mcpm router`) -- [x] MCP Profiles (`mcpm profile`) -- [x] Server copying/moving (`mcpm cp`, `mcpm mv`) -- [x] Server stashing (`mcpm stash`, `mcpm pop`) -- [x] Router remote share (`mcpm router share`) remotely access local router and mcp servers -- [ ] MCP Server Access Monitoring for MCPM Router (local only, absolutely no data leaving local machine) -- [ ] MCPM Router over STDIO (same powerful feature set with profile and monitoring, but single client/tenant) -- [ ] MCP Server for MCPM Router (experimental, allow MCP clients to dynamically switch between profiles, suggest new MCP servers from registry, etc.) -- [ ] Additional client support +### ✅ v2.0 Complete +- [x] Global server configuration model +- [x] Profile-based server tagging and organization +- [x] Interactive command interfaces +- [x] Client integration management (`mcpm client edit`) +- [x] Modern CLI with consistent UX +- [x] Registry integration and server discovery +- [x] Direct server execution and sharing +- [x] Import from existing client configurations + +### 🔮 Future Enhancements +- [ ] Advanced Server access monitoring and analytics +- [ ] Additional client support (gemini-cli, codex, etc.) +- [ ] Execution in docker ## 📦 Other Installation Methods diff --git a/README.zh-CN.md b/README.zh-CN.md index ca23ca62..594efa34 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -17,7 +17,7 @@ Built with ❤️ by Path Integral Institute # 🌟 MCPM - Model Context Protocol Manager -MCPM 是一个开源的服务和命令行界面(CLI),用于管理模型上下文协议(MCP)服务器。它简化了跨各种支持的客户端管理服务器配置、允许将服务器分组到配置文件中、通过注册表帮助发现新服务器,并包含一个强大的路由器,该路由器在单个端点后聚合多个 MCP 服务器并共享会话。 +MCPM 是一个开源的 CLI 工具,用于管理 MCP 服务器。它提供了简化的全局配置方法,让您一次安装服务器并使用配置文件进行组织,然后将它们集成到任何 MCP 客户端中。功能包括通过中央注册表发现服务器、直接执行、分享功能和客户端集成工具。 ![MCPM 运行演示](.github/readme/demo.gif) @@ -27,13 +27,15 @@ MCPM 是一个开源的服务和命令行界面(CLI),用于管理模型上下 ## 🚀 快速安装 -### 🔄 Shell 脚本(一行命令) +### 推荐: ```bash curl -sSL https://mcpm.sh/install | bash ``` -或选择您喜欢的安装方式: +或选择其他安装方式,如 [其他安装方式](#-其他安装方式) 中的 `brew`、`pipx`、`uv` 等。 + +## 📦 其他安装方式 ### 🍺 Homebrew @@ -53,7 +55,7 @@ pipx install mcpm uv tool install mcpm ``` -## 其他安装方式 +## 更多安装方式 ### 🐍 pip @@ -71,15 +73,18 @@ x install mcpm.sh ## 🔎 概述 -MCPM 简化了 MCP 服务器的安装、配置和管理,以及它们在不同应用程序(客户端)中的配置。主要功能包括: +MCPM v2.0 采用全局配置模型提供了管理 MCP 服务器的简化方法。主要功能包括: -- ✨ 轻松添加和删除支持的客户端的 MCP 服务器配置。 -- 📋 使用配置文件进行集中管理:将服务器配置分组并轻松激活/停用它们。 -- 🔍 通过中央注册表发现可用的 MCP 服务器。 -- 🔌 MCPM 路由器,用于在单个端点后聚合多个 MCP 服务器并共享会话。 -- 💻 用于所有管理任务的命令行界面 (CLI)。 +- ✨ **全局服务器管理**:一次安装,到处使用 +- 📋 **虚拟配置文件**:使用标签为不同工作流组织服务器 +- 🔍 **服务器发现**:从 MCP 注册表浏览和安装 +- 🚀 **直接执行**:通过 stdio 或 HTTP 运行服务器进行测试 +- 🌐 **公共分享**:通过安全隧道分享服务器 +- 🎛️ **客户端集成**:管理 Claude Desktop、Cursor、Windsurf 等的配置 +- 💻 **精美的 CLI**:丰富的格式化和交互式界面 +- 📊 **使用分析**:监控服务器使用情况和性能 -有关共享服务器会话和 MCPM 路由器等更多功能,请参阅 [高级功能](docs/advanced_features.md)。 +MCPM v2.0 摆脱了 v1 基于目标系统的复杂性,转而采用清晰的全局工作空间模型。 ## 🖥️ 支持的 MCP 客户端 @@ -98,9 +103,7 @@ MCPM 将支持为以下客户端管理 MCP 服务器: ## 🔥 命令行界面 (CLI) -MCPM 提供了一个使用 Python 的 Click 框架构建的全面 CLI。命令通常在当前**活动客户端**上操作。您可以使用 `mcpm client` 查看/设置活动客户端。许多命令还支持作用域修饰符,如 `@CLIENT_NAME/SERVER_NAME` 或 `%PROFILE_NAME/SERVER_NAME`,以直接针对特定客户端或配置文件。 - -以下是按功能分组的可用命令: +MCPM 提供了一个具有清晰、有组织界面的全面 CLI。v2.0 架构使用全局配置模型,其中服务器安装一次,可以使用配置文件进行组织,然后根据需要集成到特定的 MCP 客户端中。 ### ℹ️ 一般 @@ -109,108 +112,68 @@ mcpm --help # 显示帮助信息和可用命令 mcpm --version # 显示 MCPM 的当前版本 ``` -### 🖥️ 客户端管理 (`client`) - -```bash -mcpm client ls # 列出所有支持的 MCP 客户端,检测已安装的客户端,并显示活动客户端 -mcpm client edit # 在外部编辑器中打开活动客户端的 MCP 配置文件 -``` - -### 🌐 服务器管理 (`server`) +### 🌐 服务器管理 -这些命令在活动客户端上操作,除非提供了特定作用域(`@CLIENT` 或 `%PROFILE`)。 +全局服务器安装和管理命令: ```bash -# 🔍 搜索和添加 -mcpm search [QUERY] # 在 MCP 注册表中搜索可用服务器 -mcpm add SERVER_URL # 添加 MCP 服务器配置(从 URL 或注册表名称) -mcpm add SERVER_URL --alias ALIAS # 添加并使用自定义别名 - -# 🛠️ 自定义添加 -mcpm import stdio SERVER_NAME --command COMMAND --args ARGS --env ENV # 手动添加一个 stdio MCP 服务器 -mcpm import remote SERVER_NAME --url URL # 手动添加一个 remote MCP 服务器 -mcpm import interact # 通过交互式添加一个服务器 - -# 📋 列出和删除 -mcpm ls # 列出活动客户端/配置文件的服务器配置 -mcpm rm SERVER_NAME # 删除服务器配置 - -# 🔄 修改和组织 -mcpm cp SOURCE TARGET # 复制服务器配置(例如,@client1/serverA %profileB) -mcpm mv SOURCE TARGET # 移动服务器配置(例如,%profileA/serverX @client2) - -# 📦 暂存(临时禁用/启用) -mcpm stash SERVER_NAME # 临时禁用/存储服务器配置 -mcpm pop [SERVER_NAME] # 恢复最后暂存的服务器,或按名称恢复特定服务器 +# 🔍 搜索和安装 +mcpm search [QUERY] # 在 MCP 注册表中搜索可用服务器 +mcpm info SERVER_NAME # 显示服务器的详细信息 +mcpm install SERVER_NAME # 从注册表安装服务器到全局配置 +mcpm uninstall SERVER_NAME # 从全局配置中删除服务器 + +# 📋 列出和检查 +mcpm ls # 列出所有已安装的服务器及其配置文件分配 +mcpm edit SERVER_NAME # 编辑服务器配置 +mcpm inspect SERVER_NAME # 启动 MCP Inspector 来测试/调试服务器 ``` -### 📂 配置文件管理 (`profile`) +### 🚀 服务器执行 -配置文件是服务器配置的命名集合。它们允许您轻松切换不同的 MCP 服务器集。例如,您可能有一个 `work` 配置文件和一个 `personal` 配置文件,每个都包含不同的服务器。或者,您可能有一个 `production` 配置文件和一个 `development` 配置文件,每个都包含同一服务器的不同配置。 - -当前*活动*配置文件的服务器通常由 MCPM 路由器等功能使用。使用 `mcpm target set %profile_name` 设置活动配置文件。 +直接执行服务器进行测试或集成: ```bash -# 🔄 配置文件生命周期 -mcpm profile ls # 列出所有可用的 MCPM 配置文件 -mcpm profile add PROFILE_NAME # 添加新的空配置文件 -mcpm profile rm PROFILE_NAME # 删除配置文件(不删除其中的服务器) -mcpm profile rename OLD_NAME NEW_NAME # 重命名配置文件 +mcpm run SERVER_NAME # 通过 stdio 直接执行服务器 +mcpm run SERVER_NAME --http # 通过 HTTP 执行服务器进行测试 +mcpm share SERVER_NAME # 通过安全隧道分享服务器进行远程访问 +mcpm usage # 显示全面的分析和使用数据 ``` -### 🔌 路由器管理 (`router`) - -MCPM 路由器作为后台守护进程运行,充当稳定端点(例如 `http://localhost:6276`),根据当前**活动配置文件**智能地将传入的 MCP 请求路由到适当的服务器。 - -这允许您通过切换配置文件(使用 `mcpm target set %profile_name`)来更改底层服务器,而无需重新配置客户端应用程序。它们可以始终指向 MCPM 路由器的地址。 +### 📂 配置文件管理 -路由器还维护与 MCP 服务器的持久连接,使多个客户端能够共享这些服务器会话。这消除了为每个客户端启动单独服务器实例的需要,显著减少资源使用和启动时间。在 [高级功能](docs/advanced_features.md) 中了解有关这些高级功能的更多信息。 - -有关路由器实现和命名空间的更多技术细节,请参阅 [`docs/router_tech_design.md`](docs/router_tech_design.md)。 - -Router可以通过命令`mcpm router share`来将router分享到公网。注意确保生成的密钥没有暴露,并只分享给可信用户。有关分享的更多细节,请参阅[分享](docs/router_share.md)。 +配置文件是将服务器组织成不同工作流的逻辑组的虚拟标签: ```bash -mcpm router status # 检查路由器守护进程是否正在运行 -mcpm router on # 启动 MCP 路由器守护进程 -mcpm router off # 停止 MCP 路由器守护进程 -mcpm router set --host HOST --port PORT --address ADDRESS # 设置 MCP 路由器守护进程的主机,端口和分享的远程服务器 -mcpm router share # 将router分享到公网 -mcpm router unshare # 取消分享 +# 🔄 配置文件操作 +mcpm profile ls # 列出所有配置文件及其标记的服务器 +mcpm profile create PROFILE # 创建新配置文件 +mcpm profile rm PROFILE # 删除配置文件(服务器保持安装) +mcpm profile edit PROFILE # 为配置文件进行交互式服务器选择 + +# 🚀 配置文件执行 +mcpm profile run PROFILE # 通过 stdio 或 HTTP 执行配置文件中的所有服务器 +mcpm profile share PROFILE # 通过安全隧道分享配置文件中的所有服务器 +mcpm profile inspect PROFILE # 为配置文件中的所有服务器启动 MCP Inspector ``` -### 🤝 共享管理 (`share`) - -`mcpm share` 命令允许您将任何启动 MCP 服务器的 shell 命令,并立即将其公开为 SSE (Server-Sent Events) 服务器。它使用 `mcp-proxy` 处理服务器转换,然后创建一个安全隧道进行远程访问,使您的本地 MCP 服务器可以从任何地方访问。 +### 🖥️ 客户端集成 -这对于快速共享开发服务器、自定义 MCP 服务器,甚至具有特定配置的标准服务器(无需公开部署)特别有用。 +管理 MCP 客户端配置(Claude Desktop、Cursor、Windsurf 等): ```bash -# 🚀 共享本地 MCP 服务器 -mcpm share "COMMAND" # 将 COMMAND 替换为您的实际服务器启动命令 - -# ⚙️ 选项 -# COMMAND: 启动 MCP 服务器的 shell 命令 (例如 "uvx mcp-server-fetch", "npx mcp-server")。如果包含空格,则必须用引号括起来。 -# --port PORT: 指定 mcp-proxy 监听的本地端口。默认为随机可用端口。 -# --address ADDRESS: 指定隧道的公共地址 (例如 yourdomain.com:7000)。如果未提供,将生成随机隧道 URL。 -# --http: 如果设置,隧道将使用 HTTP 而不是 HTTPS。请谨慎使用。 -# --timeout TIMEOUT: mcp-proxy 等待服务器启动的超时时间(秒)。默认为 60。 -# --retry RETRY: 如果服务器启动失败,重试启动服务器的次数。默认为 0。 - -# 💡 使用示例 -mcpm share "uvx mcp-server-fetch" -mcpm share "npx mcp-server" --port 5000 -mcpm share "uv run my-mcp-server" --address myserver.com:7000 -mcpm share "npx -y @modelcontextprotocol/server-everything" --retry 3 +mcpm client ls # 列出所有支持的 MCP 客户端及其状态 +mcpm client edit CLIENT_NAME # 为客户端交互式启用/禁用服务器 +mcpm client edit CLIENT_NAME -e # 在外部编辑器中打开客户端配置 +mcpm client import CLIENT_NAME # 从客户端导入服务器配置 ``` -### 🛠️ 实用工具 (`util`) +### 🛠️ 系统与配置 ```bash -mcpm config clear-cache # 清除 MCPM 的注册表缓存。缓存默认每 1 小时刷新一次。 -mcpm config set # 设置 MCPM 的全局配置,目前仅支持 node_executable -mcpm config get # 获取 MCPM 的全局配置 -mcpm inspector # 启动 MCPM 检查器 UI 以检查服务器配置 +mcpm doctor # 检查系统健康状况和服务器状态 +mcpm config # 管理 MCPM 配置和设置 +mcpm migrate # 从 v1 迁移到 v2 配置 ``` ### 📚 注册表 @@ -219,20 +182,20 @@ MCP 注册表是可使用 MCPM 安装的可用 MCP 服务器的中央存储库 ## 🗺️ 路线图 -- [x] 登陆页面设置 (`mcpm.sh`) -- [x] 核心 CLI 基础 (Click) -- [x] 客户端检测和管理 (`mcpm client`) -- [x] 基本服务器管理 (`mcpm add`, `mcpm ls`, `mcpm rm`) -- [x] 注册表集成 (`mcpm search`, 按名称添加) -- [x] 路由器功能 (`mcpm router`) -- [x] MCP 配置文件 (`mcpm profile`) -- [x] 服务器复制/移动 (`mcpm cp`, `mcpm mv`) -- [x] 服务器暂存 (`mcpm stash`, `mcpm pop`) -- [x] 路由器远程分享 (`mcpm router share`) 远程访问本地路由器和 MCP 服务器 -- [x] MCPM 路由器的 MCP 服务器访问监控(仅限本地,绝对不会有数据离开本地机器) -- [ ] 通过 STDIO 的 MCPM 路由器(相同的强大功能集,具有配置文件和监控,但单客户端/租户) -- [ ] MCPM 路由器的 MCP 服务器(实验性,允许 MCP 客户端动态切换配置文件,从注册表建议新的 MCP 服务器等) -- [ ] 附加客户端支持(扩展注册表) +### ✅ v2.0 已完成 +- [x] 全局服务器配置模型 +- [x] 基于配置文件的服务器标记和组织 +- [x] 交互式命令界面 +- [x] 客户端集成管理 (`mcpm client edit`) +- [x] 具有一致 UX 的现代 CLI +- [x] 注册表集成和服务器发现 +- [x] 直接服务器执行和分享 +- [x] 从现有客户端配置导入 + +### 🔮 未来增强 +- [ ] 高级服务器访问监控和分析 +- [ ] 额外的客户端支持(gemini-cli、codex 等) +- [ ] 在 docker 中执行 ## 👨‍💻 开发 diff --git a/docs/advanced_features.md b/docs/advanced_features.md index 1881eb97..00368a4d 100644 --- a/docs/advanced_features.md +++ b/docs/advanced_features.md @@ -1,114 +1,255 @@ -# MCPM Router - -The MCPM Router is a module that allows you to aggregate multiple MCP servers (both SSE and STDIO) and expose them as a single SSE server. The router acts in a dual role: - -1. **As an MCP Client**: Connects to multiple downstream MCP servers -2. **As an MCP Server**: Provides a unified interface to upstream MCP clients - -This design allows for aggregation of capabilities from multiple MCP servers while providing a single, stable connection point for clients. The router also supports profile management to control which servers are available to specific clients. - -A key benefit of the MCPM Router is that it maintains persistent connections to MCP servers, allowing multiple clients to share these server sessions. This eliminates the need to start separate server instances for each client, significantly reducing resource usage and startup time. - -## How It Works - -The MCPM Router sits between your clients and multiple MCP servers, acting as a central hub: - -```mermaid -flowchart TD - %% Clients - client1[Claude Desktop
Profile: Study] - client2[Cursor
Profile: Development] - client3[Goose
Profile: Creativity] - - %% Router with profiles inside - subgraph router[MCPM Router] - subgraph profiles[Profiles] - studyProfile[Study Profile] - devProfile[Development Profile] - creativeProfile[Creativity Profile] - end - end - - %% Servers - concrete examples - server1[Notion MCP Server] - server2[Python Interpreter MCP Server] - server3[Image Generation MCP Server] - server4[Web Search MCP Server] - server5[Web Fetch MCP Server] - server6[Blender MCP Server] - server7[Slack MCP Server] - - %% Client to profile connections directly - client1 --> studyProfile - client2 --> devProfile - client3 --> creativeProfile - - %% Profile to server access - studyProfile --> server1 - studyProfile --> server4 - studyProfile --> server5 - - devProfile --> server1 - devProfile --> server2 - devProfile --> server4 - devProfile --> server5 - devProfile --> server7 - - creativeProfile --> server1 - creativeProfile --> server3 - creativeProfile --> server6 - - %% Styling - classDef client fill:#d4f1f9,stroke:#333,stroke-width:1px; - classDef router fill:#ffcc99,stroke:#333,stroke-width:1px; - classDef server fill:#d5e8d4,stroke:#333,stroke-width:1px; - classDef profile fill:#e1d5e7,stroke:#333,stroke-width:1px; - - class client1,client2,client3 client; - class router router; - class server1,server2,server3,server4,server5,server6,server7 server; - class studyProfile,devProfile,creativeProfile,profiles profile; +# MCPM v2.0 Advanced Features + +MCPM v2.0 provides advanced capabilities for power users, including server aggregation, sharing, analytics, and client integration. This document covers features beyond basic server management. + +## FastMCP Integration + +MCPM v2.0 uses FastMCP for server aggregation and advanced execution capabilities: + +### Profile Aggregation + +Execute multiple servers simultaneously through profiles: + +```bash +# Create a development profile +mcpm profile create web-dev +mcpm profile edit web-dev # Add: browse, git, filesystem servers + +# Run all servers in profile together +mcpm profile run web-dev --http --port 8080 +``` + +This aggregates all servers in the profile into a single endpoint, allowing clients to access multiple server capabilities through one connection. + +### Server Namespacing + +When multiple servers are aggregated, FastMCP automatically namespaces capabilities to avoid conflicts: + +- **Tools**: `browse_t_getPage`, `git_t_commitChanges` +- **Prompts**: `filesystem_p_listFiles` +- **Resources**: Prefixed by server name + +## Server Sharing and Tunneling + +### Individual Server Sharing + +Share single servers with secure tunnels: + +```bash +mcpm share mcp-server-browse +mcpm share mcp-server-git --port 9000 --subdomain git-server +``` + +### Profile Sharing + +Share entire profiles as aggregated endpoints: + +```bash +mcpm profile share web-dev +mcpm profile share ai-tools --auth --port 8080 +``` + +### Authentication and Security + +Protect shared servers with authentication: + +```bash +# Generate auth token for sharing +mcpm share my-server --auth + +# Local-only sharing for development +mcpm share my-server --local-only ``` -### Key Concepts - -#### 1. Unified Access -Clients connect only to the router, not directly to servers. The router provides a single endpoint for accessing capabilities from all connected servers. - -#### 2. Profiles -Profiles are configurations within the router that determine which servers' capabilities are exposed to each client: - -| Client | Profile | Available Servers | -| -------------- | ----------- | -------------------------------------------------------- | -| Claude Desktop | Study | Notion, Web Search, Web Fetch | -| Cursor | Development | Notion, Python Interpreter, Web Search, Web Fetch, Slack | -| Goose | Creativity | Notion, Image Generation, Blender | - -#### 3. Namespacing -The router prefixes capabilities from different servers to avoid conflicts: -- Tools: `notion_t_pageSearch` or `python_t_executeCode` -- Prompts: `image_p_generatePortrait` -- Resources: `webfetch:https://example.com` - -#### 4. Server Connections -The router supports both STDIO (command-line) and Remote (HTTP and SSE) server connections. For example: -- STDIO: Python Interpreter, Blender -- Remote: Web Search, Notion, Slack - -#### 5. Shared Server Sessions -The router maintains persistent connections to all configured servers, allowing multiple clients to share the same server sessions. This means: -- Only one instance of each server is needed regardless of client count -- Server initialization happens only once -- State can be shared across clients when appropriate -- Resources like memory and CPU usage are significantly reduced - -## Features - -- Aggregate multiple MCP servers as a single server -- Support both Remote and STDIO connections to underlying servers -- Namespace capabilities from different servers -- Expose a unified Remote server interface -- Profile-based server access control -- Dynamic configuration reloading -- Share server connections among multiple clients (no need for separate server instances per client) -- Reduce resource usage through connection pooling \ No newline at end of file +## Client Integration + +### Multi-Client Management + +Manage server configurations across multiple MCP clients: + +```bash +# List all detected clients +mcpm client ls + +# Configure servers for specific clients +mcpm client edit claude-desktop +mcpm client edit cursor +mcpm client edit windsurf +``` + +### Configuration Import/Export + +Import existing server configurations from clients: + +```bash +# Import from Claude Desktop +mcpm client import claude-desktop + +# Import from Cursor to a specific profile +mcpm client import cursor --profile development +``` + +## Analytics and Monitoring + +### Usage Analytics + +Track server usage patterns and performance: + +```bash +# View comprehensive usage data +mcpm usage + +# Server-specific analytics +mcpm usage --server mcp-server-browse + +# Profile usage patterns +mcpm usage --profile web-dev +``` + +### Health Monitoring + +Monitor system and server health: + +```bash +# Comprehensive health check +mcpm doctor + +# Check specific server health +mcpm doctor --server my-server + +# System diagnostics +mcpm doctor --verbose +``` + +## Development and Testing + +### HTTP Mode for Testing + +Run servers in HTTP mode for development and testing: + +```bash +# Single server HTTP mode +mcpm run my-server --http --port 8080 + +# Profile HTTP mode with aggregation +mcpm profile run web-dev --http --port 8080 +``` + +### MCP Inspector Integration + +Launch MCP Inspector for debugging: + +```bash +# Inspect individual servers +mcpm inspect mcp-server-browse + +# Inspect entire profiles +mcpm profile inspect web-dev +``` + +## Configuration Management + +### Global Configuration + +Manage MCPM settings and preferences: + +```bash +# View current configuration +mcpm config + +# Edit configuration interactively +mcpm config edit + +# Reset to defaults +mcpm config reset +``` + +### Environment Variables + +Control MCPM behavior with environment variables: + +```bash +# Custom config directory +export MCPM_CONFIG_DIR="~/.config/mcpm-custom" + +# Debug mode +export MCPM_DEBUG=1 + +# Custom registry URL +export MCPM_REGISTRY_URL="https://custom-registry.example.com" +``` + +## Performance Optimization + +### Server Caching + +MCPM automatically caches server metadata and configurations for better performance. + +### Connection Pooling + +FastMCP maintains connection pools for efficient server communication. + +### Resource Management + +Monitor and optimize resource usage: + +```bash +# View resource usage +mcpm usage --resources + +# Clean up unused servers +mcpm doctor --cleanup +``` + +## Migration from v1 + +### Router Replacement + +v2.0 eliminates the separate router daemon: + +```bash +# v1 router commands +mcpm router start +mcpm router share --profile web-dev + +# v2 equivalent +mcpm profile share web-dev +``` + +### Profile System Changes + +Profiles are now virtual tags instead of separate configurations: + +```bash +# v1 target-based profiles +mcpm target create %web-dev +mcpm add server --target %web-dev + +# v2 virtual profiles +mcpm profile create web-dev +mcpm profile edit web-dev # Interactive server selection +``` + +## Troubleshooting Advanced Features + +### Sharing Issues +- Check network connectivity and firewall settings +- Verify authentication tokens for protected shares +- Test local execution before sharing + +### Aggregation Problems +- Ensure all servers in profile are functional +- Check for naming conflicts between servers +- Verify FastMCP compatibility + +### Client Integration Issues +- Confirm client is supported and detected +- Check client configuration permissions +- Verify server compatibility with client + +### Performance Issues +- Monitor resource usage with `mcpm usage --resources` +- Use `mcpm doctor` for system diagnostics +- Consider reducing concurrent server count + +For additional support, see the [troubleshooting guide](https://github.com/pathintegral-institute/mcpm.sh/issues) or run `mcpm --help` for command-specific help. \ No newline at end of file diff --git a/docs/router_share.md b/docs/router_share.md index 2fbca258..36023fbb 100644 --- a/docs/router_share.md +++ b/docs/router_share.md @@ -1,46 +1,142 @@ - -# MCPM Router Share +# MCPM v2.0 Server Sharing ## Introduction -Your local MCPM Router can be shared in public network and others can connect to your router by the share link and use your configured MCPM Profile. In this document, we will explain how to use it and how it works. -## Create a share link +MCPM v2.0 provides simplified server sharing through secure tunnels. You can share individual servers or entire profiles, allowing others to access your MCP servers remotely through public URLs. + +## Share Individual Servers + +Share a single server from your global configuration: + +```bash +mcpm share SERVER_NAME +mcpm share SERVER_NAME --port 8080 +mcpm share SERVER_NAME --subdomain myserver +``` + +This creates a secure tunnel to your server, generating a public URL that others can use to connect. + +## Share Profiles + +Share all servers in a profile simultaneously: ```bash -mcpm router share -mcpm router share --profile --address
+mcpm profile share PROFILE_NAME +mcpm profile share web-dev --port 8080 ``` -There will be a share link and a secret. The final share link will be `http://
?s=&profile=`. You can share this link with others and by adding this share link to mcpm client, they can connect to your router. -If address is not specified, the share link will be proxied by our server `share.mcpm.sh`. You can also specify a custom address to share. +This aggregates all servers in the profile and makes them available through a single endpoint. -If profile is not specified, the share link will use the current active profile. If no active profile found, the user need to specify the profile manually. +## How It Works -To be noted that if your router is not on or your system sleeps, the shared link will not be accessible. +MCPM v2.0 uses FastMCP for server aggregation and secure tunneling: -## How it works +1. **Server Execution**: Servers run directly via stdio or HTTP +2. **Aggregation**: Multiple servers can be combined into a single endpoint +3. **Tunneling**: Secure tunnels expose local servers to the internet +4. **Authentication**: Optional authentication for secure access -We use a fork version of frp from [huggingface/frp](https://github.com/huggingface/frp) to create a tunnel to your local MCPM Router. You can also check the [original frp](https://github.com/fatedier/frp) for more details about frp. +## Authentication -If you want to set up your own frp tunnel, you can either build our docker image from scratch or use our published docker images for frps(server) and frpc(client) by following the instructions below. +Protect shared servers with authentication: -In your public server, you can create a frps config following the guide [here](https://github.com/huggingface/frp?tab=readme-ov-file#setting-up-a-share-server). Then start the frps container by: ```bash -docker run -d --name frps -p 7000:7000 -p 7001:7001 -v /path/to/frps.ini:/frp/frps.ini ghcr.io/pathintegral-institute/frps:latest +mcpm share SERVER_NAME --auth +mcpm profile share PROFILE_NAME --auth ``` -Then you can share the router with your own frp server by specifying the address: +This generates authentication tokens that must be included when connecting to shared servers. + +## Local-Only Sharing + +For development and testing, share servers locally without public tunnels: + ```bash -mcpm router share --address +mcpm share SERVER_NAME --local-only +mcpm run SERVER_NAME --http --port 8080 ``` -## Authentication -There will be a secret token generated for authentication. The user MUST specify the secret token as a query parameter `s=` when connecting to your router. Make sure to keep the secret token secure and only share it with trusted users. +## Examples + +### Basic Server Sharing +```bash +# Install and share a server +mcpm install mcp-server-browse +mcpm share mcp-server-browse + +# Share with custom settings +mcpm share mcp-server-browse --port 9000 --subdomain browse +``` -## Unshare +### Profile Sharing +```bash +# Create a profile and share it +mcpm profile create web-dev +mcpm profile edit web-dev # Add servers interactively +mcpm profile share web-dev +``` + +### Development Workflow +```bash +# Test locally first +mcpm run my-server --http --port 8080 + +# Share publicly when ready +mcpm share my-server --port 8080 +``` + +## Client Connection + +Clients can connect to shared servers using the provided URL: + +```json +{ + "mcpServers": { + "shared-server": { + "command": ["curl"], + "args": ["-X", "POST", "https://shared-url.example.com"] + } + } +} +``` + +## Security Considerations + +- **Authentication**: Use `--auth` for sensitive servers +- **Network Access**: Shared servers are publicly accessible +- **Resource Usage**: Monitor server resource consumption +- **Access Control**: Only share servers with trusted users + +## Troubleshooting + +**Share command fails** +- Check that the server exists: `mcpm ls` +- Verify server configuration: `mcpm inspect SERVER_NAME` +- Test local execution: `mcpm run SERVER_NAME` + +**Connection issues** +- Verify the shared URL is accessible +- Check authentication tokens if using `--auth` +- Ensure the server is still running locally + +**Profile sharing problems** +- Check profile exists: `mcpm profile ls` +- Verify profile has servers: `mcpm profile ls PROFILE_NAME` +- Test profile execution: `mcpm profile run PROFILE_NAME` + +## Migration from v1 Router + +If you were using the v1 router system: + +### Before (v1) +```bash +mcpm router start +mcpm router share --profile web-dev +``` +### After (v2) ```bash -mcpm router unshare +mcpm profile share web-dev ``` -This will stop the tunnel and remove the share link. +The v2.0 sharing system eliminates the need for a separate router daemon, providing direct and more reliable sharing capabilities. \ No newline at end of file diff --git a/docs/router_tech_design.md b/docs/router_tech_design.md index 76c2537a..8e72bae4 100644 --- a/docs/router_tech_design.md +++ b/docs/router_tech_design.md @@ -1,216 +1,207 @@ +# MCPM v2.0 Technical Architecture -# MCPM Router Technical Overview +## Overview + +MCPM v2.0 adopts a simplified architecture that eliminates the separate router daemon in favor of direct execution and FastMCP-based aggregation. This design provides better performance, reliability, and ease of use. ## Architecture ```mermaid flowchart TB - subgraph clients[Upstream Clients] - c1[MCP Client 1] - c2[MCP Client 2] - cn[MCP Client N] + subgraph clients[MCP Clients] + c1[Claude Desktop] + c2[Cursor] + c3[Windsurf] + end + + subgraph mcpm[MCPM v2.0] + gc[Global Configuration] + pm[Profile Manager] + cm[Client Manager] + sm[Server Manager] + gc --> pm + gc --> cm + gc --> sm end - subgraph router[MCPM Router] - r[MCPRouter] - rt[RouterSseTransport] - sc[ServerConnection] - pw[ProfileManager] - cw[ConfigWatcher] - r --> rt - r --> sc - r --> pw - r --> cw + subgraph execution[Execution Layer] + fe[FastMCP Engine] + sh[Sharing System] + ht[HTTP Transport] + st[STDIO Transport] + fe --> sh + fe --> ht + fe --> st end - subgraph servers[Downstream Servers] - s1[MCP Server 1] - s2[MCP Server 2] - sm[MCP Server M] + subgraph servers[MCP Servers] + s1[Server 1] + s2[Server 2] + s3[Server N] end - c1 <--SSE--> rt - c2 <--SSE--> rt - cn <--SSE--> rt + c1 --> cm + c2 --> cm + c3 --> cm - sc <--STDIO/SSE--> s1 - sc <--STDIO/SSE--> s2 - sc <--STDIO/SSE--> sm + pm --> fe + sm --> fe + + st --> s1 + st --> s2 + ht --> s3 classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; - classDef routerClass fill:#e1f5fe,stroke:#0277bd,stroke-width:2px; - class router routerClass; + classDef mcpmClass fill:#e1f5fe,stroke:#0277bd,stroke-width:2px; + classDef executionClass fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px; + class mcpm mcpmClass; + class execution executionClass; ``` -## Usage +## Key Components + +### Global Configuration Manager -### Basic Usage +Manages all servers in a single global configuration: ```python -import asyncio -from mcpm.router import MCPRouter -from mcpm.core.schema import STDIOServerConfig, RemoteServerConfig - -async def main(): - # Create a router - router = MCPRouter() - - # Add a STDIO server - await router.add_server( - "example1", - STDIOServerConfig( - command="python", - args=["-m", "mcp.examples.simple_server"] - ) - ) - - # Add an Remote server - await router.add_server( - "example2", - RemoteServerConfig( - url="http://localhost:3000/" - ) - ) - - # Start the Remote server - await router.start_remote_server(host="localhost", port=8080) - -if __name__ == "__main__": - asyncio.run(main()) +from mcpm.global_config import GlobalConfigManager + +config = GlobalConfigManager() +config.add_server(server_config) +servers = config.list_servers() ``` -### Configuration File +### Profile Manager (Virtual Profiles) -By default, the router uses the configuration from file `~/.config/mcpm/profile.json` to manage the servers and profiles. +Manages virtual profiles as tags on servers: -## Key Components +```python +from mcpm.profile.profile_config import ProfileConfigManager + +profiles = ProfileConfigManager() +profiles.create_profile("web-dev") +profiles.add_server_to_profile("web-dev", "mcp-server-browse") +``` + +### Client Manager -### `MCPRouter` +Handles MCP client integration and configuration: -The main orchestrator class that provides a unified API for the application: -- Initializes and coordinates all internal components -- Manages connections to downstream servers (add/remove/update) -- Maintains mappings of capabilities, tools, prompts, and resources from downstream servers -- Handles namespacing of capabilities across different servers -- Provides a unified server interface for clients -- Controls profile-based access to downstream servers +```python +from mcpm.clients.client_config import ClientConfigManager + +clients = ClientConfigManager() +clients.edit_client_config("claude-desktop", selected_servers) +``` -### `ServerConnection` +### FastMCP Integration -Manages individual connections to downstream MCP servers: -- Handles connection lifecycle for a single server -- Supports different transport types (STDIO, Remote) -- Provides methods to initialize, check health, and gracefully shut down connections -- Exposes the server's capabilities to the router +Uses FastMCP for server execution and aggregation: -### `RouterSseTransport` (deprecated) +```python +# Direct server execution +mcpm run server-name + +# Profile aggregation +mcpm profile run web-dev --http --port 8080 -Extends the SSE server transport to handle client connections: -- Provides an SSE server endpoint for clients to connect -- Maintains mappings between session IDs and client profiles -- Handles message routing between clients and the router -- Manages connection lifecycle events +# Server sharing +mcpm share server-name +mcpm profile share web-dev +``` -### `ProfileConfigManager` +## Execution Models -Manages server profiles: -- Loads and updates profile configurations -- Associates clients with specific sets of available servers -- Controls which servers are visible to which clients +### Direct STDIO Execution -### `ConfigWatcher` +Servers run directly via stdio for client integration: -Monitors configuration changes: -- Watches for changes to the profile configuration files -- Triggers router updates when configurations change -- Enables dynamic reconfiguration without router restart +```bash +# Client configuration +{ + "mcpServers": { + "browse": { + "command": ["mcpm", "run", "mcp-server-browse"] + } + } +} +``` -### `ServerConfig` and Derivatives +### HTTP Mode for Testing -Defines the configuration for connecting to downstream servers: -- Base `ServerConfig` class with common properties -- `STDIOServerConfig` for command-line based servers -- `RemoteServerConfig` for HTTP/SSE based servers -- Stores necessary connection parameters (command, args, env, URL) +Servers can run in HTTP mode for development: -## Namespacing +```bash +mcpm run server-name --http --port 8080 +``` -The router uses the following namespacing conventions: +### Profile Aggregation -- Tools: `{server_id}_t_{tool_name}` -- Prompts: `{server_id}_p_{prompt_name}` -- Resources: `{server_id}:{resource_uri}` -- Resource Templates: `{server_id}:{template_uri}` +Multiple servers can be aggregated into a single endpoint: -This allows the router to route requests to the appropriate server based on the namespaced identifier. +```bash +mcpm profile run web-dev --http --port 8080 +``` -## Communication Flow +## Data Flow -### Downstream Connections (Router as Client) +### Server Installation +1. User runs `mcpm install server-name` +2. Server metadata fetched from registry +3. Server configuration stored in global config +4. Server ready for execution or profiling -1. Router creates persistent connections to downstream MCP servers using STDIO or remote (Streamable HTTP/SSE) -2. Connections are maintained regardless of upstream client presence -3. Server capabilities are fetched and aggregated with namespacing -4. Connections are managed through the `ServerConnection` class -5. Notifications from servers are routed to appropriate upstream clients +### Profile Creation +1. User runs `mcpm profile create profile-name` +2. Profile metadata created in global config +3. User adds servers with `mcpm profile edit profile-name` +4. Servers tagged with profile name -### Upstream Connections (Router as Server) +### Client Integration +1. User runs `mcpm client edit client-name` +2. MCPM detects client configuration +3. Interactive server selection presented +4. Client config updated with selected servers -1. Router provides an streamable HTTP server interface for upstream clients -2. Clients connect with a profile identifier to determine server visibility -3. Client requests are routed to appropriate downstream servers based on profile -4. Responses and notifications are delivered back to clients -5. Session management is handled by `RouterSseTransport`(deprecated) +### Server Execution +1. Client executes `mcpm run server-name` +2. MCPM loads server config from global storage +3. FastMCP starts server process +4. Stdio/HTTP communication established -## Request Routing and Namespacing +## Performance Characteristics -```mermaid -sequenceDiagram - participant Client as MCP Client - participant Router as MCPRouter - participant SC as ServerConnection - participant Server as MCP Server - - Client->>Router: Request (with profile) - Router->>Router: Determine available servers based on profile - Router->>Router: Parse namespaced ID (server_id + separator + original_id) - Router->>SC: Forward request to appropriate server - SC->>Server: Forward request with denormalized ID - Server->>SC: Response - SC->>Router: Forward response - Router->>Client: Deliver response -``` +### Advantages of v2.0 Architecture -## Profile Management +1. **No Daemon Overhead**: Eliminates router daemon startup and maintenance +2. **Direct Execution**: Reduces latency and complexity +3. **Process Isolation**: Each server runs independently +4. **Resource Efficiency**: Servers only run when needed +5. **Simplified Debugging**: Direct process model easier to troubleshoot -1. Profiles define collections of servers that should be accessible together -2. Clients connect with a profile parameter -3. Router filters available servers based on the client's profile -4. Profile configurations can be updated dynamically -5. Changes to profiles are detected by the ConfigWatcher +### Resource Management -## Error Handling +- **On-Demand Execution**: Servers start only when invoked +- **Process Lifecycle**: Servers terminate with client sessions +- **Memory Efficiency**: No persistent router process +- **Connection Pooling**: FastMCP manages connections efficiently -1. Connection errors are isolated to affected servers -2. Failed server connections don't prevent other servers from functioning -3. Proper error propagation from downstream servers to clients -4. Graceful handling of client and server disconnections -5. Pipe errors and other connection issues are properly caught and logged +## Security Model -## Benefits of This Design +### Process Isolation +- Each server runs in its own process +- No shared state between servers +- Client-server communication isolated -1. **Decoupling**: Upstream clients are decoupled from downstream servers -2. **Resilience**: Client disconnections don't affect server connections -3. **Aggregation**: Multiple capabilities from different servers appear as one -4. **Flexibility**: Supports different transport protocols (STDIO, Remote) -5. **Scalability**: Can manage multiple clients and servers simultaneously -6. **Profile-based Access**: Controls which servers are available to which clients -7. **Dynamic Configuration**: Supports runtime changes to server configurations +### Authentication +- Optional authentication for shared servers +- Token-based access control +- Local-only execution for development -## Implementation Notes +### Network Security +- HTTPS for shared servers +- Configurable tunnel endpoints +- Optional authentication for public shares -- All communication follows the MCP protocol specification -- Asynchronous operation using Python's asyncio -- Type-safe interfaces using Python type hints -- Clean separation of concerns between components -- Support for hot reloading of configurations +For more technical details, see the source code documentation and inline comments. \ No newline at end of file diff --git a/examples/proxy_transport_types.md b/examples/proxy_transport_types.md new file mode 100644 index 00000000..7f8f42b4 --- /dev/null +++ b/examples/proxy_transport_types.md @@ -0,0 +1,88 @@ +# FastMCP Proxy with Multiple Transport Types + +The MCPM FastMCP proxy now supports aggregating servers with different transport types (stdio, HTTP, SSE) into a single unified interface. + +## Supported Server Types + +### 1. STDIO Servers (Local Command-based) +```yaml +name: local-python-server +command: python +args: ["-m", "my_mcp_server"] +env: + API_KEY: ${MY_API_KEY} +``` + +### 2. Remote HTTP/SSE Servers +```yaml +name: remote-api-server +url: https://api.example.com/mcp +headers: + Authorization: Bearer ${TOKEN} +``` + +### 3. Custom Server Configurations (Client-Specific) +```yaml +name: custom-websocket-server +config: + url: wss://ws.example.com/mcp + transport: websocket + custom_field: value +``` + +**Note**: CustomServerConfig is used for parsing non-standard MCP configs from client configuration files (like Claude Desktop, Goose, etc.) and is **not processed by MCPM's proxy system**. These are client-specific configurations that don't go through the proxy. + +## Example: Mixed Profile + +You can create a profile that combines servers with different transports: + +```bash +# Add a local stdio server +mcpm add mcp-server-time --profile mixed-demo + +# Add a remote HTTP server (hypothetical) +mcpm client add --global --server remote-weather --url https://weather-api.com/mcp + +# Run the profile - FastMCP proxy handles all transport types +mcpm profile run mixed-demo + +# Or run in HTTP mode for sharing +mcpm profile run --http mixed-demo +``` + +## How It Works + +1. **STDIO Servers**: The proxy runs the command directly with the specified arguments and environment +2. **HTTP/SSE Servers**: The proxy connects to the remote URL, forwarding headers as needed +3. **Custom Servers**: These are skipped by the proxy system (client-specific configurations) + +## Benefits + +- **Unified Interface**: Access all servers through a single endpoint +- **Transport Bridging**: Expose HTTP-only servers via stdio or vice versa +- **Authentication**: Add MCPM authentication layer to any server type +- **Monitoring**: Track usage across all server types uniformly + +## FastMCP Proxy Configuration + +When MCPM creates the FastMCP proxy, it generates a configuration like: + +```json +{ + "mcpServers": { + "local-server": { + "command": ["python", "-m", "server"], + "env": {"KEY": "value"} + }, + "remote-server": { + "url": "https://api.example.com/mcp", + "transport": "http", + "headers": {"Authorization": "Bearer token"} + } + } +} +``` + +**Note**: CustomServerConfig entries are not included in the proxy configuration as they are client-specific and not processed by MCPM's proxy system. + +FastMCP handles the complexity of connecting to each supported server type and presents a unified MCP interface. \ No newline at end of file diff --git a/pages/index.html b/pages/index.html index 7340f339..019a43b0 100644 --- a/pages/index.html +++ b/pages/index.html @@ -28,1173 +28,871 @@ - + {% include favicon.html %} {% include nav.html %}
-
-
-

MCP Manager

-
Open source, community-driven, forever free.
-
- - - - - - - - - - - - - - $ - mcpm - - - - - - - - - -
-
- -

MCPM is a CLI package management tool for MCP servers. It simplifies configuration management, enables profile grouping, provides server discovery via registry, and features a powerful router for intelligently share servers with multiple clients.

- -

Quick Installation

-
-
-
- - - - -
- -
-

Install with Homebrew:

-
- $ brew install mcpm - +
+ +
+

MCPM

+

The Modern MCP Server Manager

+

+ Open source, community-driven, forever free. A powerful CLI tool for managing + Model Context Protocol servers with global configuration, profile-based organization, + and seamless client integration. +

+ + +
+
+
+
+
+
Terminal
+
+
+
+ $ + mcpm search +
+
+ $ + mcpm install mcp-server-browse +
+
+ $ + mcpm profile create work +
+
+ $ + + +
+
+ + +
+

Quick Installation

+
+ + + + +
-
-

Install with pipx:

-
- $ pipx install mcpm - +
+
+ + $ curl -sSL https://mcpm.sh/install | bash
-
-

Install with pip:

-
- $ pip install mcpm - +
+
+ + $ brew install mcpm
-
-

Install with a single command:

-
- $ curl -sSL https://mcpm.sh/install | bash - +
+
+ + $ pipx install mcpm
-
-
- -

Server Management

-
-
-

Server Discovery

-

Find available Model Context Protocol servers:

-
- $ mcpm search - -
-
- -
-

Add Servers

-

Add MCP servers directly to your client:

-
- $ mcpm add my-server - -
-
- -
-

List Servers

-

View all your installed MCP servers:

-
- $ mcpm ls - -
-
- -
-

Remove Servers

-

Remove installed MCP servers when no longer needed:

-
- $ mcpm rm my-server - -
-
- -
-

Stash Servers

-

Temporarily store server configurations:

-
- $ mcpm stash my-server - -
-
- -
-

Pop Stashed Servers

-

Restore previously stashed configurations:

-
- $ mcpm pop my-server - -
-
-
- -

Profile Management

-
-
-

Create Profiles

-

Create named collections of server configurations:

-
- $ mcpm profile add work - -
-
- - -
-

List Profiles

-

View all available MCPM profiles:

-
- $ mcpm profile ls - + +
+
+ + $ pip install mcpm +
-
-
- -

Router Management

-
-

The MCPM Router aggregates multiple MCP servers behind a single endpoint and enables shared sessions. It connects to servers as a client while providing a unified interface to upstream clients. Key benefits include resource efficiency (only one server instance runs regardless of client count), profile-based access control, and persistent connections. Learn more →

- -
- - - - - - - - MCPM Router - - - - - - Claude - - - - - Cursor - - - - - Windsurf - - - - - - Slack - - - - - GitHub - +
+ + +
+

Core Features

+
+
+
🔍
+

Server Discovery

+

Search and discover MCP servers from our curated registry

+
$ mcpm search [query]
+
- - - Notion - +
+
📦
+

Global Installation

+

Install servers once, use everywhere with global configuration

+
$ mcpm install server-name
+
- - - AWS - +
+
🏷️
+

Profile Management

+

Organize servers with profiles for different workflows

+
$ mcpm profile create work
+
- - - MySQL - +
+
🔧
+

Client Integration

+

Seamless integration with popular MCP clients

+
$ mcpm client edit cursor
+
- - - - - - - - - - - +
+
▶️
+

Direct Execution

+

Run servers directly for testing and debugging

+
$ mcpm run server-name
+
- - - - - - - - - - - - - - - - - -
-

The MCPM Router acts as a central hub connecting all your clients to your MCP servers, enabling shared sessions and simplified management.

-
- -
-
-

Start Router

-

Start the MCPM router daemon:

-
- $ mcpm router on - -
-
- -
-

Stop Router

-

Stop the MCPM router daemon:

-
- $ mcpm router off - -
-
- -
-

Router Status

-

Check if the router daemon is running:

-
- $ mcpm router status - -
-
-
- -

Share MCP Servers (mcpm share)

-

Share a local MCP server with a public URL. MCPM uses mcp-proxy to expose a stdio MCP server as an SSE server and then creates a tunnel to make it accessible remotely.

-
-
-

Share a Server

-

Share a server using a specific command:

-
- $ mcpm share "uvx mcp-server-fetch" - -
-
-
-

Share with Options

-

Share a server and specify a port:

-
- $ mcpm share "npx mcp-server" --port 5000 - +
+
🌐
+

Server Sharing

+

Share servers securely with remote access tunnels

+
$ mcpm share server-name
+
-
-
- -

Client Management

-
-
-

Set Active Client

-

Easily switch between and manage MCP clients/profiles:

-
- $ mcpm target set @claude-desktop - + + + +
+

Supported Clients

+

+ MCPM works with any MCP client by configuring servers to use mcpm run server-name +

+
+
+
Claude Desktop
+
Anthropic's AI assistant
+
+
+
Cursor
+
AI-enhanced code editor
+
+
+
Windsurf
+
Agentic IDE
+
+
+
Continue
+
AI coding assistant
+
+
+
Cline
+
Terminal-based client
+
+
+
Any MCP Client
+
Universal compatibility via mcpm run
+
-
- -
-

Edit Client Configuration

-

View or edit your client's configuration:

-
- $ mcpm client edit - + + + +
+

Ready to Get Started?

+

+ Join thousands of developers already using MCPM to manage their MCP servers efficiently. +

+ -
-
- -
-

Supported Clients

-

MCPM currently supports these AI clients:

-
    -
  • Claude Desktop - Anthropic's AI assistant
  • -
  • Windsurf - The world's first agentic IDE
  • -
  • Cursor - AI-enhanced code editor
  • -
  • Cline - Terminal-based client
  • -
  • Continue - AI coding assistant
  • -
  • Goose - LLM interface
  • -
  • 5ire - AI assistant
  • -
  • Roo Code - Coding companion
  • -
  • More clients coming soon...
  • -
+
-
{% include footer.html %} {% include github-corner.html %} - + \ No newline at end of file diff --git a/pages/registry/index.html b/pages/registry/index.html index 20224f0f..a768ad0f 100644 --- a/pages/registry/index.html +++ b/pages/registry/index.html @@ -32,7 +32,7 @@ - + @@ -44,18 +44,25 @@ {% include colors.css %} {% include common.css %} - /* Override colors with blue and pink theme */ + /* Modern redesign with consistent theme */ :root { - --accent-color: #3b82f6; - --accent-light: #60a5fa; - --accent-dark: #2563eb; - --accent-highlight: #ec4899; - --highlight: var(--accent-highlight); - --highlight-light: #ec489933; - --success: #60a5fa; - --warning: #FEBF00; - --button-bg: var(--accent-color); - --button-hover: var(--accent-dark); + --primary-bg: #0a0e13; + --secondary-bg: #151b22; + --surface-bg: #1e2429; + --surface-elevated: #252d34; + --accent-primary: #00d9ff; + --accent-secondary: #00b8d4; + --accent-tertiary: #0097b3; + --text-primary: #ffffff; + --text-secondary: #b3bac1; + --text-muted: #6b7280; + --border-subtle: rgba(255, 255, 255, 0.06); + --border-accent: rgba(0, 217, 255, 0.2); + --gradient-primary: linear-gradient(135deg, #00d9ff 0%, #0097b3 100%); + --gradient-secondary: linear-gradient(135deg, #1e2429 0%, #252d34 100%); + --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.1); + --shadow-xl: 0 25px 50px -12px rgba(0, 0, 0, 0.4); + --animation-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); } * { @@ -65,872 +72,617 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - line-height: 1.6; - color: var(--text); - background-color: var(--background); + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + line-height: 1.7; + color: var(--text-primary); + background: var(--primary-bg); + overflow-x: hidden; + } + + /* Background gradient and particle effect */ + body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 80%, rgba(0, 217, 255, 0.15) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(0, 184, 212, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(0, 151, 179, 0.08) 0%, transparent 50%); + z-index: -1; + pointer-events: none; } .container { - max-width: 1200px; + max-width: 1400px; margin: 0 auto; padding: 0 2rem; } - .logo { - font-size: 1.5rem; - font-weight: 700; - color: var(--accent-highlight); - text-decoration: none; + main { + padding: 2rem 0 4rem; } - .github-corner { + /* Header Section */ + .header-section { + text-align: center; + padding: 3rem 0 4rem; + position: relative; + } + + .header-section::after { + content: ''; position: absolute; - top: 0; - right: 0; - width: 80px; - height: 80px; - opacity: 0.8; - color: var(--text); + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60%; + height: 1px; + background: linear-gradient(90deg, transparent, var(--accent-primary), transparent); } - .github-corner:hover { - opacity: 1; + h1 { + font-size: clamp(2.5rem, 6vw, 4rem); + font-weight: 800; + margin: 0 0 1rem; + background: var(--gradient-primary); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + line-height: 1.1; + letter-spacing: -0.02em; } - .nav a { - /* Remove all nav link styles */ + .subtitle { + font-size: clamp(1rem, 2vw, 1.25rem); + color: var(--text-secondary); + margin: 0 0 2rem; + max-width: 600px; + margin-left: auto; + margin-right: auto; } - .nav a:hover { - /* Remove all nav link styles */ + /* Tab Navigation */ + .tabs { + display: flex; + gap: 0.5rem; + margin: 2rem 0; + background: var(--surface-elevated); + padding: 0.5rem; + border-radius: 12px; + border: 1px solid var(--border-subtle); + max-width: 400px; } - main { - padding: 1.5rem 0; - /* Remove margin-top as it's handled by nav.html */ + .tab-button { + flex: 1; + padding: 0.75rem 1rem; + background: transparent; + border: none; + color: var(--text-secondary); + font-family: inherit; + font-size: 0.875rem; + font-weight: 500; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s ease; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; } - h1 { - font-size: 2rem; - font-weight: 700; - margin-bottom: 0.5rem; - background: linear-gradient(90deg, var(--accent-color), var(--accent-highlight)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - letter-spacing: -0.05em; + .tab-button:hover { + background: rgba(0, 217, 255, 0.1); + color: var(--accent-primary); } - .highlight { - display: inline-block; + .tab-button.active { + background: var(--accent-primary); + color: var(--primary-bg); + box-shadow: 0 4px 12px rgba(0, 217, 255, 0.3); + } + + .tab-content { + display: none; + } + + .tab-content.active { + display: block; + animation: fadeInUp 0.3s ease; + } + + @keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + /* Search and Filter Section */ + .search-filter-section { + background: var(--surface-bg); + border-radius: 16px; + padding: 2rem; + margin: 2rem 0; + box-shadow: var(--shadow-lg); + border: 1px solid var(--border-subtle); position: relative; - color: var(--primary); - padding: 0 0.25rem; + overflow: hidden; } - .highlight::before { + .search-filter-section::before { content: ''; position: absolute; + top: 0; left: 0; right: 0; - bottom: 0.1em; - height: 0.3em; - background-color: var(--highlight); - opacity: 0.3; - z-index: -1; - } - - .subtitle { - font-size: 1.25rem; - color: var(--secondary); - margin-bottom: 0.75rem; - line-height: 1.6; - } - - .community-note { - font-size: 0.95rem; - color: var(--light-text); - margin-bottom: 2rem; - text-align: center; + height: 3px; + background: var(--gradient-primary); } .search-container { - margin: 1.5rem 0 1rem; - display: flex; - gap: 1rem; + margin-bottom: 2rem; } .search-input { - flex: 1; - padding: 0.6rem 0.75rem; - border: 1px solid var(--border); - border-radius: 0.4rem; - font-size: 0.9rem; + width: 100%; + padding: 1rem 1.5rem; + border: 1px solid var(--border-subtle); + border-radius: 12px; + font-size: 1rem; font-family: inherit; - background-color: var(--bg-accent); + background-color: var(--surface-elevated); color: var(--text-primary); + transition: all 0.2s ease; } .search-input:focus { outline: none; - border-color: var(--secondary); - box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05); + border-color: var(--accent-primary); + box-shadow: 0 0 0 3px rgba(0, 217, 255, 0.1); + background-color: var(--primary-bg); + } + + .search-input::placeholder { + color: var(--text-muted); } .tag-filters-container { - margin-bottom: 1.5rem; + margin-bottom: 0; } .tag-filters-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 0.5rem; + margin-bottom: 1rem; } .tag-filters-title { - font-weight: 500; + font-weight: 600; color: var(--text-primary); - font-size: 0.9rem; + font-size: 1rem; } .toggle-tags-btn { - background: none; - border: none; - color: var(--accent-highlight); + background: transparent; + border: 1px solid var(--border-subtle); + color: var(--accent-primary); cursor: pointer; - font-size: 0.8rem; - padding: 0.2rem 0.4rem; - border-radius: 0.25rem; - transition: background-color 0.2s; + font-size: 0.875rem; + padding: 0.5rem 1rem; + border-radius: 8px; + transition: all 0.2s ease; + font-weight: 500; } .toggle-tags-btn:hover { - background-color: var(--accent); + background-color: var(--accent-primary); + color: var(--primary-bg); + border-color: var(--accent-primary); } .tag-filters { display: flex; flex-wrap: wrap; - gap: 0.4rem; - max-height: 2.2rem; + gap: 0.75rem; + max-height: 3rem; overflow: hidden; transition: max-height 0.3s ease; } .tag-filters.expanded { - max-height: 200px; - /* Limit height to show scrollbar */ + max-height: 300px; overflow-y: auto; - /* Add vertical scrollbar when needed */ padding-right: 5px; - /* Add some padding for the scrollbar */ } - /* Custom scrollbar styling for better appearance */ .tag-filters.expanded::-webkit-scrollbar { width: 6px; } .tag-filters.expanded::-webkit-scrollbar-track { - background: var(--accent); + background: var(--surface-elevated); border-radius: 10px; } .tag-filters.expanded::-webkit-scrollbar-thumb { - background: var(--border); + background: var(--border-subtle); border-radius: 10px; } .tag-filters.expanded::-webkit-scrollbar-thumb:hover { - background: var(--secondary); + background: var(--text-secondary); } .tag-filter { - background-color: var(--bg-accent); + background-color: var(--surface-elevated); color: var(--text-primary); - padding: 0.2rem 0.5rem; - border-radius: 0.75rem; - font-size: 0.8rem; + padding: 0.5rem 1rem; + border-radius: 20px; + font-size: 0.875rem; font-weight: 500; cursor: pointer; - border: 1px solid var(--border); + border: 1px solid var(--border-subtle); transition: all 0.2s ease; line-height: 1.2; } .tag-filter:hover, .tag-filter.active { - background-color: var(--accent-highlight); - border-color: var(--accent-highlight); - color: white; + background-color: var(--accent-primary); + border-color: var(--accent-primary); + color: var(--primary-bg); + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0, 217, 255, 0.2); } + /* Server Grid */ .servers-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); - gap: 1.5rem; - margin-top: 1.5rem; + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); + gap: 2rem; + margin-top: 2rem; } .server-card { - background-color: var(--bg-accent); - border-radius: 0.6rem; + background: var(--surface-bg); + border-radius: 16px; overflow: hidden; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); - transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease; + box-shadow: var(--shadow-lg); + transition: all 0.3s var(--animation-bounce); display: flex; flex-direction: column; - border: 1px solid var(--border); + border: 1px solid var(--border-subtle); cursor: pointer; position: relative; } + .server-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: var(--gradient-primary); + transform: scaleX(0); + transition: transform 0.3s ease; + } + .server-card:hover { - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 0 0 0 1px var(--accent-highlight); - border-color: var(--accent-highlight); + transform: translateY(-8px); + box-shadow: var(--shadow-xl); + border-color: var(--border-accent); + } + + .server-card:hover::before { + transform: scaleX(1); } .server-content { - padding: 1.25rem; + padding: 2rem; flex: 1; display: flex; flex-direction: column; - gap: 0.75rem; + gap: 1rem; } .server-header { display: flex; justify-content: space-between; align-items: flex-start; + gap: 1rem; margin-bottom: 0.5rem; } .server-card h3 { - font-size: 1.1rem; + font-size: 1.25rem; font-weight: 600; - color: var(--accent-color); - line-height: 1.2; + color: var(--text-primary); + line-height: 1.3; margin: 0; - background: linear-gradient(90deg, var(--accent-color), var(--accent-highlight)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; + flex: 1; } .server-card .description { - color: var(--secondary); - font-size: 0.85rem; - margin-bottom: 0.5rem; + color: var(--text-secondary); + font-size: 0.95rem; flex: 1; - line-height: 1.35; + line-height: 1.5; display: -webkit-box; - -webkit-line-clamp: 4; + -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; - min-height: 5.4rem; + min-height: 4.5rem; } .server-card .tags { display: flex; flex-wrap: wrap; - gap: 0.35rem; - margin-bottom: 0.5rem; + gap: 0.5rem; + margin-bottom: 1rem; } .server-card .tag { - background-color: var(--bg-accent); + background-color: var(--surface-elevated); color: var(--text-primary); - padding: 0.2rem 0.45rem; - border-radius: 0.75rem; - font-size: 0.65rem; + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-size: 0.75rem; font-weight: 500; - border: 1px solid var(--border); + border: 1px solid var(--border-subtle); transition: all 0.2s ease; - line-height: 1; } .server-card .tag:hover { - background-color: var(--accent-highlight); - border-color: var(--accent-highlight); - color: white; + background-color: var(--accent-primary); + border-color: var(--accent-primary); + color: var(--primary-bg); transform: translateY(-1px); } - /* Category styles */ .server-card .category { - background-color: transparent; - color: var(--accent-color); - padding: 0.2rem 0.45rem; - border-radius: 0.75rem; - font-size: 0.65rem; + background: transparent; + color: var(--accent-primary); + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-size: 0.75rem; font-weight: 600; - border: 1px solid var(--accent-color); + border: 1px solid var(--accent-primary); transition: all 0.2s ease; - line-height: 1; - display: inline-flex; - align-items: center; - margin: 0; } .server-card .category:hover { - background-color: var(--accent-color); - color: white; + background-color: var(--accent-primary); + color: var(--primary-bg); transform: translateY(-1px); } .server-card .meta { - font-size: 0.7rem; - color: var(--light-text); + font-size: 0.8rem; + color: var(--text-muted); display: flex; justify-content: space-between; align-items: center; - border-top: 1px solid var(--border); - padding-top: 0.5rem; + border-top: 1px solid var(--border-subtle); + padding-top: 1rem; margin-top: auto; - margin-bottom: 0; } .install-button { - background-color: var(--button-bg); - color: white; + background: var(--gradient-primary); + color: var(--primary-bg); border: none; - border-radius: 4px; - padding: 6px 12px; - font-size: 0.8rem; + border-radius: 8px; + padding: 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 600; cursor: pointer; display: flex; align-items: center; - gap: 4px; - transition: background-color 0.2s; + gap: 0.5rem; + transition: all 0.2s ease; text-decoration: none; - width: fit-content; - position: absolute; - bottom: 10px; - right: 1.25rem; - z-index: 10; + box-shadow: 0 4px 12px rgba(0, 217, 255, 0.3); } .install-button:hover { - background-color: var(--button-hover); + transform: translateY(-2px); + box-shadow: 0 8px 20px rgba(0, 217, 255, 0.4); } .install-button svg { - width: 14px; - height: 14px; + width: 16px; + height: 16px; } .server-card .meta .author { - color: var(--accent-highlight); + color: var(--accent-primary); font-weight: 600; - font-size: 0.7rem; display: flex; align-items: center; + gap: 0.25rem; } .server-card .meta .stars { display: flex; align-items: center; - font-size: 0.7rem; - } - - .server-card .meta .author svg { - margin-right: 0.25rem; - width: 10px; - height: 10px; + gap: 0.25rem; + color: var(--text-secondary); + cursor: pointer; + transition: color 0.2s ease; } - .server-card .meta .stars svg { - margin-right: 0.25rem; - width: 10px; - height: 10px; + .server-card .meta .stars:hover { + color: var(--accent-primary); } .author-placeholder, - .stars-placeholder, - .author-tag.author-placeholder { + .stars-placeholder { + opacity: 0; transition: opacity 0.3s ease; } - .server-links { - display: flex; - gap: 0.5rem; - margin-top: 1.25rem; - } - - .server-link { - padding: 0.4rem 0.75rem; - border-radius: 0.375rem; - font-size: 0.75rem; - font-weight: 500; - text-decoration: none; - display: inline-flex; - align-items: center; - gap: 0.4rem; - border: none; - cursor: pointer; - transition: all 0.2s ease; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - } - - .primary-link { - background-color: var(--accent-highlight); - color: white; - border: 1px solid var(--accent-highlight); + /* Badges */ + .official-badge { + display: inline-block; + background: var(--gradient-primary); + color: var(--primary-bg); + font-size: 0.7rem; font-weight: 600; + padding: 0.25rem 0.5rem; + border-radius: 6px; + margin-left: 0.5rem; + vertical-align: middle; + text-transform: uppercase; + letter-spacing: 0.5px; } - .primary-link:hover { - background-color: var(--accent-dark); - transform: translateY(-1px); - } - - .secondary-link { - background-color: var(--accent); - color: var(--text-primary); - border: 1px solid var(--border); - } - - .secondary-link:hover { - background-color: var(--border); - transform: translateY(-1px); - color: var(--text-primary); - } - - /* Tab Styles */ - .tabs { - display: flex; - margin: 1.5rem 0 1rem; - border-bottom: 1px solid var(--border); - } - - .tab-button { - background: none; - border: none; - padding: 0.6rem 1.25rem; - font-size: 0.9rem; - font-weight: 500; - color: var(--light-text); - cursor: pointer; - position: relative; - margin-right: 1rem; - font-family: 'Inter', sans-serif; - } - - .tab-button:hover { - color: var(--text); - } - - .tab-button.active { - color: var(--text-primary); + .archived-badge { + display: inline-block; + padding: 0.25rem 0.5rem; + background-color: #60491a; + color: var(--text-secondary); + font-size: 0.7rem; font-weight: 600; + border-radius: 6px; + margin-left: 0.5rem; + vertical-align: middle; + text-transform: uppercase; + letter-spacing: 0.5px; } - .tab-button.active::after { - content: ''; - position: absolute; - bottom: -1px; - left: 0; - width: 100%; - height: 2px; - background-color: var(--accent-highlight); - } - - .tab-content { - display: none; + .docker-icon { + display: inline-block; + margin-left: 0.5rem; + vertical-align: middle; + color: #2496ed; + transition: opacity 0.2s ease; } - .tab-content.active { - display: block; + .docker-icon:hover { + opacity: 0.8; } - /* JSON view styles */ + /* API Tab Styles */ .json-container { - background-color: var(--code-bg); - border-radius: 0.5rem; + background: var(--surface-bg); + border-radius: 16px; overflow: hidden; - margin: 1.5rem 0; - border: 1px solid var(--border); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + margin: 2rem 0; + border: 1px solid var(--border-subtle); + box-shadow: var(--shadow-lg); } .json-header { display: flex; justify-content: space-between; align-items: center; - padding: 0.75rem 1rem; - background-color: var(--bg-accent); - border-bottom: 1px solid var(--border); + padding: 1.5rem 2rem; + background: var(--surface-elevated); + border-bottom: 1px solid var(--border-subtle); } .json-title { color: var(--text-primary); - font-size: 0.875rem; + font-size: 1.125rem; font-weight: 600; } .json-header-actions { display: flex; - gap: 0.5rem; + gap: 0.75rem; } .json-action-btn { color: var(--text-primary); - background-color: var(--bg-accent); - padding: 6px 10px; - border-radius: 4px; - border: 1px solid var(--border); + background: var(--surface-bg); + padding: 0.5rem 1rem; + border-radius: 8px; + border: 1px solid var(--border-subtle); font-weight: 500; cursor: pointer; transition: all 0.2s ease; + font-size: 0.875rem; } .json-action-btn:hover { - background-color: var(--accent-highlight); - color: white; - border-color: var(--accent-highlight); + background: var(--accent-primary); + color: var(--primary-bg); + border-color: var(--accent-primary); } .json-content { overflow-x: auto; color: var(--text-primary); - font-family: 'Menlo', 'Monaco', 'Courier New', monospace; + font-family: 'JetBrains Mono', monospace; font-size: 0.875rem; line-height: 1.5; + padding: 2rem; } - /* Container background for JSON formatter */ - #jsonFormatterContainer { - background-color: var(--code-bg); - border-radius: 0.5rem; - padding: 1rem; - color: var(--text-primary); - } - - /* API URL container styling */ .api-url-container { - border-bottom: 1px solid var(--border); - background-color: var(--bg-accent); - margin-bottom: 1rem; - border-radius: 0.375rem; + background: var(--surface-bg); + border-radius: 12px; + margin: 2rem 0; + padding: 1.5rem; + border: 1px solid var(--border-subtle); } .api-url-container h3 { - margin-top: 0; - margin-bottom: 0.5rem; + margin: 0 0 1rem; font-size: 1rem; - font-weight: 500; + font-weight: 600; color: var(--text-primary); } .api-url { display: flex; align-items: center; - margin: 0.5rem 0 1.5rem; - background-color: var(--code-bg); - padding: 0.75rem; - border-radius: 0.375rem; + background: var(--primary-bg); + padding: 1rem; + border-radius: 8px; + border: 1px solid var(--border-accent); overflow-x: auto; - border: 1px solid var(--border); } .api-url code { - font-family: monospace; + font-family: 'JetBrains Mono', monospace; word-break: break-all; flex: 1; - color: #e2e8f0; - } - - /* Syntax highlighting adjustments for dark theme */ - .hljs { - color: #e2e8f0 !important; - /* Override highlight.js base text color */ - background: var(--code-bg) !important; - } - - .hljs-attr { - color: #60a5fa !important; - /* Light blue for attributes */ - font-weight: bold; - } - - .hljs-string { - color: #fca5a5 !important; - /* Light red for strings */ - } - - .hljs-number { - color: #c4b5fd !important; - /* Light purple for numbers */ - } - - .hljs-boolean { - color: #f9a8d4 !important; - /* Light pink for booleans */ - font-weight: bold; - } - - .hljs-null { - color: #9ca3af !important; - /* Grey for null values */ - } - - /* JSON formatter overrides for better visibility */ - .json-formatter-row, - .json-formatter-row a, - .json-formatter-row a:hover { - color: #e2e8f0 !important; - /* Light gray for base text */ - } - - .json-formatter-row .json-formatter-row { - margin-left: 1rem; - } - - .json-formatter-row .json-formatter-key { - color: #60a5fa !important; - /* Light blue for keys */ - font-weight: 600; - } - - .json-formatter-row .json-formatter-string { - color: #fca5a5 !important; - /* Light red for strings */ - } - - .json-formatter-row .json-formatter-number { - color: #c4b5fd !important; - /* Light purple for numbers */ - } - - .json-formatter-row .json-formatter-boolean { - color: #f9a8d4 !important; - /* Light pink for booleans */ - } - - .json-formatter-row .json-formatter-null { - color: #9ca3af !important; - /* Grey for null values */ - } - - .json-formatter-row .json-formatter-bracket { - color: #e2e8f0 !important; - /* Light gray for brackets */ - } - - .json-formatter-row .json-formatter-comma { - color: #e2e8f0 !important; - /* Light gray for commas */ - } - - /* Override JSON formatter default styling */ - .json-formatter-dark.json-formatter-row, - .json-formatter-dark.json-formatter-row .json-formatter-row { - background: none !important; - color: #e2e8f0 !important; - } - - .json-formatter-dark.json-formatter-row .toggler:after { - color: #e2e8f0 !important; - } - - /* Fix JSON formatter toggler (expand/collapse arrow) */ - .json-formatter-row .toggler { - font-size: 0.8em; - margin-right: 0.2em; - opacity: 0.8; - color: #e2e8f0 !important; - } - - .json-formatter-row .toggler:hover { - opacity: 1; - color: white !important; - } - - /* Installation options styling */ - .installation-options { - margin-bottom: 1.5rem; - border-bottom: 1px solid var(--border); - padding-bottom: 1.5rem; - } - - .installation-tabs { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - margin-bottom: 1rem; + color: var(--accent-primary); + font-size: 0.875rem; } - .installation-tab { + .copy-button { + background: var(--surface-elevated); + color: var(--text-primary); + border: 1px solid var(--border-subtle); padding: 0.5rem 1rem; - background-color: var(--bg-accent); - border: 1px solid var(--border); - border-radius: 0.375rem; - cursor: pointer; + border-radius: 6px; font-size: 0.875rem; - font-weight: 500; - display: flex; - align-items: center; - gap: 0.5rem; + cursor: pointer; + white-space: nowrap; + margin-left: 1rem; transition: all 0.2s ease; - color: var(--text-primary); - } - - .installation-tab.active { - background-color: var(--accent-highlight); - color: white; - border-color: var(--accent-highlight); - } - - .installation-tab:hover:not(.active) { - background-color: var(--accent-highlight); - color: white; - } - - .installation-tab svg { - width: 14px; - height: 14px; - } - - .installation-tab .recommended { - font-size: 0.75rem; - font-weight: 400; - opacity: 0.8; - } - - .installation-panel { - display: none; - padding: 1rem; - border: 1px solid var(--border); - border-radius: 0.375rem; - background-color: var(--accent); - } - - .installation-panel.active { - display: block; - } - - .installation-command h4, - .installation-env h4 { - margin-top: 0; - margin-bottom: 0.5rem; - font-size: 0.875rem; - font-weight: 600; - } - - .command-box { - display: flex; - align-items: stretch; - background-color: var(--bg-accent); - border: 1px solid var(--border); - border-radius: 0.375rem; - overflow: hidden; - } - - .command-box pre { - margin: 0; - padding: 0.75rem; - flex-grow: 1; - font-family: monospace; - font-size: 0.875rem; - overflow-x: auto; - color: var(--text); - } - - .command-box .copy-button { - border-radius: 0; - margin: 0; - height: auto; - border-left: 1px solid var(--border); - } - - .env-table { - width: 100%; - border-collapse: collapse; - margin-top: 0.5rem; - font-size: 0.875rem; - } - - .env-table th, - .env-table td { - border: 1px solid var(--border); - padding: 0.5rem 0.75rem; - text-align: left; - } - - .env-table th { - background-color: var(--bg-accent); - font-weight: 600; - } - - .env-table td code { - background-color: var(--accent); - padding: 0.125rem 0.25rem; - border-radius: 0.25rem; - font-family: monospace; - font-size: 0.8125rem; - color: var(--text); - } - - .installation-env { - margin-top: 1.5rem; - } - - .json-content { - margin-top: 1.5rem; - } - - .json-header-row { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 0.5rem; - } - - .json-header-row h3 { - margin: 0; - } - - .json-content pre { - background-color: var(--code-bg); - padding: 0.75rem; - border-radius: 0.375rem; - overflow-x: auto; - font-family: monospace; - margin: 0.5rem 0; - max-height: 400px; - overflow-y: auto; - white-space: pre-wrap; - border: 1px solid var(--border); - color: #e2e8f0; + font-weight: 500; } - /* Footer styling moved to footer.html include */ - - @media (max-width: 768px) { - main { - padding-top: calc(80px + 1.5rem) !important; - /* Adjust for taller mobile nav */ - } - - .header-content { - flex-direction: column; - align-items: flex-start; - gap: 1rem; - } - - .nav { - margin-top: 1rem; - } - - .nav a { - margin-left: 0; - margin-right: 1.5rem; - } - + .copy-button:hover { + background: var(--accent-primary); + transform: translateY(-1px); + color: var(--primary-bg); + border-color: var(--accent-primary); } /* Modal Styles */ @@ -941,191 +693,83 @@ left: 0; width: 100%; height: 100%; - background-color: rgba(0, 0, 0, 0.7); + background-color: rgba(0, 0, 0, 0.8); z-index: 1000; justify-content: center; align-items: center; - padding: 1rem; + padding: 2rem; } .modal-content { - background-color: var(--bg-accent); - border-radius: 0.5rem; - max-width: 800px; + background: var(--surface-bg); + border-radius: 16px; + max-width: 900px; width: 100%; max-height: 90vh; overflow-y: auto; - padding: 1.5rem; + padding: 2rem; position: relative; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - border: 1px solid var(--border); + box-shadow: var(--shadow-xl); + border: 1px solid var(--border-subtle); } #modalTitle { - background: linear-gradient(90deg, var(--accent-color), var(--accent-highlight)); + background: var(--gradient-primary); -webkit-background-clip: text; background-clip: text; - color: transparent; - font-size: 1.5rem; - margin-bottom: 1rem; - } - - .manifest-info h3 { - color: var(--accent-color); - font-size: 1.1rem; - margin-top: 1.5rem; - margin-bottom: 0.5rem; + -webkit-text-fill-color: transparent; + font-size: 1.75rem; + font-weight: 700; + margin-bottom: 1.5rem; } .close-button { position: absolute; - top: 1rem; - right: 1.5rem; - font-size: 1.5rem; - cursor: pointer; - color: var(--light-text); - } - - .manifest-info { - margin-top: 1.5rem; - } - - .copy-button { - background-color: var(--bg-accent); - color: var(--text-primary); - border: 1px solid var(--border); - padding: 0.375rem 0.75rem; - border-radius: 0.25rem; - font-size: 0.875rem; - cursor: pointer; - white-space: nowrap; - margin-left: 0.75rem; - transition: all 0.2s ease; - font-weight: 600; - } - - .copy-button:hover { - background-color: var(--accent-highlight); - transform: translateY(-1px); - color: white; - border-color: var(--accent-highlight); - } - - .modal-content .api-url { - border-left: 3px solid var(--accent-highlight); - margin: 0.5rem 0 1.5rem; - } - - .modal-content .json-content pre { - border-left: 3px solid var(--accent-highlight); - } - - .modal-content .category { - background-color: transparent; - color: var(--accent-color); - padding: 0.3rem 0.6rem; - border-radius: 0.75rem; - font-size: 0.75rem; - font-weight: 600; - border: 1px solid var(--accent-color); - display: inline-block; - margin-bottom: 1rem; - } - - /* Server Details Styling */ - .server-details { - margin: 0.75rem 0; - } - - .details-section { - margin-bottom: 0.75rem; - padding: 0.5rem; - background-color: var(--bg-accent); - border-radius: 0.5rem; - border: 1px solid var(--border); - } - - .details-section h3 { - color: var(--accent-color); - font-size: 0.9rem; - margin-bottom: 0.5rem; - padding-bottom: 0.25rem; - border-bottom: 1px solid var(--border); - } - - .details-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 0.25rem; - } - - .detail-item { - display: flex; - flex-direction: row; - align-items: baseline; - gap: 0.5rem; - font-size: 0.8rem; - } - - .description-item { - grid-column: 1 / -1; - margin-top: 0.25rem; - } - - .detail-label { - font-weight: 600; - color: var(--text-primary); - min-width: 80px; - flex-shrink: 0; - } - - .detail-value { - color: var(--secondary); - word-break: break-word; - flex: 1; + top: 1.5rem; + right: 2rem; + font-size: 1.5rem; + cursor: pointer; + color: var(--text-muted); + transition: color 0.2s ease; } - /* Meta Information Styling */ - .meta-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 0.25rem; + .close-button:hover { + color: var(--text-primary); } - .meta-column { - display: flex; - flex-direction: column; - gap: 0.25rem; + .manifest-info { + margin: 1.5rem 0; } - .meta-item { - display: flex; - flex-direction: row; - align-items: baseline; - gap: 0.5rem; - font-size: 0.8rem; + .manifest-info h3 { + color: var(--accent-primary); + font-size: 1.1rem; + margin: 1.5rem 0 1rem; + font-weight: 600; } - .meta-label { - font-weight: 600; - color: var(--text-primary); - min-width: 70px; - flex-shrink: 0; + .details-section { + margin-bottom: 1.5rem; + padding: 1rem; + background: var(--surface-elevated); + border-radius: 12px; + border: 1px solid var(--border-subtle); } - .meta-value { - color: var(--secondary); - word-break: break-word; - flex: 1; + .details-section h3 { + color: var(--accent-primary); + font-size: 1rem; + margin-bottom: 0.75rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--border-subtle); } - /* Collapsible Sections */ .collapsible .section-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; - padding: 0.25rem 0; + padding: 0.5rem 0; } .collapsible .section-header h3 { @@ -1136,7 +780,7 @@ .toggle-icon { font-size: 0.8rem; - color: var(--secondary); + color: var(--text-secondary); transition: transform 0.2s ease; } @@ -1146,171 +790,190 @@ .section-content { display: none; - padding-top: 0.5rem; + padding: 1rem; + background: var(--primary-bg); + border-radius: 8px; + margin-top: 0.75rem; + border: 1px solid var(--border-subtle); } .collapsible:not(.collapsed) .section-content { display: block; } - /* Lists Styling */ - .argument-list, - .tool-list, - .resource-list, - .prompt-list { - font-size: 0.8rem; - color: var(--secondary); - } - - .argument-list ul, - .tool-list ul, - .resource-list ul, - .prompt-list ul { - margin: 0; - padding-left: 1.5rem; - list-style-type: none; - } - - .argument-list li, - .tool-list li, - .resource-list li, - .prompt-list li { - margin-bottom: 0.25rem; + .meta-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1rem; } - /* Details/Summary Styling */ - details { - margin: 0.5rem 0; + .meta-item { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.875rem; } - details>summary { - cursor: pointer; - color: var(--accent-color); + .meta-label { font-weight: 600; - margin-bottom: 0.5rem; - } - - details>summary:hover { - color: var(--accent-highlight); - } - - details>ul { - margin-left: 1rem !important; - padding: 0.5rem 0 0.5rem 1rem !important; - border-left: 2px solid var(--border); - } - - details pre { - margin: 0.5rem 0; - padding: 0.5rem; - background-color: var(--code-bg); - border-radius: 0.25rem; - font-family: monospace; - font-size: 0.85em; - white-space: pre-wrap; color: var(--text-primary); } - .section-content { - padding: 0.75rem; - background: var(--code-bg); - border-radius: 0.25rem; - margin-top: 0.5rem; + .meta-value { + color: var(--text-secondary); + word-break: break-word; } - /* Links */ - .detail-value a, .meta-value a { - color: var(--accent-color); + color: var(--accent-primary); text-decoration: none; + transition: color 0.2s ease; } - .detail-value a:hover, .meta-value a:hover { + color: var(--accent-secondary); text-decoration: underline; } - /* Tags and Categories */ #detailCategories, #detailTags { display: flex; flex-wrap: wrap; - gap: 0.25rem; + gap: 0.5rem; } #detailCategories .category, #detailTags .tag { display: inline-flex; align-items: center; - padding: 0.1rem 0.3rem; - border-radius: 0.375rem; - font-size: 0.7rem; + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-size: 0.75rem; font-weight: 500; } #detailCategories .category { - background-color: transparent; - color: var(--accent-color); - border: 1px solid var(--accent-color); + background: transparent; + color: var(--accent-primary); + border: 1px solid var(--accent-primary); } #detailTags .tag { - background-color: var(--bg-accent); + background: var(--surface-elevated); color: var(--text-primary); - border: 1px solid var(--border); + border: 1px solid var(--border-subtle); } - .server-card .meta .category { - background-color: var(--accent-color); - color: white; - padding: 0.1rem 0.5rem; - border-radius: 3px; - font-size: 0.7rem; - margin-left: 0.5rem; - font-weight: 600; + /* Responsive Design */ + @media (max-width: 768px) { + .container { + padding: 0 1rem; + } + + .header-section { + padding: 2rem 0 3rem; + } + + .servers-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .tabs { + flex-direction: column; + max-width: none; + } + + .search-filter-section { + padding: 1.5rem; + } + + .tag-filters { + gap: 0.5rem; + } + + .modal { + padding: 1rem; + } + + .modal-content { + padding: 1.5rem; + } } - .official-badge { - display: inline-block; - background-color: var(--accent-color); - color: var(--text-secondary); - font-size: 0.7rem; - font-weight: 600; - padding: 2px 6px; - border-radius: 2px; - margin-left: 8px; - vertical-align: middle; - text-transform: uppercase; - letter-spacing: 0.5px; + /* Animations */ + .animate-on-scroll { + opacity: 0; + transform: translateY(30px); + transition: all 0.6s ease; } - .archived-badge { - display: inline-block; - padding: 2px 6px; - background-color: #60491a; - color: var(--text-secondary); - font-size: 0.7rem; + .animate-on-scroll.visible { + opacity: 1; + transform: translateY(0); + } + + /* JSON Formatter Overrides */ + #jsonFormatterContainer { + background: var(--primary-bg); + border-radius: 8px; + padding: 1.5rem; + color: var(--text-primary); + } + + .json-formatter-row, + .json-formatter-row a, + .json-formatter-row a:hover { + color: var(--text-primary) !important; + } + + .json-formatter-row .json-formatter-key { + color: var(--accent-primary) !important; font-weight: 600; - border-radius: 2px; - margin-left: 8px; - vertical-align: middle; - text-transform: uppercase; - letter-spacing: 0.5px; } - .docker-icon { - display: inline-block; - margin-left: 8px; - vertical-align: middle; - color: #2496ed; + .json-formatter-row .json-formatter-string { + color: #fca5a5 !important; } - .docker-icon svg { - vertical-align: middle; + .json-formatter-row .json-formatter-number { + color: #c4b5fd !important; } - .docker-icon:hover { - opacity: 0.8; + .json-formatter-row .json-formatter-boolean { + color: #f9a8d4 !important; + } + + .json-formatter-row .json-formatter-null { + color: var(--text-muted) !important; + } + + /* Syntax highlighting adjustments */ + .hljs { + color: var(--text-primary) !important; + background: var(--primary-bg) !important; + } + + .hljs-attr { + color: var(--accent-primary) !important; + font-weight: bold; + } + + .hljs-string { + color: #fca5a5 !important; + } + + .hljs-number { + color: #c4b5fd !important; + } + + .hljs-boolean { + color: #f9a8d4 !important; + font-weight: bold; + } + + .hljs-null { + color: var(--text-muted) !important; } @@ -1320,49 +983,60 @@
-

MCP Server Registry

- -

The single open source MCP registry we all need.

+ +
+

MCP Server Registry

+

The single open source MCP registry we all need. Discover and explore MCP servers for your projects.

+
+
-
+
-
- -
- -
-
- Filter by tag: - + +
+
+
-
- All + +
+
+ Filter by tag: + +
+
+ All +
-
+
+
+
@@ -1391,6 +1065,7 @@

Servers Manifest API Endpoint:

{% include footer.html %} {% include github-corner.html %} +