fd-open-data-protocol
Wire (柏讯) product line · the open-data supply line of FindData — the datasource manifest contract
English | 中文
The open-data datasource protocol: a manifest contract a datasource exposes
(datasource + functions + columns + concept hints + fetch reference) so that
fd-open-data-mcp - or any consumer - can ingest it via register_datasource.
Ship one manifest file -> the datasource is added. No consumer-side wiring.
One-click install
This library is a dependency of fd-open-data-mcp (pulled in transitively). To
install the entire finddata stack (hub + every datasource + ontology DB):
pip install "fd-open-data-mcp[data]" fd-polygon fd-cn-report
fd-open-data-mcp migrate \
&& fd-open-data-mcp import-catalog \
&& fd-open-data-mcp consume-concepts \
&& fd-open-data-mcp propose-bindings \
&& fd-open-data-mcp seed-entities \
&& fd-open-data-mcp generate-schedules \
&& fd-open-data-mcp register-discovered
fd-open-data-mcp serve
The manifest
A YAML/JSON file (or a Python module exposing CATALOG):
version: "1"
name: my-source
label: My Source
ranking_seed: [0.7, 0.7] # [quality, accessibility] heuristic seed
functions:
- command: get_data
frequency: daily
parameters: [{name: symbol, type: str, required: true}]
columns:
- {name: close, type: float, frequency: daily}
concepts: # column -> concept hints (measure/entity_type here)
- {column: close, concept: price.close, entity_type: stock, unit: currency, frequency: daily}
fetch:
runner: my-source # built-in runner name, OR module: "pkg.mod:run"
See examples/example_stock.yaml (declarative) and examples/example_macro.py
(a DataProvider class with run()).
Load + validate
from fd_open_data_protocol.loader import load_catalog
manifest = load_catalog("examples/example_stock.yaml")
print(manifest.name, len(manifest.functions))
load_catalog accepts a YAML/JSON file path, a .py file exposing CATALOG,
a "pkg.mod" module path, or a dict.
Register with fd-open-data-mcp
fd-open-data-mcp register-datasource examples/example_stock.yaml
or the MCP tool register_datasource(path).
Publish a datasource from another project
In your datasource package's pyproject.toml:
[project.entry-points."fd_open_data_mcp.datasources"]
my-source = "my_pkg.catalog:CATALOG"
pip install my-pkg -> fd-open-data-mcp auto-registers it on import_catalog.
Schema
DatasourceManifest: name, label, source_url, scanner_mode, ranking_seed, functions[], concepts[], entities[], entity_definitions[], relationships[], fetch.FunctionSpec: command, category, description, parameters[], columns[], frequency, verified.ColumnSpec: name, type, description, meaning, semantic_type,frequency+datasource(column-level).ConceptHint: column, concept,entity_type,measure, unit, frequency, confidence,concept_family(optional).EntitySpec: entity_type, coverage ("universe"|"explicit"), codes[] (for explicit coverage).Entity: entity_type, code, name_en, name_zh, metadata{}, relationships[].EntityRelationship: target_entity_type, target_code, relation_type, confidence, metadata{}.RelationshipSpec: relation_type, source_entity_type, target_entity_type, resolver_module.FetchRef: runner (built-in name) | module ("pkg.mod:func").
measure + entity_type are concept-level (disambiguate GDP-nominal vs
GDP-PPP; stock close vs fund NAV). Column-level frequency/datasource support
composite functions whose columns come from different sources at different cadences.
Entity Definitions
The protocol supports two ways to declare entities:
1. Coverage Declaration (entities[])
Declares which entity types the datasource covers:
entities:
- entity_type: stock
coverage: explicit
codes: [AAPL, MSFT, GOOGL]
coverage: "universe"- datasource can fetch data for all entities of this typecoverage: "explicit"- datasource only covers the listed codes
2. Entity Metadata (entity_definitions[])
Defines canonical entity metadata (names, attributes, relationships):
entity_definitions:
- entity_type: stock
code: AAPL
name_en: Apple Inc.
name_zh: 苹果公司
metadata:
exchange: NASDAQ
sector: Technology
relationships:
- target_entity_type: industry
target_code: gics_10
relation_type: belongs_to
When included, entities are registered in the ontology database during register_datasource().
Reserved metadata key: external_ids
An entity definition may anchor itself in an external entity graph under the
reserved metadata key external_ids. Registration persists each entry as a
per-source identifier, so consumers can resolve the external id back to the
local entity.
entity_definitions:
- entity_type: country
code: CN
name_en: China
metadata:
external_ids:
wikidata: Q148 # Wikidata QID (Q followed by digits)
datacommons: country/CHN # Data Commons DCID
Supported anchor sources are wikidata (QID, validated as Q<digits>) and
datacommons (non-empty DCID). A malformed or unknown anchor is logged and
skipped — it never fails registration.
Canonical Entity Types
The entity-type vocabulary is defined by
fd_open_data_protocol/vocabulary/entity_types.yaml
(14 types) and is the authority for manifest validation:
| Type | Description | Example IDs |
|---|---|---|
country |
ISO codes | CN, US, JP |
city |
Municipalities | beijing, shanghai |
stock |
A-shares | 600000.SH, 000001.SZ |
fund |
ETFs/funds | etf_code, fund_code |
bond |
Bonds | bond_code |
index |
Indices | SH000001, SZ399001 |
future |
Futures | cu2412, rb2401 |
crypto |
Cryptocurrencies | btc, eth |
organization |
General orgs | org_code |
industry |
Classifications | shenwan_1_01, gics_10 |
exchange |
Exchanges / venues | XNYS, XNAS, SSE |
company |
Public companies | AAPL, TSLA |
commodity |
Raw goods | steel, oil, grain |
person |
Humans (fund managers) | person_code |
Semantic vocabulary
The protocol ships the publishable semantic core of FindData as versioned YAML
under fd_open_data_protocol/vocabulary/:
| File | Registry |
|---|---|
entity_types.yaml |
entity types (the manifest vocabulary above) |
concepts.yaml |
concept families + their seeded Variables |
qualifiers.yaml |
qualifiers (nominal_current, real_constant, ppp, per_capita, growth, ...) |
units.yaml |
units of measure (UN/CEFACT codes + ISO 4217 currencies) |
relation_types.yaml |
entity relationship types |
event_types.yaml |
event types (empty in this release) |
crosswalks/*.yaml |
Variable ↔ external-vocabulary assertions |
The vocabulary files ship as package data (0.3.0+), so load_vocabulary()
works from an installed wheel with no checkout on disk.
from fd_open_data_protocol.vocabulary import load_vocabulary, validate_vocabulary
vocab = load_vocabulary() # shipped files
vocab = load_vocabulary("/path/to/dir") # or an explicit directory
vocab.version # release version of the file set
vocab.get("concept", "GDP").uri # https://schema.finddata.tech/concept/GDP
vocab.entity_type_ids() # the manifest entity-type vocabulary
vocab.seeded_variables() # Variables a family declares
errors = validate_vocabulary() # [] when the file set is valid
Every entry carries a stable URI of the form
https://schema.finddata.tech/<kind>/<Id>, where <kind> is one of
entity-type, concept, qualifier, unit, relation-type, event-type.
Stability rules. A URI is never reassigned to a different meaning and
entries are never deleted. Retirement is expressed with a superseded_by
pointer to the successor entry, which keeps the URI resolvable. The file set
carries one release version, and the loader rejects a file set whose files
disagree.
Concept families and Variables
Concepts are two-level. A concept family (fd:GDP, fd:Population) is the
small curated vocabulary from concepts.yaml; a Variable is the qualified
combination (code, entity_type, measure, unit, frequency) — the identity a
datasource actually binds columns to.
A manifest concept hint may point at its family with the optional
concept_family field, which the loader validates against concepts.yaml:
concepts:
- {column: close, concept: price.close, entity_type: stock, unit: currency,
frequency: daily, concept_family: PriceClose}
Omitting it preserves the previous behaviour — no family validation occurs, and the consumer derives a family from the concept code.
Manifest Declaration Requirement
Every fd- datasource package MUST declare a DatasourceManifest via one of the following mechanisms:*
- Python module: Expose a
CATALOGdict in a module (e.g.,catalog.py) that conforms to theDatasourceManifestschema - YAML/JSON file: Place a manifest file at the package root (e.g.,
catalog.yamlorcatalog.json) - Entry-point declaration: Register the manifest path in
pyproject.tomlunder[project.entry-points."fd_open_data_mcp.datasources"]
The declaration SHALL be discoverable by fd-open-data-mcp's auto-discovery mechanism (register-discovered command). Packages without a CATALOG declaration SHALL NOT be considered compliant with the fd-open-data-protocol.
Recommended Package Structure
my-datasource/
├── pyproject.toml # declares entry-point
└── my_pkg/
├── __init__.py
└── catalog.py # exposes CATALOG = { ... }
Entry-Point Declaration
In your pyproject.toml:
[project.entry-points."fd_open_data_mcp.datasources"]
my-source = "my_pkg.catalog:CATALOG"
After pip install my-pkg, the package is automatically discoverable:
fd-open-data-mcp register-discovered
Auto-Discovery Flow
- Install package →
pip install my-datasource - Entry-point registered → setuptools records
my-source = "my_pkg.catalog:CATALOG" - Auto-discover →
fd-open-data-mcp register-discoveredscans all entry-points - Load manifest →
load_catalog()validates and parses the CATALOG dict - Register to ontology →
register_datasource()upserts sources/functions/columns/concepts
Compliance Checklist
Before publishing a new datasource package, ensure:
- Package exposes a
CATALOGdict or manifest file -
pyproject.tomldeclares entry-point underfd_open_data_mcp.datasourcesgroup - CATALOG conforms to
DatasourceManifestschema (version, name, label, functions[], concepts[], fetch) -
load_catalog()can successfully parse the manifest -
fd-open-data-mcp register-discovereddiscovers and registers the package
Working Examples
- fd-world:
fd_world/catalog.py+ entry-point inpyproject.toml - fd-cn-gov:
fd_cn_gov/catalog.py+ entry-point inpyproject.toml - fd-cn-report:
catalog.py+ entry-point inpyproject.toml
Template
Copy template/datasource.template.yaml (declarative) or
template/provider_template.py (a BaseDataProvider class with run()).
Metadata
Release files for fd-open-data-protocol 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fd_open_data_protocol-0.3.1.tar.gz | 45.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fd_open_data_protocol-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.0 kB
Release files / fd_open_data_protocol-0.3.1.tar.gz
| Download URL | fd_open_data_protocol-0.3.1.tar.gz |
|---|---|
| Size | 45.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83b5d616c12ea40c78e622287bc22a131a7793f0c8da33b784839544900f8a2a
|
|
BLAKE2b-256 checksum How to use checksums |
48d6d0e3d2299616b7a03d964f807a77414c6a64ba7ae89b035201aa980480f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / fd_open_data_protocol-0.3.1-py3-none-any.whl
| Download URL | fd_open_data_protocol-0.3.1-py3-none-any.whl |
|---|---|
| Size | 40.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ce3d0f9e502ab07759e58de34955ddbcbba9814fd4b1d060730e48e140b703e
|
|
BLAKE2b-256 checksum How to use checksums |
acfb307833b51f9d3319081a6e2773742f9e7ed22bc982799ae2f85f872ca82b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log