netintel-mcp 1.1.52 → 1.1.54
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 +21 -0
- package/README.md +21 -10
- package/dist/client.js +45 -5
- package/dist/index.js +42 -10
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Karim Gueye (NetIntel)
|
|
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
CHANGED
|
@@ -4,6 +4,17 @@ MCP server for NetIntel — 122 network intelligence tools for AI agents.
|
|
|
4
4
|
DNS, SSL, WHOIS, email security, cloud fingerprinting, OSINT and more.
|
|
5
5
|
Pay-per-call via x402 — the NetIntel API accepts USDC on Base or Solana; this MCP server pays on Base. No API keys needed — just a wallet with USDC.
|
|
6
6
|
|
|
7
|
+
## Install as a Claude Code plugin (recommended)
|
|
8
|
+
|
|
9
|
+
The plugin installs the MCP server **and** a skill that knows which NetIntel endpoint fits a task and what it costs, and prompts once for the agent wallet key (stored in Claude Code's secure storage, never in settings files):
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/plugin marketplace add kjgueye/netintel-mcp
|
|
13
|
+
/plugin install netintel@netintel
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then just ask — "is this IP malicious?", "does this domain have DMARC?", "fetch this URL as JSON" — and the tools pay per call from that wallet.
|
|
17
|
+
|
|
7
18
|
## Install
|
|
8
19
|
|
|
9
20
|
```bash
|
|
@@ -26,8 +37,8 @@ Or add manually to your Claude Desktop config:
|
|
|
26
37
|
```
|
|
27
38
|
|
|
28
39
|
## Requirements
|
|
29
|
-
-
|
|
30
|
-
-
|
|
40
|
+
- **Optional:** `EVM_PRIVATE_KEY` — a dedicated agent wallet holding USDC on Base mainnet (gasless; a few dollars is plenty). With it, every tool pays its listed price automatically.
|
|
41
|
+
- **Without a wallet** the server still runs: `netintel_dns_lookup`, `netintel_ssl_cert`, `netintel_whois_lookup`, `netintel_subnet_calc` and `netintel_email_auth` work free (about 30 calls/hour per client, then the normal price), and paid tools reply with what they cost and how to fund. `netintel_wallet_status` shows the wallet, its USDC balance and the free tools.
|
|
31
42
|
|
|
32
43
|
## Tools
|
|
33
44
|
|
|
@@ -35,7 +46,7 @@ Or add manually to your Claude Desktop config:
|
|
|
35
46
|
|
|
36
47
|
| Tool | Description | Price |
|
|
37
48
|
|------|-------------|-------|
|
|
38
|
-
| netintel_dns_lookup | DNS lookup
|
|
49
|
+
| netintel_dns_lookup | DNS lookup for any domain — resolve A, AAAA, MX, TXT, NS, CNAME, SOA… | $0.002 |
|
|
39
50
|
| netintel_ssl_analyze | Performs a TLS handshake to inspect the certificate chain, probes… | $0.007 |
|
|
40
51
|
| netintel_redirect_trace | Follows a URL through its full redirect chain (up to 20 hops)… | $0.01 |
|
|
41
52
|
| netintel_security_headers | Fetches a URL and evaluates 10 security-critical response headers (CSP… | $0.01 |
|
|
@@ -43,7 +54,7 @@ Or add manually to your Claude Desktop config:
|
|
|
43
54
|
| netintel_cloud_fingerprint | Fingerprints a domain's cloud infrastructure — DNS records, HTTP… | $0.01 |
|
|
44
55
|
| netintel_schema_parse | Extract structured data from any unstructured text into your own JSON… | $0.01 |
|
|
45
56
|
| netintel_asn_lookup | Resolves an IP address or domain to its Autonomous System Number (ASN)… | $0.03 |
|
|
46
|
-
| netintel_whois_lookup |
|
|
57
|
+
| netintel_whois_lookup | Domain registration lookup, WHOIS via RDAP — registrar, registration… | $0.003 |
|
|
47
58
|
| netintel_cert_transparency | Query the crt.sh certificate transparency log database to enumerate all… | $0.01 |
|
|
48
59
|
| netintel_subnet_calc | Calculates IPv4/IPv6 subnet details from CIDR notation —… | $0.005 |
|
|
49
60
|
| netintel_dns_propagation | Query a domain's DNS record across 10 geographically distributed public… | $0.03 |
|
|
@@ -60,7 +71,7 @@ Or add manually to your Claude Desktop config:
|
|
|
60
71
|
| netintel_rss_parser | Fetch and parse any RSS 2.0 or Atom feed URL and return structured… | $0.01 |
|
|
61
72
|
| netintel_username_check | Check username availability across 20+ social platforms and developer… | $0.03 |
|
|
62
73
|
| netintel_wayback_lookup | Query the Internet Archive Wayback Machine to check if a URL has ever… | $0.01 |
|
|
63
|
-
| netintel_ip_reputation |
|
|
74
|
+
| netintel_ip_reputation | IP reputation and malicious-IP check — screens an address against… | $0.05 |
|
|
64
75
|
| netintel_cron_parser | Parse any cron expression into a human-readable explanation, validate… | $0.03 |
|
|
65
76
|
| netintel_currency_exchange | Convert any amount between 32 fiat currencies (live European Central… | $0.01 |
|
|
66
77
|
| netintel_github_intel | Fetch public metadata for any GitHub repository — stars, forks, open… | $0.03 |
|
|
@@ -79,7 +90,7 @@ Or add manually to your Claude Desktop config:
|
|
|
79
90
|
| netintel_name_gen | Generate brandable startup/product names from a keyword using prefixes… | $0.05 |
|
|
80
91
|
| netintel_tld_price | Reference registration/renewal/transfer pricing from a curated table of… | $0.01 |
|
|
81
92
|
| netintel_typosquat | Generate common typo and look-alike variations of a domain and check… | $0.05 |
|
|
82
|
-
| netintel_classify |
|
|
93
|
+
| netintel_classify | Classify text into your own categories — zero-shot: supply 2–20 labels… | $0.005 |
|
|
83
94
|
| netintel_content_moderate | Moderate text content using Claude Haiku — flags categories like… | $0.005 |
|
|
84
95
|
| netintel_entity_extract | Extract named entities from text using Claude Haiku — people… | $0.05 |
|
|
85
96
|
| netintel_sentiment | Sentiment analysis API — analyze sentiment of text and get a text… | $0.002 |
|
|
@@ -99,7 +110,7 @@ Or add manually to your Claude Desktop config:
|
|
|
99
110
|
| netintel_markdown | Convert messy HTML or text into clean, well-structured Markdown using… | $0.03 |
|
|
100
111
|
| netintel_normalize | Conform messy or inconsistent JSON to a target schema using Claude… | $0.05 |
|
|
101
112
|
| netintel_text_to_json | Turn unstructured text into structured JSON matching a caller-supplied… | $0.05 |
|
|
102
|
-
| netintel_web | Extract
|
|
113
|
+
| netintel_web | Extract text from a web page or PDF as clean Markdown — HTML to… | $0.003 |
|
|
103
114
|
| netintel_money | Normalize any messy money string into a typed decimal amount plus ISO… | $0.01 |
|
|
104
115
|
| netintel_calendar | Turn event fields into a valid RFC 5545 .ics calendar file — handles… | $0.005 |
|
|
105
116
|
| netintel_event_classify | Cheap, fast "is this a dateable event?" filter for social and web text… | $0.02 |
|
|
@@ -134,7 +145,7 @@ Or add manually to your Claude Desktop config:
|
|
|
134
145
|
| netintel_v1_chat_completions | OpenAI-compatible chat completions gateway — standard… | $0.005 |
|
|
135
146
|
| netintel_crypto_market | Structured live crypto market data for ~50 top assets in one JSON call:… | $0.005 |
|
|
136
147
|
| netintel_gas_price | Live gas prices across Base, Ethereum, Arbitrum, Optimism, and Polygon… | $0.002 |
|
|
137
|
-
| netintel_crypto_price |
|
|
148
|
+
| netintel_crypto_price | Crypto prices for up to 25 coins in one call — live cryptocurrency spot… | $0.005 |
|
|
138
149
|
| netintel_crypto_ohlc | Historical OHLC candles for any major crypto asset — hourly or daily… | $0.02 |
|
|
139
150
|
| netintel_currency_exchange_batch | Convert one base currency to up to 30 targets in a single call — fiat… | $0.02 |
|
|
140
151
|
| netintel_currency_exchange_history | Daily historical exchange-rate series for any currency pair — fiat via… | $0.02 |
|
|
@@ -148,11 +159,11 @@ Or add manually to your Claude Desktop config:
|
|
|
148
159
|
| netintel_weather_forecast | Multi-day weather forecast for any city or lat/lon worldwide — up to 16… | $0.003 |
|
|
149
160
|
| netintel_prediction_markets | Live prediction-market odds from Polymarket — list the top active… | $0.005 |
|
|
150
161
|
| netintel_prediction_market | Full detail for ONE Polymarket prediction market by id or slug —… | $0.003 |
|
|
151
|
-
| netintel_ssl_cert |
|
|
162
|
+
| netintel_ssl_cert | SSL certificate check for any domain — issuer, subject, SANs, valid… | $0.003 |
|
|
152
163
|
| netintel_text_chunk | Split text into overlapping chunks for RAG ingestion — by characters or… | $0.001 |
|
|
153
164
|
| netintel_text_stats | Instant text statistics — characters (with/without spaces), words… | $0.001 |
|
|
154
165
|
| netintel_embeddings | Multilingual text embeddings (384-dim) served in-house, no OpenAI… | $0.001 |
|
|
155
|
-
| netintel_email_verify |
|
|
166
|
+
| netintel_email_verify | Validate an email address — email verification before you send: syntax… | $0.001 |
|
|
156
167
|
| netintel_exa_search | Exa neural web search for AI agents — POST or GET a query, get ranked… | $0.01 |
|
|
157
168
|
| netintel_web_search | Web search for AI agents — one query in, ranked live results out… | $0.01 |
|
|
158
169
|
| netintel_exa_contents | Clean page text for up to 3 URLs in one call via Exa's index + live… | $0.005 |
|
package/dist/client.js
CHANGED
|
@@ -1,18 +1,58 @@
|
|
|
1
1
|
import { x402Client, wrapAxiosWithPayment } from "@x402/axios";
|
|
2
2
|
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
3
3
|
import { privateKeyToAccount } from "viem/accounts";
|
|
4
|
+
import { createPublicClient, http, formatUnits } from "viem";
|
|
5
|
+
import { base } from "viem/chains";
|
|
4
6
|
import axios from "axios";
|
|
5
7
|
// Canonical domain. The legacy netintel-production-440c.up.railway.app host
|
|
6
8
|
// still serves the same app as a fallback, but new clients target netintel.dev.
|
|
7
9
|
const BASE_URL = "https://netintel.dev";
|
|
10
|
+
/** USDC on Base mainnet — the asset every NetIntel price is quoted in. */
|
|
11
|
+
const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
12
|
+
/** Tools that work with NO wallet: NetIntel's free tier (per-client quota, then the normal price). */
|
|
13
|
+
export const FREE_TOOLS = [
|
|
14
|
+
"netintel_dns_lookup",
|
|
15
|
+
"netintel_ssl_cert",
|
|
16
|
+
"netintel_whois_lookup",
|
|
17
|
+
"netintel_subnet_calc",
|
|
18
|
+
"netintel_email_auth",
|
|
19
|
+
];
|
|
20
|
+
let walletAddress = null;
|
|
21
|
+
/** The configured agent wallet's address, or null when the server runs wallet-less. */
|
|
22
|
+
export function configuredWallet() {
|
|
23
|
+
return walletAddress;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The HTTP client every tool uses. With EVM_PRIVATE_KEY set, responses that
|
|
27
|
+
* demand payment are paid automatically (x402) and retried; without it, the
|
|
28
|
+
* server still starts — the free-tier tools work as-is and paid tools return
|
|
29
|
+
* an explanation of what a call costs and how to fund a wallet, instead of
|
|
30
|
+
* failing to boot for everyone who installed the plugin before funding one.
|
|
31
|
+
*/
|
|
8
32
|
export async function createClient() {
|
|
9
|
-
const key = process.env.EVM_PRIVATE_KEY;
|
|
33
|
+
const key = process.env.EVM_PRIVATE_KEY?.trim();
|
|
34
|
+
const plain = axios.create({ baseURL: BASE_URL });
|
|
10
35
|
if (!key) {
|
|
11
|
-
|
|
12
|
-
"
|
|
36
|
+
console.error("[netintel-mcp] No EVM_PRIVATE_KEY set — running wallet-less. Free-tier tools work " +
|
|
37
|
+
`(${FREE_TOOLS.join(", ")}); paid tools will explain how to fund an agent wallet.`);
|
|
38
|
+
return plain;
|
|
13
39
|
}
|
|
14
|
-
const client = new x402Client();
|
|
15
40
|
const signer = privateKeyToAccount(key);
|
|
41
|
+
walletAddress = signer.address;
|
|
42
|
+
const client = new x402Client();
|
|
16
43
|
registerExactEvmScheme(client, { signer });
|
|
17
|
-
return wrapAxiosWithPayment(
|
|
44
|
+
return wrapAxiosWithPayment(plain, client);
|
|
45
|
+
}
|
|
46
|
+
/** USDC balance of the configured wallet on Base (keyless public RPC). */
|
|
47
|
+
export async function walletUsdcBalance() {
|
|
48
|
+
if (!walletAddress)
|
|
49
|
+
return null;
|
|
50
|
+
const pc = createPublicClient({ chain: base, transport: http() });
|
|
51
|
+
const raw = await pc.readContract({
|
|
52
|
+
address: USDC_BASE,
|
|
53
|
+
abi: [{ type: "function", name: "balanceOf", stateMutability: "view", inputs: [{ name: "a", type: "address" }], outputs: [{ type: "uint256" }] }],
|
|
54
|
+
functionName: "balanceOf",
|
|
55
|
+
args: [walletAddress],
|
|
56
|
+
});
|
|
57
|
+
return formatUnits(raw, 6);
|
|
18
58
|
}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { createClient } from "./client.js";
|
|
5
|
+
import { createClient, configuredWallet, walletUsdcBalance, FREE_TOOLS } from "./client.js";
|
|
6
6
|
function ok(data) {
|
|
7
7
|
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
8
8
|
}
|
|
@@ -10,6 +10,16 @@ function err(e) {
|
|
|
10
10
|
const ax = e;
|
|
11
11
|
const status = ax.response?.status ?? "unknown";
|
|
12
12
|
const msg = ax.message ?? String(e);
|
|
13
|
+
if (status === 402) {
|
|
14
|
+
// The one error a user can act on: the call needs a payment that did not
|
|
15
|
+
// happen. Say what it costs and exactly what to do, instead of "402".
|
|
16
|
+
const price = ax.response?.data?.accepts?.[0]?.price;
|
|
17
|
+
const cost = price ? `This tool costs ${price} per call (USDC on Base). ` : "This tool is paid per call (USDC on Base). ";
|
|
18
|
+
const fix = configuredWallet()
|
|
19
|
+
? `The agent wallet ${configuredWallet()} is configured but the payment did not settle — usually an empty wallet. Run netintel_wallet_status to check its USDC balance, then fund it on Base.`
|
|
20
|
+
: `No agent wallet is configured, so it cannot be paid. Set EVM_PRIVATE_KEY to a wallet holding USDC on Base (or enter it in the Claude Code plugin config), then retry. Without a wallet these tools still work free, up to a quota: ${FREE_TOOLS.join(", ")}.`;
|
|
21
|
+
return { content: [{ type: "text", text: `Payment required. ${cost}${fix}` }], isError: true };
|
|
22
|
+
}
|
|
13
23
|
return {
|
|
14
24
|
content: [{ type: "text", text: `Error (${status}): ${msg}` }],
|
|
15
25
|
isError: true,
|
|
@@ -25,7 +35,7 @@ function params(obj) {
|
|
|
25
35
|
}
|
|
26
36
|
function registerTools(server, api) {
|
|
27
37
|
// 1. DNS Lookup
|
|
28
|
-
server.tool("netintel_dns_lookup", "
|
|
38
|
+
server.tool("netintel_dns_lookup", "DNS lookup for any domain — resolve A, AAAA, MX, TXT, NS, CNAME, SOA and PTR records in one call. Parses SPF/DMARC from TXT plus DKIM, and cross-checks A records across Google, Cloudflare and Quad9 resolvers for propagation consistency.", { domain: z.string() }, async ({ domain }) => {
|
|
29
39
|
try {
|
|
30
40
|
const res = await api.get("/dns/lookup", { params: { domain } });
|
|
31
41
|
return ok(res.data);
|
|
@@ -105,7 +115,7 @@ function registerTools(server, api) {
|
|
|
105
115
|
}
|
|
106
116
|
});
|
|
107
117
|
// 9. WHOIS Lookup
|
|
108
|
-
server.tool("netintel_whois_lookup", "
|
|
118
|
+
server.tool("netintel_whois_lookup", "Domain registration lookup, WHOIS via RDAP — registrar, registration and expiry dates, last-updated date, nameservers, and status flags from the authoritative registry, plus an actionability score for domain trustworthiness, ownership, or availability risk.", { domain: z.string() }, async ({ domain }) => {
|
|
109
119
|
try {
|
|
110
120
|
const res = await api.get("/whois-rdap/lookup", { params: { domain } });
|
|
111
121
|
return ok(res.data);
|
|
@@ -223,7 +233,7 @@ function registerTools(server, api) {
|
|
|
223
233
|
}
|
|
224
234
|
});
|
|
225
235
|
// 20. Page Extract
|
|
226
|
-
server.tool("netintel_page_extract", "Fetch any article or web page and extract clean readable text stripped of ads and boilerplate. Returns content, word count, reading time, and language.", { url: z.string() }, async ({ url }) => {
|
|
236
|
+
server.tool("netintel_page_extract", "Fetch any article or web page and extract clean readable text stripped of ads and boilerplate. Returns content, word count, reading time, and language. For JavaScript-rendered or bot-walled pages a plain fetch can't read, use netintel_exa_contents instead.", { url: z.string() }, async ({ url }) => {
|
|
227
237
|
try {
|
|
228
238
|
const res = await api.get("/page-extract/read", { params: { url } });
|
|
229
239
|
return ok(res.data);
|
|
@@ -287,7 +297,7 @@ function registerTools(server, api) {
|
|
|
287
297
|
}
|
|
288
298
|
});
|
|
289
299
|
// 26. IP Reputation
|
|
290
|
-
server.tool("netintel_ip_reputation", "
|
|
300
|
+
server.tool("netintel_ip_reputation", "IP reputation and malicious-IP check — screens an address against AbuseIPDB and AlienVault OTX threat feeds and returns a composite risk score, threat categories, malware families, and full source data.", { ip: z.string() }, async ({ ip }) => {
|
|
291
301
|
try {
|
|
292
302
|
const res = await api.get("/ip-reputation/analyze", { params: { ip } });
|
|
293
303
|
return ok(res.data);
|
|
@@ -481,7 +491,7 @@ function registerTools(server, api) {
|
|
|
481
491
|
}
|
|
482
492
|
});
|
|
483
493
|
// 45. Classify (POST)
|
|
484
|
-
server.tool("netintel_classify", "Classify text into
|
|
494
|
+
server.tool("netintel_classify", "Classify text into your own categories — zero-shot: supply 2–20 labels and Claude Haiku returns the best-matching category with confidence and per-label scores. Route, tag, triage, and detect intent or topic with your own taxonomy in one call.", { text: z.string(), labels: z.array(z.string()), multi_label: z.boolean().optional() }, async ({ text, labels, multi_label }) => {
|
|
485
495
|
try {
|
|
486
496
|
const res = await api.post("/classify", { text, labels, multi_label });
|
|
487
497
|
return ok(res.data);
|
|
@@ -681,7 +691,7 @@ function registerTools(server, api) {
|
|
|
681
691
|
}
|
|
682
692
|
});
|
|
683
693
|
// 65. Web
|
|
684
|
-
server.tool("netintel_web", "
|
|
694
|
+
server.tool("netintel_web", "Extract text from a web page or PDF as clean Markdown — HTML to Markdown for any URL: strips scripts, nav, ads, and boilerplate while preserving headings, links, lists, tables, code blocks, and blockquotes; extracts the text layer from PDFs. Returns the Markdown body, title, word count, and a quality grade. For JavaScript-rendered or bot-walled pages a plain fetch can't read, use netintel_exa_contents instead.", { url: z.string() }, async ({ url }) => {
|
|
685
695
|
try {
|
|
686
696
|
const res = await api.get("/web/extract", { params: { url } });
|
|
687
697
|
return ok(res.data);
|
|
@@ -1031,7 +1041,7 @@ function registerTools(server, api) {
|
|
|
1031
1041
|
}
|
|
1032
1042
|
});
|
|
1033
1043
|
// 100. Crypto
|
|
1034
|
-
server.tool("netintel_crypto_price", "
|
|
1044
|
+
server.tool("netintel_crypto_price", "Crypto prices for up to 25 coins in one call — live cryptocurrency spot prices for BTC, ETH, SOL and more in USD, EUR, or GBP from Coinbase with Kraken and CoinGecko fallback; no API key, one flat price. Per asset: price, 24h change when the source provides it, source, cache age.", { symbols: z.string().optional(), vs: z.string().optional() }, async ({ symbols, vs }) => {
|
|
1035
1045
|
try {
|
|
1036
1046
|
const res = await api.get("/crypto/price", { params: params({ symbols, vs }) });
|
|
1037
1047
|
return ok(res.data);
|
|
@@ -1172,7 +1182,7 @@ function registerTools(server, api) {
|
|
|
1172
1182
|
}
|
|
1173
1183
|
});
|
|
1174
1184
|
// 115. Ssl (POST)
|
|
1175
|
-
server.tool("netintel_ssl_cert", "
|
|
1185
|
+
server.tool("netintel_ssl_cert", "SSL certificate check for any domain — issuer, subject, SANs, valid from/to, days until expiry, expired/self-signed flags, TLS version, chain length. One TLS handshake, sub-2-second answer. The light, cheap tier under netintel_ssl_analyze (full analysis, grading).", { domain: z.string(), port: z.number().optional() }, async ({ domain, port }) => {
|
|
1176
1186
|
try {
|
|
1177
1187
|
const res = await api.post("/ssl/cert", { domain, port });
|
|
1178
1188
|
return ok(res.data);
|
|
@@ -1212,7 +1222,7 @@ function registerTools(server, api) {
|
|
|
1212
1222
|
}
|
|
1213
1223
|
});
|
|
1214
1224
|
// 119. Email (POST)
|
|
1215
|
-
server.tool("netintel_email_verify", "
|
|
1225
|
+
server.tool("netintel_email_verify", "Validate an email address — email verification before you send: syntax + MX + disposable/role/free-provider detection in one call, boolean-first (deliverable, safe_to_send) with a machine-readable reason. DNS-level check only, no SMTP mailbox probe. For a scored trust report instead of a yes/no gate, see netintel_email_intel.", { email: z.string() }, async ({ email }) => {
|
|
1216
1226
|
try {
|
|
1217
1227
|
const res = await api.post("/email/verify", { email });
|
|
1218
1228
|
return ok(res.data);
|
|
@@ -1262,6 +1272,27 @@ function registerTools(server, api) {
|
|
|
1262
1272
|
}
|
|
1263
1273
|
});
|
|
1264
1274
|
}
|
|
1275
|
+
// Wallet status — free, local: lets an agent (or a human) tell "no wallet",
|
|
1276
|
+
// "empty wallet" and "funded" apart before spending a call on finding out.
|
|
1277
|
+
// Deliberately OUTSIDE registerTools(): scripts/sync-ecosystem.ts pairs each
|
|
1278
|
+
// server.tool() in there with the api.get/post path that follows it, and this
|
|
1279
|
+
// tool makes no API call.
|
|
1280
|
+
function registerWalletTool(server) {
|
|
1281
|
+
server.tool("netintel_wallet_status", "Check the agent wallet this MCP server pays NetIntel with: whether a key is configured, its address, and its USDC balance on Base. Free and local (no NetIntel call). Use when a paid tool reports 'Payment required', before funding, or to confirm a top-up arrived. Also lists the tools that work with no wallet at all.", {}, async () => {
|
|
1282
|
+
const address = configuredWallet();
|
|
1283
|
+
const free = { free_without_wallet: [...FREE_TOOLS], note: "Free tools are rate-limited per client (about 30/hour); over the quota they cost their normal price." };
|
|
1284
|
+
if (!address) {
|
|
1285
|
+
return ok({ wallet_configured: false, how_to_fund: "Set EVM_PRIVATE_KEY (or the plugin's wallet config) to a dedicated agent wallet, then send it a few dollars of USDC on Base mainnet — no ETH needed, settlement is gasless.", ...free });
|
|
1286
|
+
}
|
|
1287
|
+
try {
|
|
1288
|
+
const usdc = await walletUsdcBalance();
|
|
1289
|
+
return ok({ wallet_configured: true, address, usdc_balance_base: usdc, funded: Number(usdc) > 0, top_up: Number(usdc) > 0 ? undefined : `Send USDC on Base to ${address}`, ...free });
|
|
1290
|
+
}
|
|
1291
|
+
catch (e) {
|
|
1292
|
+
return ok({ wallet_configured: true, address, usdc_balance_base: null, balance_error: String(e.message).slice(0, 160), ...free });
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1265
1296
|
async function main() {
|
|
1266
1297
|
const api = await createClient();
|
|
1267
1298
|
const server = new McpServer({
|
|
@@ -1269,6 +1300,7 @@ async function main() {
|
|
|
1269
1300
|
version: "1.1.0",
|
|
1270
1301
|
});
|
|
1271
1302
|
registerTools(server, api);
|
|
1303
|
+
registerWalletTool(server);
|
|
1272
1304
|
const transport = new StdioServerTransport();
|
|
1273
1305
|
await server.connect(transport);
|
|
1274
1306
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netintel-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.54",
|
|
4
4
|
"mcpName": "io.github.kjgueye/netintel-mcp",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/kjgueye/netintel-mcp.git"
|
|
8
8
|
},
|
|
9
|
-
"description": "MCP server for NetIntel
|
|
9
|
+
"description": "MCP server for NetIntel — DNS, SSL, WHOIS, email security, OSINT via x402 micropayments",
|
|
10
10
|
"main": "dist/index.js",
|
|
11
11
|
"bin": {
|
|
12
12
|
"netintel-mcp": "dist/index.js"
|