Skip to content

Commit 40a115b

Browse files
authored
Toreleon cli (#22)
* Add CI/CD workflows for testing, version bumping, and PyPI publishing; enhance README with development and CI/CD details; implement comprehensive tests for MCPHub and MCPServers functionality. * Enhance CI workflow by installing all extras with Poetry * Refactor CI workflow to include version bumping and streamline package publishing using Poetry * Update README to clarify MCPHub installation options with framework-specific dependencies * Restrict pull request triggers to the release branch only * Update CI workflow to enable fail-fast strategy and restrict Python versions to 3.12 only * Refactor CI workflows to remove version bumping from CI and add tagging functionality; update README for clarity on automatic versioning and tagging process. * Refactor CI workflows to integrate version bumping and ensure proper versioning before publishing; update version-bump workflow to set outputs for new version. * Bump version to 0.1.6 in pyproject.toml * Refactor CI workflows: remove version-bump workflow and integrate version extraction and tagging directly in the publish job; update package version to 0.1.7 in pyproject.toml * Fix test data structure in TestMCPServersParams to match expected format Updated the mock data in the test for _load_predefined_servers_params to reflect the correct structure, ensuring that the "mcpServers" key wraps the predefined server details. This change enhances the accuracy of the test and aligns it with the actual implementation. * Add CLI commands and utilities for MCPHub configuration management - Implemented CLI commands for initializing, adding, removing, and listing MCP servers. - Created utility functions for loading and saving configuration files. - Added tests for CLI commands to ensure proper functionality and error handling.
1 parent 19288e1 commit 40a115b

File tree

6 files changed

+827
-13
lines changed

6 files changed

+827
-13
lines changed
File renamed without changes.

examples/without_config/test.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
from mcphub import MCPHub
2-
import json
32

4-
async def main():
3+
server_name = "Gloomysunday28/mcp-server"
54

5+
async def framework_examples():
66
hub = MCPHub()
77

8+
# 1. OpenAI Agents Integration
89
async with hub.fetch_openai_mcp_server(
9-
mcp_name="MCP-Mirror/Automata-Labs-team_MCP-Server-Playwright",
10+
mcp_name=server_name,
1011
cache_tools_list=True
1112
) as server:
12-
# Step 3: List available tools from the MCP server
13-
# This shows what capabilities are available to your agent
1413
tools = await server.list_tools()
15-
16-
# Pretty print the tools for better readability
17-
tools_dict = [
18-
dict(tool) if hasattr(tool, "__dict__") else tool for tool in tools
19-
]
20-
print("Available MCP Tools:")
21-
print(json.dumps(tools_dict, indent=2))
14+
print(f"Tools from MCP server: {tools}")
15+
# 2. LangChain Tools Integration
16+
langchain_tools = await hub.fetch_langchain_mcp_tools(
17+
mcp_name=server_name,
18+
cache_tools_list=True
19+
)
20+
21+
print(f"LangChain tools from MCP server: {langchain_tools}")
22+
23+
# 3. Autogen Adapters Integration
24+
autogen_adapters = await hub.fetch_autogen_mcp_adapters(
25+
mcp_name=server_name
26+
)
27+
# Use adapters with Autogen
28+
29+
print(f"Autogen adapters from MCP server: {autogen_adapters}")
2230

2331

2432
if __name__ == "__main__":
2533
import asyncio
26-
asyncio.run(main())
34+
asyncio.run(framework_examples())

src/mcphub/cli/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# CLI package for MCPHub

src/mcphub/cli/commands.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
"""CLI commands for mcphub."""
2+
import argparse
3+
import json
4+
import sys
5+
from pathlib import Path
6+
from typing import Dict, Any, List, Optional
7+
8+
from .utils import (
9+
load_config,
10+
save_config,
11+
DEFAULT_CONFIG,
12+
get_config_path,
13+
add_server_config,
14+
remove_server_config,
15+
list_available_servers,
16+
list_configured_servers
17+
)
18+
19+
def init_command(args):
20+
"""Initialize a new .mcphub.json configuration file in the current directory."""
21+
config_path = get_config_path()
22+
if config_path.exists():
23+
print(f"Configuration file already exists at: {config_path}")
24+
return
25+
26+
save_config(DEFAULT_CONFIG)
27+
print(f"Created new configuration file at: {config_path}")
28+
29+
def add_command(args):
30+
"""Add a preconfigured MCP server to the local config."""
31+
server_name = args.mcp_name
32+
non_interactive = args.non_interactive if hasattr(args, 'non_interactive') else False
33+
34+
success, missing_env_vars = add_server_config(server_name, interactive=not non_interactive)
35+
36+
if not success:
37+
print(f"Error: MCP server '{server_name}' not found in preconfigured servers")
38+
# Show available options
39+
print("\nAvailable preconfigured servers:")
40+
available_servers = list_available_servers()
41+
for name in available_servers:
42+
print(f"- {name}")
43+
sys.exit(1)
44+
45+
print(f"Added configuration for '{server_name}' to .mcphub.json")
46+
47+
# Notify about missing environment variables
48+
if missing_env_vars:
49+
print("\nWarning: The following environment variables are required but not set:")
50+
for var in missing_env_vars:
51+
print(f"- {var}")
52+
print("\nYou can either:")
53+
print("1. Set them in your environment before using this server")
54+
print("2. Run 'mcphub add-env' to add them to your configuration")
55+
print("3. Edit .mcphub.json manually to set the values")
56+
57+
def remove_command(args):
58+
"""Remove an MCP server configuration from the local config."""
59+
server_name = args.mcp_name
60+
if remove_server_config(server_name):
61+
print(f"Removed configuration for '{server_name}' from .mcphub.json")
62+
else:
63+
print(f"Error: MCP server '{server_name}' not found in current configuration")
64+
# Show what's currently configured
65+
configured = list_configured_servers()
66+
if configured:
67+
print("\nCurrently configured servers:")
68+
for name in configured:
69+
print(f"- {name}")
70+
sys.exit(1)
71+
72+
def list_command(args):
73+
"""List all configured and available MCP servers."""
74+
show_all = args.all if hasattr(args, 'all') else False
75+
76+
configured = list_configured_servers()
77+
print("Configured MCP servers:")
78+
if configured:
79+
for name in configured:
80+
print(f"- {name}")
81+
else:
82+
print(" No servers configured in local .mcphub.json")
83+
84+
if show_all:
85+
available = list_available_servers()
86+
print("\nAvailable preconfigured MCP servers:")
87+
if available:
88+
for name in available:
89+
print(f"- {name}")
90+
else:
91+
print(" No preconfigured servers available")
92+
93+
def parse_args(args=None):
94+
"""Parse command line arguments."""
95+
parser = argparse.ArgumentParser(
96+
description="MCPHub CLI tool for managing MCP server configurations"
97+
)
98+
99+
subparsers = parser.add_subparsers(dest="command", help="Commands")
100+
101+
# Init command
102+
init_parser = subparsers.add_parser(
103+
"init",
104+
help="Create a new .mcphub.json file in the current directory"
105+
)
106+
107+
# Add command
108+
add_parser = subparsers.add_parser(
109+
"add",
110+
help="Add a preconfigured MCP server to your local config"
111+
)
112+
add_parser.add_argument(
113+
"mcp_name",
114+
help="Name of the preconfigured MCP server to add"
115+
)
116+
add_parser.add_argument(
117+
"-n", "--non-interactive",
118+
action="store_true",
119+
help="Don't prompt for environment variables"
120+
)
121+
122+
# Remove command
123+
remove_parser = subparsers.add_parser(
124+
"remove",
125+
help="Remove an MCP server from your local config"
126+
)
127+
remove_parser.add_argument(
128+
"mcp_name",
129+
help="Name of the MCP server to remove"
130+
)
131+
132+
# List command
133+
list_parser = subparsers.add_parser(
134+
"list",
135+
help="List configured MCP servers"
136+
)
137+
list_parser.add_argument(
138+
"-a", "--all",
139+
action="store_true",
140+
help="Show all available preconfigured servers"
141+
)
142+
143+
return parser.parse_args(args)
144+
145+
def main():
146+
"""Main entry point for the CLI."""
147+
args = parse_args()
148+
149+
if args.command == "init":
150+
init_command(args)
151+
elif args.command == "add":
152+
add_command(args)
153+
elif args.command == "remove":
154+
remove_command(args)
155+
elif args.command == "list":
156+
list_command(args)
157+
else:
158+
# Show help if no command is provided
159+
parse_args(["-h"])
160+
161+
if __name__ == "__main__":
162+
main()

0 commit comments

Comments
 (0)