mcp-server-fxmacrodata 0.1.0__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.
@@ -0,0 +1,5 @@
1
+ """MCP server for the FXMacroData API."""
2
+
3
+ from .server import main
4
+
5
+ __all__ = ["main"]
@@ -0,0 +1,264 @@
1
+ """FXMacroData MCP Server — stdio transport for AI agent clients.
2
+
3
+ Exposes the full FXMacroData API surface as typed MCP tools that any
4
+ MCP-compatible client (Claude Desktop, Cursor, Windsurf, OpenClaw, etc.)
5
+ can discover and invoke.
6
+
7
+ Usage:
8
+ uvx mcp-server-fxmacrodata # USD data (free)
9
+ FXMACRODATA_API_KEY=key uvx mcp-server-fxmacrodata # all currencies
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import os
16
+ import sys
17
+ from typing import Optional
18
+
19
+ import httpx
20
+ from mcp.server.fastmcp import FastMCP
21
+
22
+ from fxmacrodata import Client, FXMacroDataError
23
+
24
+ # ---------------------------------------------------------------------------
25
+ # Configuration
26
+ # ---------------------------------------------------------------------------
27
+
28
+ API_KEY = os.environ.get("FXMACRODATA_API_KEY", "")
29
+ BASE_URL = os.environ.get("FXMACRODATA_BASE_URL", "https://fxmacrodata.com/api")
30
+
31
+ _client = Client(api_key=API_KEY or None)
32
+
33
+ # Override base URL if the user changed it (e.g., for dev server).
34
+ if BASE_URL != "https://fxmacrodata.com/api":
35
+ _client.BASE_URL = BASE_URL
36
+
37
+ # ---------------------------------------------------------------------------
38
+ # MCP server
39
+ # ---------------------------------------------------------------------------
40
+
41
+ mcp = FastMCP(
42
+ name="FXMacroData",
43
+ instructions=(
44
+ "FXMacroData provides macroeconomic indicator data, release calendars, "
45
+ "COT positioning, commodities, forex rates, and FX market session info. "
46
+ "USD data is free. Non-USD data requires an API key."
47
+ ),
48
+ )
49
+
50
+
51
+ # ---------------------------------------------------------------------------
52
+ # Helpers
53
+ # ---------------------------------------------------------------------------
54
+
55
+ def _api_url(path: str) -> str:
56
+ """Build a full API URL from a relative path."""
57
+ return f"{BASE_URL}{path}"
58
+
59
+
60
+ def _auth_headers() -> dict[str, str]:
61
+ """Return auth headers if an API key is configured."""
62
+ if API_KEY:
63
+ return {"X-API-Key": API_KEY}
64
+ return {}
65
+
66
+
67
+ def _handle_error(tool_name: str, exc: Exception) -> str:
68
+ """Format a tool error as a user-friendly JSON string."""
69
+ msg = str(exc)
70
+ if "API key required" in msg or "401" in msg:
71
+ return json.dumps({
72
+ "error": f"{tool_name} requires an API key for this request.",
73
+ "help": "Set the FXMACRODATA_API_KEY environment variable. "
74
+ "Get your key at https://fxmacrodata.com/api-management",
75
+ })
76
+ return json.dumps({"error": msg})
77
+
78
+
79
+ # ---------------------------------------------------------------------------
80
+ # Tools
81
+ # ---------------------------------------------------------------------------
82
+
83
+ @mcp.tool(
84
+ name="ping",
85
+ description="Verify that the FXMacroData API is reachable.",
86
+ )
87
+ def ping() -> str:
88
+ """Health check."""
89
+ resp = httpx.get(_api_url("/v1/ping"), headers=_auth_headers(), timeout=10)
90
+ resp.raise_for_status()
91
+ return json.dumps(resp.json())
92
+
93
+
94
+ @mcp.tool(
95
+ name="data_catalogue",
96
+ description=(
97
+ "List available macroeconomic indicators for a currency. "
98
+ "Supported currencies include: AUD, BRL, CAD, CHF, CNY, DKK, EUR, "
99
+ "GBP, JPY, NZD, PLN, SEK, SGD, USD."
100
+ ),
101
+ )
102
+ def data_catalogue(currency: str) -> str:
103
+ """Return the indicator catalogue for a currency."""
104
+ try:
105
+ result = _client.get_data_catalogue(currency)
106
+ return json.dumps(result)
107
+ except FXMacroDataError as exc:
108
+ return _handle_error("data_catalogue", exc)
109
+
110
+
111
+ @mcp.tool(
112
+ name="release_calendar",
113
+ description=(
114
+ "Get upcoming macroeconomic release dates for a currency, with optional "
115
+ "indicator filter."
116
+ ),
117
+ )
118
+ def release_calendar(currency: str, indicator: Optional[str] = None) -> str:
119
+ """Return the release calendar for a currency."""
120
+ try:
121
+ result = _client.get_calendar(currency, indicator=indicator)
122
+ return json.dumps(result)
123
+ except FXMacroDataError as exc:
124
+ return _handle_error("release_calendar", exc)
125
+
126
+
127
+ @mcp.tool(
128
+ name="forex",
129
+ description=(
130
+ "Get FX spot rates for a currency pair with optional technical indicators. "
131
+ "The indicators parameter accepts a comma-separated list of technical "
132
+ "indicator slugs (e.g. 'sma_20,ema_50,rsi_14,bbands_20,atr_14,macd')."
133
+ ),
134
+ )
135
+ def forex(
136
+ base: str,
137
+ quote: str,
138
+ start_date: Optional[str] = None,
139
+ end_date: Optional[str] = None,
140
+ indicators: Optional[str] = None,
141
+ ) -> str:
142
+ """Return FX spot rates and optional technical indicators."""
143
+ try:
144
+ result = _client.get_fx_price(
145
+ base, quote,
146
+ start_date=start_date,
147
+ end_date=end_date,
148
+ indicators=indicators,
149
+ )
150
+ return json.dumps(result)
151
+ except FXMacroDataError as exc:
152
+ return _handle_error("forex", exc)
153
+
154
+
155
+ @mcp.tool(
156
+ name="indicator_query",
157
+ description=(
158
+ "Get macroeconomic indicator time series for a currency. "
159
+ "Returns announcement dates, values, and prior readings. "
160
+ "Use data_catalogue to discover valid currency + indicator slugs."
161
+ ),
162
+ )
163
+ def indicator_query(
164
+ currency: str,
165
+ indicator: str,
166
+ start_date: Optional[str] = None,
167
+ end_date: Optional[str] = None,
168
+ ) -> str:
169
+ """Return an indicator announcement time series."""
170
+ try:
171
+ # Match the hosted MCP behaviour: COMM routes to commodities
172
+ if currency.upper() == "COMM":
173
+ result = _client.get_commodities(
174
+ indicator, start_date=start_date, end_date=end_date,
175
+ )
176
+ else:
177
+ result = _client.get_indicator(
178
+ currency, indicator,
179
+ start_date=start_date, end_date=end_date,
180
+ )
181
+ return json.dumps(result)
182
+ except FXMacroDataError as exc:
183
+ return _handle_error("indicator_query", exc)
184
+
185
+
186
+ @mcp.tool(
187
+ name="market_sessions",
188
+ description=(
189
+ "Get the current FX market-session timetable and overlap windows, "
190
+ "or request a snapshot for a specific UTC timestamp. "
191
+ "Covers Sydney, Tokyo, London, and New York sessions."
192
+ ),
193
+ )
194
+ def market_sessions(at: Optional[str] = None) -> str:
195
+ """Return FX market session status."""
196
+ params: dict[str, str] = {}
197
+ if at:
198
+ params["at"] = at
199
+ resp = httpx.get(
200
+ _api_url("/v1/market_sessions"),
201
+ params=params,
202
+ headers=_auth_headers(),
203
+ timeout=10,
204
+ )
205
+ resp.raise_for_status()
206
+ return json.dumps(resp.json())
207
+
208
+
209
+ @mcp.tool(
210
+ name="cot_data",
211
+ description=(
212
+ "Get CFTC Commitment of Traders (COT) weekly positioning data "
213
+ "for a currency's FX futures contract. "
214
+ "Supported: AUD, CAD, CHF, EUR, GBP, JPY, NZD, USD."
215
+ ),
216
+ )
217
+ def cot_data(
218
+ currency: str,
219
+ start_date: Optional[str] = None,
220
+ end_date: Optional[str] = None,
221
+ ) -> str:
222
+ """Return COT positioning data for a currency."""
223
+ try:
224
+ result = _client.get_cot(
225
+ currency, start_date=start_date, end_date=end_date,
226
+ )
227
+ return json.dumps(result)
228
+ except FXMacroDataError as exc:
229
+ return _handle_error("cot_data", exc)
230
+
231
+
232
+ @mcp.tool(
233
+ name="commodities",
234
+ description=(
235
+ "Get commodity price time series. "
236
+ "Supported indicators: gold, silver, platinum."
237
+ ),
238
+ )
239
+ def commodities(
240
+ indicator: str,
241
+ start_date: Optional[str] = None,
242
+ end_date: Optional[str] = None,
243
+ ) -> str:
244
+ """Return commodity price data."""
245
+ try:
246
+ result = _client.get_commodities(
247
+ indicator, start_date=start_date, end_date=end_date,
248
+ )
249
+ return json.dumps(result)
250
+ except FXMacroDataError as exc:
251
+ return _handle_error("commodities", exc)
252
+
253
+
254
+ # ---------------------------------------------------------------------------
255
+ # Entry point
256
+ # ---------------------------------------------------------------------------
257
+
258
+ def main():
259
+ """Run the MCP server on stdio transport."""
260
+ mcp.run(transport="stdio")
261
+
262
+
263
+ if __name__ == "__main__":
264
+ main()
@@ -0,0 +1,182 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-server-fxmacrodata
3
+ Version: 0.1.0
4
+ Summary: MCP server for the FXMacroData API — macroeconomic indicators, release calendars, COT, commodities, and forex for AI agents.
5
+ Author-email: FXMacroData <info@fxmacrodata.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://fxmacrodata.com
8
+ Project-URL: Documentation, https://fxmacrodata.com/documentation
9
+ Project-URL: Source, https://github.com/fxmacrodata/mcp-server-fxmacrodata
10
+ Project-URL: Issues, https://github.com/fxmacrodata/mcp-server-fxmacrodata/issues
11
+ Keywords: mcp,model-context-protocol,forex,macro,macroeconomics,trading,fxmacrodata,ai-agent
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: mcp>=1.0
24
+ Requires-Dist: fxmacrodata>=1.1
25
+ Requires-Dist: httpx>=0.27
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0; extra == "dev"
28
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
29
+ Requires-Dist: python-dotenv>=1.1; extra == "dev"
30
+ Requires-Dist: ruff>=0.0; extra == "dev"
31
+ Requires-Dist: build>=1.0; extra == "dev"
32
+ Requires-Dist: twine>=4.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # mcp-server-fxmacrodata
36
+
37
+ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for the [FXMacroData API](https://fxmacrodata.com) — macroeconomic indicators, release calendars, COT positioning, commodities, and FX rates for AI agents.
38
+
39
+ ## Quick start
40
+
41
+ No install needed — run with [`uvx`](https://docs.astral.sh/uv/guides/tools/):
42
+
43
+ ```bash
44
+ uvx mcp-server-fxmacrodata
45
+ ```
46
+
47
+ USD data works immediately with no API key. For all currencies, set your key:
48
+
49
+ ```bash
50
+ FXMACRODATA_API_KEY=your_key uvx mcp-server-fxmacrodata
51
+ ```
52
+
53
+ Get a free API key at [fxmacrodata.com/api-management](https://fxmacrodata.com/api-management).
54
+
55
+ ## Configure your MCP client
56
+
57
+ ### Claude Desktop
58
+
59
+ Add to `claude_desktop_config.json`:
60
+
61
+ ```json
62
+ {
63
+ "mcpServers": {
64
+ "fxmacrodata": {
65
+ "command": "uvx",
66
+ "args": ["mcp-server-fxmacrodata"],
67
+ "env": {
68
+ "FXMACRODATA_API_KEY": "your_key"
69
+ }
70
+ }
71
+ }
72
+ }
73
+ ```
74
+
75
+ ### Cursor
76
+
77
+ Add to `.cursor/mcp.json`:
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "fxmacrodata": {
83
+ "command": "uvx",
84
+ "args": ["mcp-server-fxmacrodata"],
85
+ "env": {
86
+ "FXMACRODATA_API_KEY": "your_key"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### VS Code / GitHub Copilot
94
+
95
+ Add to `.vscode/mcp.json`:
96
+
97
+ ```json
98
+ {
99
+ "servers": {
100
+ "fxmacrodata": {
101
+ "command": "uvx",
102
+ "args": ["mcp-server-fxmacrodata"],
103
+ "env": {
104
+ "FXMACRODATA_API_KEY": "your_key"
105
+ }
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### OpenClaw
112
+
113
+ Add to `~/.openclaw/openclaw.json`:
114
+
115
+ ```json
116
+ {
117
+ "mcpServers": {
118
+ "fxmacrodata": {
119
+ "command": "uvx",
120
+ "args": ["mcp-server-fxmacrodata"],
121
+ "env": {
122
+ "FXMACRODATA_API_KEY": "your_key"
123
+ }
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ > **Tip:** If your MCP client supports remote HTTP servers, you can connect directly to `https://fxmacrodata.com/mcp` instead — no local install needed. Append `?api_key=your_key` for non-USD data.
130
+
131
+ ## Available tools
132
+
133
+ | Tool | Description |
134
+ |------|-------------|
135
+ | `ping` | Verify FXMacroData API connectivity |
136
+ | `data_catalogue` | List available indicators for a currency |
137
+ | `release_calendar` | Upcoming macro release dates |
138
+ | `forex` | FX spot rates with optional technical indicators |
139
+ | `indicator_query` | Macro indicator time series (announcements) |
140
+ | `market_sessions` | FX session timetable (Sydney, Tokyo, London, New York) |
141
+ | `cot_data` | CFTC Commitment of Traders positioning |
142
+ | `commodities` | Commodity prices (gold, silver, platinum) |
143
+
144
+ ## Environment variables
145
+
146
+ | Variable | Default | Description |
147
+ |----------|---------|-------------|
148
+ | `FXMACRODATA_API_KEY` | *(none)* | API key for non-USD data |
149
+ | `FXMACRODATA_BASE_URL` | `https://fxmacrodata.com/api` | Override API base URL |
150
+
151
+ ## Install with pip
152
+
153
+ ```bash
154
+ pip install mcp-server-fxmacrodata
155
+ ```
156
+
157
+ Then run:
158
+
159
+ ```bash
160
+ mcp-server-fxmacrodata
161
+ ```
162
+
163
+ ## Development
164
+
165
+ ```bash
166
+ git clone https://github.com/fxmacrodata/mcp-server-fxmacrodata
167
+ cd mcp-server-fxmacrodata
168
+ pip install -e ".[dev]"
169
+ pytest
170
+ ```
171
+
172
+ ## Debugging
173
+
174
+ Use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
175
+
176
+ ```bash
177
+ npx @modelcontextprotocol/inspector uvx mcp-server-fxmacrodata
178
+ ```
179
+
180
+ ## License
181
+
182
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,8 @@
1
+ mcp_server_fxmacrodata/__init__.py,sha256=JSTyR1k-ocdxjbpcTurKDwfpCq3xiUsOdwGp1DtDsIU,93
2
+ mcp_server_fxmacrodata/server.py,sha256=Ztp06GI7_M0iGfMyxuHBtdPszH241S_yrApYwDi2Kc0,8268
3
+ mcp_server_fxmacrodata-0.1.0.dist-info/licenses/LICENSE,sha256=mLVV_vNUMbtObjBLP4s10Tc8K4m_5sbNJ96E169Td84,1089
4
+ mcp_server_fxmacrodata-0.1.0.dist-info/METADATA,sha256=Wag65dWKyitCpsc5gApgBHF9ifefj_uyobykih3MdmU,4832
5
+ mcp_server_fxmacrodata-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
6
+ mcp_server_fxmacrodata-0.1.0.dist-info/entry_points.txt,sha256=2_53kqyMfj4L323faofTwQe65-JHqrYmAXYDwL_Vmys,78
7
+ mcp_server_fxmacrodata-0.1.0.dist-info/top_level.txt,sha256=irHYDi4E5aeN3WrMw-hAL6ursJjPjBPAUl5E3KKIDuw,23
8
+ mcp_server_fxmacrodata-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mcp-server-fxmacrodata = mcp_server_fxmacrodata.server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FXMacroData
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 @@
1
+ mcp_server_fxmacrodata