@forgemeshlabs/anomaly-mcp 0.1.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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ForgeMesh Labs
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.
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # Anomaly Tracker MCP
2
+
3
+ Blockchain event sequence anomaly detection for MCP clients and x402-powered agents.
4
+
5
+ This MCP server gives AI agents access to the ForgeMesh Anomaly Tracker API, which converts blockchain event streams into symbol sequences and scores them for anomalies using NASA ARC-16053-1 SequenceMiner. Returns a human-readable story label and anomaly score (0-100), not just a number.
6
+
7
+ This package is a thin client around the hosted API:
8
+
9
+ `https://anomaly.forgemesh.io`
10
+
11
+ Architecture:
12
+
13
+ `Agent/MCP client -> this MCP server -> ForgeMesh Anomaly Tracker API`
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install -g @forgemeshlabs/anomaly-mcp
19
+ ```
20
+
21
+ Or run directly:
22
+
23
+ ```bash
24
+ npx -y @forgemeshlabs/anomaly-mcp
25
+ ```
26
+
27
+ ## Claude Desktop
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "anomaly-tracker": {
33
+ "command": "npx",
34
+ "args": ["-y", "@forgemeshlabs/anomaly-mcp"],
35
+ "env": {
36
+ "ANOMALY_API_BASE": "https://anomaly.forgemesh.io"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Tools
44
+
45
+ | Tool | Description | Cost |
46
+ | --- | --- | --- |
47
+ | `get_api_status` | API health check | Free |
48
+ | `get_discovery_metadata` | Fetch llms.txt, openapi.json, or x402.json | Free |
49
+ | `inspect_x402_challenge` | Inspect x402 payment challenge without settling | Free |
50
+ | `detect_sequence_anomaly` | Score a blockchain event window for sequence anomalies | $0.05 USDC |
51
+ | `get_model_status` | SequenceMiner model health and training stats per chain | $0.01 USDC |
52
+
53
+ ## Anomaly Detection
54
+
55
+ The `detect_sequence_anomaly` tool accepts:
56
+
57
+ - **domain**: Event domain (`financial` is currently live)
58
+ - **chain**: `ethereum`, `base`, or `arbitrum`
59
+ - **window**: Lookback period: `1h`, `4h`, `24h`, or `168h`
60
+
61
+ Returns:
62
+ - **sequence_score**: 0 (normal) to 100 (highly anomalous)
63
+ - **story**: Human-readable label like "Supply Expansion", "Exchange Drain", "Normal Activity"
64
+ - **novelty**: `low`, `medium`, `high`, or `extreme`
65
+ - **peak_window**: The most anomalous symbol sequence found
66
+ - **possible_failure_modes**: What could go wrong if this pattern continues
67
+
68
+ ## Symbol Alphabet
69
+
70
+ The financial domain tracks 16 event types across whale wallets, exchanges, bridges, and stablecoin issuers:
71
+
72
+ `WHALE_BUY`, `WHALE_SELL`, `CEX_INFLOW`, `CEX_OUTFLOW`, `BRIDGE_IN`, `BRIDGE_OUT`, `DEX_SWAP`, `DEX_LIQUIDITY_ADD`, `DEX_LIQUIDITY_REMOVE`, `STABLECOIN_MINT`, `STABLECOIN_REDEEM`, `STABLECOIN_BURN`, `TOKEN_MINT`, `TOKEN_BURN`, `FUNDING_SPIKE`, `LIQUIDATION`
73
+
74
+ ## Payment
75
+
76
+ Paid endpoints use x402 protocol. Agents pay per call in USDC on Base mainnet. No API key needed.
77
+
78
+ By default, paid endpoints return x402 challenge metadata (pricing, network, wallet) without settling. To settle payments, configure a wallet private key in your agent's x402 client.
79
+
80
+ ## Environment Variables
81
+
82
+ | Variable | Description | Default |
83
+ | --- | --- | --- |
84
+ | `ANOMALY_API_BASE` | Hosted API base URL | `https://anomaly.forgemesh.io` |
85
+
86
+ ## Links
87
+
88
+ - Hosted API: https://anomaly.forgemesh.io
89
+ - ForgeMesh: https://forgemesh.io
90
+ - npm: https://www.npmjs.com/package/@forgemeshlabs/anomaly-mcp
91
+ - GitHub: https://github.com/forgemeshlabs/anomaly-mcp
92
+
93
+ ## License
94
+
95
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
+ import { callTool, tools } from "./tools.js";
6
+ const server = new Server({
7
+ name: "anomaly-mcp",
8
+ version: "0.1.0"
9
+ }, {
10
+ capabilities: {
11
+ tools: {}
12
+ }
13
+ });
14
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
15
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
16
+ const result = await callTool(request.params.name, isObject(request.params.arguments) ? request.params.arguments : {});
17
+ return {
18
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
19
+ };
20
+ });
21
+ const transport = new StdioServerTransport();
22
+ await server.connect(transport);
23
+ function isObject(value) {
24
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25
+ }
@@ -0,0 +1,78 @@
1
+ export declare const tools: ({
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ file?: undefined;
8
+ endpoint?: undefined;
9
+ domain?: undefined;
10
+ chain?: undefined;
11
+ window?: undefined;
12
+ };
13
+ required?: undefined;
14
+ };
15
+ } | {
16
+ name: string;
17
+ description: string;
18
+ inputSchema: {
19
+ type: "object";
20
+ properties: {
21
+ file: {
22
+ type: string;
23
+ enum: string[];
24
+ description: string;
25
+ };
26
+ endpoint?: undefined;
27
+ domain?: undefined;
28
+ chain?: undefined;
29
+ window?: undefined;
30
+ };
31
+ required: string[];
32
+ };
33
+ } | {
34
+ name: string;
35
+ description: string;
36
+ inputSchema: {
37
+ type: "object";
38
+ properties: {
39
+ endpoint: {
40
+ type: string;
41
+ enum: string[];
42
+ description: string;
43
+ };
44
+ file?: undefined;
45
+ domain?: undefined;
46
+ chain?: undefined;
47
+ window?: undefined;
48
+ };
49
+ required: string[];
50
+ };
51
+ } | {
52
+ name: string;
53
+ description: string;
54
+ inputSchema: {
55
+ type: "object";
56
+ properties: {
57
+ domain: {
58
+ type: string;
59
+ enum: string[];
60
+ description: string;
61
+ };
62
+ chain: {
63
+ type: string;
64
+ enum: string[];
65
+ description: string;
66
+ };
67
+ window: {
68
+ type: string;
69
+ enum: string[];
70
+ description: string;
71
+ };
72
+ file?: undefined;
73
+ endpoint?: undefined;
74
+ };
75
+ required?: undefined;
76
+ };
77
+ })[];
78
+ export declare function callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
package/dist/tools.js ADDED
@@ -0,0 +1,154 @@
1
+ const API_BASE = process.env.ANOMALY_API_BASE || "https://anomaly.forgemesh.io";
2
+ export const tools = [
3
+ {
4
+ name: "get_api_status",
5
+ description: "Check ForgeMesh Anomaly Tracker API health.",
6
+ inputSchema: { type: "object", properties: {} }
7
+ },
8
+ {
9
+ name: "get_discovery_metadata",
10
+ description: "Fetch agent discovery files: llms.txt, openapi.json, or .well-known/x402.json.",
11
+ inputSchema: {
12
+ type: "object",
13
+ properties: {
14
+ file: {
15
+ type: "string",
16
+ enum: ["llms.txt", "openapi.json", "x402.json"],
17
+ description: "Which discovery file to fetch"
18
+ }
19
+ },
20
+ required: ["file"]
21
+ }
22
+ },
23
+ {
24
+ name: "inspect_x402_challenge",
25
+ description: "Inspect the x402 payment challenge for a paid endpoint without settling. Returns pricing, network, wallet, and Bazaar metadata.",
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {
29
+ endpoint: {
30
+ type: "string",
31
+ enum: ["sequence-anomaly", "status"],
32
+ description: "Which paid endpoint to inspect"
33
+ }
34
+ },
35
+ required: ["endpoint"]
36
+ }
37
+ },
38
+ {
39
+ name: "detect_sequence_anomaly",
40
+ description: "Score a blockchain event window for sequence anomalies using NASA ARC-16053-1 SequenceMiner. Returns a story label, anomaly score (0-100), novelty level, and the peak anomalous symbol window. Costs $0.05 USDC on Base mainnet.",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {
44
+ domain: {
45
+ type: "string",
46
+ enum: ["financial"],
47
+ description: "Event domain. Currently only 'financial' is live."
48
+ },
49
+ chain: {
50
+ type: "string",
51
+ enum: ["ethereum", "base", "arbitrum"],
52
+ description: "Blockchain to analyze (default: ethereum)"
53
+ },
54
+ window: {
55
+ type: "string",
56
+ enum: ["1h", "4h", "24h", "168h"],
57
+ description: "Lookback window (default: 24h)"
58
+ }
59
+ }
60
+ }
61
+ },
62
+ {
63
+ name: "get_model_status",
64
+ description: "Get SequenceMiner model health and training stats per chain. Costs $0.01 USDC on Base mainnet.",
65
+ inputSchema: {
66
+ type: "object",
67
+ properties: {}
68
+ }
69
+ }
70
+ ];
71
+ async function apiGet(path) {
72
+ const res = await fetch(`${API_BASE}${path}`);
73
+ if (res.status === 402) {
74
+ const challenge = res.headers.get("payment-required");
75
+ let decoded = null;
76
+ if (challenge) {
77
+ try {
78
+ decoded = JSON.parse(Buffer.from(challenge, "base64").toString());
79
+ }
80
+ catch { }
81
+ }
82
+ return {
83
+ x402_status: 402,
84
+ message: "Payment required — this endpoint costs USDC on Base mainnet via x402 protocol.",
85
+ challenge: decoded
86
+ };
87
+ }
88
+ return res.json();
89
+ }
90
+ async function apiPost(path, body) {
91
+ const res = await fetch(`${API_BASE}${path}`, {
92
+ method: "POST",
93
+ headers: { "Content-Type": "application/json" },
94
+ body: JSON.stringify(body)
95
+ });
96
+ if (res.status === 402) {
97
+ const challenge = res.headers.get("payment-required");
98
+ let decoded = null;
99
+ if (challenge) {
100
+ try {
101
+ decoded = JSON.parse(Buffer.from(challenge, "base64").toString());
102
+ }
103
+ catch { }
104
+ }
105
+ return {
106
+ x402_status: 402,
107
+ message: "Payment required — this endpoint costs USDC on Base mainnet via x402 protocol.",
108
+ challenge: decoded
109
+ };
110
+ }
111
+ return res.json();
112
+ }
113
+ export async function callTool(name, args) {
114
+ switch (name) {
115
+ case "get_api_status":
116
+ return apiGet("/health");
117
+ case "get_discovery_metadata": {
118
+ const file = args.file;
119
+ const pathMap = {
120
+ "llms.txt": "/llms.txt",
121
+ "openapi.json": "/openapi.json",
122
+ "x402.json": "/.well-known/x402.json"
123
+ };
124
+ const path = pathMap[file];
125
+ if (!path)
126
+ return { error: "Unknown file. Use: llms.txt, openapi.json, or x402.json" };
127
+ if (file === "llms.txt") {
128
+ const res = await fetch(`${API_BASE}${path}`);
129
+ return { content: await res.text() };
130
+ }
131
+ return apiGet(path);
132
+ }
133
+ case "inspect_x402_challenge": {
134
+ const ep = args.endpoint;
135
+ if (ep === "sequence-anomaly") {
136
+ return apiPost("/api/sequence-anomaly", { domain: "financial", chain: "ethereum", window: "24h" });
137
+ }
138
+ if (ep === "status") {
139
+ return apiGet("/api/sequence-anomaly/status");
140
+ }
141
+ return { error: "Unknown endpoint. Use: sequence-anomaly or status" };
142
+ }
143
+ case "detect_sequence_anomaly":
144
+ return apiPost("/api/sequence-anomaly", {
145
+ domain: args.domain || "financial",
146
+ chain: args.chain || "ethereum",
147
+ window: args.window || "24h"
148
+ });
149
+ case "get_model_status":
150
+ return apiGet("/api/sequence-anomaly/status");
151
+ default:
152
+ return { error: `Unknown tool: ${name}` };
153
+ }
154
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "anomaly-tracker": {
4
+ "command": "npx",
5
+ "args": ["-y", "@forgemeshlabs/anomaly-mcp"],
6
+ "env": {
7
+ "ANOMALY_API_BASE": "https://anomaly.forgemesh.io"
8
+ }
9
+ }
10
+ }
11
+ }
package/glama.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "clawdbotworker"
5
+ ]
6
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@forgemeshlabs/anomaly-mcp",
3
+ "version": "0.1.0",
4
+ "mcpName": "io.github.forgemeshlabs/anomaly-mcp",
5
+ "description": "Blockchain event sequence anomaly detection MCP server. Scores event streams using NASA ARC-16053-1 SequenceMiner via x402 micropayments.",
6
+ "type": "module",
7
+ "bin": {
8
+ "anomaly-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE.md",
14
+ "glama.json",
15
+ "server.json",
16
+ "smithery.yaml",
17
+ "docs",
18
+ "examples"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.json",
22
+ "typecheck": "tsc -p tsconfig.json --noEmit",
23
+ "start": "node dist/index.js",
24
+ "dev": "tsx src/index.ts"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "x402",
30
+ "agent-payments",
31
+ "anomaly-detection",
32
+ "sequence-mining",
33
+ "blockchain",
34
+ "ethereum",
35
+ "base",
36
+ "arbitrum",
37
+ "forgemesh",
38
+ "usdc",
39
+ "nasa",
40
+ "sequenceminer"
41
+ ],
42
+ "author": "forgemeshlabs",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/forgemeshlabs/anomaly-mcp.git"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/forgemeshlabs/anomaly-mcp/issues"
50
+ },
51
+ "homepage": "https://github.com/forgemeshlabs/anomaly-mcp#readme",
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "engines": {
56
+ "node": ">=20"
57
+ },
58
+ "devDependencies": {
59
+ "tsx": "^4.19.2",
60
+ "typescript": "^5.7.3"
61
+ },
62
+ "dependencies": {
63
+ "@modelcontextprotocol/sdk": "^1.29.0"
64
+ }
65
+ }
package/server.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.forgemeshlabs/anomaly-mcp",
4
+ "description": "Blockchain event sequence anomaly detection using NASA ARC-16053-1 SequenceMiner. Scores event streams and returns story labels via x402 micropayments.",
5
+ "repository": {
6
+ "url": "https://github.com/forgemeshlabs/anomaly-mcp",
7
+ "source": "github"
8
+ },
9
+ "version": "0.1.0",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "@forgemeshlabs/anomaly-mcp",
14
+ "version": "0.1.0",
15
+ "transport": {
16
+ "type": "stdio"
17
+ },
18
+ "environmentVariables": [
19
+ {
20
+ "name": "ANOMALY_API_BASE",
21
+ "description": "Optional hosted API base URL override. Defaults to https://anomaly.forgemesh.io.",
22
+ "isRequired": false,
23
+ "isSecret": false,
24
+ "format": "string"
25
+ }
26
+ ]
27
+ }
28
+ ]
29
+ }
package/smithery.yaml ADDED
@@ -0,0 +1,18 @@
1
+ startCommand:
2
+ type: stdio
3
+ configSchema:
4
+ type: object
5
+ properties:
6
+ apiBase:
7
+ type: string
8
+ description: Optional hosted API base URL override. Defaults to https://anomaly.forgemesh.io.
9
+ commandFunction: |-
10
+ (config) => ({
11
+ command: 'npx',
12
+ args: ['-y', '@forgemeshlabs/anomaly-mcp'],
13
+ env: {
14
+ ANOMALY_API_BASE: config.apiBase || 'https://anomaly.forgemesh.io'
15
+ }
16
+ })
17
+ exampleConfig:
18
+ apiBase: 'https://anomaly.forgemesh.io'