openbq-org/openbb/develop-extension
Claude Code and agent skill by openbq-org/openbb
- community
- ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Checking that the SKILL.md file is still in the repository.
This is a complete guide for creating a new OpenBB Platform extension from scratch. Follow every phase in order. When the user says "build me an application that does X", use this guide to scaffold, implement, install, and verify the extension.
Install
npx vskill@latest install openbq-org/openbb/develop-extensionSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
Build an OpenBB Platform Extension
This is a complete guide for creating a new OpenBB Platform extension from scratch. Follow every phase in order. When the user says "build me an application that does X", use this guide to scaffold, implement, install, and verify the extension.
Phase 1 — Scaffold the Project
The openbb-cookiecutter package must be installed in the active Python environment before scaffolding. Install it with:
Then run the CLI to generate the project skeleton. All variables have sensible defaults; override only what you need.
Template Variables
| Variable | Default | Description | |
|---|---|---|---|
full_name | "Hello World" | Author name | |
email | "hello@world.com" | Author email | |
project_name | "OpenBB Python Extension Template" | Human-readable project name | |
project_tag | derived from project_name | Hyphenated slug (used as directory name and package identifier) | |
package_name | derived from project_name | Python package name (lower_snake_case) | |
provider_name | derived from project_name | Provider identifier (lower_snake_case) | |
router_name | derived from project_name | Router identifier (lower_snake_case) | |
obbject_name | derived from project_name | OBBject accessor name (lower_snake_case) |
All derived values are automatically generated from project_name — you only need to supply project_name for most cases.
CLI Command
Add more --extra-context KEY=VALUE pairs to override individual variables. Use -f to overwrite an existing directory.
Phase 2 — Understand the Generated Structure
After scaffolding, you get this tree (with template variables resolved):
The Four Plugin Types
OpenBB discovers extensions via Python entry points in pyproject.toml. Each plugin type has its own entry point group:
| Entry Point Group | What It Registers | Where It Lives | |
|---|---|---|---|
openbb_provider_extension | Data provider (fetchers) | providers/<name>/__init__.py | |
openbb_core_extension | Router (API endpoints/commands) | routers/<name>.py | |
openbb_charting_extension | Chart views | routers/<name>_views.py | |
openbb_obbject_extension | Result post-processing accessors | obbject/<name>/__init__.py |
Phase 3 — Implement the Data Provider
This is the core of any extension. A provider fetches data from an external source and returns it as typed Pydantic models.
The Three-Class Fetcher Pattern
Every data fetcher follows this structure:
Class 1 — QueryParams (input schema):
- Inherits from
openbb_core.provider.abstract.query_params.QueryParams - Define all parameters the user can pass (e.g.,
symbol,start_date) - Use
pydantic.Fieldfor descriptions and defaults
Class 2 — Data (output schema):
- Inherits from
openbb_core.provider.abstract.data.Data - Define all fields in the response (e.g.,
open,high,low,close,volume) - Use
pydantic.Fieldfor descriptions - Use
__alias_dict__to map source field names to your schema names
Class 3 — Fetcher (orchestrator):
- Inherits from
Fetcher[YourQueryParams, list[YourData]] - Has exactly three static methods:
transform_query(params: dict) -> YourQueryParams
Pre-process user input. Return a validated QueryParams instance.
extract_data(query, credentials, **kwargs) -> list[dict]
Make the actual HTTP request to the data source. Return raw data as dicts. For async fetching, name it aextract_data instead.
transform_data(query, data, **kwargs) -> list[YourData]
Convert raw dicts into typed Data model instances.
Imports for Fetcher Files
HTTP Requests — Required Utilities
IMPORTANT: All HTTP requests inside fetchers and utility helpers must use the built-in utilities from openbb_core.provider.utils.helpers. Do not create raw requests, aiohttp, or httpx clients from scratch. The built-in helpers apply the user's configured HTTP settings (proxy, timeout, user-agent, etc.) from system_settings.json automatically.
Building Query Strings
Convert a QueryParams model to a URL query string, optionally excluding parameters that should not appear in the URL:
model_dump() strips None values automatically. Pass parameter names to exclude in the second argument as a list (use [] if nothing to exclude).
Synchronous Requests
For use inside extract_data (sync fetchers):
All requests.get/requests.post keyword arguments are passed through.
If you need a session object for multiple requests:
Asynchronous Requests (Preferred)
For use inside aextract_data (async fetchers). Always prefer async.
Single URL — returns parsed JSON by default:
Multiple URLs — downloads concurrently and returns a list:
Custom response handling (e.g., CSV): Both amake_request and amake_requests default to parsing JSON. For non-JSON content (CSV, text, binary), pass a response_callback:
For CSV files with header rows to skip, pass skiprows to read_csv:
Async session object — if you need a raw aiohttp.ClientSession:
Summary: Which Helper to Use
| Scenario | Function | Module | |
|---|---|---|---|
| Build a query string | get_querystring() | openbb_core.provider.utils.helpers | |
| Sync single request | make_request() | openbb_core.provider.utils.helpers | |
| Sync session | get_requests_session() | openbb_core.provider.utils.helpers | |
| Async single request (JSON) | amake_request() | openbb_core.provider.utils.helpers | |
| Async multiple URLs (JSON) | amake_requests() | openbb_core.provider.utils.helpers | |
| Async single/multi (CSV/text) | amake_request() + response_callback | openbb_core.provider.utils.helpers | |
| Async raw session | get_async_requests_session() | openbb_core.provider.utils.helpers |
Using Standard Models (Multi-Provider Endpoints)
To plug into existing endpoints that other providers already serve (like EquityHistorical), inherit from the standard query/data classes instead of the abstract base classes:
Then add provider-specific fields as extra attributes. Use __alias_dict__ to map the source's field names to the standard field names.
Registering Fetchers in the Provider
In providers/<provider_name>/__init__.py, create a Provider instance:
The fetcher_dict keys are model names. When a key matches a standard model name (like "EquityHistorical"), this provider becomes selectable via the provider parameter on that existing endpoint.
For custom/new model names, you must also create a router command that references that model name (see Phase 4).
Credentials
If your provider needs an API key:
- Add
credentials=["api_key"]to the Provider constructor - Access it in
extract_dataviacredentials.get("<provider_name>_api_key")(theProviderprefixes each credential with its lower-casedname) - Users configure it in their OpenBB user settings
Phase 4 — Implement the Router
The router defines the API endpoints (commands) that users call.
Router Basics
The top-level prefix is determined by the entry point name in pyproject.toml, not by the prefix argument. Only set prefix for sub-routers.
Provider-Backed Command (Standard Pattern)
This is the most common pattern. It connects a router command to one or more provider fetchers via the model name:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingopenbb_platform/extensions/mcp_server/openbb_mcp_server/skills/develop_extension/SKILL.md
Popularity
- Repository stars
- 73,706
- Repository forks
- 7,633
- 7-day trend score
- 56
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Extension points
hookPre/post lifecycle hooks
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/openbq-org/openbb/develop-extension)