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.
@@ -0,0 +1,10 @@
1
+ import asyncio
2
+
3
+ from . import server
4
+
5
+
6
+ def main() -> None:
7
+ asyncio.run(server.main())
8
+
9
+
10
+ __all__ = ["main", "server"]
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,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ bicscan-mcp = bicscan_mcp:main
@@ -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.