iflow-mcp_ahnlabio-bicscan-mcp 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.
- bicscan_mcp/__init__.py +10 -0
- bicscan_mcp/server.py +131 -0
- iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/METADATA +152 -0
- iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/RECORD +7 -0
- iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/WHEEL +4 -0
- iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/licenses/LICENSE +21 -0
bicscan_mcp/__init__.py
ADDED
bicscan_mcp/server.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
from urllib.parse import urljoin
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
from mcp.server import FastMCP
|
|
10
|
+
|
|
11
|
+
load_dotenv()
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger("bicscan-mcp")
|
|
14
|
+
logger.setLevel(logging.INFO)
|
|
15
|
+
|
|
16
|
+
# add console handler
|
|
17
|
+
console_handler = logging.StreamHandler()
|
|
18
|
+
formatter = logging.Formatter(
|
|
19
|
+
"%(asctime)s - %(name)s:%(lineno)s - %(levelname)s - %(message)s"
|
|
20
|
+
)
|
|
21
|
+
console_handler.setFormatter(formatter)
|
|
22
|
+
logger.addHandler(console_handler)
|
|
23
|
+
|
|
24
|
+
# add file handler
|
|
25
|
+
# file_handler = logging.FileHandler("./data/bicscan-mcp.log")
|
|
26
|
+
# file_handler.setFormatter(formatter)
|
|
27
|
+
# logger.addHandler(file_handler)
|
|
28
|
+
|
|
29
|
+
# Add more detailed logging
|
|
30
|
+
logger.info("FastMCP server initialized with name: BICScan")
|
|
31
|
+
|
|
32
|
+
# Initialize FastMCP server
|
|
33
|
+
mcp = FastMCP("BICScan")
|
|
34
|
+
|
|
35
|
+
# Constants
|
|
36
|
+
BICSCAN_API_BASE = "https://api.bicscan.io"
|
|
37
|
+
BICSCAN_API_KEY = os.getenv("BICSCAN_API_KEY")
|
|
38
|
+
TEST_MODE = os.getenv("TEST_MODE", "false").lower() == "true"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async def post_request(
|
|
42
|
+
endpoint: str, data: dict[str, Any] | None = None
|
|
43
|
+
) -> dict[str, Any] | None:
|
|
44
|
+
"""Make a request to BICScan API with proper error handling."""
|
|
45
|
+
# Test mode: return mock data
|
|
46
|
+
if TEST_MODE:
|
|
47
|
+
logger.info(f"TEST_MODE: Returning mock data for {endpoint}")
|
|
48
|
+
return {
|
|
49
|
+
"summary": {
|
|
50
|
+
"bicscan_score": 0,
|
|
51
|
+
"risk_level": "low",
|
|
52
|
+
"address": data.get("query", "unknown") if data else "unknown"
|
|
53
|
+
},
|
|
54
|
+
"assets": [],
|
|
55
|
+
"status": "test_mode"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
headers = {
|
|
59
|
+
"User-Agent": "bicscan-mcp/1.0",
|
|
60
|
+
"Accept": "application/json",
|
|
61
|
+
"X-Api-Key": BICSCAN_API_KEY,
|
|
62
|
+
}
|
|
63
|
+
url = urljoin(BICSCAN_API_BASE, endpoint)
|
|
64
|
+
|
|
65
|
+
async with httpx.AsyncClient() as client:
|
|
66
|
+
try:
|
|
67
|
+
logger.info(f"Making request to {url}")
|
|
68
|
+
logger.debug(f"{headers=} {data=}")
|
|
69
|
+
response = await client.post(url, headers=headers, json=data, timeout=30)
|
|
70
|
+
response.raise_for_status()
|
|
71
|
+
logger.info(f"Received response: {response.status_code}")
|
|
72
|
+
return response.json()
|
|
73
|
+
except httpx.HTTPStatusError as http_err:
|
|
74
|
+
logger.error(f"Received response: {http_err}, {response.text}")
|
|
75
|
+
return response.json()
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.exception(f"Received response: {e}, {response.text}")
|
|
78
|
+
return {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@mcp.tool()
|
|
82
|
+
async def get_risk_score(address: str) -> dict:
|
|
83
|
+
"""Get Risk Score for Crypto, Domain Name, ENS, CNS, KNS or even Hostname Address
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
address: EOA, CA, ENS, CNS, KNS or even HostName
|
|
87
|
+
Returns:
|
|
88
|
+
Dict: where summary.bicscan_score is from 0 to 100. 100 is high risk.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
logger.info(f"Getting risk score for address: {address}")
|
|
92
|
+
endpoint = "/v1/scan"
|
|
93
|
+
data = {
|
|
94
|
+
"query": address,
|
|
95
|
+
"sync": True,
|
|
96
|
+
"assets": False,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return await post_request(endpoint, data=data)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@mcp.tool()
|
|
103
|
+
async def get_assets(address: str) -> dict:
|
|
104
|
+
"""Get Assets holdings by CryptoAddress
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
address: EOA, CA, ENS, CNS, KNS.
|
|
108
|
+
Returns:
|
|
109
|
+
Dict: where assets is a list of assets
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
logger.info(f"Getting assets for address: {address}")
|
|
113
|
+
endpoint = "/v1/scan"
|
|
114
|
+
data = {
|
|
115
|
+
"query": address,
|
|
116
|
+
"sync": True,
|
|
117
|
+
"assets": True,
|
|
118
|
+
"engines": ["ofac"],
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return await post_request(endpoint, data=data)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async def main() -> None:
|
|
125
|
+
"""Run the MCP BICScan server."""
|
|
126
|
+
# Import here to avoid issues with event loops
|
|
127
|
+
await mcp.run_stdio_async()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iflow-mcp_ahnlabio-bicscan-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: BICScan MCP Server
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: httpx>=0.28.1
|
|
8
|
+
Requires-Dist: mcp[cli]>=1.5.0
|
|
9
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# BICScan MCP Server
|
|
13
|
+
|
|
14
|
+
A powerful and efficient Blockchain address risk scoring API MCP Server, leveraging the BICScan API to provide comprehensive risk assessments and asset information for blockchain addresses, domains, and decentralized applications (dApps).
|
|
15
|
+
|
|
16
|
+
🎉 We're listed on https://github.com/modelcontextprotocol/servers for official integration 🎉
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
https://github.com/user-attachments/assets/f9425429-1cb1-4508-b962-81351075258b
|
|
20
|
+
|
|
21
|
+
## Key Features
|
|
22
|
+
- **Risk Scoring**: Obtain risk scores for various blockchain entities, including crypto addresses, domain names, and decentralized application URLs, with scores ranging from 0 to 100, where 100 indicates high risk.
|
|
23
|
+
- **Asset Information**: Retrieve detailed asset holdings for specified crypto addresses, including cryptocurrencies and tokens, with support for multiple blockchain networks.
|
|
24
|
+
- **Real-time Scanning**: Utilize the BICScan API to perform real-time scans and receive up-to-date information on potential risks and asset holdings.
|
|
25
|
+
- **Secure and Reliable**: Built with robust error handling and logging to ensure secure and reliable operations.
|
|
26
|
+
|
|
27
|
+
## Example Output
|
|
28
|
+
|
|
29
|
+
## How to use.
|
|
30
|
+
|
|
31
|
+
You con either use Python with `uv` or `docker` depending on your preference.
|
|
32
|
+
|
|
33
|
+
Depending on your environment, you can choose to use either `uv`, `docker`, or `uvx`.
|
|
34
|
+
|
|
35
|
+
### 1. Running with `uv`
|
|
36
|
+
|
|
37
|
+
#### 1-1. Requirements
|
|
38
|
+
1. Python 3.10 or higher
|
|
39
|
+
2. uv 0.6.x
|
|
40
|
+
3. git
|
|
41
|
+
|
|
42
|
+
#### 1.2. Clone the repository
|
|
43
|
+
```sh
|
|
44
|
+
git clone https://github.com/ahnlabio/bicscan-mcp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### 1.3. Config `claude_desktop_config.json`
|
|
48
|
+
|
|
49
|
+
Append following to `claude_desktop_config.json`.
|
|
50
|
+
|
|
51
|
+
Make sure to replace:
|
|
52
|
+
- `YOUR_BICSCAN_REPO_DIR_HERE`: to something like `C:\\Users\\ABC\\repo\\bicscan-mcp` or `/home/abc/repo/bicscan-mcp` similarly.
|
|
53
|
+
- `YOUR_BICSCAN_API_KEY_HERE`: to free API key can be obtained from https://bicscan.io (details below)
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
... some other mcp servers ...,
|
|
59
|
+
"bicscan": {
|
|
60
|
+
"command": "uv",
|
|
61
|
+
"args": [
|
|
62
|
+
"--directory",
|
|
63
|
+
"YOUR_BICSCAN_REPO_DIR_HERE",
|
|
64
|
+
"run",
|
|
65
|
+
"bicscan-mcp"
|
|
66
|
+
],
|
|
67
|
+
"env": {
|
|
68
|
+
"BICSCAN_API_KEY": "YOUR_BICSCAN_API_KEY_HERE"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Running with `Docker`
|
|
76
|
+
|
|
77
|
+
#### 2.1. Requirements
|
|
78
|
+
1. Docker environment
|
|
79
|
+
|
|
80
|
+
#### 2.2. Clone the repository
|
|
81
|
+
```sh
|
|
82
|
+
git clone https://github.com/ahnlabio/bicscan-mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### 2.3. Build Docker image.
|
|
86
|
+
|
|
87
|
+
Just run `make` in the repository directory to build docker image.
|
|
88
|
+
|
|
89
|
+
#### 2.4. Config
|
|
90
|
+
Append following to `claude_desktop_config.json`
|
|
91
|
+
|
|
92
|
+
Make sure to replace:
|
|
93
|
+
- `YOUR_BICSCAN_API_KEY_HERE` to API key obtained from https://bicscan.io (details below)
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
... some other mcp servers ...,
|
|
99
|
+
"bicscan": {
|
|
100
|
+
"command": "docker",
|
|
101
|
+
"args": [
|
|
102
|
+
"run",
|
|
103
|
+
"--rm",
|
|
104
|
+
"--interactive",
|
|
105
|
+
"--env", "BICSCAN_API_KEY=YOUR_BICSCAN_API_KEY_HERE",
|
|
106
|
+
"bicscan-mcp"
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 3. Running with `uvx`
|
|
114
|
+
|
|
115
|
+
#### 3.1. Requirements
|
|
116
|
+
1. Python 3.10 or higher
|
|
117
|
+
2. uv 0.6.x
|
|
118
|
+
3. git
|
|
119
|
+
|
|
120
|
+
#### 3.2. Config `claude_desktop_config.json`
|
|
121
|
+
|
|
122
|
+
Append following to `claude_desktop_config.json`.
|
|
123
|
+
|
|
124
|
+
Make sure to replace:
|
|
125
|
+
- `YOUR_BICSCAN_API_KEY_HERE`: to free API key can be obtained from https://bicscan.io (details below)
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"mcpServers": {
|
|
130
|
+
... some other mcp servers ...,
|
|
131
|
+
"bicscan": {
|
|
132
|
+
"command": "uvx",
|
|
133
|
+
"args": [
|
|
134
|
+
"--from",
|
|
135
|
+
"git+https://github.com/ahnlabio/bicscan-mcp",
|
|
136
|
+
"bicscan-mcp"
|
|
137
|
+
],
|
|
138
|
+
"env": {
|
|
139
|
+
"BICSCAN_API_KEY": "YOUR_BICSCAN_API_KEY_HERE"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## How to obtain Free BICScan API Key?
|
|
147
|
+
|
|
148
|
+
1. Visit `https://bicscan.io` and register.
|
|
149
|
+
2. Go to profile and create "Create App"
|
|
150
|
+
3. Enter name and description on your choice.
|
|
151
|
+
4. Replace `YOUR_BICSCAN_API_KEY_HERE` part from above config to your newly obtained key.
|
|
152
|
+
5. restart the Claude Desktop.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
bicscan_mcp/__init__.py,sha256=LeC-t6pNHUKezhSnITJBHAelVaZhng01BoheShm0nn0,131
|
|
2
|
+
bicscan_mcp/server.py,sha256=aiRgBRTdCh_XsSO83Xs8-3lXWSr3uo3q7AwUguJ8uxY,3638
|
|
3
|
+
iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/METADATA,sha256=d6GY0hoX4UcXKXborEkXfYocVwvDO92Rflf13-ihioU,4136
|
|
4
|
+
iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
5
|
+
iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/entry_points.txt,sha256=9WTgz31t0pNUlkkrkb9IkS08pRROWkKC1FRy1BNQ8q0,49
|
|
6
|
+
iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/licenses/LICENSE,sha256=QmypwNL8ez3ouD9DIskbTWQ4279KbPrc52qWuh_6y54,1088
|
|
7
|
+
iflow_mcp_ahnlabio_bicscan_mcp-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AhnLab Blockchain Company, INC.
|
|
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.
|