fd-daas-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. fd_daas_mcp-0.1.0/LICENSE +21 -0
  2. fd_daas_mcp-0.1.0/PKG-INFO +201 -0
  3. fd_daas_mcp-0.1.0/README.md +142 -0
  4. fd_daas_mcp-0.1.0/pyproject.toml +94 -0
  5. fd_daas_mcp-0.1.0/setup.cfg +4 -0
  6. fd_daas_mcp-0.1.0/src/fd_daas_mcp/__init__.py +13 -0
  7. fd_daas_mcp-0.1.0/src/fd_daas_mcp/cli.py +151 -0
  8. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/alert_database.py +429 -0
  9. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/alert_tools.py +149 -0
  10. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/engine.py +204 -0
  11. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/expressions.py +266 -0
  12. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/messaging.py +37 -0
  13. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/__init__.py +18 -0
  14. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/base.py +45 -0
  15. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/dingtalk.py +61 -0
  16. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/discord.py +32 -0
  17. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/feishu.py +60 -0
  18. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/registry.py +67 -0
  19. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/slack.py +31 -0
  20. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/telegram.py +51 -0
  21. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/twitter.py +128 -0
  22. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/notifiers/wecowork.py +44 -0
  23. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/selfcheck.py +281 -0
  24. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/alerts/server.py +216 -0
  25. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/composite_database.py +434 -0
  26. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/composite_tools.py +350 -0
  27. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/seed_example.py +51 -0
  28. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/selfcheck.py +144 -0
  29. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/selfcheck_ui_tool.py +64 -0
  30. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/server.py +115 -0
  31. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/composite/ui_tools.py +130 -0
  32. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/agent_runner.py +121 -0
  33. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/database.py +32 -0
  34. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/main.py +6 -0
  35. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/registry.py +33 -0
  36. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/scheduler.py +140 -0
  37. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/server.py +375 -0
  38. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/tasks/__init__.py +23 -0
  39. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/tasks/fetch_via_leader.py +81 -0
  40. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/cron/tasks.py +23 -0
  41. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/README.md +90 -0
  42. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/backfill_massive.py +188 -0
  43. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/collection_writer.py +316 -0
  44. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/daas_database.py +290 -0
  45. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/daas_tools.py +490 -0
  46. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/entity_collection_sync.py +209 -0
  47. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/entity_collection_tools.py +278 -0
  48. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/entity_rule_script.py +134 -0
  49. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/entity_sync.py +534 -0
  50. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/entity_tools.py +146 -0
  51. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/fetch_data_cli.py +74 -0
  52. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/indicator_collection_tools.py +253 -0
  53. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/indicator_tools.py +187 -0
  54. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/migrate_process_cron.py +111 -0
  55. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/pipeline_tools.py +864 -0
  56. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/process_api.py +264 -0
  57. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/process_database.py +626 -0
  58. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/process_tools.py +394 -0
  59. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/register_us_leaders_cron.py +111 -0
  60. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/registry_service.py +2229 -0
  61. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/rule_engine.py +458 -0
  62. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/rule_tools.py +389 -0
  63. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/seed_external_mcps.py +705 -0
  64. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/seed_massive_endpoints.py +671 -0
  65. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/seed_pipeline_from_mapping.py +210 -0
  66. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/seed_us_leaders_indicators.py +110 -0
  67. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck.py +276 -0
  68. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_collection_writer.py +162 -0
  69. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_entity_collection_script.py +344 -0
  70. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_entity_collections.py +390 -0
  71. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_indicator_scores.py +402 -0
  72. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_massive_endpoints.py +203 -0
  73. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_pipeline.py +324 -0
  74. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_process.py +271 -0
  75. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/selfcheck_scores.py +228 -0
  76. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/server.py +318 -0
  77. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/daas/sources/__init__.py +1 -0
  78. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/backfill_dashboards.py +130 -0
  79. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/dashboard_database.py +344 -0
  80. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/dashboards/build_us_leaders_dashboard.py +395 -0
  81. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/dashboards/daas.md +6 -0
  82. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/dashboards/fetch_pool_indicators.py +95 -0
  83. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/dashboards/screen_us_top300.py +143 -0
  84. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/selfcheck_dashboards.py +103 -0
  85. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/dashboard/server.py +282 -0
  86. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/README.md +147 -0
  87. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/__init__.py +1 -0
  88. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/data_crew.py +237 -0
  89. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/database.py +125 -0
  90. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/gateway_database.py +240 -0
  91. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/gateway_tools.py +401 -0
  92. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/leader_crew.py +243 -0
  93. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/leader_database.py +140 -0
  94. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/leader_tools.py +671 -0
  95. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/migrate_registry.py +228 -0
  96. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/registry_service.py +129 -0
  97. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/seed_massive_upstream.py +94 -0
  98. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/seed_specialist_agents.py +135 -0
  99. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/seed_upstreams.py +168 -0
  100. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/selfcheck_gateway.py +189 -0
  101. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/selfcheck_tiers.py +144 -0
  102. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/selfcheck_workflow.py +298 -0
  103. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/server.py +166 -0
  104. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/specialist_agents.py +555 -0
  105. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/tests/test_datasource.py +267 -0
  106. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/workflow_database.py +621 -0
  107. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/leader/workflow_tools.py +681 -0
  108. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/pdf/embedding_client.py +196 -0
  109. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/pdf/pdf_database.py +332 -0
  110. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/pdf/pdf_tools.py +445 -0
  111. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/pdf/selfcheck.py +142 -0
  112. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/pdf/server.py +79 -0
  113. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/research/research_database.py +86 -0
  114. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/research/research_report.py +139 -0
  115. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/research/research_tools.py +639 -0
  116. fd_daas_mcp-0.1.0/src/fd_daas_mcp/mcp/research/server.py +49 -0
  117. fd_daas_mcp-0.1.0/src/fd_daas_mcp/models.py +1935 -0
  118. fd_daas_mcp-0.1.0/src/fd_daas_mcp/registry.py +341 -0
  119. fd_daas_mcp-0.1.0/src/fd_daas_mcp/selfcheck.py +154 -0
  120. fd_daas_mcp-0.1.0/src/fd_daas_mcp/server.py +49 -0
  121. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/PKG-INFO +201 -0
  122. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/SOURCES.txt +141 -0
  123. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/dependency_links.txt +1 -0
  124. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/entry_points.txt +3 -0
  125. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/requires.txt +37 -0
  126. fd_daas_mcp-0.1.0/src/fd_daas_mcp.egg-info/top_level.txt +1 -0
  127. fd_daas_mcp-0.1.0/tests/test_alert_tools.py +211 -0
  128. fd_daas_mcp-0.1.0/tests/test_cli.py +99 -0
  129. fd_daas_mcp-0.1.0/tests/test_composite_tools.py +128 -0
  130. fd_daas_mcp-0.1.0/tests/test_core_group_tools.py +80 -0
  131. fd_daas_mcp-0.1.0/tests/test_cron_tools.py +206 -0
  132. fd_daas_mcp-0.1.0/tests/test_dashboard_tools.py +134 -0
  133. fd_daas_mcp-0.1.0/tests/test_entity_collection_sync.py +136 -0
  134. fd_daas_mcp-0.1.0/tests/test_indicator_collection_sync.py +112 -0
  135. fd_daas_mcp-0.1.0/tests/test_leader_tools.py +165 -0
  136. fd_daas_mcp-0.1.0/tests/test_pdf_optional.py +82 -0
  137. fd_daas_mcp-0.1.0/tests/test_registration_report.py +65 -0
  138. fd_daas_mcp-0.1.0/tests/test_registry.py +77 -0
  139. fd_daas_mcp-0.1.0/tests/test_research_tools.py +434 -0
  140. fd_daas_mcp-0.1.0/tests/test_rule_engine.py +182 -0
  141. fd_daas_mcp-0.1.0/tests/test_rule_tools.py +191 -0
  142. fd_daas_mcp-0.1.0/tests/test_run_indicator_eviction.py +87 -0
  143. fd_daas_mcp-0.1.0/tests/test_selfcheck.py +31 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FindDataOfficial
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: fd-daas-mcp
3
+ Version: 0.1.0
4
+ Summary: Consolidated DAAS MCP server + CLI - hosts the alerts, cron, composite, daas, dashboard, leader, pdf, and research tool groups (~187 tools) behind one stdio FastMCP server and one Click CLI. Both consume fd_daas_mcp/registry.py so the server and CLI surfaces cannot drift.
5
+ Author: FindDataOfficial
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/FindDataOfficial/fd-daas-mcp
8
+ Project-URL: Documentation, https://finddataofficial.github.io/fd-daas-mcp/
9
+ Project-URL: Repository, https://github.com/FindDataOfficial/fd-daas-mcp
10
+ Project-URL: Issues, https://github.com/FindDataOfficial/fd-daas-mcp/issues
11
+ Project-URL: Changelog, https://github.com/FindDataOfficial/fd-daas-mcp/blob/main/CHANGELOG.md
12
+ Keywords: mcp,model-context-protocol,fastmcp,data,finance,indicators,dashboards
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Financial and Insurance Industry
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Database
23
+ Classifier: Topic :: Office/Business :: Financial
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.12
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: fastmcp>=3.4.2
29
+ Requires-Dist: click>=8.0
30
+ Requires-Dist: pandas>=1.0
31
+ Requires-Dist: sqlalchemy>=2.0
32
+ Requires-Dist: python-dotenv>=1.0
33
+ Requires-Dist: apscheduler>=3.11.2
34
+ Provides-Extra: crew
35
+ Requires-Dist: crewai; extra == "crew"
36
+ Requires-Dist: litellm; extra == "crew"
37
+ Provides-Extra: akshare
38
+ Requires-Dist: akshare>=1.13; extra == "akshare"
39
+ Provides-Extra: es
40
+ Requires-Dist: elasticsearch>=8.0; extra == "es"
41
+ Provides-Extra: pdf
42
+ Requires-Dist: sentence-transformers; extra == "pdf"
43
+ Requires-Dist: sqlite-vec; extra == "pdf"
44
+ Requires-Dist: pdfplumber; extra == "pdf"
45
+ Requires-Dist: pypdf; extra == "pdf"
46
+ Provides-Extra: position
47
+ Requires-Dist: lxml; extra == "position"
48
+ Requires-Dist: cssselect; extra == "position"
49
+ Requires-Dist: jsonpath-ng; extra == "position"
50
+ Provides-Extra: repl
51
+ Requires-Dist: prompt_toolkit>=3.0; extra == "repl"
52
+ Provides-Extra: dev
53
+ Requires-Dist: pytest>=8.0; extra == "dev"
54
+ Requires-Dist: mkdocs>=1.6; extra == "dev"
55
+ Requires-Dist: mkdocs-material>=9.5; extra == "dev"
56
+ Requires-Dist: mkdocs-static-i18n>=1.2; extra == "dev"
57
+ Requires-Dist: twine>=5.0; extra == "dev"
58
+ Dynamic: license-file
59
+
60
+ # fd-daas-mcp
61
+
62
+ [![PyPI version](https://img.shields.io/pypi/v/fd-daas-mcp.svg)](https://pypi.org/project/fd-daas-mcp/)
63
+ [![Python](https://img.shields.io/pypi/pyversions/fd-daas-mcp.svg)](https://pypi.org/project/fd-daas-mcp/)
64
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
65
+ [![Docs](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://finddataofficial.github.io/fd-daas-mcp/)
66
+
67
+ A single MCP server + CLI for skill-driven data access across financial,
68
+ economic, and statistical sources. Browse thousands of indicators, build entity
69
+ & indicator collections, run research workflows, and share dashboards - all
70
+ behind one stdio server with **181 tools across 8 groups** (187 with the
71
+ optional `pdf` extra).
72
+
73
+ `fd-daas-mcp` is the engine behind the [DAAS](https://github.com/FindDataOfficial)
74
+ skill-driven data-fetch workflow. Point any MCP client (Claude Code, etc.) at
75
+ it and the tools show up as `<group>_<tool>` calls - e.g. `daas_list_sources`,
76
+ `alerts_create_alert_rule`, `research_create`.
77
+
78
+ ## Install
79
+
80
+ ```bash
81
+ pip install fd-daas-mcp
82
+ ```
83
+
84
+ Optional extras (all lazy-loaded - a missing extra degrades to a per-feature
85
+ error, never a startup crash):
86
+
87
+ ```bash
88
+ pip install "fd-daas-mcp[pdf]" # local PDF/text vector search (sqlite-vec)
89
+ pip install "fd-daas-mcp[crew]" # CrewAI router for the leader group
90
+ pip install "fd-daas-mcp[akshare]" # live A-share OHLCV/fundamentals
91
+ pip install "fd-daas-mcp[position]" # CSS/xpath/json-path rule extraction
92
+ pip install "fd-daas-mcp[repl]" # REPL history/autocomplete
93
+ pip install "fd-daas-mcp[dev]" # pytest + mkdocs for contributors
94
+ ```
95
+
96
+ ## 60-second quickstart
97
+
98
+ ```bash
99
+ # 1. Install
100
+ pip install fd-daas-mcp
101
+
102
+ # 2. Point your MCP client at it. For Claude Code, add to your .mcp.json:
103
+ ```
104
+
105
+ ```jsonc
106
+ // .mcp.json
107
+ {
108
+ "mcpServers": {
109
+ "fd-daas-mcp": {
110
+ "command": "fd-daas-mcp-server",
111
+ "args": []
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ```bash
118
+ # 3. Set a database URL (the schema auto-creates on first startup via
119
+ # Base.metadata.create_all - no manual init step):
120
+ export DAAS_DATABASE_URL=sqlite:///daas.db
121
+
122
+ # 4. Or use the CLI directly:
123
+ fd-daas-mcp --help # see every group + tool
124
+ fd-daas-mcp daas list_sources # invoke a tool: <group> <tool> [key=value ...]
125
+ fd-daas-mcp # drop into the REPL (needs [repl] extra)
126
+ ```
127
+
128
+ On server startup the schema auto-creates and you'll see the registration
129
+ report:
130
+
131
+ ```
132
+ registry: 181 tools across 8 sources (failed=0, skipped_optional=1)
133
+ ```
134
+
135
+ (181 tools with the default install; 187 with the `pdf` extra installed. The
136
+ `pdf` group is optional and skipped when `sqlite-vec` is absent.)
137
+
138
+ ## Tool groups
139
+
140
+ | Group | Surface prefix | What it does |
141
+ |-------------|------------------|-----------------------------------------------------------------------|
142
+ | `daas` | `daas_*` | Datasource/function/column catalog, entities, indicators, collections, rules, pipelines |
143
+ | `alerts` | `alerts_*` | Rule-based alerting over indicator series (Feishu/Discord/Slack/Telegram/DingTalk/WeCom/Twitter) |
144
+ | `cron` | `cron_*` | Scheduled task execution + history |
145
+ | `composite` | `composite_*` | Compose + chain tools across upstream MCPs |
146
+ | `dashboard` | `dashboard_*` | Standalone-HTML dashboard registry + query |
147
+ | `leader` | `leader_*` | CrewAI DataCrew router, specialist agents, workflows, snapshots |
148
+ | `pdf` | `pdf_*` | Local PDF/text semantic vector search (optional - needs `sqlite-vec`) |
149
+ | `research` | `research_*` | Persisted research bundles + generated markdown reports |
150
+
151
+ The CLI tree mirrors this: `fd-daas-mcp <group> <tool>`. Both server and CLI
152
+ are generated from the same `registry.build()`, so they cannot drift.
153
+
154
+ ## Skills
155
+
156
+ The `skills/` directory (in the repo, not the wheel) contains 15 Claude Code
157
+ skills that turn the raw tools into guided workflows - data fetch, research
158
+ orchestration, dashboard building, rule authoring, and more. To use them:
159
+
160
+ ```bash
161
+ git clone https://github.com/FindDataOfficial/fd-daas-mcp.git
162
+ # Then point Claude Code at skills/ in the clone (or symlink into ~/.claude/skills/).
163
+ ```
164
+
165
+ See [CONTRIBUTING.md](CONTRIBUTING.md) and the [docs site](https://finddataofficial.github.io/fd-daas-mcp/) for details.
166
+
167
+ ## Architecture
168
+
169
+ ```
170
+ src/fd_daas_mcp/ # the installable package
171
+ server.py # FastMCP app - registers every tool as <group>_<tool>
172
+ cli.py # Click CLI - auto-generated from registry.build()
173
+ registry.py # AST-harvests tools from each mcp/<group>/ (per-group sys.modules isolation)
174
+ selfcheck.py # offline invariants (run_invariants())
175
+ models.py # vendored SQLAlchemy schema (Base + ORM for every domain)
176
+ mcp/ # tool-group source (shipped as package data)
177
+ alerts/ cron/ composite/ daas/ dashboard/ leader/ pdf/ research/
178
+ ```
179
+
180
+ The registry loads each group's `server.py` and harvests `@app.tool`-decorated
181
+ functions (inline groups) or the `*_tools.py` modules they import (non-inline
182
+ groups), with per-group `sys.modules` isolation so leaf modules like
183
+ `database.py` don't collide across groups. The `cron` group is loaded with
184
+ `suppress=True` to neutralize APScheduler's import-time thread while keeping
185
+ its idempotent DDL.
186
+
187
+ ## Development
188
+
189
+ ```bash
190
+ git clone https://github.com/FindDataOfficial/fd-daas-mcp.git
191
+ cd fd-daas-mcp
192
+ uv sync --extra dev # editable install + dev deps (pytest, mkdocs, twine)
193
+ uv run pytest # offline test suite
194
+ uv run python -m fd_daas_mcp.selfcheck
195
+ ```
196
+
197
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
198
+
199
+ ## License
200
+
201
+ [MIT](LICENSE) - © FindDataOfficial.
@@ -0,0 +1,142 @@
1
+ # fd-daas-mcp
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/fd-daas-mcp.svg)](https://pypi.org/project/fd-daas-mcp/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/fd-daas-mcp.svg)](https://pypi.org/project/fd-daas-mcp/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Docs](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://finddataofficial.github.io/fd-daas-mcp/)
7
+
8
+ A single MCP server + CLI for skill-driven data access across financial,
9
+ economic, and statistical sources. Browse thousands of indicators, build entity
10
+ & indicator collections, run research workflows, and share dashboards - all
11
+ behind one stdio server with **181 tools across 8 groups** (187 with the
12
+ optional `pdf` extra).
13
+
14
+ `fd-daas-mcp` is the engine behind the [DAAS](https://github.com/FindDataOfficial)
15
+ skill-driven data-fetch workflow. Point any MCP client (Claude Code, etc.) at
16
+ it and the tools show up as `<group>_<tool>` calls - e.g. `daas_list_sources`,
17
+ `alerts_create_alert_rule`, `research_create`.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install fd-daas-mcp
23
+ ```
24
+
25
+ Optional extras (all lazy-loaded - a missing extra degrades to a per-feature
26
+ error, never a startup crash):
27
+
28
+ ```bash
29
+ pip install "fd-daas-mcp[pdf]" # local PDF/text vector search (sqlite-vec)
30
+ pip install "fd-daas-mcp[crew]" # CrewAI router for the leader group
31
+ pip install "fd-daas-mcp[akshare]" # live A-share OHLCV/fundamentals
32
+ pip install "fd-daas-mcp[position]" # CSS/xpath/json-path rule extraction
33
+ pip install "fd-daas-mcp[repl]" # REPL history/autocomplete
34
+ pip install "fd-daas-mcp[dev]" # pytest + mkdocs for contributors
35
+ ```
36
+
37
+ ## 60-second quickstart
38
+
39
+ ```bash
40
+ # 1. Install
41
+ pip install fd-daas-mcp
42
+
43
+ # 2. Point your MCP client at it. For Claude Code, add to your .mcp.json:
44
+ ```
45
+
46
+ ```jsonc
47
+ // .mcp.json
48
+ {
49
+ "mcpServers": {
50
+ "fd-daas-mcp": {
51
+ "command": "fd-daas-mcp-server",
52
+ "args": []
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ```bash
59
+ # 3. Set a database URL (the schema auto-creates on first startup via
60
+ # Base.metadata.create_all - no manual init step):
61
+ export DAAS_DATABASE_URL=sqlite:///daas.db
62
+
63
+ # 4. Or use the CLI directly:
64
+ fd-daas-mcp --help # see every group + tool
65
+ fd-daas-mcp daas list_sources # invoke a tool: <group> <tool> [key=value ...]
66
+ fd-daas-mcp # drop into the REPL (needs [repl] extra)
67
+ ```
68
+
69
+ On server startup the schema auto-creates and you'll see the registration
70
+ report:
71
+
72
+ ```
73
+ registry: 181 tools across 8 sources (failed=0, skipped_optional=1)
74
+ ```
75
+
76
+ (181 tools with the default install; 187 with the `pdf` extra installed. The
77
+ `pdf` group is optional and skipped when `sqlite-vec` is absent.)
78
+
79
+ ## Tool groups
80
+
81
+ | Group | Surface prefix | What it does |
82
+ |-------------|------------------|-----------------------------------------------------------------------|
83
+ | `daas` | `daas_*` | Datasource/function/column catalog, entities, indicators, collections, rules, pipelines |
84
+ | `alerts` | `alerts_*` | Rule-based alerting over indicator series (Feishu/Discord/Slack/Telegram/DingTalk/WeCom/Twitter) |
85
+ | `cron` | `cron_*` | Scheduled task execution + history |
86
+ | `composite` | `composite_*` | Compose + chain tools across upstream MCPs |
87
+ | `dashboard` | `dashboard_*` | Standalone-HTML dashboard registry + query |
88
+ | `leader` | `leader_*` | CrewAI DataCrew router, specialist agents, workflows, snapshots |
89
+ | `pdf` | `pdf_*` | Local PDF/text semantic vector search (optional - needs `sqlite-vec`) |
90
+ | `research` | `research_*` | Persisted research bundles + generated markdown reports |
91
+
92
+ The CLI tree mirrors this: `fd-daas-mcp <group> <tool>`. Both server and CLI
93
+ are generated from the same `registry.build()`, so they cannot drift.
94
+
95
+ ## Skills
96
+
97
+ The `skills/` directory (in the repo, not the wheel) contains 15 Claude Code
98
+ skills that turn the raw tools into guided workflows - data fetch, research
99
+ orchestration, dashboard building, rule authoring, and more. To use them:
100
+
101
+ ```bash
102
+ git clone https://github.com/FindDataOfficial/fd-daas-mcp.git
103
+ # Then point Claude Code at skills/ in the clone (or symlink into ~/.claude/skills/).
104
+ ```
105
+
106
+ See [CONTRIBUTING.md](CONTRIBUTING.md) and the [docs site](https://finddataofficial.github.io/fd-daas-mcp/) for details.
107
+
108
+ ## Architecture
109
+
110
+ ```
111
+ src/fd_daas_mcp/ # the installable package
112
+ server.py # FastMCP app - registers every tool as <group>_<tool>
113
+ cli.py # Click CLI - auto-generated from registry.build()
114
+ registry.py # AST-harvests tools from each mcp/<group>/ (per-group sys.modules isolation)
115
+ selfcheck.py # offline invariants (run_invariants())
116
+ models.py # vendored SQLAlchemy schema (Base + ORM for every domain)
117
+ mcp/ # tool-group source (shipped as package data)
118
+ alerts/ cron/ composite/ daas/ dashboard/ leader/ pdf/ research/
119
+ ```
120
+
121
+ The registry loads each group's `server.py` and harvests `@app.tool`-decorated
122
+ functions (inline groups) or the `*_tools.py` modules they import (non-inline
123
+ groups), with per-group `sys.modules` isolation so leaf modules like
124
+ `database.py` don't collide across groups. The `cron` group is loaded with
125
+ `suppress=True` to neutralize APScheduler's import-time thread while keeping
126
+ its idempotent DDL.
127
+
128
+ ## Development
129
+
130
+ ```bash
131
+ git clone https://github.com/FindDataOfficial/fd-daas-mcp.git
132
+ cd fd-daas-mcp
133
+ uv sync --extra dev # editable install + dev deps (pytest, mkdocs, twine)
134
+ uv run pytest # offline test suite
135
+ uv run python -m fd_daas_mcp.selfcheck
136
+ ```
137
+
138
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
139
+
140
+ ## License
141
+
142
+ [MIT](LICENSE) - © FindDataOfficial.
@@ -0,0 +1,94 @@
1
+ [project]
2
+ name = "fd-daas-mcp"
3
+ version = "0.1.0"
4
+ description = "Consolidated DAAS MCP server + CLI - hosts the alerts, cron, composite, daas, dashboard, leader, pdf, and research tool groups (~187 tools) behind one stdio FastMCP server and one Click CLI. Both consume fd_daas_mcp/registry.py so the server and CLI surfaces cannot drift."
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "FindDataOfficial" }]
9
+ keywords = ["mcp", "model-context-protocol", "fastmcp", "data", "finance", "indicators", "dashboards"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Environment :: Console",
13
+ "Intended Audience :: Developers",
14
+ "Intended Audience :: Financial and Insurance Industry",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Database",
21
+ "Topic :: Office/Business :: Financial",
22
+ "Typing :: Typed",
23
+ ]
24
+ dependencies = [
25
+ "fastmcp>=3.4.2",
26
+ "click>=8.0",
27
+ "pandas>=1.0",
28
+ "sqlalchemy>=2.0",
29
+ "python-dotenv>=1.0",
30
+ "apscheduler>=3.11.2",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/FindDataOfficial/fd-daas-mcp"
35
+ Documentation = "https://finddataofficial.github.io/fd-daas-mcp/"
36
+ Repository = "https://github.com/FindDataOfficial/fd-daas-mcp"
37
+ Issues = "https://github.com/FindDataOfficial/fd-daas-mcp/issues"
38
+ Changelog = "https://github.com/FindDataOfficial/fd-daas-mcp/blob/main/CHANGELOG.md"
39
+
40
+ [project.optional-dependencies]
41
+ # CrewAI powers leader's DataCrew router (ask_data_crew) + specialist agents.
42
+ # Falls back to a deterministic direct router when absent.
43
+ crew = ["crewai", "litellm"]
44
+ # akshare is imported lazily by daas source modules; install for live A-share fetches.
45
+ akshare = ["akshare>=1.13"]
46
+ # elasticsearch powers cnreport ES store/search tools.
47
+ es = ["elasticsearch>=8.0"]
48
+ # Local PDF/text vector search: sentence-transformers (embeddings) + sqlite-vec
49
+ # (vec0 ANN index) + pdfplumber/pypdf (text extraction). Loaded as an optional
50
+ # `pdf` tool group gated on `sqlite_vec` (see registry.py). No API key, no egress.
51
+ pdf = ["sentence-transformers", "sqlite-vec", "pdfplumber", "pypdf"]
52
+ # Position rules: CSS/xpath (lxml+cssselect) + json-path (jsonpath-ng) extraction.
53
+ # regex needs no extra dep. Lazy-imported by rule_engine._eval_position, so a
54
+ # missing install degrades to a per-rule error, never a server-startup crash.
55
+ position = ["lxml", "cssselect", "jsonpath-ng"]
56
+ # REPL history/autocomplete.
57
+ repl = ["prompt_toolkit>=3.0"]
58
+ dev = [
59
+ "pytest>=8.0",
60
+ "mkdocs>=1.6",
61
+ "mkdocs-material>=9.5",
62
+ "mkdocs-static-i18n>=1.2",
63
+ "twine>=5.0",
64
+ ]
65
+
66
+ [project.scripts]
67
+ fd-daas-mcp = "fd_daas_mcp.cli:cli"
68
+ fd-daas-mcp-server = "fd_daas_mcp.server:main"
69
+
70
+ [tool.setuptools.packages.find]
71
+ where = ["src"]
72
+ include = ["fd_daas_mcp*"]
73
+
74
+ [tool.setuptools.package-data]
75
+ fd_daas_mcp = [
76
+ "mcp/**/*.py",
77
+ "mcp/**/*.md",
78
+ "mcp/**/*.json",
79
+ "mcp/**/*.yaml",
80
+ "mcp/**/*.yml",
81
+ "mcp/**/*.txt",
82
+ ]
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ pythonpath = ["src"]
87
+ # The .venv leaks micromamba site-packages whose logfire pytest plugin crashes
88
+ # on import (opentelemetry._tail_sampling). `-p no:X` is a no-op when the plugin
89
+ # isn't registered, so this is safe in a clean venv too.
90
+ addopts = "-p no:logfire -p no:pytest_logfire"
91
+
92
+ [build-system]
93
+ requires = ["setuptools>=68.0"]
94
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,13 @@
1
+ """fd-daas-mcp - the single consolidated MCP server for the DAAS platform.
2
+
3
+ This is the only MCP in the project. Tool logic is hosted in-package at
4
+ ``fd-daas-mcp/<group>-mcp/`` (moved, not rewritten, from the former ``mcp/``
5
+ source dirs). The :mod:`registry` imports each group's tool functions with
6
+ per-group ``sys.modules`` isolation and re-exposes them under a collision-free
7
+ ``<group>_<tool>`` namespace on one FastMCP server (and one Click CLI).
8
+
9
+ Groups (core always-on unless the extra is absent): alerts, cron, composite,
10
+ daas, dashboard, leader, pdf, cnreport, massive, scrapling, firecrawl.
11
+ """
12
+
13
+ __version__ = "0.1.0"
@@ -0,0 +1,151 @@
1
+ """Click CLI for fd-daas-mcp - auto-generated from the same registry as the server.
2
+
3
+ Usage:
4
+ fd-daas-mcp <group> <tool> [key=value ...] [--json]
5
+ fd-daas-mcp # REPL mode (needs [repl] extra for history)
6
+ fd-daas-mcp --help # authoritative live surface (no drift)
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import inspect
12
+ import json
13
+ import sys
14
+ from pathlib import Path
15
+ from typing import Any
16
+
17
+ import click
18
+
19
+ from fd_daas_mcp import registry
20
+
21
+
22
+ def _parse_value(v: str) -> Any:
23
+ try:
24
+ return json.loads(v)
25
+ except (json.JSONDecodeError, ValueError):
26
+ return v
27
+
28
+
29
+ def _print(result: Any, as_json: bool) -> None:
30
+ if isinstance(result, (dict, list)) or as_json:
31
+ try:
32
+ click.echo(json.dumps(result, default=str, ensure_ascii=False, indent=2))
33
+ return
34
+ except (TypeError, ValueError):
35
+ pass
36
+ click.echo(str(result))
37
+
38
+
39
+ def _make_command(name: str, func: Any) -> click.Command:
40
+ sig = inspect.signature(func)
41
+ params = list(sig.parameters.values())
42
+ help_text = ""
43
+ if func.__doc__:
44
+ help_text = func.__doc__.strip().split("\n\n", 1)[0][:200]
45
+
46
+ @click.command(name=name, help=help_text or name)
47
+ @click.argument("kv", nargs=-1)
48
+ @click.option("--json", "as_json", is_flag=True, help="Print raw JSON output")
49
+ def _cmd(kv, as_json):
50
+ kwargs: dict[str, Any] = {}
51
+ for pair in kv:
52
+ if "=" not in pair:
53
+ click.echo(f"error: argument {pair!r} is not key=value", err=True)
54
+ sys.exit(2)
55
+ k, v = pair.split("=", 1)
56
+ kwargs[k] = _parse_value(v)
57
+ for p in params:
58
+ if p.name not in kwargs and p.default is inspect.Parameter.empty:
59
+ click.echo(f"error: missing required parameter {p.name}", err=True)
60
+ sys.exit(2)
61
+ try:
62
+ if inspect.iscoroutinefunction(func):
63
+ result = asyncio.run(func(**kwargs))
64
+ else:
65
+ result = func(**kwargs)
66
+ except SystemExit:
67
+ raise
68
+ except Exception as e: # noqa: BLE001
69
+ click.echo(f"error: {type(e).__name__}: {e}", err=True)
70
+ sys.exit(1)
71
+ _print(result, as_json)
72
+
73
+ return _cmd
74
+
75
+
76
+ @click.group(invoke_without_command=True)
77
+ @click.pass_context
78
+ def cli(ctx: click.Context) -> None:
79
+ """fd-daas-mcp - the consolidated DAAS MCP CLI. Run with no subcommand for REPL."""
80
+ if ctx.invoked_subcommand is None:
81
+ _repl()
82
+
83
+
84
+ def _repl() -> None:
85
+ session = None
86
+ try:
87
+ from prompt_toolkit import PromptSession
88
+ from prompt_toolkit.history import FileHistory
89
+
90
+ hist = Path.home() / ".cache" / "fd-daas-mcp" / "history"
91
+ hist.parent.mkdir(parents=True, exist_ok=True)
92
+ session = PromptSession(history=FileHistory(str(hist)))
93
+ except ImportError:
94
+ pass
95
+ click.echo("fd-daas-mcp REPL. Ctrl-D to exit. `--help` lists groups/tools.")
96
+ while True:
97
+ try:
98
+ line = (session.prompt("fd-daas-mcp> ") if session else input("fd-daas-mcp> ")).strip()
99
+ except (EOFError, KeyboardInterrupt):
100
+ click.echo("")
101
+ break
102
+ if not line:
103
+ continue
104
+ try:
105
+ cli.main(line.split(), standalone_mode=False)
106
+ except click.exceptions.UsageError as e:
107
+ click.echo(str(e), err=True)
108
+ except SystemExit:
109
+ pass
110
+
111
+
112
+ for _group, _name, _func in registry.build():
113
+ if _group not in cli.commands:
114
+ _grp = click.Group(name=_group, help=f"{_group} group")
115
+ cli.add_command(_grp)
116
+ cli.commands[_group].add_command(_make_command(_name, _func))
117
+
118
+
119
+ def _pdf_branch(argv: list[str]) -> int:
120
+ """In-process cron branches --pdf-ingest / --pdf-search for the optional
121
+ pdf group (mirror daas-mcp/server.py's --run-rule). Reachable as:
122
+ ``python -m fd_daas_mcp.cli --pdf-ingest <path|url>`` /
123
+ ``--pdf-search "<query>"``. Returns a structured error when the [pdf]
124
+ extra is absent."""
125
+ _pdf_dir = Path(__file__).resolve().parents[2] / "pdf-mcp"
126
+ if str(_pdf_dir) not in sys.path:
127
+ sys.path.insert(0, str(_pdf_dir))
128
+ try:
129
+ from pdf_tools import cli_ingest, cli_search # type: ignore
130
+ except Exception as e: # noqa: BLE001
131
+ click.echo(json.dumps({"error": f"pdf extra not installed: {e}. uv sync --extra pdf"}))
132
+ return 1
133
+ if "--pdf-ingest" in argv:
134
+ i = argv.index("--pdf-ingest")
135
+ if i + 1 >= len(argv):
136
+ click.echo(json.dumps({"error": "--pdf-ingest requires a <path|url> argument"}))
137
+ return 2
138
+ return cli_ingest(argv[i + 1])
139
+ if "--pdf-search" in argv:
140
+ i = argv.index("--pdf-search")
141
+ if i + 1 >= len(argv):
142
+ click.echo(json.dumps({"error": "--pdf-search requires a <query> argument"}))
143
+ return 2
144
+ return cli_search(argv[i + 1])
145
+ return 0
146
+
147
+
148
+ if __name__ == "__main__":
149
+ if "--pdf-ingest" in sys.argv or "--pdf-search" in sys.argv:
150
+ sys.exit(_pdf_branch(sys.argv[1:]))
151
+ cli()