mcp-server-saxo-openapi 0.1.1__py3-none-any.whl

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 (97) hide show
  1. mcp_server_saxo_openapi-0.1.1.dist-info/METADATA +214 -0
  2. mcp_server_saxo_openapi-0.1.1.dist-info/RECORD +97 -0
  3. mcp_server_saxo_openapi-0.1.1.dist-info/WHEEL +4 -0
  4. mcp_server_saxo_openapi-0.1.1.dist-info/entry_points.txt +3 -0
  5. mcp_server_saxo_openapi-0.1.1.dist-info/licenses/LICENSE +21 -0
  6. saxo_doc_helper/__init__.py +32 -0
  7. saxo_doc_helper/__main__.py +6 -0
  8. saxo_doc_helper/cli.py +95 -0
  9. saxo_doc_helper/commands.py +119 -0
  10. saxo_doc_helper/data/__init__.py +1 -0
  11. saxo_doc_helper/data/json/atr/cashmanagement-beneficiaryinstructions.json +83 -0
  12. saxo_doc_helper/data/json/atr/cashmanagement-cashwithdrawal.json +76 -0
  13. saxo_doc_helper/data/json/atr/cashmanagement-cashwithdrawallimits.json +63 -0
  14. saxo_doc_helper/data/json/atr/cashmanagement-interaccounttransfers.json +48 -0
  15. saxo_doc_helper/data/json/atr/cashmanagement-periodicpayment.json +389 -0
  16. saxo_doc_helper/data/json/atr/partner-cashtransfer.json +227 -0
  17. saxo_doc_helper/data/json/atr/partner-cashtransferlimits.json +63 -0
  18. saxo_doc_helper/data/json/atr/partner-prefunding.json +108 -0
  19. saxo_doc_helper/data/json/atr/securitiestransfers.json +1268 -0
  20. saxo_doc_helper/data/json/ca/elections.json +156 -0
  21. saxo_doc_helper/data/json/ca/events.json +1446 -0
  22. saxo_doc_helper/data/json/ca/eventviews.json +876 -0
  23. saxo_doc_helper/data/json/ca/holdings.json +281 -0
  24. saxo_doc_helper/data/json/ca/proxyvoting.json +347 -0
  25. saxo_doc_helper/data/json/ca/standinginstructions.json +401 -0
  26. saxo_doc_helper/data/json/chart/charts.json +1707 -0
  27. saxo_doc_helper/data/json/cm/accounts.json +41 -0
  28. saxo_doc_helper/data/json/cm/clientrenewals.json +3244 -0
  29. saxo_doc_helper/data/json/cm/documents.json +108 -0
  30. saxo_doc_helper/data/json/cm/signups.json +633 -0
  31. saxo_doc_helper/data/json/cm/users.json +45 -0
  32. saxo_doc_helper/data/json/cr/historicalreportdata-accountstatement.json +82 -0
  33. saxo_doc_helper/data/json/cr/historicalreportdata-portfoliomanagement.json +157 -0
  34. saxo_doc_helper/data/json/cr/historicalreportdata-tradedetails.json +82 -0
  35. saxo_doc_helper/data/json/cr/historicalreportdata-tradesexecuted.json +57 -0
  36. saxo_doc_helper/data/json/cs/audit-orderactivities.json +257 -0
  37. saxo_doc_helper/data/json/cs/cashmanagement-interaccounttransfer.json +68 -0
  38. saxo_doc_helper/data/json/cs/cashmanagement-wiretransfers.json +66 -0
  39. saxo_doc_helper/data/json/cs/clientinfo.json +164 -0
  40. saxo_doc_helper/data/json/cs/historicalreportdata-aggregatedamounts.json +149 -0
  41. saxo_doc_helper/data/json/cs/historicalreportdata-bookings.json +257 -0
  42. saxo_doc_helper/data/json/cs/historicalreportdata-closedpositions.json +111 -0
  43. saxo_doc_helper/data/json/cs/historicalreportdata-trades.json +139 -0
  44. saxo_doc_helper/data/json/cs/support-cases.json +565 -0
  45. saxo_doc_helper/data/json/cs/tradingconditions-contractoption.json +122 -0
  46. saxo_doc_helper/data/json/cs/tradingconditions-cost.json +919 -0
  47. saxo_doc_helper/data/json/cs/tradingconditions.json +899 -0
  48. saxo_doc_helper/data/json/dm/disclaimermanagement.json +129 -0
  49. saxo_doc_helper/data/json/ens/clientactivities.json +1512 -0
  50. saxo_doc_helper/data/json/hist/accountvalues.json +57 -0
  51. saxo_doc_helper/data/json/hist/historicalpositions.json +800 -0
  52. saxo_doc_helper/data/json/hist/performance.json +1082 -0
  53. saxo_doc_helper/data/json/hist/transactions.json +367 -0
  54. saxo_doc_helper/data/json/hist/unsettledamounts.json +524 -0
  55. saxo_doc_helper/data/json/mkt/instrumentdocument.json +1512 -0
  56. saxo_doc_helper/data/json/partnerintegration/advisoryaccounts.json +490 -0
  57. saxo_doc_helper/data/json/partnerintegration/externalaccounts.json +785 -0
  58. saxo_doc_helper/data/json/partnerintegration/fundinginstruction.json +266 -0
  59. saxo_doc_helper/data/json/partnerintegration/interactiveesigning.json +235 -0
  60. saxo_doc_helper/data/json/partnerintegration/interactiveidverification.json +185 -0
  61. saxo_doc_helper/data/json/partnerintegration/partnerbulkbookings.json +80 -0
  62. saxo_doc_helper/data/json/partnerintegration/updatepricing.json +716 -0
  63. saxo_doc_helper/data/json/port/accountgroups.json +191 -0
  64. saxo_doc_helper/data/json/port/accounts.json +1106 -0
  65. saxo_doc_helper/data/json/port/balances.json +3457 -0
  66. saxo_doc_helper/data/json/port/clients.json +1418 -0
  67. saxo_doc_helper/data/json/port/closedpositions.json +612 -0
  68. saxo_doc_helper/data/json/port/exposure.json +2987 -0
  69. saxo_doc_helper/data/json/port/netpositions.json +2079 -0
  70. saxo_doc_helper/data/json/port/orders.json +664 -0
  71. saxo_doc_helper/data/json/port/positions.json +852 -0
  72. saxo_doc_helper/data/json/port/users.json +1047 -0
  73. saxo_doc_helper/data/json/ref/algostrategies.json +102 -0
  74. saxo_doc_helper/data/json/ref/countries.json +244 -0
  75. saxo_doc_helper/data/json/ref/cultures.json +74 -0
  76. saxo_doc_helper/data/json/ref/currencies.json +91 -0
  77. saxo_doc_helper/data/json/ref/currencypairs.json +86 -0
  78. saxo_doc_helper/data/json/ref/exchanges.json +76 -0
  79. saxo_doc_helper/data/json/ref/instruments.json +3475 -0
  80. saxo_doc_helper/data/json/ref/languages.json +83 -0
  81. saxo_doc_helper/data/json/ref/standarddates.json +69 -0
  82. saxo_doc_helper/data/json/ref/timezones.json +129 -0
  83. saxo_doc_helper/data/json/reg/financialoverview.json +483 -0
  84. saxo_doc_helper/data/json/reg/investmentprofile.json +843 -0
  85. saxo_doc_helper/data/json/reg/knowledgeandexperience.json +131 -0
  86. saxo_doc_helper/data/json/trade/allocationkeys.json +1044 -0
  87. saxo_doc_helper/data/json/trade/infoprices.json +2811 -0
  88. saxo_doc_helper/data/json/trade/messages.json +362 -0
  89. saxo_doc_helper/data/json/trade/optionschain.json +1179 -0
  90. saxo_doc_helper/data/json/trade/orders.json +10001 -0
  91. saxo_doc_helper/data/json/trade/positions.json +1395 -0
  92. saxo_doc_helper/data/json/trade/prices.json +3053 -0
  93. saxo_doc_helper/data/json/trade/trades.json +936 -0
  94. saxo_doc_helper/data/json/vas/pricealerts.json +1933 -0
  95. saxo_doc_helper/index.py +151 -0
  96. saxo_doc_helper/mcp_server.py +146 -0
  97. saxo_doc_helper/py.typed +0 -0
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-server-saxo-openapi
3
+ Version: 0.1.1
4
+ Summary: MCP server and CLI for Saxo Bank OpenAPI spec lookup (offline; no trading)
5
+ Project-URL: Homepage, https://github.com/nohikomiso/mcp-server-saxo-openapi
6
+ Project-URL: Repository, https://github.com/nohikomiso/mcp-server-saxo-openapi
7
+ Project-URL: Issues, https://github.com/nohikomiso/mcp-server-saxo-openapi/issues
8
+ Author: nohikomiso
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,mcp,model-context-protocol,openapi,saxo,saxo-bank,saxobank,trading
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+
27
+ # mcp-server-saxo-openapi
28
+
29
+ **Saxo Bank OpenAPI spec lookup — CLI tool and MCP server**
30
+
31
+ English | [日本語](https://github.com/nohikomiso/mcp-server-saxo-openapi/blob/main/README.ja.md)
32
+
33
+ ---
34
+
35
+ ![License](https://img.shields.io/badge/license-MIT-green.svg)
36
+ ![Python](https://img.shields.io/badge/python-3.10+-blue.svg)
37
+ ![CLI](https://img.shields.io/badge/CLI-saxo--doc--helper-blue.svg)
38
+ ![MCP](https://img.shields.io/badge/MCP-stdio-orange.svg)
39
+ ![Spec updated](https://img.shields.io/github/last-commit/nohikomiso/mcp-server-saxo-openapi/main?label=spec%20updated)
40
+
41
+ Look up **Saxo Bank** / **Saxobank** OpenAPI endpoint parameters and JSON samples from your terminal, or attach the same tools to Cursor, Claude Desktop, and other MCP clients — without wrestling the deep official reference tree.
42
+
43
+ Zero third-party dependencies (Python stdlib only). Spec database: ~260 endpoints across 17 service groups, shipped inside the wheel.
44
+
45
+ ---
46
+
47
+ ## Spec snapshot
48
+
49
+ **Spec snapshot: 2026-07-08** (Saxo Release Notes through **2025/05/15**).
50
+
51
+ Structured endpoint specs for agents and developers. Saxo does not publish a single docs semver; we record the crawl date and the newest Release Notes heading present at that time. Details: [SPEC_FRESHNESS.md](SPEC_FRESHNESS.md).
52
+
53
+ Missing endpoint, wrong parameter, or something that looks out of date? Please [open an Issue](https://github.com/nohikomiso/mcp-server-saxo-openapi/issues). Pull requests: [CONTRIBUTING.md](CONTRIBUTING.md).
54
+
55
+ ---
56
+
57
+ ## What this is / is not
58
+
59
+ | This package | Not this package |
60
+ |--------------|------------------|
61
+ | Offline **spec lookup** (CLI + MCP) | Live trading / portfolio API calls |
62
+ | No Saxo credentials required | OAuth, order placement, balances |
63
+ | Token-efficient progressive disclosure | A substitute for a full OpenAPI client |
64
+
65
+ For **live** Saxo OpenAPI access from an MCP client, see community servers such as [`@borgels/mcp-server-saxo`](https://www.npmjs.com/package/@borgels/mcp-server-saxo) (npm, unofficial, separate project).
66
+
67
+ **Unofficial** — not affiliated with or endorsed by Saxo Bank A/S.
68
+
69
+ ---
70
+
71
+ ## Features
72
+
73
+ - **Structured spec database** — nested parameters and request/response samples
74
+ - **CLI** — `search-endpoints`, `get-endpoint`, `get-schema` with depth control and "Did you mean?" suggestions
75
+ - **MCP server** — stdio JSON-RPC; same three tools
76
+ - **Token-efficient** — progressive disclosure (collapsed nested schemas, drill down on demand)
77
+
78
+ **Requirements:** Python 3.10+
79
+
80
+ ---
81
+
82
+ ## Getting started — recommended (uvx)
83
+
84
+ ### Production PyPI
85
+
86
+ ```bash
87
+ uvx mcp-server-saxo-openapi
88
+ uvx --from mcp-server-saxo-openapi saxo-doc-helper search-endpoints orders
89
+ uvx --from mcp-server-saxo-openapi saxo-doc-helper --version
90
+ ```
91
+
92
+ `uvx` resolves the **package** name; use `--from mcp-server-saxo-openapi` to run the `saxo-doc-helper` console script.
93
+
94
+ MCP client config:
95
+
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "saxo-openapi": {
100
+ "command": "uvx",
101
+ "args": ["mcp-server-saxo-openapi"]
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### From GitHub
108
+
109
+ ```bash
110
+ uvx --from git+https://github.com/nohikomiso/mcp-server-saxo-openapi.git saxo-doc-helper search-endpoints orders
111
+ uvx --from git+https://github.com/nohikomiso/mcp-server-saxo-openapi.git mcp-server-saxo-openapi
112
+ ```
113
+
114
+ ### TestPyPI (development only)
115
+
116
+ ```bash
117
+ uvx --index-url https://test.pypi.org/simple/ \
118
+ --index https://pypi.org/simple/ \
119
+ --from mcp-server-saxo-openapi \
120
+ saxo-doc-helper search-endpoints orders
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Getting started — local clone
126
+
127
+ ```bash
128
+ git clone https://github.com/nohikomiso/mcp-server-saxo-openapi.git
129
+ cd mcp-server-saxo-openapi
130
+ python tools/saxo_doc_helper.py search-endpoints orders
131
+ python tools/saxo_doc_helper.py get-endpoint POST /trade/v2/orders
132
+ python tools/saxo_doc_helper.py get-schema algorithmicorderdata
133
+ ```
134
+
135
+ Or install editable:
136
+
137
+ ```bash
138
+ uv sync
139
+ uv run saxo-doc-helper --version
140
+ uv run saxo-doc-helper search-endpoints orders
141
+ ```
142
+
143
+ ### Input normalization
144
+
145
+ | Input | Normalized |
146
+ |-------|------------|
147
+ | `post` | `POST` |
148
+ | `trade/v2/orders` | `/trade/v2/orders` |
149
+ | `https://gateway.saxobank.com/sim/openapi/trade/v2/orders` | `/trade/v2/orders` |
150
+
151
+ If no exact match is found, **Did you mean?** suggestions are returned.
152
+
153
+ ---
154
+
155
+ ## MCP tools exposed
156
+
157
+ | Tool | Description |
158
+ |------|-------------|
159
+ | `search_saxo_endpoints(query)` | Keyword search across all endpoints |
160
+ | `get_saxo_endpoint_spec(method, path, depth?)` | Parameters + request/response samples |
161
+ | `get_saxo_schema_spec(schema_name, depth?)` | Nested schema drill-down |
162
+
163
+ ---
164
+
165
+ ## Agent integration
166
+
167
+ > When researching Saxo OpenAPI specs, do **not** read `spec/json/` files directly.
168
+ > Use `saxo-doc-helper` (or `python tools/saxo_doc_helper.py` from a clone).
169
+
170
+ ---
171
+
172
+ ## Repository layout
173
+
174
+ ```text
175
+ mcp-server-saxo-openapi/
176
+ ├── pyproject.toml
177
+ ├── SPEC_FRESHNESS.md
178
+ ├── LICENSE
179
+ ├── README.md / README.ja.md
180
+ ├── CONTRIBUTING.md
181
+ ├── docs/
182
+ │ └── MAINTAINER.md
183
+ ├── src/saxo_doc_helper/ # installable package (+ data/json)
184
+ ├── spec/json/ # maintainer source of truth
185
+ ├── tests/
186
+ └── tools/
187
+ └── saxo_doc_helper.py # thin clone-compatible wrapper
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Related projects
193
+
194
+ | Project | Role |
195
+ |---------|------|
196
+ | [saxo-apy](https://github.com/nohikomiso/saxo-apy) | OAuth and session management |
197
+ | [saxo-openapi](https://github.com/nohikomiso/saxo-openapi) | Python REST/WebSocket client (AI-ready) |
198
+ | [@borgels/mcp-server-saxo](https://www.npmjs.com/package/@borgels/mcp-server-saxo) | Live Saxo OpenAPI MCP (npm; unofficial) |
199
+
200
+ This repository provides **spec lookup**. Runtime API access is a separate concern.
201
+
202
+ ---
203
+
204
+ ## Feedback and maintainers
205
+
206
+ - Bugs / stale specs: [GitHub Issues](https://github.com/nohikomiso/mcp-server-saxo-openapi/issues)
207
+ - Maintainers: [docs/MAINTAINER.md](docs/MAINTAINER.md)
208
+ - Source crawl: public Saxo Developer Portal reference docs
209
+
210
+ ---
211
+
212
+ ## License
213
+
214
+ [MIT License](LICENSE)
@@ -0,0 +1,97 @@
1
+ saxo_doc_helper/__init__.py,sha256=jgAACGnHmifW1pM2gySGgI3lqy2TiLlkRus75fFcfXY,698
2
+ saxo_doc_helper/__main__.py,sha256=LtnpzKxHY-8E9Uh-yHKZnEtAZC6PJB7OxH5MD0ZUE4U,120
3
+ saxo_doc_helper/cli.py,sha256=bhF8iNx1EsG0lNKRSAaInmEild5JEAv6GwVYNvQk6fY,2924
4
+ saxo_doc_helper/commands.py,sha256=CK4OifhnsGmxXlI6uOxiyYqBh7XKoOJ-VpzKF1yLIl8,4173
5
+ saxo_doc_helper/index.py,sha256=c1W1zNlRb57fBsrkCYOIQSfUnz8pMQjV7lBQDjUhls0,5218
6
+ saxo_doc_helper/mcp_server.py,sha256=nWD2PVr-GjWesSb24xpKwRmpKhOmYkbcjnPtUNT5JFk,5070
7
+ saxo_doc_helper/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ saxo_doc_helper/data/__init__.py,sha256=akk-TI8vMzEAQ91pbrj5o9ZCQIHAPy4-k6G7vBvORD0,58
9
+ saxo_doc_helper/data/json/atr/cashmanagement-beneficiaryinstructions.json,sha256=NIsKFEEDKQIFumFuUJM6m9WCQnCpDfWfOCrpuTG9PN4,2680
10
+ saxo_doc_helper/data/json/atr/cashmanagement-cashwithdrawal.json,sha256=cUVSyLzFCZpu0hwIQHtgvsVwk04hpb4WCjKpnwGLa3w,2675
11
+ saxo_doc_helper/data/json/atr/cashmanagement-cashwithdrawallimits.json,sha256=2ZOqXFW3x1Y9y-NItacdsSozah5wKZf6sUeJxCX0KzA,1947
12
+ saxo_doc_helper/data/json/atr/cashmanagement-interaccounttransfers.json,sha256=xYypjh-7l7gXTG1o8pOpDu73gXDg0Oiec1SQxN36yt0,1611
13
+ saxo_doc_helper/data/json/atr/cashmanagement-periodicpayment.json,sha256=D5l2q1XWRYpoa96i4pLvmbdVegXoR3BZCv_budO5R8Y,12634
14
+ saxo_doc_helper/data/json/atr/partner-cashtransfer.json,sha256=h4lf0qRgEPhSs45WJdTd_Yz6SzfvqqJvdzqMl7Uut7Q,8843
15
+ saxo_doc_helper/data/json/atr/partner-cashtransferlimits.json,sha256=bLi-ZFnDmmRwx_HWeC0vxtguZXTMxjFgu-LWUXeU3QA,1879
16
+ saxo_doc_helper/data/json/atr/partner-prefunding.json,sha256=NEO3zx9G0nJyqAs20TJT01MG8Z9cJUtWS4bj54nUwd0,3117
17
+ saxo_doc_helper/data/json/atr/securitiestransfers.json,sha256=5lQmKGFwqKcWhYzCy3VxWBtLyAVu6NAIKX-8X0l7SR4,40835
18
+ saxo_doc_helper/data/json/ca/elections.json,sha256=qPR7LWpZF2K8OKJaZZpOfqKFyDCfmMEG_856BstquHc,4540
19
+ saxo_doc_helper/data/json/ca/events.json,sha256=Uc_FB7hEkAna0DslwB27DF7MNjD31lP9vGd1JbeZ2qs,56805
20
+ saxo_doc_helper/data/json/ca/eventviews.json,sha256=hJYXhfgpQaZmbHCSf-L6hHMEs2bGyiEZkV_G3B6DI9Y,34603
21
+ saxo_doc_helper/data/json/ca/holdings.json,sha256=cAjKpTgMLgSSJV-mPqFg27pMQ7lgZ1jTsxSxSuQIQtE,8556
22
+ saxo_doc_helper/data/json/ca/proxyvoting.json,sha256=zeXhuUAcLInxAg4tsaUvJKJnLE5MaaAJ7ySMZc7MSFE,10462
23
+ saxo_doc_helper/data/json/ca/standinginstructions.json,sha256=4qnTUC6HbUw1LpI_95X7Xcj9EtGZ7iSnyso5CuMa7I4,14460
24
+ saxo_doc_helper/data/json/chart/charts.json,sha256=EZVWb0lqk9ujoQVzHbPeX1sy80nIqI52NxbmU7Wm1O4,69680
25
+ saxo_doc_helper/data/json/cm/accounts.json,sha256=mUWHRjYC2OtmHBeZXaupLiv786R2JsBBUftujQdlBL8,1160
26
+ saxo_doc_helper/data/json/cm/clientrenewals.json,sha256=wkLw2dF-9QVyssRaSDyaE_SvkRoVm95x5hUQcVE8bEc,121956
27
+ saxo_doc_helper/data/json/cm/documents.json,sha256=oBfdkX4N3kDMjmcT6HGwPn12Z3jOQBQQpd9_Q1LZTL0,3704
28
+ saxo_doc_helper/data/json/cm/signups.json,sha256=4ARUo3I_hPr7ORYFdtj_ANDjDJmwPtwVJ6R8gn90wBg,21788
29
+ saxo_doc_helper/data/json/cm/users.json,sha256=Fg7XmGmdGbA3LZ3dLGW_k8gZwxum3EYDkQjJVVq59yA,1299
30
+ saxo_doc_helper/data/json/cr/historicalreportdata-accountstatement.json,sha256=fbwNQ-YcB4rlz7HcgV7XB2XRErpSACDk5EaBHEle6Ic,2803
31
+ saxo_doc_helper/data/json/cr/historicalreportdata-portfoliomanagement.json,sha256=NaC9SL1cfxISxt0ObbSQra_5BO9xbTxSpWOvbzTidws,4873
32
+ saxo_doc_helper/data/json/cr/historicalreportdata-tradedetails.json,sha256=to-FjuSXM1Cm2F8-fnkqZ0q3tId7F4yqeTx3yUGiCSw,2567
33
+ saxo_doc_helper/data/json/cr/historicalreportdata-tradesexecuted.json,sha256=H0rs31KnM4PrUL4m-fnv1f70X-SE5EJyvb9z43xqFv4,2133
34
+ saxo_doc_helper/data/json/cs/audit-orderactivities.json,sha256=CScmK654B60lIT_fjkoY5v0TE1cC3dfyq-EwxeLfFEo,9002
35
+ saxo_doc_helper/data/json/cs/cashmanagement-interaccounttransfer.json,sha256=erGyWtA2foECdB3G6CkGxnKKi2lpAFdqmfoIz2cZri4,1942
36
+ saxo_doc_helper/data/json/cs/cashmanagement-wiretransfers.json,sha256=Ac8FSOBBBsvcd350cw0pCqeM_1aLkTaBVjtKA0nZqu0,2127
37
+ saxo_doc_helper/data/json/cs/clientinfo.json,sha256=_tcDCnvAa59EW7mABs00jUNeVDxn_vg_znKZGYzaAxU,5256
38
+ saxo_doc_helper/data/json/cs/historicalreportdata-aggregatedamounts.json,sha256=P86S3VlFTe5tmNW2mYfkeJNoVUVT-4jekXAGhsybCl8,5168
39
+ saxo_doc_helper/data/json/cs/historicalreportdata-bookings.json,sha256=kRPk9jMhLq-nIUYRKAt_kaHepc3qcmiKqoB2QLjj51Y,9387
40
+ saxo_doc_helper/data/json/cs/historicalreportdata-closedpositions.json,sha256=gtgsXRc6sjwYuoEkETCkSRFOS_TmyGEzHHTM7W2zMvA,3977
41
+ saxo_doc_helper/data/json/cs/historicalreportdata-trades.json,sha256=v6jdWuJ_KajVEc9HpTOBtJiJEqytNGjH-vcqcGlACZ8,4653
42
+ saxo_doc_helper/data/json/cs/support-cases.json,sha256=wX46VGtV38lU_jF7agnIJ1TTjiJXz3aLJ-XupoStkG4,17378
43
+ saxo_doc_helper/data/json/cs/tradingconditions-contractoption.json,sha256=HSt_0z3WMMPMXyelLYYCHfd92D2ab7izItyndk8l2rg,3904
44
+ saxo_doc_helper/data/json/cs/tradingconditions-cost.json,sha256=G_ZSHduuCgBwn-hGitIG7Q69ZPx7JVFAh6SAmVTCVow,34163
45
+ saxo_doc_helper/data/json/cs/tradingconditions.json,sha256=0eie6MnB50TK_cu43QpURIcuaBTCWJ-PEXMuURYw71g,33629
46
+ saxo_doc_helper/data/json/dm/disclaimermanagement.json,sha256=Zbz09kxb39DnCcj0K_001t9x5-UzDAaDt55iJgdPdiY,4087
47
+ saxo_doc_helper/data/json/ens/clientactivities.json,sha256=bUA9yYCIiyz3t1VIsU7VubB8dOU3TvhtLeoQBRBiotA,56968
48
+ saxo_doc_helper/data/json/hist/accountvalues.json,sha256=KV-eK4eF6HDtMiO9Ta36gMZjN3YhvZkui8rwcROdpBM,1673
49
+ saxo_doc_helper/data/json/hist/historicalpositions.json,sha256=RX69wVgPkZY6YaqfIsiw3yGJmz5om65tAQy7jDXpCDU,31230
50
+ saxo_doc_helper/data/json/hist/performance.json,sha256=JPDeWjAOc5i7cMNOC01Un2VzjawMGnlj2kMIwLALLUM,32486
51
+ saxo_doc_helper/data/json/hist/transactions.json,sha256=fEue4etjGleRqC1Fb59e6Da1uhIhrMySq_XuhRZfmvM,12508
52
+ saxo_doc_helper/data/json/hist/unsettledamounts.json,sha256=8Sgano8cIhYkzFNWr1XGIXUBLi6zfByLUdZw0aKJBKc,16232
53
+ saxo_doc_helper/data/json/mkt/instrumentdocument.json,sha256=JKARdIGgTrAhHfQK6OUrwp_KpM0VPNNB2wif6WXesF0,58337
54
+ saxo_doc_helper/data/json/partnerintegration/advisoryaccounts.json,sha256=R3LbafiZqgQR_geh7YwjuYU6ndp8rR74AJdkoI1aA8s,14990
55
+ saxo_doc_helper/data/json/partnerintegration/externalaccounts.json,sha256=WSQzmDPoMjmTZUPyahPLAcKxmxjbLduu3e9Mp7TqQ6I,24166
56
+ saxo_doc_helper/data/json/partnerintegration/fundinginstruction.json,sha256=ZcJDIdyuHBp59cyLu7TWvGUWY9cYz4UWkNTJP6KYZ10,9454
57
+ saxo_doc_helper/data/json/partnerintegration/interactiveesigning.json,sha256=YzHJMwmExEHRCP_Um5JOQ61cUGE6AJA3e67KYPJziZ8,8043
58
+ saxo_doc_helper/data/json/partnerintegration/interactiveidverification.json,sha256=wrRnlZmFSUfJKzVM0lGovhQGFs-ieQqgFg5ABix2fQ8,7839
59
+ saxo_doc_helper/data/json/partnerintegration/partnerbulkbookings.json,sha256=MWxSxj20ioYMrEVjRT5p0Sti1z1nOk7F1_Mb0u6xJLw,2638
60
+ saxo_doc_helper/data/json/partnerintegration/updatepricing.json,sha256=GKxg9YlgaJ5kUjK6fXpGr8Z7Q6Cz23quFa0EgQiEHXg,30372
61
+ saxo_doc_helper/data/json/port/accountgroups.json,sha256=q6bdllOVQhbhhzfeAmPx8z-lBwWnqW1DLp6uXWfcJPY,6833
62
+ saxo_doc_helper/data/json/port/accounts.json,sha256=kQz5QzX4jHLPUCXd1aDZwyr1y1ZDQOCq14q6HZh1Dew,44562
63
+ saxo_doc_helper/data/json/port/balances.json,sha256=6pubwQ02nyfGDrAJQH3EVqHv2kysJFxRON7SlZ1MDq4,151500
64
+ saxo_doc_helper/data/json/port/clients.json,sha256=pjd67drLipy9VB_UOBG46oRead6T6HBoq7fP9X0LuOE,53783
65
+ saxo_doc_helper/data/json/port/closedpositions.json,sha256=rt5DnLNnVny07WzdvMNesd7YdYekMRVl9ypAx9RuJW8,23193
66
+ saxo_doc_helper/data/json/port/exposure.json,sha256=JjdhsEtgUpVu1IcmHKPZ_xVJj1LyedK1g2rdO0NCzm8,121480
67
+ saxo_doc_helper/data/json/port/netpositions.json,sha256=3v0Kwl0k5krVqMXCNl6m9p-cjUXgvdWtx-iXqTmuIY4,82634
68
+ saxo_doc_helper/data/json/port/orders.json,sha256=mZ14pqh3w8aDH-kwMY9ftLRROnbNmzPQfhZ0zfpAgK0,24706
69
+ saxo_doc_helper/data/json/port/positions.json,sha256=-7SOXFNQzpz31Yyg9arjUtOg3enoab4Wk0ZDHSnH5AQ,30559
70
+ saxo_doc_helper/data/json/port/users.json,sha256=lcvCfJqIJHuflnnZbk0tHSIjhaOxQOZtIiGGWfgSsik,38556
71
+ saxo_doc_helper/data/json/ref/algostrategies.json,sha256=ZhRH9V8dpj6r7QHFGSwvVFT4CsHIXWZb9pYMppA21n0,2898
72
+ saxo_doc_helper/data/json/ref/countries.json,sha256=-N54qPyW1GBljwPX64r5qX4M_XvAzcl_BDtsGwG6pa0,6382
73
+ saxo_doc_helper/data/json/ref/cultures.json,sha256=AiU1CzKB63CnbFcQf0_bH7SVUfeM5EakatJ6ZYu8CY0,2207
74
+ saxo_doc_helper/data/json/ref/currencies.json,sha256=oLUlQnBiIKPI7FwgPjpSR6zl80FHtxXnS4ZO8_zmrs8,2665
75
+ saxo_doc_helper/data/json/ref/currencypairs.json,sha256=wm4--ZMgfxAlh5L3f1ywvao_PashMoNyjdJbjSd5L1w,2101
76
+ saxo_doc_helper/data/json/ref/exchanges.json,sha256=nf_Une7xoIlvI9mXU6gBeSXhkl08O5wkByOsoAkamZo,2204
77
+ saxo_doc_helper/data/json/ref/instruments.json,sha256=RqhecpyEf4h7Oo4z-V0Efav9CACvYu6z403xEsdMyBw,132970
78
+ saxo_doc_helper/data/json/ref/languages.json,sha256=wEGssgj6JyMgp6VaqFNJOar4r0GRbowXJ6MTRnzNzqw,2619
79
+ saxo_doc_helper/data/json/ref/standarddates.json,sha256=RRtNG7l_iblldgS2HES3FXZHLWaYgks-h9dMlY6VRnw,2011
80
+ saxo_doc_helper/data/json/ref/timezones.json,sha256=8YMukXNSGzFp3WY7ahHhjHtYQGvvhBe3b9vLPgscJNU,3969
81
+ saxo_doc_helper/data/json/reg/financialoverview.json,sha256=IP6YBAdnjOqpyQW8Q23ZDaPSPrNI6c6fDAXeXPx7faI,15645
82
+ saxo_doc_helper/data/json/reg/investmentprofile.json,sha256=TpUnpOAIpuhYdDOma85Op5bAtkzsW9cLtCE7gXpK8hk,32023
83
+ saxo_doc_helper/data/json/reg/knowledgeandexperience.json,sha256=aHqTGu-HHdGDPSH47jrRKn-sb-OBGcIFRGwxPSxIHRM,4390
84
+ saxo_doc_helper/data/json/trade/allocationkeys.json,sha256=Em_eZ-_o5DhtOJwwF1ZGzAAwvzx8SJnvS_qMnH2mApI,40244
85
+ saxo_doc_helper/data/json/trade/infoprices.json,sha256=KaJLwwGoK_JEHv_iL-zx48ftSTmRW5eXso0t29E3huo,109859
86
+ saxo_doc_helper/data/json/trade/messages.json,sha256=njZ0gP0Kg4hIun6Nbq0gAuQwzZ0IgRPtw5-qk6ciDvg,13341
87
+ saxo_doc_helper/data/json/trade/optionschain.json,sha256=T-yrA7q2txgrw7VHoBRkZ3XSqn7GckKBKJFwZU1Ioxw,47487
88
+ saxo_doc_helper/data/json/trade/orders.json,sha256=eiBgEbbt5H9dhEr4mBl9PawOTxqdNtlfDxTjveXKOLU,396941
89
+ saxo_doc_helper/data/json/trade/positions.json,sha256=2JGdfwp6HnMmIa51jyJ25tHlFgKSihfoqml_-PY4nJE,54533
90
+ saxo_doc_helper/data/json/trade/prices.json,sha256=jO3Pk1VTJipJWTeTSBKAQmqe76xPfnQmHugneS1Rs4o,127465
91
+ saxo_doc_helper/data/json/trade/trades.json,sha256=JX2Ie20bE0owWuid75buoyqbit7Sxya--Tz9rdr8cYY,36142
92
+ saxo_doc_helper/data/json/vas/pricealerts.json,sha256=VDuknIGAUJa8A-PWCeIx1VA2uB7vHRTE99oAMyJ__Yg,73789
93
+ mcp_server_saxo_openapi-0.1.1.dist-info/METADATA,sha256=4Fe-f6clAQlD8c6oZ8m8X11dME1V3S6ULVsFpk6ZN9E,7104
94
+ mcp_server_saxo_openapi-0.1.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
95
+ mcp_server_saxo_openapi-0.1.1.dist-info/entry_points.txt,sha256=YSgs4xx7gQ1lBTH3cd6rg5OAsrlOIpIB5-ek-mtFM_w,116
96
+ mcp_server_saxo_openapi-0.1.1.dist-info/licenses/LICENSE,sha256=_HRu5kqPvkdh0yNADHdfHiBRiCyUAwHOm8Fk8VJYxy4,1067
97
+ mcp_server_saxo_openapi-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ mcp-server-saxo-openapi = saxo_doc_helper.cli:mcp_main
3
+ saxo-doc-helper = saxo_doc_helper.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nohikomiso
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,32 @@
1
+ """Saxo OpenAPI spec lookup — CLI and MCP server."""
2
+
3
+ __version__ = "0.1.1"
4
+ SPEC_SNAPSHOT_DATE = "2026-07-08"
5
+ SAXO_RELEASE_NOTES_THROUGH = "2025/05/15"
6
+
7
+ from saxo_doc_helper.index import (
8
+ SaxoDocIndex,
9
+ normalize_method,
10
+ normalize_path,
11
+ normalize_schema_name,
12
+ resolve_spec_dir,
13
+ )
14
+ from saxo_doc_helper.commands import (
15
+ cmd_get_endpoint,
16
+ cmd_get_schema,
17
+ cmd_search_endpoints,
18
+ )
19
+
20
+ __all__ = [
21
+ "SAXO_RELEASE_NOTES_THROUGH",
22
+ "SPEC_SNAPSHOT_DATE",
23
+ "SaxoDocIndex",
24
+ "__version__",
25
+ "cmd_get_endpoint",
26
+ "cmd_get_schema",
27
+ "cmd_search_endpoints",
28
+ "normalize_method",
29
+ "normalize_path",
30
+ "normalize_schema_name",
31
+ "resolve_spec_dir",
32
+ ]
@@ -0,0 +1,6 @@
1
+ """Allow ``python -m saxo_doc_helper``."""
2
+
3
+ from saxo_doc_helper.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
saxo_doc_helper/cli.py ADDED
@@ -0,0 +1,95 @@
1
+ """CLI and MCP entry points."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+
8
+ from saxo_doc_helper import (
9
+ SAXO_RELEASE_NOTES_THROUGH,
10
+ SPEC_SNAPSHOT_DATE,
11
+ __version__,
12
+ )
13
+ from saxo_doc_helper.commands import cmd_get_endpoint, cmd_get_schema, cmd_search_endpoints
14
+ from saxo_doc_helper.index import SaxoDocIndex, resolve_spec_dir
15
+ from saxo_doc_helper.mcp_server import run_mcp_server
16
+
17
+
18
+ def version_string() -> str:
19
+ return (
20
+ f"mcp-server-saxo-openapi {__version__} "
21
+ f"(spec snapshot {SPEC_SNAPSHOT_DATE}; "
22
+ f"saxo RN through {SAXO_RELEASE_NOTES_THROUGH})"
23
+ )
24
+
25
+
26
+ def mcp_main() -> None:
27
+ """Entry point for ``mcp-server-saxo-openapi`` (stdio MCP only)."""
28
+ index = SaxoDocIndex(resolve_spec_dir())
29
+ run_mcp_server(index)
30
+
31
+
32
+ def main(argv: list[str] | None = None) -> None:
33
+ """Entry point for ``saxo-doc-helper`` and ``python -m saxo_doc_helper``."""
34
+ parser = argparse.ArgumentParser(
35
+ description="Saxo OpenAPI spec lookup — CLI & MCP helper",
36
+ formatter_class=argparse.RawDescriptionHelpFormatter,
37
+ epilog="""
38
+ Examples:
39
+ saxo-doc-helper search-endpoints orders
40
+ saxo-doc-helper get-endpoint POST /trade/v2/orders
41
+ saxo-doc-helper get-endpoint post trade/v2/orders --depth 1
42
+ saxo-doc-helper get-schema algorithmicorderdata
43
+ saxo-doc-helper --mcp
44
+ mcp-server-saxo-openapi
45
+ """,
46
+ )
47
+ parser.add_argument(
48
+ "--version",
49
+ action="version",
50
+ version=version_string(),
51
+ )
52
+ parser.add_argument("--mcp", action="store_true", help="Run as MCP stdio server")
53
+ parser.add_argument(
54
+ "command",
55
+ nargs="?",
56
+ choices=["search-endpoints", "get-endpoint", "get-schema"],
57
+ help="CLI command to run",
58
+ )
59
+ parser.add_argument("args", nargs=argparse.REMAINDER, help="Command arguments")
60
+
61
+ parsed = parser.parse_args(argv)
62
+ index = SaxoDocIndex(resolve_spec_dir())
63
+
64
+ if parsed.mcp:
65
+ run_mcp_server(index)
66
+ return
67
+
68
+ if not parsed.command:
69
+ parser.print_help()
70
+ sys.exit(1)
71
+
72
+ if parsed.command == "search-endpoints":
73
+ if not parsed.args:
74
+ print("Usage: search-endpoints <query>")
75
+ sys.exit(1)
76
+ print(cmd_search_endpoints(index, " ".join(parsed.args)))
77
+
78
+ elif parsed.command == "get-endpoint":
79
+ sub = argparse.ArgumentParser()
80
+ sub.add_argument("method")
81
+ sub.add_argument("path")
82
+ sub.add_argument("--depth", type=int, default=0)
83
+ a = sub.parse_args(parsed.args)
84
+ print(cmd_get_endpoint(index, a.method, a.path, a.depth))
85
+
86
+ elif parsed.command == "get-schema":
87
+ sub = argparse.ArgumentParser()
88
+ sub.add_argument("schema_name")
89
+ sub.add_argument("--depth", type=int, default=0)
90
+ a = sub.parse_args(parsed.args)
91
+ print(cmd_get_schema(index, a.schema_name, a.depth))
92
+
93
+
94
+ if __name__ == "__main__":
95
+ main()
@@ -0,0 +1,119 @@
1
+ """CLI command implementations for Saxo OpenAPI spec lookup."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+
7
+ from saxo_doc_helper.index import SaxoDocIndex, normalize_method, normalize_path, normalize_schema_name
8
+
9
+
10
+ def _format_params(params: list, depth: int = 0, max_depth: int = 0) -> list[str]:
11
+ lines = []
12
+ for p in params:
13
+ indent = " " * depth
14
+ origin = f" ({p['origin']})" if p.get("origin") else ""
15
+ line = f"{indent}- **{p['name']}** (`{p['type']}`){origin}: {p.get('description', '')}"
16
+ lines.append(line)
17
+
18
+ children = p.get("children", [])
19
+ if children:
20
+ link = p.get("link") or ""
21
+ schema_key = (
22
+ normalize_schema_name(link.split("/schema-")[-1]) if "/schema-" in link else ""
23
+ )
24
+ if depth < max_depth:
25
+ lines.extend(_format_params(children, depth + 1, max_depth))
26
+ else:
27
+ hint = f" [Refer to Schema: {schema_key}]" if schema_key else ""
28
+ lines.append(f"{indent} * (Nested parameters collapsed.{hint})")
29
+ return lines
30
+
31
+
32
+ def _render_json_sample(sample, label: str) -> str:
33
+ if sample is None:
34
+ return ""
35
+ if isinstance(sample, (dict, list)):
36
+ body = json.dumps(sample, indent=2, ensure_ascii=False)
37
+ else:
38
+ body = str(sample)
39
+ return f"\n{label}:\n{body}"
40
+
41
+
42
+ def cmd_search_endpoints(index: SaxoDocIndex, query: str) -> str:
43
+ q = query.lower()
44
+ results = [
45
+ ep
46
+ for ep in index.endpoints
47
+ if q in ep["path"].lower()
48
+ or q in ep["name"].lower()
49
+ or q in ep["service"].lower()
50
+ or q in ep["category"].lower()
51
+ ]
52
+ if not results:
53
+ return f"No endpoints found matching '{query}'."
54
+ lines = [f"Found {len(results)} endpoint(s) matching '{query}':\n"]
55
+ for ep in results:
56
+ lines.append(
57
+ f" [{ep['service']}/{ep['category']}] {ep['method']} {ep['path']} -> {ep['name']}"
58
+ )
59
+ return "\n".join(lines)
60
+
61
+
62
+ def cmd_get_endpoint(index: SaxoDocIndex, method: str, path: str, depth: int = 0) -> str:
63
+ method = normalize_method(method)
64
+ path = normalize_path(path)
65
+
66
+ match = next(
67
+ (ep for ep in index.endpoints if ep["method"] == method and ep["path"] == path),
68
+ None,
69
+ )
70
+
71
+ if match is None:
72
+ candidates = [
73
+ ep for ep in index.endpoints if (path.rstrip("s") in ep["path"] or path in ep["path"])
74
+ ]
75
+ lines = [f'Error: Endpoint "{method} {path}" not found.']
76
+ if candidates:
77
+ lines.append("\nDid you mean one of these?")
78
+ for c in candidates[:5]:
79
+ lines.append(f" - {c['method']} {c['path']} ({c['name']})")
80
+ return "\n".join(lines)
81
+
82
+ param_lines = _format_params(match["parameters"], max_depth=depth)
83
+ out = [
84
+ f"Name: {match['name']}",
85
+ f"Path: {match['method']} {match['path']}",
86
+ f"URL: {match['url']}",
87
+ "",
88
+ "Parameters:",
89
+ ]
90
+ out.extend(param_lines if param_lines else [" (no parameters)"])
91
+ out.append(_render_json_sample(match["request_sample"], "Request Sample"))
92
+ out.append(_render_json_sample(match["response_sample"], "Response Sample"))
93
+ return "\n".join(out).strip()
94
+
95
+
96
+ def cmd_get_schema(index: SaxoDocIndex, schema_name: str, depth: int = 0) -> str:
97
+ key = normalize_schema_name(schema_name)
98
+ schema = index.schemas.get(key)
99
+ if schema is None:
100
+ candidates = [k for k in index.schemas if key in k or k in key]
101
+ if candidates:
102
+ schema = index.schemas[candidates[0]]
103
+ key = candidates[0]
104
+ else:
105
+ available = sorted(index.schemas.keys())[:10]
106
+ return (
107
+ f'Error: Schema "{schema_name}" not found.\n'
108
+ f"Available schemas (first 10): {available}"
109
+ )
110
+
111
+ param_lines = _format_params(schema["parameters"], max_depth=depth)
112
+ out = [
113
+ f"Schema: {schema['type_name']} (key: {key})",
114
+ f"Description: {schema['description']}",
115
+ "",
116
+ "Parameters:",
117
+ ]
118
+ out.extend(param_lines if param_lines else [" (no parameters)"])
119
+ return "\n".join(out)
@@ -0,0 +1 @@
1
+ # Package data marker (JSON files live under data/json/).