diff --git a/README.md b/README.md index 9889c3c..13c8b02 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,9 @@ The following variables can be set in the environment. | Name | Description | Default | |-------|------------|---------------| -| `MCPSERVER_PORT` | Port to run MCP server on, if using http variant | 8089 | +| `MCPSERVER_PORT` | Port to run MCP server on, if using http variant | `8089` | +| `MCPSERVER_HOST` | Default host to run MCP server (http) | `0.0.0.0` | +| `MCPSERVER_PATH` | Default path for server endpoint | `/mcp` | | `MCPSERVER_TOKEN` | Token to use for testing | unset | ## Examples diff --git a/mcpserver/cli/__init__.py b/mcpserver/cli/__init__.py index 7ee221e..664bb01 100644 --- a/mcpserver/cli/__init__.py +++ b/mcpserver/cli/__init__.py @@ -10,6 +10,7 @@ install() import mcpserver +from mcpserver.cli.args import populate_start_args from mcpserver.logger import setup_logger default_port = os.environ.get("MCPSERVER_PORT") or 8000 @@ -59,39 +60,7 @@ def get_parser(): formatter_class=argparse.RawTextHelpFormatter, description="generate subsystem metadata for a cluster", ) - start.add_argument( - "--port", default=default_port, type=int, help="port to run the agent gateway" - ) - - # Note from V: SSE is considered deprecated (don't use it...) - start.add_argument( - "-t", - "--transport", - default="stdio", - help="Transport to use (defaults to stdin)", - choices=["stdio", "http", "sse", "streamable-http"], - ) - start.add_argument("--host", default="0.0.0.0", help="Host (defaults to 0.0.0.0)") - start.add_argument( - "--tool-module", - action="append", - help="Additional tool module paths to discover from.", - default=[], - ) - start.add_argument("--tool", action="append", help="Direct tool to import.", default=[]) - start.add_argument("--resource", action="append", help="Direct resource to import.", default=[]) - start.add_argument("--prompt", action="append", help="Direct prompt to import.", default=[]) - start.add_argument("--include", help="Include tags", action="append", default=None) - start.add_argument("--exclude", help="Exclude tag", action="append", default=None) - start.add_argument("--path", help="Server path for mcp", default="/mcp") - start.add_argument("--config", help="Configuration file for server.") - - start.add_argument( - "--mask-error_details", - help="Mask error details (for higher security deployments)", - action="store_true", - default=False, - ) + populate_start_args(start) return parser diff --git a/mcpserver/cli/args.py b/mcpserver/cli/args.py new file mode 100644 index 0000000..2e89426 --- /dev/null +++ b/mcpserver/cli/args.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +import os + +default_port = os.environ.get("MCPSERVER_PORT") or 8000 +default_host = os.environ.get("MCPSERVER_HOST") or "0.0.0.0" +default_path = os.environ.get("MCPSERVER_PATH") or "/mcp" + + +def populate_start_args(start): + """ + Given the argparse parser, add start args to it. + + We provide this so a secondary library can consistently + add parsing args to its parser. + """ + start.add_argument( + "--port", default=default_port, type=int, help="port to run the agent gateway" + ) + + # Note from V: SSE is considered deprecated (don't use it...) + start.add_argument( + "-t", + "--transport", + default="stdio", + help="Transport to use (defaults to stdin)", + choices=["stdio", "http", "sse", "streamable-http"], + ) + start.add_argument("--host", default=default_host, help=f"Host (defaults to {default_host})") + start.add_argument( + "--tool-module", + action="append", + help="Additional tool module paths to discover from.", + default=[], + ) + start.add_argument("--tool", action="append", help="Direct tool to import.", default=[]) + start.add_argument("--resource", action="append", help="Direct resource to import.", default=[]) + start.add_argument("--prompt", action="append", help="Direct prompt to import.", default=[]) + start.add_argument("--include", help="Include tags", action="append", default=None) + start.add_argument("--exclude", help="Exclude tag", action="append", default=None) + start.add_argument("--path", help="Server path for mcp", default=default_path) + start.add_argument("--config", help="Configuration file for server.") + + start.add_argument( + "--mask-error_details", + help="Mask error details (for higher security deployments)", + action="store_true", + default=False, + ) diff --git a/mcpserver/cli/manager.py b/mcpserver/cli/manager.py new file mode 100644 index 0000000..025f28f --- /dev/null +++ b/mcpserver/cli/manager.py @@ -0,0 +1,42 @@ +from mcpserver.core.config import MCPConfig +from mcpserver.tools.manager import ToolManager + +# Discover and register defaults +manager = ToolManager() +manager.register() + + +def get_manager(mcp, cfg): + """ + Get the common tool manager and register tools. + """ + # Add additional module paths (custom out of tree modules) + for path in cfg.discovery: + print(f"🧐 Registering additional module: {path}") + manager.register(path) + + # explicit egistration + for endpoint in register(mcp, cfg): + print(f" ✅ Registered: {endpoint.name}") + + # Load into the manager (tools, resources, prompts) + for tool in manager.load_tools(mcp, cfg.include, cfg.exclude): + print(f" ✅ Registered: {tool.name}") + + +def register(mcp, cfg: MCPConfig): + """ + Registers specific tools, prompts, and resources defined in the config. + Replaces the previous args-based register function. + """ + # Define which config lists map to which manager methods + registries = [ + (cfg.tools, manager.register_tool), + (cfg.prompts, manager.register_prompt), + (cfg.resources, manager.register_resource), + ] + + for capability_list, register_func in registries: + for item in capability_list: + # item is a CapabilityConfig object with .path and .name + yield register_func(mcp, item.path, name=item.name) diff --git a/mcpserver/cli/start.py b/mcpserver/cli/start.py index 442b6c7..161ade0 100644 --- a/mcpserver/cli/start.py +++ b/mcpserver/cli/start.py @@ -1,15 +1,11 @@ from fastapi import FastAPI from mcpserver.app import init_mcp +from mcpserver.cli.manager import get_manager from mcpserver.core.config import MCPConfig # These are routes also served here from mcpserver.routes import * -from mcpserver.tools.manager import ToolManager - -# Discover and register defaults -manager = ToolManager() -manager.register() def main(args, extra, **kwargs): @@ -23,28 +19,14 @@ def main(args, extra, **kwargs): else: cfg = MCPConfig.from_args(args) + # Get the tool manager and register discovered tools mcp = init_mcp(cfg.exclude, cfg.include, args.mask_error_details) + manager = get_manager(mcp, cfg) # Create ASGI app from MCP server mcp_app = mcp.http_app(path=cfg.server.path) app = FastAPI(title="MCP Server", lifespan=mcp_app.lifespan) - # Dynamic Loading of Tools - print(f"🔌 Loading tools... ") - - # Add additional module paths (custom out of tree modules) - for path in cfg.discovery: - print(f"🧐 Registering additional module: {path}") - manager.register(path) - - # explicit egistration - for endpoint in register(mcp, cfg): - print(f" ✅ Registered: {endpoint.name}") - - # Load into the manager (tools, resources, prompts) - for tool in manager.load_tools(mcp, cfg.include, cfg.exclude): - print(f" ✅ Registered: {tool.name}") - # Mount the MCP server. Note from V: we can use mount with antother FastMCP # mcp.run can also be replaced with mcp.run_async app.mount("/", mcp_app) @@ -61,21 +43,3 @@ def main(args, extra, **kwargs): # For testing we usually control+C, let's not make it ugly except KeyboardInterrupt: print("🖥️ Shutting down...") - - -def register(mcp, cfg: MCPConfig): - """ - Registers specific tools, prompts, and resources defined in the config. - Replaces the previous args-based register function. - """ - # Define which config lists map to which manager methods - registries = [ - (cfg.tools, manager.register_tool), - (cfg.prompts, manager.register_prompt), - (cfg.resources, manager.register_resource), - ] - - for capability_list, register_func in registries: - for item in capability_list: - # item is a CapabilityConfig object with .path and .name - yield register_func(mcp, item.path, name=item.name) diff --git a/mcpserver/version.py b/mcpserver/version.py index 04c633d..983fa24 100644 --- a/mcpserver/version.py +++ b/mcpserver/version.py @@ -1,4 +1,4 @@ -__version__ = "0.0.11" +__version__ = "0.0.12" AUTHOR = "Vanessa Sochat" AUTHOR_EMAIL = "vsoch@users.noreply.github.com" NAME = "mcp-serve"