Skip to main content
Glama

OpenBB Widgets JSON MCP Server

by DidierRLopes
main.py15.8 kB
import os import uvicorn import requests from mcp.server.fastmcp import FastMCP from starlette.middleware.cors import CORSMiddleware # Dictionary of OpenBB documentation tools OPENBB_DOCS_TOOLS = { # Main developer docs "data-integration": { "description": "Documentation for integrating data sources into the OpenBB platform", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/data-integration.md" }, # AI Agents "ai-agents_ai-agents": { "description": "Documentation about AI agents in OpenBB", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/ai-agents/ai-agents.md" }, # Apps "apps_apps": { "description": "Documentation about OpenBB applications", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/apps/apps.md" }, # JSON Specs "json-specs_agents-json-reference": { "description": "JSON reference documentation for agents configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/json-specs/agents-json-reference.md" }, "json-specs_apps-json-reference": { "description": "JSON reference documentation for apps configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/json-specs/apps-json-reference.md" }, "json-specs_widgets-json-reference": { "description": "JSON reference documentation for widgets configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/json-specs/widgets-json-reference.md" }, # Widget Configuration "widget-cfg_category-subcategory": { "description": "Documentation for widget category and subcategory configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/category-subcategory.md" }, "widget-cfg_error-handling": { "description": "Documentation for widget error handling", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/error-handling.md" }, "widget-cfg_grid-size": { "description": "Documentation for widget grid size configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/grid-size.md" }, "widget-cfg_refetch-interval": { "description": "Documentation for widget refetch interval configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/refetch-interval.md" }, "widget-cfg_render-functions": { "description": "Documentation for widget render functions", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/render-functions.md" }, "widget-cfg_run-button": { "description": "Documentation for widget run button configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/run-button.md" }, "widget-cfg_stale-time": { "description": "Documentation for widget stale time configuration", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-configuration/stale-time.md" }, # Widget Parameters "widget-params_advanced-dropdown": { "description": "Documentation for advanced dropdown widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/advanced-dropdown.md" }, "widget-params_boolean-toggle": { "description": "Documentation for boolean toggle widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/boolean-toggle.md" }, "widget-params_cell-click-grouping": { "description": "Documentation for cell click grouping in widgets", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/cell-click-grouping.md" }, "widget-params_date-picker": { "description": "Documentation for date picker widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/date-picker.md" }, "widget-params_dependent-dropdown": { "description": "Documentation for dependent dropdown widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/dependent-dropdown.md" }, "widget-params_dropdown": { "description": "Documentation for dropdown widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/dropdown.md" }, "widget-params_input-form": { "description": "Documentation for input form widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/input-form.md" }, "widget-params_number-input": { "description": "Documentation for number input widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/number-input.md" }, "widget-params_parameter-grouping": { "description": "Documentation for parameter grouping in widgets", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/parameter-grouping.md" }, "widget-params_parameter-positioning": { "description": "Documentation for parameter positioning in widgets", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/parameter-positioning.md" }, "widget-params_text-input": { "description": "Documentation for text input widget parameters", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-parameters/text-input.md" }, # Widget Types "widget-types_aggrid-table-charts": { "description": "Documentation for AgGrid table charts widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/aggrid-table-charts.md" }, "widget-types_file-viewer": { "description": "Documentation for file viewer widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/file-viewer.md" }, "widget-types_highcharts": { "description": "Documentation for Highcharts widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/highcharts.md" }, "widget-types_html": { "description": "Documentation for HTML widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/html.md" }, "widget-types_live-grid": { "description": "Documentation for live grid widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/live-grid.md" }, "widget-types_markdown": { "description": "Documentation for markdown widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/markdown.md" }, "widget-types_metric": { "description": "Documentation for metric widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/metric.md" }, "widget-types_newsfeed": { "description": "Documentation for newsfeed widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/newsfeed.md" }, "widget-types_omni": { "description": "Documentation for omni widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/omni.md" }, "widget-types_plotly-charts": { "description": "Documentation for Plotly charts widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/plotly-charts.md" }, "widget-types_ssrm-mode": { "description": "Documentation for SSRM mode in widgets", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/ssrm_mode.md" }, "widget-types_tradingview-charts": { "description": "Documentation for TradingView charts widget type", "context": "https://raw.githubusercontent.com/OpenBB-finance/openbb-docs/main/content/workspace/developers/widget-types/tradingview-charts.md" } } mcp = FastMCP(name="OpenBB Widgets JSON MCP") # Create MCP tools for each documentation file for tool_name, tool_info in OPENBB_DOCS_TOOLS.items(): # Create a closure to capture the current tool_info def create_tool_function(name, info): def tool_function() -> str: """Fetch and return OpenBB documentation content.""" try: response = requests.get(info["context"]) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: return f"Error fetching documentation: {str(e)}" # Set function attributes for MCP tool_function.__name__ = name.replace("-", "_") tool_function.__doc__ = info["description"] return tool_function # Register the tool with MCP tool_func = create_tool_function(tool_name, tool_info) mcp.tool()(tool_func) # ========================== # Ad-hoc Tools Section # ========================== @mcp.tool() def building_widgets_on_openbb() -> str: """Essential boilerplate code for building OpenBB Workspace widgets. This provides the foundational FastAPI setup, CORS configuration, widgets.json endpoints, and register_widget decorator pattern. ALWAYS call this first when creating OpenBB widgets to get the required boilerplate structure.""" return """# Essential Boilerplate Code for OpenBB Workspace Widgets ```python # Import required libraries from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from functools import wraps import asyncio # Initialize empty dictionary for widgets WIDGETS = {} # Decorator that registers a widget configuration in the WIDGETS dictionary. def register_widget(widget_config): \"\"\" Decorator that registers a widget configuration in the WIDGETS dictionary. Args: widget_config (dict): The widget configuration to add to the WIDGETS dictionary. This should follow the same structure as other entries in WIDGETS. Returns: function: The decorated function. \"\"\" def decorator(func): @wraps(func) async def async_wrapper(*args, **kwargs): # Call the original function return await func(*args, **kwargs) @wraps(func) def sync_wrapper(*args, **kwargs): # Call the original function return func(*args, **kwargs) # Extract the endpoint from the widget_config endpoint = widget_config.get("endpoint") if endpoint: # Add an id field to the widget_config if not already present if "widgetId" not in widget_config: widget_config["widgetId"] = endpoint # Use id as the key to allow multiple widgets per endpoint widget_id = widget_config["widgetId"] WIDGETS[widget_id] = widget_config # Return the appropriate wrapper based on whether the function is async if asyncio.iscoroutinefunction(func): return async_wrapper return sync_wrapper return decorator # Initialize FastAPI application with metadata app = FastAPI( title="Simple Backend", description="Simple backend app for OpenBB Workspace", version="0.0.1" ) # Define allowed origins for CORS (Cross-Origin Resource Sharing) # This restricts which domains can access the API origins = [ "https://pro.openbb.co", ] # Configure CORS middleware to handle cross-origin requests # This allows the specified origins to make requests to the API app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], # Allow all HTTP methods allow_headers=["*"], # Allow all headers ) ROOT_PATH = Path(__file__).parent.resolve() @app.get("/") def read_root(): \"\"\"Root endpoint that returns basic information about the API\"\"\" return {"Info": "Hello World"} # Endpoint that returns the registered widgets configuration # The WIDGETS dictionary is maintained by the registry.py helper # which automatically registers widgets when using the @register_widget decorator @app.get("/widgets.json") def get_widgets(): \"\"\"Returns the configuration of all registered widgets The widgets are automatically registered through the @register_widget decorator and stored in the WIDGETS dictionary from registry.py Returns: dict: The configuration of all registered widgets \"\"\" return WIDGETS ``` ## Important Notes: - **CORS Configuration**: Always include the OpenBB Workspace origin (`https://pro.openbb.co`) in your CORS settings - **widgets.json Endpoint**: This endpoint is required for OpenBB Workspace to discover available widgets - **Register Widget Decorator**: The @register_widget decorator automatically manages widget registration ## Running the Application: ```bash # Using uvicorn directly uvicorn main:app --reload --port 8000 # Or add this to your Python file if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` """ # Get the Starlette app and add CORS middleware app = mcp.streamable_http_app() # Add CORS middleware with proper header exposure for MCP session management app.add_middleware( CORSMiddleware, allow_origins=["*"], # Configure this more restrictively in production allow_credentials=True, allow_methods=["GET", "POST", "OPTIONS"], allow_headers=["*"], expose_headers=["mcp-session-id", "mcp-protocol-version"], # Allow client to read session ID max_age=86400, ) if __name__ == "__main__": # Use PORT environment variable port = int(os.environ.get("PORT", 8081)) # Run the MCP server with HTTP transport using uvicorn uvicorn.run( app, host="0.0.0.0", # Listen on all interfaces for containerized deployment port=port, log_level="debug" )

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DidierRLopes/openbb-widgets-json-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server