@basis-protocol/mcp-server 1.0.0
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.
- package/README.md +62 -0
- package/build/api.d.ts +12 -0
- package/build/api.d.ts.map +1 -0
- package/build/api.js +46 -0
- package/build/api.js.map +1 -0
- package/build/config.d.ts +168 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +24 -0
- package/build/config.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +81 -0
- package/build/index.js.map +1 -0
- package/build/tools.d.ts +3 -0
- package/build/tools.d.ts.map +1 -0
- package/build/tools.js +573 -0
- package/build/tools.js.map +1 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @basis-protocol/mcp-server
|
|
2
|
+
|
|
3
|
+
<!-- mcp-name: io.github.shlok-lgtm/basis-mcp -->
|
|
4
|
+
|
|
5
|
+
MCP server for Basis Protocol — verifiable risk intelligence for on-chain finance.
|
|
6
|
+
|
|
7
|
+
Query stablecoin integrity scores, wallet risk profiles, transaction risk assessment, and scoring methodology across 44,000+ wallets tracking $67B+ in stablecoin value.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx @basis-protocol/mcp-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Tools
|
|
16
|
+
|
|
17
|
+
| Tool | Description |
|
|
18
|
+
|------|-------------|
|
|
19
|
+
| `get_stablecoin_scores` | All scored stablecoins with SII scores and grades |
|
|
20
|
+
| `get_stablecoin_detail` | Full score breakdown for a specific stablecoin |
|
|
21
|
+
| `get_wallet_risk` | Risk profile for any Ethereum wallet |
|
|
22
|
+
| `get_wallet_holdings` | Per-asset holdings breakdown with SII scores |
|
|
23
|
+
| `get_riskiest_wallets` | Wallets with most at-risk capital |
|
|
24
|
+
| `get_scoring_backlog` | Unscored assets ranked by capital exposure |
|
|
25
|
+
| `check_transaction_risk` | Composite risk assessment: asset + sender + receiver |
|
|
26
|
+
| `get_methodology` | Current SII formula, weights, and version |
|
|
27
|
+
|
|
28
|
+
## Usage with Claude Desktop
|
|
29
|
+
|
|
30
|
+
Add to your `claude_desktop_config.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"basis-protocol": {
|
|
36
|
+
"command": "npx",
|
|
37
|
+
"args": ["-y", "@basis-protocol/mcp-server"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage with HTTP transport
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx @basis-protocol/mcp-server --http
|
|
47
|
+
# Listens on port 3000, endpoint: /mcp
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Data
|
|
51
|
+
|
|
52
|
+
- 17 stablecoins scored (SII v1.0.0)
|
|
53
|
+
- 44,000+ wallets indexed on Ethereum mainnet
|
|
54
|
+
- $67B+ in stablecoin value tracked
|
|
55
|
+
- Risk scores, concentration analysis (HHI), coverage quality
|
|
56
|
+
- Deterministic, version-controlled methodology
|
|
57
|
+
|
|
58
|
+
## Links
|
|
59
|
+
|
|
60
|
+
- [Live Dashboard](https://basis-deploy-guide.replit.app)
|
|
61
|
+
- [GitHub](https://github.com/shlok-lgtm/basis-mcp)
|
|
62
|
+
- [Basis Protocol](https://basisprotocol.xyz)
|
package/build/api.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ScoresResponse, type StablecoinDetail, type WalletProfile, type RiskiestWalletsResponse, type BacklogResponse, type MethodologyResponse } from "./config.js";
|
|
2
|
+
export declare function fetchScores(): Promise<ScoresResponse>;
|
|
3
|
+
export declare function fetchScoreDetail(coin: string): Promise<StablecoinDetail & {
|
|
4
|
+
__status?: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function fetchWalletProfile(address: string): Promise<WalletProfile & {
|
|
7
|
+
__status?: number;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function fetchRiskiestWallets(limit: number): Promise<RiskiestWalletsResponse>;
|
|
10
|
+
export declare function fetchBacklog(limit: number): Promise<BacklogResponse>;
|
|
11
|
+
export declare function fetchMethodology(): Promise<MethodologyResponse>;
|
|
12
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AA+BrB,wBAAsB,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,CAE3D;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAInD;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAIhD;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,uBAAuB,CAAC,CAIlC;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAE1E;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAErE"}
|
package/build/api.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BASE_URL, API_TIMEOUT_MS, } from "./config.js";
|
|
2
|
+
async function apiFetch(path) {
|
|
3
|
+
const controller = new AbortController();
|
|
4
|
+
const timer = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
|
|
5
|
+
try {
|
|
6
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
7
|
+
signal: controller.signal,
|
|
8
|
+
headers: { Accept: "application/json" },
|
|
9
|
+
});
|
|
10
|
+
if (res.status === 404) {
|
|
11
|
+
return { __status: 404 };
|
|
12
|
+
}
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
15
|
+
}
|
|
16
|
+
return (await res.json());
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
if (err.name === "AbortError") {
|
|
20
|
+
throw new Error("Request timed out after 10s");
|
|
21
|
+
}
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function fetchScores() {
|
|
29
|
+
return apiFetch("/api/scores");
|
|
30
|
+
}
|
|
31
|
+
export async function fetchScoreDetail(coin) {
|
|
32
|
+
return apiFetch(`/api/scores/${encodeURIComponent(coin.toLowerCase())}`);
|
|
33
|
+
}
|
|
34
|
+
export async function fetchWalletProfile(address) {
|
|
35
|
+
return apiFetch(`/api/wallets/${encodeURIComponent(address)}`);
|
|
36
|
+
}
|
|
37
|
+
export async function fetchRiskiestWallets(limit) {
|
|
38
|
+
return apiFetch(`/api/wallets/riskiest?limit=${limit}`);
|
|
39
|
+
}
|
|
40
|
+
export async function fetchBacklog(limit) {
|
|
41
|
+
return apiFetch(`/api/backlog?limit=${limit}`);
|
|
42
|
+
}
|
|
43
|
+
export async function fetchMethodology() {
|
|
44
|
+
return apiFetch("/api/methodology");
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=api.js.map
|
package/build/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,cAAc,GAOf,MAAM,aAAa,CAAC;AAErB,KAAK,UAAU,QAAQ,CAAI,IAAY;IACrC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,cAAc,CAAC,CAAC;IAEnE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE;YAC5C,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAkB,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAAa,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,QAAQ,CAAiB,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY;IAEZ,OAAO,QAAQ,CACb,eAAe,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe;IAEf,OAAO,QAAQ,CACb,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAC9C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAa;IAEb,OAAO,QAAQ,CACb,+BAA+B,KAAK,EAAE,CACvC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,OAAO,QAAQ,CAAkB,sBAAsB,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,QAAQ,CAAsB,kBAAkB,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export declare const BASE_URL = "https://basis-deploy-guide.replit.app";
|
|
2
|
+
export declare const GRADE_ORDER: Record<string, number>;
|
|
3
|
+
export declare const API_TIMEOUT_MS = 10000;
|
|
4
|
+
export type GradeString = "A+" | "A" | "A-" | "B+" | "B" | "B-" | "C+" | "C" | "C-" | "D" | "F";
|
|
5
|
+
export type SortBy = "score_desc" | "score_asc" | "name";
|
|
6
|
+
export interface StablecoinScore {
|
|
7
|
+
symbol: string;
|
|
8
|
+
name: string;
|
|
9
|
+
issuer?: string;
|
|
10
|
+
score: number;
|
|
11
|
+
grade: string;
|
|
12
|
+
price?: number;
|
|
13
|
+
market_cap?: number;
|
|
14
|
+
daily_change?: number;
|
|
15
|
+
categories?: {
|
|
16
|
+
peg?: number;
|
|
17
|
+
liquidity?: number;
|
|
18
|
+
flows?: number;
|
|
19
|
+
distribution?: number;
|
|
20
|
+
structural?: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface ScoresResponse {
|
|
24
|
+
stablecoins?: StablecoinScore[];
|
|
25
|
+
scores?: StablecoinScore[];
|
|
26
|
+
count?: number;
|
|
27
|
+
formula_version?: string;
|
|
28
|
+
timestamp?: string;
|
|
29
|
+
methodology_summary?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface CategoryDetail {
|
|
32
|
+
score: number;
|
|
33
|
+
weight: number;
|
|
34
|
+
}
|
|
35
|
+
export interface StablecoinDetail {
|
|
36
|
+
symbol: string;
|
|
37
|
+
name: string;
|
|
38
|
+
issuer?: string;
|
|
39
|
+
score: number;
|
|
40
|
+
grade: string;
|
|
41
|
+
price?: number;
|
|
42
|
+
market_cap?: number;
|
|
43
|
+
categories?: {
|
|
44
|
+
peg?: number | CategoryDetail;
|
|
45
|
+
liquidity?: number | CategoryDetail;
|
|
46
|
+
flows?: number | CategoryDetail;
|
|
47
|
+
distribution?: number | CategoryDetail;
|
|
48
|
+
structural?: number | CategoryDetail;
|
|
49
|
+
};
|
|
50
|
+
structural_breakdown?: Record<string, {
|
|
51
|
+
score: number;
|
|
52
|
+
weight: number;
|
|
53
|
+
}>;
|
|
54
|
+
weakest_category?: string;
|
|
55
|
+
strongest_category?: string;
|
|
56
|
+
component_count?: number;
|
|
57
|
+
formula_version?: string;
|
|
58
|
+
daily_change?: number;
|
|
59
|
+
weekly_change?: number;
|
|
60
|
+
computed_at?: string;
|
|
61
|
+
is_scored?: boolean;
|
|
62
|
+
error?: boolean;
|
|
63
|
+
message?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface WalletHolding {
|
|
66
|
+
symbol: string;
|
|
67
|
+
token_address?: string;
|
|
68
|
+
balance?: number;
|
|
69
|
+
value_usd?: number;
|
|
70
|
+
pct_of_wallet?: number;
|
|
71
|
+
is_scored: boolean;
|
|
72
|
+
sii_score?: number | null;
|
|
73
|
+
sii_grade?: string | null;
|
|
74
|
+
risk_contribution?: string;
|
|
75
|
+
}
|
|
76
|
+
export interface WalletProfile {
|
|
77
|
+
address: string;
|
|
78
|
+
risk_score?: number;
|
|
79
|
+
risk_grade?: string;
|
|
80
|
+
total_stablecoin_value?: number;
|
|
81
|
+
size_tier?: string;
|
|
82
|
+
label?: string;
|
|
83
|
+
is_contract?: boolean;
|
|
84
|
+
concentration?: {
|
|
85
|
+
hhi?: number;
|
|
86
|
+
grade?: string;
|
|
87
|
+
dominant_asset?: string;
|
|
88
|
+
dominant_asset_pct?: number;
|
|
89
|
+
interpretation?: string;
|
|
90
|
+
};
|
|
91
|
+
coverage?: {
|
|
92
|
+
quality?: string;
|
|
93
|
+
scored_holdings?: number;
|
|
94
|
+
unscored_holdings?: number;
|
|
95
|
+
unscored_pct?: number;
|
|
96
|
+
interpretation?: string;
|
|
97
|
+
};
|
|
98
|
+
holdings?: WalletHolding[];
|
|
99
|
+
formula_version?: string;
|
|
100
|
+
last_indexed_at?: string;
|
|
101
|
+
found_in_index?: boolean;
|
|
102
|
+
error?: boolean;
|
|
103
|
+
message?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface RiskiestWallet {
|
|
106
|
+
address: string;
|
|
107
|
+
risk_score: number;
|
|
108
|
+
risk_grade: string;
|
|
109
|
+
total_stablecoin_value: number;
|
|
110
|
+
size_tier?: string;
|
|
111
|
+
dominant_asset?: string;
|
|
112
|
+
dominant_asset_pct?: number;
|
|
113
|
+
coverage_quality?: string;
|
|
114
|
+
unscored_pct?: number;
|
|
115
|
+
capital_at_risk_interpretation?: string;
|
|
116
|
+
}
|
|
117
|
+
export interface RiskiestWalletsResponse {
|
|
118
|
+
wallets?: RiskiestWallet[];
|
|
119
|
+
count?: number;
|
|
120
|
+
total_at_risk_capital?: number;
|
|
121
|
+
timestamp?: string;
|
|
122
|
+
}
|
|
123
|
+
export interface BacklogItem {
|
|
124
|
+
symbol: string;
|
|
125
|
+
name?: string;
|
|
126
|
+
token_address?: string;
|
|
127
|
+
total_value_held?: number;
|
|
128
|
+
wallets_holding?: number;
|
|
129
|
+
avg_holding_value?: number;
|
|
130
|
+
max_single_holding?: number;
|
|
131
|
+
scoring_status?: string;
|
|
132
|
+
scoring_priority?: number;
|
|
133
|
+
coverage_gap_interpretation?: string;
|
|
134
|
+
}
|
|
135
|
+
export interface BacklogResponse {
|
|
136
|
+
backlog?: BacklogItem[];
|
|
137
|
+
count?: number;
|
|
138
|
+
total_unscored_value?: number;
|
|
139
|
+
timestamp?: string;
|
|
140
|
+
}
|
|
141
|
+
export interface MethodologyResponse {
|
|
142
|
+
version?: string;
|
|
143
|
+
formula?: string;
|
|
144
|
+
structural_formula?: string;
|
|
145
|
+
weights?: {
|
|
146
|
+
top_level?: Record<string, number>;
|
|
147
|
+
structural?: Record<string, number>;
|
|
148
|
+
};
|
|
149
|
+
grade_scale?: Record<string, string>;
|
|
150
|
+
total_components?: number;
|
|
151
|
+
automated_components?: number;
|
|
152
|
+
data_sources?: string[];
|
|
153
|
+
wallet_scoring?: {
|
|
154
|
+
version?: string;
|
|
155
|
+
method?: string;
|
|
156
|
+
concentration?: string;
|
|
157
|
+
};
|
|
158
|
+
verification?: {
|
|
159
|
+
methodology_is_public?: boolean;
|
|
160
|
+
scores_are_deterministic?: boolean;
|
|
161
|
+
no_customer_specific_adjustments?: boolean;
|
|
162
|
+
methodology_locked_since?: string;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export type OverallAssessment = "LOW_RISK" | "MEDIUM_RISK" | "HIGH_RISK" | "UNKNOWN";
|
|
166
|
+
export declare function gradeRank(grade: string | undefined | null): number;
|
|
167
|
+
export declare function isGradeAtLeast(grade: string | undefined | null, minGrade: string): boolean;
|
|
168
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/build/config.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const BASE_URL = "https://basis-deploy-guide.replit.app";
|
|
2
|
+
export const GRADE_ORDER = {
|
|
3
|
+
"A+": 11,
|
|
4
|
+
"A": 10,
|
|
5
|
+
"A-": 9,
|
|
6
|
+
"B+": 8,
|
|
7
|
+
"B": 7,
|
|
8
|
+
"B-": 6,
|
|
9
|
+
"C+": 5,
|
|
10
|
+
"C": 4,
|
|
11
|
+
"C-": 3,
|
|
12
|
+
"D": 2,
|
|
13
|
+
"F": 1,
|
|
14
|
+
};
|
|
15
|
+
export const API_TIMEOUT_MS = 10_000;
|
|
16
|
+
export function gradeRank(grade) {
|
|
17
|
+
if (!grade)
|
|
18
|
+
return 0;
|
|
19
|
+
return GRADE_ORDER[grade] ?? 0;
|
|
20
|
+
}
|
|
21
|
+
export function isGradeAtLeast(grade, minGrade) {
|
|
22
|
+
return gradeRank(grade) >= gradeRank(minGrade);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,uCAAuC,CAAC;AAEhE,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,EAAE;IACP,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;CACP,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AA8LrC,MAAM,UAAU,SAAS,CAAC,KAAgC;IACxD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAAgC,EAChC,QAAgB;IAEhB,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import express from "express";
|
|
5
|
+
import { registerTools } from "./tools.js";
|
|
6
|
+
const SERVER_NAME = "basis-protocol";
|
|
7
|
+
const SERVER_VERSION = "1.0.0";
|
|
8
|
+
const SERVER_DESCRIPTION = "Decision integrity infrastructure for on-chain finance. Verifiable risk scores for stablecoins and wallet risk profiles.";
|
|
9
|
+
function createServer() {
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: SERVER_NAME,
|
|
12
|
+
version: SERVER_VERSION,
|
|
13
|
+
}, {
|
|
14
|
+
capabilities: {
|
|
15
|
+
tools: {},
|
|
16
|
+
},
|
|
17
|
+
instructions: SERVER_DESCRIPTION,
|
|
18
|
+
});
|
|
19
|
+
registerTools(server);
|
|
20
|
+
return server;
|
|
21
|
+
}
|
|
22
|
+
const isHttp = process.argv.includes("--http");
|
|
23
|
+
if (isHttp) {
|
|
24
|
+
const rawPort = process.env["PORT"] ?? "3000";
|
|
25
|
+
const port = Number(rawPort);
|
|
26
|
+
const app = express();
|
|
27
|
+
app.use(express.json());
|
|
28
|
+
app.post("/mcp", async (req, res) => {
|
|
29
|
+
const server = createServer();
|
|
30
|
+
const transport = new StreamableHTTPServerTransport({
|
|
31
|
+
sessionIdGenerator: undefined,
|
|
32
|
+
});
|
|
33
|
+
res.on("close", () => {
|
|
34
|
+
transport.close().catch(() => { });
|
|
35
|
+
server.close().catch(() => { });
|
|
36
|
+
});
|
|
37
|
+
await server.connect(transport);
|
|
38
|
+
await transport.handleRequest(req, res, req.body);
|
|
39
|
+
});
|
|
40
|
+
app.get("/mcp", async (req, res) => {
|
|
41
|
+
const server = createServer();
|
|
42
|
+
const transport = new StreamableHTTPServerTransport({
|
|
43
|
+
sessionIdGenerator: undefined,
|
|
44
|
+
});
|
|
45
|
+
res.on("close", () => {
|
|
46
|
+
transport.close().catch(() => { });
|
|
47
|
+
server.close().catch(() => { });
|
|
48
|
+
});
|
|
49
|
+
await server.connect(transport);
|
|
50
|
+
await transport.handleRequest(req, res);
|
|
51
|
+
});
|
|
52
|
+
app.delete("/mcp", async (req, res) => {
|
|
53
|
+
const server = createServer();
|
|
54
|
+
const transport = new StreamableHTTPServerTransport({
|
|
55
|
+
sessionIdGenerator: undefined,
|
|
56
|
+
});
|
|
57
|
+
res.on("close", () => {
|
|
58
|
+
transport.close().catch(() => { });
|
|
59
|
+
server.close().catch(() => { });
|
|
60
|
+
});
|
|
61
|
+
await server.connect(transport);
|
|
62
|
+
await transport.handleRequest(req, res);
|
|
63
|
+
});
|
|
64
|
+
app.get("/health", (_req, res) => {
|
|
65
|
+
res.json({
|
|
66
|
+
status: "ok",
|
|
67
|
+
server: SERVER_NAME,
|
|
68
|
+
version: SERVER_VERSION,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
app.listen(port, () => {
|
|
72
|
+
process.stderr.write(`[basis-mcp] HTTP server listening on port ${port} — endpoint: /mcp\n`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const server = createServer();
|
|
77
|
+
const transport = new StdioServerTransport();
|
|
78
|
+
process.stderr.write(`[basis-mcp] Starting stdio transport — ${SERVER_NAME} v${SERVER_VERSION}\n`);
|
|
79
|
+
await server.connect(transport);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/build/tools.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgDpE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2qBrD"}
|
package/build/tools.js
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { fetchScores, fetchScoreDetail, fetchWalletProfile, fetchRiskiestWallets, fetchBacklog, fetchMethodology, } from "./api.js";
|
|
3
|
+
import { GRADE_ORDER, isGradeAtLeast, } from "./config.js";
|
|
4
|
+
const API_ERROR_RESPONSE = {
|
|
5
|
+
error: true,
|
|
6
|
+
message: "Basis API unavailable. Please try again shortly.",
|
|
7
|
+
retry_after_seconds: 30,
|
|
8
|
+
};
|
|
9
|
+
function formatMoney(value) {
|
|
10
|
+
if (value == null)
|
|
11
|
+
return "unknown";
|
|
12
|
+
if (value >= 1_000_000_000)
|
|
13
|
+
return `$${(value / 1_000_000_000).toFixed(1)}B`;
|
|
14
|
+
if (value >= 1_000_000)
|
|
15
|
+
return `$${(value / 1_000_000).toFixed(1)}M`;
|
|
16
|
+
if (value >= 1_000)
|
|
17
|
+
return `$${(value / 1_000).toFixed(1)}K`;
|
|
18
|
+
return `$${value.toFixed(2)}`;
|
|
19
|
+
}
|
|
20
|
+
function gradeAtLeast(grade, min) {
|
|
21
|
+
return isGradeAtLeast(grade, min);
|
|
22
|
+
}
|
|
23
|
+
function getCategoryScore(val) {
|
|
24
|
+
if (val == null)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (typeof val === "number")
|
|
27
|
+
return val;
|
|
28
|
+
return val.score;
|
|
29
|
+
}
|
|
30
|
+
export function registerTools(server) {
|
|
31
|
+
const TOOL_ANNOTATIONS = {
|
|
32
|
+
readOnlyHint: true,
|
|
33
|
+
openWorldHint: true,
|
|
34
|
+
};
|
|
35
|
+
server.registerTool("get_stablecoin_scores", {
|
|
36
|
+
description: "Get current SII scores for all scored stablecoins. Use before any decision involving stablecoins — portfolio assessment, swap routing, or collateral evaluation.",
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
min_grade: z
|
|
39
|
+
.enum(["A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D", "F"])
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Optional minimum grade filter (e.g. 'B+' returns B+ and above)"),
|
|
42
|
+
sort_by: z
|
|
43
|
+
.enum(["score_desc", "score_asc", "name"])
|
|
44
|
+
.optional()
|
|
45
|
+
.default("score_desc")
|
|
46
|
+
.describe("Sort order for results"),
|
|
47
|
+
}),
|
|
48
|
+
annotations: TOOL_ANNOTATIONS,
|
|
49
|
+
}, async ({ min_grade, sort_by }) => {
|
|
50
|
+
try {
|
|
51
|
+
const data = await fetchScores();
|
|
52
|
+
let coins = (data.stablecoins ?? data.scores ?? []);
|
|
53
|
+
if (min_grade) {
|
|
54
|
+
const minRank = GRADE_ORDER[min_grade] ?? 0;
|
|
55
|
+
coins = coins.filter((c) => (GRADE_ORDER[c.grade] ?? 0) >= minRank);
|
|
56
|
+
}
|
|
57
|
+
const sortKey = sort_by ?? "score_desc";
|
|
58
|
+
if (sortKey === "score_desc") {
|
|
59
|
+
coins.sort((a, b) => b.score - a.score);
|
|
60
|
+
}
|
|
61
|
+
else if (sortKey === "score_asc") {
|
|
62
|
+
coins.sort((a, b) => a.score - b.score);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
coins.sort((a, b) => a.symbol.localeCompare(b.symbol));
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: "text",
|
|
71
|
+
text: JSON.stringify({
|
|
72
|
+
stablecoins: coins,
|
|
73
|
+
count: coins.length,
|
|
74
|
+
formula_version: data.formula_version ?? "sii-v1.0.0",
|
|
75
|
+
timestamp: data.timestamp ?? new Date().toISOString(),
|
|
76
|
+
methodology_summary: data.methodology_summary ??
|
|
77
|
+
"SII = 0.30×Peg + 0.25×Liquidity + 0.15×Flows + 0.10×Distribution + 0.20×Structural",
|
|
78
|
+
}, null, 2),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return {
|
|
85
|
+
content: [
|
|
86
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
server.registerTool("get_stablecoin_detail", {
|
|
92
|
+
description: "Full score breakdown for a specific stablecoin including category scores, structural subscores, and methodology version. Use to deep-dive into why an asset scored the way it did.",
|
|
93
|
+
inputSchema: z.object({
|
|
94
|
+
coin: z
|
|
95
|
+
.string()
|
|
96
|
+
.describe("Stablecoin identifier (e.g. 'usdc', 'usdt', 'dai')"),
|
|
97
|
+
}),
|
|
98
|
+
annotations: TOOL_ANNOTATIONS,
|
|
99
|
+
}, async ({ coin }) => {
|
|
100
|
+
try {
|
|
101
|
+
const data = await fetchScoreDetail(coin);
|
|
102
|
+
if (data.__status === 404) {
|
|
103
|
+
return {
|
|
104
|
+
content: [
|
|
105
|
+
{
|
|
106
|
+
type: "text",
|
|
107
|
+
text: JSON.stringify({
|
|
108
|
+
error: false,
|
|
109
|
+
is_scored: false,
|
|
110
|
+
symbol: coin.toUpperCase(),
|
|
111
|
+
message: "This stablecoin is not yet scored by SII. It may appear in the scoring backlog.",
|
|
112
|
+
}),
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const cats = data.categories ?? {};
|
|
118
|
+
const catScores = {};
|
|
119
|
+
for (const [k, v] of Object.entries(cats)) {
|
|
120
|
+
const s = getCategoryScore(v);
|
|
121
|
+
if (s != null)
|
|
122
|
+
catScores[k] = s;
|
|
123
|
+
}
|
|
124
|
+
let weakest;
|
|
125
|
+
let strongest;
|
|
126
|
+
if (Object.keys(catScores).length > 0) {
|
|
127
|
+
weakest = Object.entries(catScores).sort(([, a], [, b]) => a - b)[0]?.[0];
|
|
128
|
+
strongest = Object.entries(catScores).sort(([, a], [, b]) => b - a)[0]?.[0];
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: JSON.stringify({
|
|
135
|
+
...data,
|
|
136
|
+
weakest_category: data.weakest_category ?? weakest,
|
|
137
|
+
strongest_category: data.strongest_category ?? strongest,
|
|
138
|
+
}, null, 2),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return {
|
|
145
|
+
content: [
|
|
146
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
server.registerTool("get_wallet_risk", {
|
|
152
|
+
description: "Get risk profile for a specific Ethereum wallet — composite risk score, concentration risk, coverage quality, dominant holdings. Use for counterparty due diligence before a transaction.",
|
|
153
|
+
inputSchema: z.object({
|
|
154
|
+
address: z
|
|
155
|
+
.string()
|
|
156
|
+
.regex(/^0x/i, "Address must start with 0x")
|
|
157
|
+
.describe("Ethereum wallet address (0x-prefixed, 42 characters)"),
|
|
158
|
+
}),
|
|
159
|
+
annotations: TOOL_ANNOTATIONS,
|
|
160
|
+
}, async ({ address }) => {
|
|
161
|
+
try {
|
|
162
|
+
const data = await fetchWalletProfile(address);
|
|
163
|
+
if (data.__status === 404 || data.found_in_index === false) {
|
|
164
|
+
return {
|
|
165
|
+
content: [
|
|
166
|
+
{
|
|
167
|
+
type: "text",
|
|
168
|
+
text: JSON.stringify({
|
|
169
|
+
error: false,
|
|
170
|
+
found_in_index: false,
|
|
171
|
+
address,
|
|
172
|
+
message: "Wallet not yet indexed by Basis. Only wallets with stablecoin holdings are indexed.",
|
|
173
|
+
}),
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const totalVal = formatMoney(data.total_stablecoin_value);
|
|
179
|
+
const dominantPct = data.concentration?.dominant_asset_pct?.toFixed(1) ?? "?";
|
|
180
|
+
const dominantAsset = data.concentration?.dominant_asset ?? "unknown";
|
|
181
|
+
const unscoredPct = data.coverage?.unscored_pct?.toFixed(1) ?? "0";
|
|
182
|
+
const result = {
|
|
183
|
+
...data,
|
|
184
|
+
found_in_index: true,
|
|
185
|
+
concentration: {
|
|
186
|
+
...data.concentration,
|
|
187
|
+
interpretation: data.concentration?.interpretation ??
|
|
188
|
+
`${dominantPct}% concentrated in ${dominantAsset}`,
|
|
189
|
+
},
|
|
190
|
+
coverage: {
|
|
191
|
+
...data.coverage,
|
|
192
|
+
interpretation: data.coverage?.interpretation ??
|
|
193
|
+
`${(100 - parseFloat(unscoredPct)).toFixed(1)}% of stablecoin value has SII coverage`,
|
|
194
|
+
},
|
|
195
|
+
risk_interpretation: `This wallet holds ${totalVal} in stablecoins with a ${data.risk_grade ?? "?"} risk grade. ` +
|
|
196
|
+
`Primary exposure is ${dominantAsset} (${dominantPct}%). ` +
|
|
197
|
+
`Coverage is ${data.coverage?.quality ?? "unknown"} with ${(100 - parseFloat(unscoredPct)).toFixed(1)}% of value scored by SII.`,
|
|
198
|
+
};
|
|
199
|
+
return {
|
|
200
|
+
content: [
|
|
201
|
+
{
|
|
202
|
+
type: "text",
|
|
203
|
+
text: JSON.stringify(result, null, 2),
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return {
|
|
210
|
+
content: [
|
|
211
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
server.registerTool("get_wallet_holdings", {
|
|
217
|
+
description: "Detailed holdings breakdown for an Ethereum wallet with per-asset SII scores. Use to understand exactly what a wallet holds and identify unscored exposure.",
|
|
218
|
+
inputSchema: z.object({
|
|
219
|
+
address: z
|
|
220
|
+
.string()
|
|
221
|
+
.describe("Ethereum wallet address (0x-prefixed)"),
|
|
222
|
+
}),
|
|
223
|
+
annotations: TOOL_ANNOTATIONS,
|
|
224
|
+
}, async ({ address }) => {
|
|
225
|
+
try {
|
|
226
|
+
const data = await fetchWalletProfile(address);
|
|
227
|
+
if (data.__status === 404 || data.found_in_index === false) {
|
|
228
|
+
return {
|
|
229
|
+
content: [
|
|
230
|
+
{
|
|
231
|
+
type: "text",
|
|
232
|
+
text: JSON.stringify({
|
|
233
|
+
error: false,
|
|
234
|
+
found_in_index: false,
|
|
235
|
+
address,
|
|
236
|
+
message: "Wallet not yet indexed by Basis. Only wallets with stablecoin holdings are indexed.",
|
|
237
|
+
}),
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const holdings = (data.holdings ?? []).map((h) => {
|
|
243
|
+
const pct = h.pct_of_wallet?.toFixed(1) ?? "?";
|
|
244
|
+
let risk_contribution;
|
|
245
|
+
if (h.is_scored && h.sii_grade) {
|
|
246
|
+
risk_contribution = `${h.sii_grade} grade. ${pct}% of portfolio.`;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
risk_contribution = `UNSCORED — no SII coverage. ${pct}% exposure without risk assessment.`;
|
|
250
|
+
}
|
|
251
|
+
return { ...h, risk_contribution };
|
|
252
|
+
});
|
|
253
|
+
const scoredValue = holdings
|
|
254
|
+
.filter((h) => h.is_scored)
|
|
255
|
+
.reduce((sum, h) => sum + (h.value_usd ?? 0), 0);
|
|
256
|
+
const unscoredValue = holdings
|
|
257
|
+
.filter((h) => !h.is_scored)
|
|
258
|
+
.reduce((sum, h) => sum + (h.value_usd ?? 0), 0);
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{
|
|
262
|
+
type: "text",
|
|
263
|
+
text: JSON.stringify({
|
|
264
|
+
address,
|
|
265
|
+
total_stablecoin_value: data.total_stablecoin_value,
|
|
266
|
+
holdings,
|
|
267
|
+
scored_value: scoredValue,
|
|
268
|
+
unscored_value: unscoredValue,
|
|
269
|
+
indexed_at: data.last_indexed_at,
|
|
270
|
+
}, null, 2),
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return {
|
|
277
|
+
content: [
|
|
278
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
279
|
+
],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
server.registerTool("get_riskiest_wallets", {
|
|
284
|
+
description: "Wallets with the most capital at risk — lowest risk scores weighted by total value. Use for systemic risk monitoring and identifying wallets most impacted by a stablecoin failure.",
|
|
285
|
+
inputSchema: z.object({
|
|
286
|
+
limit: z
|
|
287
|
+
.number()
|
|
288
|
+
.int()
|
|
289
|
+
.min(1)
|
|
290
|
+
.max(100)
|
|
291
|
+
.optional()
|
|
292
|
+
.default(20)
|
|
293
|
+
.describe("Number of wallets to return (1–100, default 20)"),
|
|
294
|
+
}),
|
|
295
|
+
annotations: TOOL_ANNOTATIONS,
|
|
296
|
+
}, async ({ limit }) => {
|
|
297
|
+
try {
|
|
298
|
+
const data = await fetchRiskiestWallets(limit ?? 20);
|
|
299
|
+
const wallets = (data.wallets ?? []).map((w) => {
|
|
300
|
+
const val = formatMoney(w.total_stablecoin_value);
|
|
301
|
+
const unscoredVal = formatMoney(((w.unscored_pct ?? 0) / 100) * (w.total_stablecoin_value ?? 0));
|
|
302
|
+
const interpretation = w.capital_at_risk_interpretation ??
|
|
303
|
+
`${val} in stablecoins with ${w.risk_grade} grade. ` +
|
|
304
|
+
`${w.dominant_asset_pct?.toFixed(1) ?? "?"}% concentrated in ${w.dominant_asset ?? "unknown"}. ` +
|
|
305
|
+
`${unscoredVal} in unscored assets.`;
|
|
306
|
+
return { ...w, capital_at_risk_interpretation: interpretation };
|
|
307
|
+
});
|
|
308
|
+
const totalAtRisk = data.total_at_risk_capital ??
|
|
309
|
+
wallets.reduce((s, w) => s + (w.total_stablecoin_value ?? 0), 0);
|
|
310
|
+
return {
|
|
311
|
+
content: [
|
|
312
|
+
{
|
|
313
|
+
type: "text",
|
|
314
|
+
text: JSON.stringify({
|
|
315
|
+
wallets,
|
|
316
|
+
count: wallets.length,
|
|
317
|
+
total_at_risk_capital: totalAtRisk,
|
|
318
|
+
timestamp: data.timestamp ?? new Date().toISOString(),
|
|
319
|
+
}, null, 2),
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return {
|
|
326
|
+
content: [
|
|
327
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
328
|
+
],
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
server.registerTool("get_scoring_backlog", {
|
|
333
|
+
description: "Unscored stablecoin assets ranked by total capital exposure across all indexed wallets. Shows which unscored assets represent the most risk.",
|
|
334
|
+
inputSchema: z.object({
|
|
335
|
+
limit: z
|
|
336
|
+
.number()
|
|
337
|
+
.int()
|
|
338
|
+
.min(1)
|
|
339
|
+
.max(100)
|
|
340
|
+
.optional()
|
|
341
|
+
.default(20)
|
|
342
|
+
.describe("Number of backlog items to return (1–100, default 20)"),
|
|
343
|
+
}),
|
|
344
|
+
annotations: TOOL_ANNOTATIONS,
|
|
345
|
+
}, async ({ limit }) => {
|
|
346
|
+
try {
|
|
347
|
+
const data = await fetchBacklog(limit ?? 20);
|
|
348
|
+
const items = (data.backlog ?? []).map((item) => {
|
|
349
|
+
const totalVal = formatMoney(item.total_value_held);
|
|
350
|
+
const maxVal = formatMoney(item.max_single_holding);
|
|
351
|
+
const interpretation = item.coverage_gap_interpretation ??
|
|
352
|
+
`${totalVal} across ${item.wallets_holding ?? 0} wallets has no SII coverage. Largest single exposure: ${maxVal}.`;
|
|
353
|
+
return { ...item, coverage_gap_interpretation: interpretation };
|
|
354
|
+
});
|
|
355
|
+
const totalUnscored = data.total_unscored_value ??
|
|
356
|
+
items.reduce((s, i) => s + (i.total_value_held ?? 0), 0);
|
|
357
|
+
return {
|
|
358
|
+
content: [
|
|
359
|
+
{
|
|
360
|
+
type: "text",
|
|
361
|
+
text: JSON.stringify({
|
|
362
|
+
backlog: items,
|
|
363
|
+
count: items.length,
|
|
364
|
+
total_unscored_value: totalUnscored,
|
|
365
|
+
timestamp: data.timestamp ?? new Date().toISOString(),
|
|
366
|
+
}, null, 2),
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return {
|
|
373
|
+
content: [
|
|
374
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
375
|
+
],
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
server.registerTool("check_transaction_risk", {
|
|
380
|
+
description: "Composite risk assessment for a proposed stablecoin transaction — evaluates the asset, sender wallet, and receiver wallet. The core agent decision gate before executing any stablecoin transfer, swap, or deposit.",
|
|
381
|
+
inputSchema: z.object({
|
|
382
|
+
from_address: z
|
|
383
|
+
.string()
|
|
384
|
+
.describe("Sender's Ethereum wallet address"),
|
|
385
|
+
to_address: z
|
|
386
|
+
.string()
|
|
387
|
+
.describe("Receiver's Ethereum wallet address"),
|
|
388
|
+
asset_symbol: z
|
|
389
|
+
.string()
|
|
390
|
+
.describe("Symbol of the stablecoin being transferred (e.g. 'usdc', 'dai')"),
|
|
391
|
+
}),
|
|
392
|
+
annotations: TOOL_ANNOTATIONS,
|
|
393
|
+
}, async ({ from_address, to_address, asset_symbol }) => {
|
|
394
|
+
try {
|
|
395
|
+
const [assetResult, senderResult, receiverResult] = await Promise.all([
|
|
396
|
+
fetchScoreDetail(asset_symbol),
|
|
397
|
+
fetchWalletProfile(from_address),
|
|
398
|
+
fetchWalletProfile(to_address),
|
|
399
|
+
]);
|
|
400
|
+
const assetNotFound = assetResult.__status === 404;
|
|
401
|
+
const senderNotFound = senderResult.__status === 404 ||
|
|
402
|
+
senderResult.found_in_index === false;
|
|
403
|
+
const receiverNotFound = receiverResult.__status === 404 ||
|
|
404
|
+
receiverResult.found_in_index === false;
|
|
405
|
+
const assetGrade = assetResult.grade;
|
|
406
|
+
const senderGrade = senderResult.risk_grade;
|
|
407
|
+
const receiverGrade = receiverResult.risk_grade;
|
|
408
|
+
const senderCoverage = senderResult.coverage?.quality;
|
|
409
|
+
const receiverCoverage = receiverResult.coverage?.quality;
|
|
410
|
+
let overall_assessment;
|
|
411
|
+
const risk_factors = [];
|
|
412
|
+
if (assetNotFound) {
|
|
413
|
+
overall_assessment = "UNKNOWN";
|
|
414
|
+
risk_factors.push(`Asset ${asset_symbol.toUpperCase()} is not scored by SII — risk cannot be assessed.`);
|
|
415
|
+
}
|
|
416
|
+
else if (gradeAtLeast(assetGrade, "C+") === false ||
|
|
417
|
+
(!senderNotFound && !gradeAtLeast(senderGrade, "C")) ||
|
|
418
|
+
(!receiverNotFound && !gradeAtLeast(receiverGrade, "C")) ||
|
|
419
|
+
senderNotFound ||
|
|
420
|
+
receiverNotFound) {
|
|
421
|
+
overall_assessment = "HIGH_RISK";
|
|
422
|
+
}
|
|
423
|
+
else if (gradeAtLeast(assetGrade, "A-") &&
|
|
424
|
+
gradeAtLeast(senderGrade, "B") &&
|
|
425
|
+
gradeAtLeast(receiverGrade, "B") &&
|
|
426
|
+
(senderCoverage === "full" || senderCoverage === "high") &&
|
|
427
|
+
(receiverCoverage === "full" || receiverCoverage === "high")) {
|
|
428
|
+
overall_assessment = "LOW_RISK";
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
overall_assessment = "MEDIUM_RISK";
|
|
432
|
+
}
|
|
433
|
+
if (!assetNotFound) {
|
|
434
|
+
if (gradeAtLeast(assetGrade, "B+")) {
|
|
435
|
+
risk_factors.push(`Asset ${assetResult.symbol ?? asset_symbol.toUpperCase()} has strong SII score (${assetResult.score?.toFixed(1) ?? "?"}, ${assetGrade}).`);
|
|
436
|
+
}
|
|
437
|
+
else if (gradeAtLeast(assetGrade, "C+")) {
|
|
438
|
+
risk_factors.push(`Asset ${assetResult.symbol ?? asset_symbol.toUpperCase()} has moderate SII score (${assetResult.score?.toFixed(1) ?? "?"}, ${assetGrade}).`);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
risk_factors.push(`Asset ${assetResult.symbol ?? asset_symbol.toUpperCase()} has weak SII score (${assetResult.score?.toFixed(1) ?? "?"}, ${assetGrade}).`);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (senderNotFound) {
|
|
445
|
+
risk_factors.push("Sender wallet not found in index — no stablecoin exposure data available.");
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
const conc = senderResult.concentration;
|
|
449
|
+
if (conc?.grade && !gradeAtLeast(conc.grade, "B")) {
|
|
450
|
+
risk_factors.push(`Sender wallet has high concentration risk (${conc.dominant_asset_pct?.toFixed(1) ?? "?"}% in ${conc.dominant_asset ?? "unknown"}).`);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
risk_factors.push(`Sender wallet risk grade: ${senderGrade ?? "?"}.`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if (receiverNotFound) {
|
|
457
|
+
risk_factors.push("Receiver wallet not found in index — no stablecoin exposure data available.");
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
const unscPct = receiverResult.coverage?.unscored_pct ?? 0;
|
|
461
|
+
if (unscPct > 10) {
|
|
462
|
+
risk_factors.push(`Receiver wallet has ${unscPct.toFixed(1)}% unscored stablecoin exposure (${formatMoney(((unscPct / 100) * (receiverResult.total_stablecoin_value ?? 0)))}).`);
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
risk_factors.push(`Receiver wallet risk grade: ${receiverGrade ?? "?"}.`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
const recommendationMap = {
|
|
469
|
+
LOW_RISK: "Asset is well-scored and both wallets have strong risk profiles. Proceed with confidence.",
|
|
470
|
+
MEDIUM_RISK: "Proceed with awareness — review the risk factors below before executing.",
|
|
471
|
+
HIGH_RISK: "Do not proceed without further review. One or more critical risk factors identified.",
|
|
472
|
+
UNKNOWN: "Cannot assess — asset is not yet scored by SII. Check the scoring backlog.",
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
content: [
|
|
476
|
+
{
|
|
477
|
+
type: "text",
|
|
478
|
+
text: JSON.stringify({
|
|
479
|
+
transaction_risk: {
|
|
480
|
+
overall_assessment,
|
|
481
|
+
recommendation: recommendationMap[overall_assessment],
|
|
482
|
+
risk_factors,
|
|
483
|
+
},
|
|
484
|
+
asset: assetNotFound
|
|
485
|
+
? {
|
|
486
|
+
symbol: asset_symbol.toUpperCase(),
|
|
487
|
+
is_scored: false,
|
|
488
|
+
message: "Not scored by SII",
|
|
489
|
+
}
|
|
490
|
+
: {
|
|
491
|
+
symbol: assetResult.symbol,
|
|
492
|
+
sii_score: assetResult.score,
|
|
493
|
+
sii_grade: assetGrade,
|
|
494
|
+
is_scored: true,
|
|
495
|
+
weakest_category: assetResult.weakest_category,
|
|
496
|
+
},
|
|
497
|
+
sender: senderNotFound
|
|
498
|
+
? { address: from_address, found_in_index: false }
|
|
499
|
+
: {
|
|
500
|
+
address: from_address,
|
|
501
|
+
risk_score: senderResult.risk_score,
|
|
502
|
+
risk_grade: senderGrade,
|
|
503
|
+
total_stablecoin_value: senderResult.total_stablecoin_value,
|
|
504
|
+
coverage_quality: senderCoverage,
|
|
505
|
+
found_in_index: true,
|
|
506
|
+
},
|
|
507
|
+
receiver: receiverNotFound
|
|
508
|
+
? { address: to_address, found_in_index: false }
|
|
509
|
+
: {
|
|
510
|
+
address: to_address,
|
|
511
|
+
risk_score: receiverResult.risk_score,
|
|
512
|
+
risk_grade: receiverGrade,
|
|
513
|
+
total_stablecoin_value: receiverResult.total_stablecoin_value,
|
|
514
|
+
coverage_quality: receiverCoverage,
|
|
515
|
+
unscored_pct: receiverResult.coverage?.unscored_pct,
|
|
516
|
+
found_in_index: true,
|
|
517
|
+
},
|
|
518
|
+
timestamp: new Date().toISOString(),
|
|
519
|
+
}, null, 2),
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
return {
|
|
526
|
+
content: [
|
|
527
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
528
|
+
],
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
server.registerTool("get_methodology", {
|
|
533
|
+
description: "Returns the current SII formula, category weights, structural subweights, grade scale, data sources, and version information. Use for explaining scoring decisions and audit transparency.",
|
|
534
|
+
inputSchema: z.object({}),
|
|
535
|
+
annotations: TOOL_ANNOTATIONS,
|
|
536
|
+
}, async () => {
|
|
537
|
+
try {
|
|
538
|
+
const data = await fetchMethodology();
|
|
539
|
+
const result = {
|
|
540
|
+
...data,
|
|
541
|
+
verification: {
|
|
542
|
+
methodology_is_public: true,
|
|
543
|
+
scores_are_deterministic: true,
|
|
544
|
+
no_customer_specific_adjustments: true,
|
|
545
|
+
methodology_locked_since: "2026-01-15",
|
|
546
|
+
...(data.verification ?? {}),
|
|
547
|
+
},
|
|
548
|
+
wallet_scoring: {
|
|
549
|
+
version: "wallet-v1.0.0",
|
|
550
|
+
method: "Value-weighted average of SII scores across scored holdings",
|
|
551
|
+
concentration: "Herfindahl-Hirschman Index normalized to 0–100",
|
|
552
|
+
...(data.wallet_scoring ?? {}),
|
|
553
|
+
},
|
|
554
|
+
};
|
|
555
|
+
return {
|
|
556
|
+
content: [
|
|
557
|
+
{
|
|
558
|
+
type: "text",
|
|
559
|
+
text: JSON.stringify(result, null, 2),
|
|
560
|
+
},
|
|
561
|
+
],
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
return {
|
|
566
|
+
content: [
|
|
567
|
+
{ type: "text", text: JSON.stringify(API_ERROR_RESPONSE) },
|
|
568
|
+
],
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@basis-protocol/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Basis Protocol — verifiable risk intelligence for stablecoins and wallet risk profiles",
|
|
5
|
+
"keywords": ["mcp", "risk", "stablecoin", "defi", "wallet", "basis-protocol"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "https://github.com/shlok-lgtm/basis-mcp",
|
|
8
|
+
"files": ["build"],
|
|
9
|
+
"private": false,
|
|
10
|
+
"type": "module",
|
|
11
|
+
"bin": {
|
|
12
|
+
"basis-mcp": "./build/index.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "node --enable-source-maps ./build/index.js",
|
|
17
|
+
"start": "node --enable-source-maps ./build/index.js",
|
|
18
|
+
"start:http": "node --enable-source-maps ./build/index.js --http",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
23
|
+
"express": "^5",
|
|
24
|
+
"zod": "^3.23.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/express": "^5.0.6",
|
|
28
|
+
"@types/node": "^22.0.0",
|
|
29
|
+
"typescript": "~5.9.2"
|
|
30
|
+
}
|
|
31
|
+
}
|