binance-futures-mcp 1.0.7__py3-none-any.whl → 1.0.8__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.
- {binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info}/METADATA +19 -8
- binance_futures_mcp-1.0.8.dist-info/RECORD +9 -0
- {binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info}/WHEEL +1 -1
- binance_mcp/server.py +122 -22
- binance_futures_mcp-1.0.7.dist-info/RECORD +0 -9
- {binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info}/entry_points.txt +0 -0
- {binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info/licenses}/LICENSE +0 -0
- {binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,14 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: binance-futures-mcp
|
3
|
-
Version: 1.0.
|
4
|
-
Summary: A Model Context Protocol server for Binance Futures API
|
3
|
+
Version: 1.0.8
|
4
|
+
Summary: A Model Context Protocol server for Binance Futures API with comprehensive trading tools
|
5
5
|
Home-page: https://github.com/alexcandrabersiva/bin-mcp
|
6
6
|
Author: Binance MCP Server
|
7
|
-
|
7
|
+
License-Expression: MIT
|
8
|
+
Project-URL: Homepage, https://github.com/alexcandrabersiva/bin-mcp
|
8
9
|
Project-URL: Repository, https://github.com/alexcandrabersiva/bin-mcp.git
|
9
|
-
|
10
|
+
Project-URL: Issues, https://github.com/alexcandrabersiva/bin-mcp/issues
|
11
|
+
Keywords: mcp,binance,trading,futures,api,model-context-protocol
|
10
12
|
Classifier: Development Status :: 4 - Beta
|
11
13
|
Classifier: Intended Audience :: Developers
|
12
14
|
Classifier: Programming Language :: Python :: 3
|
@@ -20,9 +22,18 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
20
22
|
Requires-Python: >=3.8
|
21
23
|
Description-Content-Type: text/markdown
|
22
24
|
License-File: LICENSE
|
23
|
-
Requires-Dist: mcp
|
24
|
-
Requires-Dist: aiohttp
|
25
|
-
Requires-Dist: pydantic
|
25
|
+
Requires-Dist: mcp>=1.0.0
|
26
|
+
Requires-Dist: aiohttp>=3.8.0
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
28
|
+
Provides-Extra: dev
|
29
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
30
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
31
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
32
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
33
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
34
|
+
Dynamic: home-page
|
35
|
+
Dynamic: license-file
|
36
|
+
Dynamic: requires-python
|
26
37
|
|
27
38
|
# Binance MCP Server
|
28
39
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
binance_futures_mcp-1.0.8.dist-info/licenses/LICENSE,sha256=zqfwopvOi7kOx5YVOnehgmRFR-IU3x1n9JEShr3QOYg,1075
|
2
|
+
binance_mcp/__init__.py,sha256=ExUxc1kp3GoSwmEtC7eGgFMZlvSQ4IdW1T5xhw-NT98,106
|
3
|
+
binance_mcp/__main__.py,sha256=_9DBrtv0PAvjLjCqKk_cMfGtkqSUOcmU6HeQKFjuFMQ,214
|
4
|
+
binance_mcp/server.py,sha256=RNLNWe_lF24HKti32MBPFo3rsACBWZ6yF02C3owtDB4,48057
|
5
|
+
binance_futures_mcp-1.0.8.dist-info/METADATA,sha256=32MQTpog3BDvt0acBdZpD6dJyURTEGG54nYqVHa9qNA,11845
|
6
|
+
binance_futures_mcp-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
+
binance_futures_mcp-1.0.8.dist-info/entry_points.txt,sha256=-1iVs9AF7JQBS-xMichP9hQhbCY7YfLFRJVaNKwuN34,69
|
8
|
+
binance_futures_mcp-1.0.8.dist-info/top_level.txt,sha256=RqGhe1caZUvBF_ezvTiLZD8kVS25eiWVkfJfmoND9m8,12
|
9
|
+
binance_futures_mcp-1.0.8.dist-info/RECORD,,
|
binance_mcp/server.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
|
3
3
|
import asyncio
|
4
|
+
import argparse
|
4
5
|
import hashlib
|
5
6
|
import hmac
|
6
7
|
import json
|
8
|
+
import os
|
7
9
|
import time
|
8
10
|
from datetime import datetime
|
9
11
|
from typing import Any, Dict, List, Optional, Union
|
@@ -48,7 +50,7 @@ class BinanceClient:
|
|
48
50
|
timeout=timeout,
|
49
51
|
connector=connector,
|
50
52
|
headers={
|
51
|
-
'User-Agent': 'binance-mcp-server/1.0.
|
53
|
+
'User-Agent': 'binance-mcp-server/1.0.8',
|
52
54
|
'Content-Type': 'application/x-www-form-urlencoded'
|
53
55
|
}
|
54
56
|
)
|
@@ -96,15 +98,21 @@ class BinanceClient:
|
|
96
98
|
try:
|
97
99
|
if method == "GET":
|
98
100
|
async with self.session.get(url, params=params, headers=headers, ssl=False) as response:
|
99
|
-
response.
|
101
|
+
if response.status != 200:
|
102
|
+
error_text = await response.text()
|
103
|
+
raise Exception(f"HTTP {response.status}: {error_text}")
|
100
104
|
return await response.json()
|
101
105
|
elif method == "POST":
|
102
106
|
async with self.session.post(url, data=params, headers=headers, ssl=False) as response:
|
103
|
-
response.
|
107
|
+
if response.status != 200:
|
108
|
+
error_text = await response.text()
|
109
|
+
raise Exception(f"HTTP {response.status}: {error_text}")
|
104
110
|
return await response.json()
|
105
111
|
elif method == "DELETE":
|
106
112
|
async with self.session.delete(url, data=params, headers=headers, ssl=False) as response:
|
107
|
-
response.
|
113
|
+
if response.status != 200:
|
114
|
+
error_text = await response.text()
|
115
|
+
raise Exception(f"HTTP {response.status}: {error_text}")
|
108
116
|
return await response.json()
|
109
117
|
else:
|
110
118
|
raise ValueError(f"Unsupported HTTP method: {method}")
|
@@ -244,26 +252,26 @@ class BinanceMCPServer:
|
|
244
252
|
"properties": {
|
245
253
|
"symbol": {"type": "string", "description": "Trading pair symbol"},
|
246
254
|
"side": {"type": "string", "description": "Order side ('BUY' or 'SELL')"},
|
247
|
-
"
|
255
|
+
"type": {"type": "string", "description": "Order type ('MARKET', 'LIMIT', 'STOP', 'STOP_MARKET', 'TRAILING_STOP_MARKET', etc)"},
|
248
256
|
"quantity": {"type": "number", "description": "Order quantity"},
|
249
257
|
"price": {"type": "number", "description": "Order price (for LIMIT orders)"},
|
250
|
-
"
|
251
|
-
"
|
252
|
-
"
|
253
|
-
"
|
254
|
-
"
|
255
|
-
"
|
256
|
-
"
|
257
|
-
"
|
258
|
-
"
|
259
|
-
"
|
260
|
-
"
|
261
|
-
"
|
258
|
+
"stopPrice": {"type": "number", "description": "Stop price (for STOP orders)"},
|
259
|
+
"timeInForce": {"type": "string", "description": "Time in force (GTC, IOC, FOK)"},
|
260
|
+
"positionSide": {"type": "string", "description": "Position side ('BOTH', 'LONG', 'SHORT')"},
|
261
|
+
"reduceOnly": {"type": "string", "description": "Reduce only flag ('true' or 'false')"},
|
262
|
+
"newClientOrderId": {"type": "string", "description": "Custom order ID"},
|
263
|
+
"closePosition": {"type": "string", "description": "Close position flag ('true' or 'false')"},
|
264
|
+
"activationPrice": {"type": "number", "description": "Activation price (for TRAILING_STOP_MARKET)"},
|
265
|
+
"callbackRate": {"type": "number", "description": "Callback rate (for TRAILING_STOP_MARKET)"},
|
266
|
+
"workingType": {"type": "string", "description": "Working type (MARK_PRICE, CONTRACT_PRICE)"},
|
267
|
+
"priceProtect": {"type": "string", "description": "Price protection flag ('TRUE' or 'FALSE')"},
|
268
|
+
"newOrderRespType": {"type": "string", "description": "Response type ('ACK', 'RESULT')"},
|
269
|
+
"recvWindow": {"type": "integer", "description": "Receive window"},
|
262
270
|
"timestamp": {"type": "integer", "description": "Timestamp"},
|
263
271
|
"quantity_precision": {"type": "integer", "description": "Quantity precision for validation"},
|
264
272
|
"price_precision": {"type": "integer", "description": "Price precision for validation"}
|
265
273
|
},
|
266
|
-
"required": ["symbol", "side", "
|
274
|
+
"required": ["symbol", "side", "type"]
|
267
275
|
}
|
268
276
|
),
|
269
277
|
Tool(
|
@@ -386,6 +394,20 @@ class BinanceMCPServer:
|
|
386
394
|
"required": ["symbol", "order_id"]
|
387
395
|
}
|
388
396
|
),
|
397
|
+
Tool(
|
398
|
+
name="close_position",
|
399
|
+
description="Close current position for a symbol (market order to close all or part of position)",
|
400
|
+
inputSchema={
|
401
|
+
"type": "object",
|
402
|
+
"properties": {
|
403
|
+
"symbol": {"type": "string", "description": "Trading pair symbol"},
|
404
|
+
"position_side": {"type": "string", "description": "Position side to close ('BOTH', 'LONG', 'SHORT'). Default 'BOTH' for One-way mode"},
|
405
|
+
"quantity": {"type": "number", "description": "Quantity to close (optional, if not provided will close entire position)"},
|
406
|
+
"close_all": {"type": "boolean", "description": "If true, closes entire position using closePosition=true parameter"}
|
407
|
+
},
|
408
|
+
"required": ["symbol"]
|
409
|
+
}
|
410
|
+
),
|
389
411
|
|
390
412
|
# Trading Configuration Tools
|
391
413
|
Tool(
|
@@ -656,10 +678,31 @@ class BinanceMCPServer:
|
|
656
678
|
|
657
679
|
# Order Management Tools
|
658
680
|
elif name == "place_order":
|
681
|
+
# Filter out precision parameters and pass through all other parameters directly
|
659
682
|
params = {k: v for k, v in arguments.items() if v is not None and k not in ["quantity_precision", "price_precision"]}
|
660
|
-
|
661
|
-
|
662
|
-
|
683
|
+
|
684
|
+
# Validate mandatory parameters based on order type
|
685
|
+
order_type = params.get("type")
|
686
|
+
if order_type == "LIMIT":
|
687
|
+
required_params = ["timeInForce", "quantity", "price"]
|
688
|
+
missing = [p for p in required_params if p not in params]
|
689
|
+
if missing:
|
690
|
+
raise ValueError(f"LIMIT order missing required parameters: {missing}")
|
691
|
+
elif order_type == "MARKET":
|
692
|
+
if "quantity" not in params:
|
693
|
+
raise ValueError("MARKET order missing required parameter: quantity")
|
694
|
+
elif order_type in ["STOP", "TAKE_PROFIT"]:
|
695
|
+
required_params = ["quantity", "price", "stopPrice"]
|
696
|
+
missing = [p for p in required_params if p not in params]
|
697
|
+
if missing:
|
698
|
+
raise ValueError(f"{order_type} order missing required parameters: {missing}")
|
699
|
+
elif order_type in ["STOP_MARKET", "TAKE_PROFIT_MARKET"]:
|
700
|
+
if "stopPrice" not in params:
|
701
|
+
raise ValueError(f"{order_type} order missing required parameter: stopPrice")
|
702
|
+
elif order_type == "TRAILING_STOP_MARKET":
|
703
|
+
if "callbackRate" not in params:
|
704
|
+
raise ValueError("TRAILING_STOP_MARKET order missing required parameter: callbackRate")
|
705
|
+
|
663
706
|
result = await client._make_request("POST", "/fapi/v1/order", params, "TRADE")
|
664
707
|
elif name == "place_multiple_orders":
|
665
708
|
# This requires special handling for batch orders
|
@@ -697,6 +740,63 @@ class BinanceMCPServer:
|
|
697
740
|
elif name == "query_order":
|
698
741
|
params = {"symbol": arguments["symbol"], "orderId": arguments["order_id"]}
|
699
742
|
result = await client._make_request("GET", "/fapi/v1/order", params, "USER_DATA")
|
743
|
+
elif name == "close_position":
|
744
|
+
# Handle position closing
|
745
|
+
symbol = arguments["symbol"]
|
746
|
+
position_side = arguments.get("position_side", "BOTH")
|
747
|
+
quantity = arguments.get("quantity")
|
748
|
+
close_all = arguments.get("close_all", False)
|
749
|
+
|
750
|
+
# First, get current position to determine the side and quantity to close
|
751
|
+
position_params = {"symbol": symbol}
|
752
|
+
positions = await client._make_request("GET", "/fapi/v2/positionRisk", position_params, "USER_DATA")
|
753
|
+
|
754
|
+
# Find the position to close
|
755
|
+
position_to_close = None
|
756
|
+
for pos in positions:
|
757
|
+
if pos["symbol"] == symbol and float(pos["positionAmt"]) != 0:
|
758
|
+
if position_side == "BOTH" or pos["positionSide"] == position_side:
|
759
|
+
position_to_close = pos
|
760
|
+
break
|
761
|
+
|
762
|
+
if not position_to_close:
|
763
|
+
raise ValueError(f"No open position found for {symbol} with position side {position_side}")
|
764
|
+
|
765
|
+
position_amt = float(position_to_close["positionAmt"])
|
766
|
+
current_position_side = position_to_close["positionSide"]
|
767
|
+
|
768
|
+
# Determine order side (opposite of position)
|
769
|
+
if position_amt > 0: # Long position
|
770
|
+
order_side = "SELL"
|
771
|
+
else: # Short position
|
772
|
+
order_side = "BUY"
|
773
|
+
position_amt = abs(position_amt) # Make positive for order quantity
|
774
|
+
|
775
|
+
# Determine quantity to close
|
776
|
+
if close_all:
|
777
|
+
# Use closePosition parameter to close entire position
|
778
|
+
order_params = {
|
779
|
+
"symbol": symbol,
|
780
|
+
"side": order_side,
|
781
|
+
"type": "MARKET",
|
782
|
+
"closePosition": "true"
|
783
|
+
}
|
784
|
+
if current_position_side != "BOTH":
|
785
|
+
order_params["positionSide"] = current_position_side
|
786
|
+
else:
|
787
|
+
# Close specific quantity or entire position
|
788
|
+
close_quantity = quantity if quantity else position_amt
|
789
|
+
order_params = {
|
790
|
+
"symbol": symbol,
|
791
|
+
"side": order_side,
|
792
|
+
"type": "MARKET",
|
793
|
+
"quantity": close_quantity,
|
794
|
+
"reduceOnly": "true"
|
795
|
+
}
|
796
|
+
if current_position_side != "BOTH":
|
797
|
+
order_params["positionSide"] = current_position_side
|
798
|
+
|
799
|
+
result = await client._make_request("POST", "/fapi/v1/order", order_params, "TRADE")
|
700
800
|
|
701
801
|
# Trading Configuration Tools
|
702
802
|
elif name == "change_leverage":
|
@@ -816,7 +916,7 @@ async def main():
|
|
816
916
|
write_stream,
|
817
917
|
InitializationOptions(
|
818
918
|
server_name="binance-futures-mcp-server",
|
819
|
-
server_version="1.0.
|
919
|
+
server_version="1.0.8",
|
820
920
|
capabilities={
|
821
921
|
"tools": {}
|
822
922
|
}
|
@@ -1,9 +0,0 @@
|
|
1
|
-
binance_mcp/__init__.py,sha256=ExUxc1kp3GoSwmEtC7eGgFMZlvSQ4IdW1T5xhw-NT98,106
|
2
|
-
binance_mcp/__main__.py,sha256=_9DBrtv0PAvjLjCqKk_cMfGtkqSUOcmU6HeQKFjuFMQ,214
|
3
|
-
binance_mcp/server.py,sha256=mBuB1HX6xf5GSviYV5oIPqKz2werdBiibyxTUA-qnpY,41669
|
4
|
-
binance_futures_mcp-1.0.7.dist-info/LICENSE,sha256=zqfwopvOi7kOx5YVOnehgmRFR-IU3x1n9JEShr3QOYg,1075
|
5
|
-
binance_futures_mcp-1.0.7.dist-info/METADATA,sha256=GgB3I-rPgq5YKmV9Usi-RYvAtpQ9rk7LowADz1-Q5j8,11418
|
6
|
-
binance_futures_mcp-1.0.7.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
7
|
-
binance_futures_mcp-1.0.7.dist-info/entry_points.txt,sha256=-1iVs9AF7JQBS-xMichP9hQhbCY7YfLFRJVaNKwuN34,69
|
8
|
-
binance_futures_mcp-1.0.7.dist-info/top_level.txt,sha256=RqGhe1caZUvBF_ezvTiLZD8kVS25eiWVkfJfmoND9m8,12
|
9
|
-
binance_futures_mcp-1.0.7.dist-info/RECORD,,
|
{binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info}/entry_points.txt
RENAMED
File without changes
|
{binance_futures_mcp-1.0.7.dist-info → binance_futures_mcp-1.0.8.dist-info/licenses}/LICENSE
RENAMED
File without changes
|
File without changes
|