diff --git a/openbb_platform/extensions/mcp_server/README.md b/openbb_platform/extensions/mcp_server/README.md index f66c32c5082..0ffeb88f249 100644 --- a/openbb_platform/extensions/mcp_server/README.md +++ b/openbb_platform/extensions/mcp_server/README.md @@ -67,8 +67,8 @@ Enter `openbb-mcp --help` to see the docstring from the command line. A comma-separated list of tool categories to be enabled by default. Defaults to 'all'. ---no-tool-discovery - If set, tool discovery will be disabled. +--tool-discovery + If set, tool discovery will be enabled. --system-prompt Path to a TXT file with the system prompt. @@ -221,7 +221,7 @@ All settings in the `MCPSettings` model can be configured via the `mcp_settings. | `instructions` | `OPENBB_MCP_INSTRUCTIONS` | string | `None` | Server instructions sent during the MCP `initialize` handshake. Auto-populated from system prompt if not set. | | `default_tool_categories` | `OPENBB_MCP_DEFAULT_TOOL_CATEGORIES` | list[string] | `["all"]` | Default active tool categories on startup. | | `allowed_tool_categories` | `OPENBB_MCP_ALLOWED_TOOL_CATEGORIES` | list[string] | `None` | Restricts available tool categories to this list. | -| `enable_tool_discovery` | `OPENBB_MCP_ENABLE_TOOL_DISCOVERY` | boolean | `True` | Enable per-session tool discovery (admin tools for browse/activate/deactivate). | +| `enable_tool_discovery` | `OPENBB_MCP_ENABLE_TOOL_DISCOVERY` | boolean | `False` | Enable per-session tool discovery (admin tools for browse/activate/deactivate). | | `list_page_size` | `OPENBB_MCP_LIST_PAGE_SIZE` | integer | `None` | Max items per page in MCP list responses. `None` disables pagination. | | `describe_responses` | `OPENBB_MCP_DESCRIBE_RESPONSES` | boolean | `False` | Include response types in tool descriptions. | | `system_prompt_file` | `OPENBB_MCP_SYSTEM_PROMPT_FILE` | string | `None` | Path to a text file for the system prompt. | @@ -294,7 +294,7 @@ An additional set of tools are tagged as "admin", or "prompt". ## Tool Discovery -When `enable_tool_discovery` is enabled (default), the server registers a small set of admin tools that let agents progressively discover and activate what they need: +When `enable_tool_discovery` is enabled, the server registers a small set of admin tools that let agents progressively discover and activate what they need: 1. **Browse** — `available_categories` returns the category tree with tool counts. 2. **Inspect** — `available_tools` lists every tool in a category with its active/inactive state and a short description. @@ -305,7 +305,7 @@ All visibility changes are **per-session** — each client maintains its own act To take full advantage of minimal startup tools, set `--default-categories admin` so only the discovery tools are active on connect. -For scenarios where you want a completely fixed toolset (no discovery overhead), disable it with `--no-tool-discovery` and control the available tools via `allowed_tool_categories` and `default_tool_categories`. +For scenarios where you want discovery available, enable it with `--tool-discovery`. Otherwise the server runs with a fixed toolset and you can control the available tools via `allowed_tool_categories` and `default_tool_categories`. ## System Prompt @@ -612,8 +612,8 @@ openbb-mcp --default-categories equity,news --host 0.0.0.0 --port 8080 # Start with allowed categories restriction openbb-mcp --allowed-categories equity,crypto,news -# Disable tool discovery for multi-client usage -openbb-mcp --no-tool-discovery +# Enable tool discovery for per-session activation +openbb-mcp --tool-discovery ``` ### Claude Desktop: diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py b/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py index 32f81e8c7d0..ee4c19581da 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py @@ -97,6 +97,7 @@ def _get_mcp_config_from_route(fa_route: APIRoute | None) -> dict: def _strip_api_prefix(path: str, api_prefix: str) -> str: """Strip the exact api_prefix (from SystemService) from an absolute path. + Returns the remainder without a leading slash. """ if not path: @@ -242,7 +243,7 @@ def _add_prompts_from_json(mcp: FastMCP, settings: MCPSettings) -> None: continue prompt_tags = prompt_def.get("tags", []) - tags = set(prompt_tags) if isinstance(prompt_tags, (list, set)) else set() + tags = set(prompt_tags) if isinstance(prompt_tags, list | set) else set() tags.add("server") mcp.add_prompt( StaticPrompt( @@ -271,7 +272,7 @@ def _add_inline_prompts(mcp: FastMCP, prompt_definitions: list) -> None: prompt_tags = prompt_def.get("tags", []) tool = prompt_def.get("tool", "") - tags = set(prompt_tags) if isinstance(prompt_tags, (list, set)) else set() + tags = set(prompt_tags) if isinstance(prompt_tags, list | set) else set() tags.add("route-specific") tags.add(tool) @@ -369,7 +370,7 @@ def create_mcp_server( The configured FastMCP server instance. """ auth_provider = None - if auth and isinstance(auth, (list, tuple)) and len(auth) == 2 and all(auth): + if auth and isinstance(auth, list | tuple) and len(auth) == 2 and all(auth): # pylint: disable=import-outside-toplevel from .auth import get_auth_provider @@ -405,7 +406,6 @@ def create_mcp_server( component: OpenAPITool | OpenAPIResource | OpenAPIResourceTemplate, ) -> None: """Apply naming, tags, enable/disable, and resource mime type using per-route config.""" - # Map back to FastAPI route to read openapi_extra fa_route = route_lookup.get((route.path, route.method.upper())) mcp_cfg = _get_mcp_config_from_route(fa_route) @@ -962,8 +962,8 @@ def main(): if hasattr(args, "default_categories") and args.default_categories: cli_overrides["default_categories"] = args.default_categories - if hasattr(args, "no_tool_discovery") and args.no_tool_discovery: - cli_overrides["no_tool_discovery"] = args.no_tool_discovery + if hasattr(args, "tool_discovery") and args.tool_discovery: + cli_overrides["tool_discovery"] = args.tool_discovery if hasattr(args, "system_prompt") and args.system_prompt: cli_overrides["system_prompt"] = args.system_prompt diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/models/settings.py b/openbb_platform/extensions/mcp_server/openbb_mcp_server/models/settings.py index e6c5baa6706..4de61c5c4f3 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/models/settings.py +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/models/settings.py @@ -60,7 +60,7 @@ the exact same operations available to REST clients.""", # Tool discovery configuration enable_tool_discovery: bool = Field( - default=True, + default=False, description=""" Enable tool discovery, allowing the agent to hot-swap tools at runtime. Disable for multi-client or fixed toolset deployments. diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/service/mcp_service.py b/openbb_platform/extensions/mcp_server/openbb_mcp_server/service/mcp_service.py index 1f86aad17a7..eee2af5aeac 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/service/mcp_service.py +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/service/mcp_service.py @@ -199,7 +199,7 @@ class MCPService(metaclass=SingletonMeta): cli_to_settings_map = { "allowed_categories": "allowed_tool_categories", "default_categories": "default_tool_categories", - "no_tool_discovery": "enable_tool_discovery", + "tool_discovery": "enable_tool_discovery", "system_prompt": "system_prompt_file", "system-prompt": "system_prompt_file", "server_prompts": "server_prompts_file", @@ -251,10 +251,7 @@ class MCPService(metaclass=SingletonMeta): uvicorn_config[key] = value elif key in cli_to_settings_map: mapped_key = cli_to_settings_map[key] - if mapped_key == "enable_tool_discovery": - settings_overrides[mapped_key] = not value - else: - settings_overrides[mapped_key] = value + settings_overrides[mapped_key] = value elif key in mcp_settings_fields: settings_overrides[key] = value else: diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/configure_mcp_server/SKILL.md b/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/configure_mcp_server/SKILL.md index 2a86ed1239a..4947b17d642 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/configure_mcp_server/SKILL.md +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/configure_mcp_server/SKILL.md @@ -79,7 +79,7 @@ openbb-mcp --app ./my_app.py:create_app --factory | `--transport ` | `streamable-http`, `sse`, or `stdio` | `streamable-http` | | `--default-categories ` | Comma-separated default active tool categories | `all` | | `--allowed-categories ` | Restrict available categories to this list | All categories | -| `--no-tool-discovery` | Disable runtime tool activation/deactivation | Discovery enabled | +| `--tool-discovery` | Enable runtime tool activation/deactivation | Discovery disabled | | `--system-prompt ` | Path to a `.txt` system prompt file | None | | `--server-prompts ` | Path to a `.json` server prompts file | None | @@ -104,7 +104,7 @@ Create `~/.openbb_platform/mcp_settings.json`: { "name": "My MCP Server", "default_tool_categories": ["equity", "economy"], - "enable_tool_discovery": true, + "enable_tool_discovery": false, "describe_responses": false, "system_prompt_file": "/path/to/system_prompt.txt", "server_prompts_file": "/path/to/prompts.json" @@ -141,7 +141,7 @@ OPENBB_MCP_SERVER_PROMPTS_FILE="/path/to/prompts.json" |---|---|---|---| | `default_tool_categories` | `OPENBB_MCP_DEFAULT_TOOL_CATEGORIES` | `list[str]` | `["all"]` | | `allowed_tool_categories` | `OPENBB_MCP_ALLOWED_TOOL_CATEGORIES` | `list[str] \| None` | `None` | -| `enable_tool_discovery` | `OPENBB_MCP_ENABLE_TOOL_DISCOVERY` | `bool` | `true` | +| `enable_tool_discovery` | `OPENBB_MCP_ENABLE_TOOL_DISCOVERY` | `bool` | `false` | | `list_page_size` | `OPENBB_MCP_LIST_PAGE_SIZE` | `int \| None` | `None` | | `describe_responses` | `OPENBB_MCP_DESCRIBE_RESPONSES` | `bool` | `false` | | `api_prefix` | `OPENBB_MCP_API_PREFIX` | `str \| None` | `None` | @@ -241,7 +241,7 @@ mcp = create_mcp_server(settings, my_fastapi_app, auth=my_auth_provider) ## Tool Discovery -When `enable_tool_discovery` is `true` (the default), five admin tools are +When `enable_tool_discovery` is `true`, five admin tools are available to the agent: | Tool | Description | @@ -281,14 +281,14 @@ openbb-mcp --allowed-categories equity,economy,crypto Categories not in this list cannot be activated even via discovery tools. -### Disabling Discovery +### Enabling Discovery ``` -openbb-mcp --no-tool-discovery +openbb-mcp --tool-discovery ``` All tools in `default_tool_categories` are active and the admin tools are -not registered. +not registered unless discovery is enabled. --- @@ -644,7 +644,7 @@ async def hello(): settings = MCPSettings( name="My Custom MCP", default_tool_categories=["all"], - enable_tool_discovery=True, + enable_tool_discovery=False, ) mcp = create_mcp_server(settings, app) diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/work_with_server/SKILL.md b/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/work_with_server/SKILL.md index 75434a12d65..505e349fc59 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/work_with_server/SKILL.md +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/skills/work_with_server/SKILL.md @@ -115,7 +115,7 @@ This reduces noise in the active tool list and can improve context efficiency. ### When Discovery Is Disabled -If the server was started with `--no-tool-discovery`, the admin tools are not +If the server was started without `--tool-discovery`, the admin tools are not available. All tools in `default_tool_categories` are permanently active. --- diff --git a/openbb_platform/extensions/mcp_server/openbb_mcp_server/utils/app_import.py b/openbb_platform/extensions/mcp_server/openbb_mcp_server/utils/app_import.py index 1a9abff24c9..d251d95ca7c 100644 --- a/openbb_platform/extensions/mcp_server/openbb_mcp_server/utils/app_import.py +++ b/openbb_platform/extensions/mcp_server/openbb_mcp_server/utils/app_import.py @@ -155,8 +155,8 @@ Options: A comma-separated list of tool categories to be enabled by default. Defaults to 'all'. - --no-tool-discovery - If set, tool discovery will be disabled. + --tool-discovery + If set, tool discovery will be enabled. --system-prompt Path to a TXT file with the system prompt. @@ -234,7 +234,7 @@ def parse_args(): transport = _kwargs.pop("transport", "streamable-http") allowed_categories = _kwargs.pop("allowed_categories", None) default_categories = _kwargs.pop("default_categories", "all") - no_tool_discovery = _kwargs.pop("no_tool_discovery", False) + tool_discovery = _kwargs.pop("tool_discovery", False) system_prompt = _kwargs.pop("system_prompt", None) server_prompts = _kwargs.pop("server_prompts", None) @@ -247,7 +247,7 @@ def parse_args(): self.transport = transport self.allowed_categories = allowed_categories self.default_categories = default_categories - self.no_tool_discovery = no_tool_discovery + self.tool_discovery = tool_discovery self.system_prompt = system_prompt self.server_prompts = server_prompts self.uvicorn_config = _kwargs # All remaining kwargs go to uvicorn diff --git a/openbb_platform/extensions/mcp_server/tests/models/test_mcp_settings.py b/openbb_platform/extensions/mcp_server/tests/models/test_mcp_settings.py index 4fc3d878d4a..47e34c3a29a 100644 --- a/openbb_platform/extensions/mcp_server/tests/models/test_mcp_settings.py +++ b/openbb_platform/extensions/mcp_server/tests/models/test_mcp_settings.py @@ -9,7 +9,7 @@ def test_mcp_settings_defaults(): assert settings.name == "OpenBB MCP" assert settings.default_tool_categories == ["all"] assert settings.allowed_tool_categories is None - assert settings.enable_tool_discovery is True + assert settings.enable_tool_discovery is False assert settings.describe_responses is False diff --git a/openbb_platform/extensions/mcp_server/tests/service/test_mcp_service.py b/openbb_platform/extensions/mcp_server/tests/service/test_mcp_service.py index a7a86031d02..323bed2edc1 100644 --- a/openbb_platform/extensions/mcp_server/tests/service/test_mcp_service.py +++ b/openbb_platform/extensions/mcp_server/tests/service/test_mcp_service.py @@ -149,7 +149,7 @@ def test_map_cli_args_to_settings(service: MCPService): "host": "10.10.10.10", "port": 9000, "allowed_categories": "stocks,crypto", - "no_tool_discovery": True, + "tool_discovery": True, "httpx_timeout": 30, "unknown_param": "some_value", } @@ -159,7 +159,7 @@ def test_map_cli_args_to_settings(service: MCPService): assert mapped["uvicorn_config"]["host"] == "10.10.10.10" assert mapped["uvicorn_config"]["port"] == 9000 assert mapped["allowed_tool_categories"] == "stocks,crypto" - assert mapped["enable_tool_discovery"] is False + assert mapped["enable_tool_discovery"] is True assert mapped["httpx_client_kwargs"]["timeout"] == 30 assert mapped["uvicorn_config"]["unknown_param"] == "some_value" diff --git a/openbb_platform/extensions/mcp_server/tests/utils/test_app_import.py b/openbb_platform/extensions/mcp_server/tests/utils/test_app_import.py index 07d4eb4c649..69a24a9e9ae 100644 --- a/openbb_platform/extensions/mcp_server/tests/utils/test_app_import.py +++ b/openbb_platform/extensions/mcp_server/tests/utils/test_app_import.py @@ -99,14 +99,14 @@ def test_parse_args_simple(): "test_transport", "--allowed_categories", "cat1,cat2", - "--no-tool-discovery", + "--tool-discovery", "true", ] with patch.object(sys, "argv", test_args): args = parse_args() assert args.transport == "test_transport" assert args.allowed_categories == "cat1,cat2" - assert args.no_tool_discovery is True + assert args.tool_discovery is True assert args.imported_app is None @@ -365,8 +365,6 @@ class TestModuleColonNotationHelper: def test_simple_module_notation(self): """Test simple module:name notation is detected correctly.""" # These should be recognized as module colon notation - from openbb_mcp_server.utils.app_import import import_app - # We test the behavior indirectly through import_app # Module notation without file should try import first with pytest.raises((ImportError, FileNotFoundError)):