Skip to content

Commit 799f1cf

Browse files
author
Polygon
committed
Add docker support + fix list_trades
1 parent 051bdd8 commit 799f1cf

File tree

4 files changed

+56
-61
lines changed

4 files changed

+56
-61
lines changed

Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM python:3.13-slim
2+
3+
WORKDIR /app
4+
5+
# Install uv for dependency management
6+
RUN pip install uv
7+
8+
COPY . ./
9+
10+
RUN uv pip install --system -e .
11+
RUN chmod +x entrypoint.py
12+
13+
ENV PYTHONPATH=/app/src:$PYTHONPATH
14+
15+
ENTRYPOINT ["python", "./entrypoint.py"]

docker-compose.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
mcp_polygon:
3+
build: .
4+
volumes:
5+
- .:/app
6+
container_name: mcp_polygon_server
7+
environment:
8+
- POLYGON_API_KEY=${POLYGON_API_KEY}
9+
stdin_open: true
10+
tty: true

entrypoint.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env python
2+
from mcp_polygon import main
3+
4+
if __name__ == "__main__":
5+
main()

src/mcp_polygon/server.py

Lines changed: 26 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -211,39 +211,25 @@ async def handle_get_aggs(arguments: dict) -> list[types.TextContent]:
211211
ticker = arguments.get("ticker")
212212
multiplier = arguments.get("multiplier", 1)
213213
timespan = arguments.get("timespan", "day")
214-
from_date = arguments.get("from_date")
215-
to_date = arguments.get("to_date")
214+
from_ = arguments.get("from")
215+
to = arguments.get("to")
216216
limit = arguments.get("limit", 10)
217217

218-
if not ticker or not from_date or not to_date:
219-
raise ValueError("Missing required parameters: ticker, from_date, or to_date")
218+
if not ticker or not from_ or not to or not timespan or not multiplier:
219+
raise ValueError("Missing required parameters: ticker, from_, or to")
220220

221221
try:
222222
# Call Polygon API
223-
aggs = polygon_client.get_aggs(
223+
results = polygon_client.get_aggs(
224224
ticker=ticker,
225225
multiplier=multiplier,
226226
timespan=timespan,
227-
from_=from_date,
228-
to=to_date,
227+
from_=from_,
228+
to=to,
229229
limit=limit
230230
)
231-
232-
# Format response
233-
results = []
234-
for agg in aggs:
235-
results.append({
236-
"timestamp": agg.timestamp,
237-
"open": agg.open,
238-
"high": agg.high,
239-
"low": agg.low,
240-
"close": agg.close,
241-
"volume": agg.volume,
242-
"vwap": getattr(agg, 'vwap', None),
243-
"transactions": getattr(agg, 'transactions', None)
244-
})
245-
246-
response_text = f"Aggregated data for {ticker} from {from_date} to {to_date}:\n\n"
231+
232+
response_text = f"Aggregated data for {ticker} from {from_} to {to}:\n\n"
247233
response_text += f"Found {len(results)} results\n\n"
248234

249235
# Include the first few results in the text response
@@ -274,7 +260,7 @@ async def handle_get_aggs(arguments: dict) -> list[types.TextContent]:
274260
)
275261
]
276262

277-
async def handle_get_trades(arguments: dict) -> list[types.TextContent]:
263+
async def handle_list_trades(arguments: dict) -> list[types.TextContent]:
278264
"""
279265
Get historical trade data from Polygon API.
280266
@@ -293,54 +279,33 @@ async def handle_get_trades(arguments: dict) -> list[types.TextContent]:
293279
]
294280

295281
ticker = arguments.get("ticker")
296-
date_str = arguments.get("date")
297-
timestamp = arguments.get("timestamp", 0)
298-
limit = arguments.get("limit", 10)
299282

300-
if not ticker or not date_str:
283+
if not ticker:
301284
raise ValueError("Missing required parameters: ticker or date")
302285

286+
limit = arguments.get("limit", 100)
303287
try:
304288
# Call Polygon API
305-
trades = polygon_client.get_trades(
289+
results = polygon_client.list_trades(
306290
ticker=ticker,
307-
timestamp=timestamp,
291+
timestamp_gte=arguments.get("timestamp.gte", None),
292+
timestamp_gt=arguments.get("timestamp.gt", None),
293+
timestamp_lte=arguments.get("timestamp.lte", None),
294+
timestamp_lt=arguments.get("timestamp.lt", None),
308295
order="asc",
296+
sort=arguments.get("sort", "asc"),
309297
limit=limit,
310-
timestamp_lt=None,
311-
timestamp_lte=None,
312-
timestamp_gt=None,
313-
timestamp_gte=None,
314-
date=date_str
315298
)
316299

317-
# Format response
318-
results = []
319-
for trade in trades:
320-
results.append({
321-
"transaction_id": getattr(trade, 'transaction_id', None),
322-
"exchange": getattr(trade, 'exchange', None),
323-
"price": getattr(trade, 'price', None),
324-
"size": getattr(trade, 'size', None),
325-
"conditions": getattr(trade, 'conditions', None),
326-
"timestamp": getattr(trade, 'timestamp', None),
327-
"tape": getattr(trade, 'tape', None)
328-
})
329-
330-
response_text = f"Trade data for {ticker} on {date_str}:\n\n"
331-
response_text += f"Found {len(results)} trades\n\n"
332-
300+
response_text = f"Trade data for {ticker}:\n\n"
301+
333302
# Include the first few results in the text response
334303
if results:
335-
for i, result in enumerate(results[:5]):
336-
response_text += f"Trade {i+1}:\n"
337-
for key, value in result.items():
338-
if value is not None:
339-
response_text += f" {key}: {value}\n"
340-
response_text += "\n"
341-
342-
if len(results) > 5:
343-
response_text += f"...and {len(results) - 5} more trades."
304+
for i, result in enumerate(results):
305+
if i >= limit:
306+
break
307+
response_text += f"Trade {i+1}:\n {result}\n"
308+
344309
else:
345310
response_text += "No trade data found."
346311

@@ -375,7 +340,7 @@ async def handle_call_tool(
375340
elif name == "get-aggs":
376341
return await handle_get_aggs(arguments)
377342
elif name == "get-trades":
378-
return await handle_get_trades(arguments)
343+
return await handle_list_trades(arguments)
379344
else:
380345
raise ValueError(f"Unknown tool: {name}")
381346

0 commit comments

Comments
 (0)