shieldapi-mcp 2.0.1 → 2.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/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # 🛡️ ShieldAPI MCP Server
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/shieldapi-mcp.svg)](https://www.npmjs.com/package/shieldapi-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dm/shieldapi-mcp.svg)](https://www.npmjs.com/package/shieldapi-mcp)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![x402](https://img.shields.io/badge/x402-enabled-green.svg)](https://x402.org)
7
+ [![Listed on x402scan](https://img.shields.io/badge/x402scan-listed-brightgreen.svg)](https://www.x402scan.com/server/55c99a38-34b3-4b2c-8987-f58ebd88a7df)
8
+
3
9
  Security intelligence tools for AI agents — prompt injection detection, skill security scanning, URL/domain/IP/email/password checks. Pay-per-request with USDC micropayments via [x402](https://www.x402.org/), or use free demo mode.
4
10
 
5
11
  **Now with AI-native security:** Detect prompt injection in real-time and scan AI skills for supply chain attacks.
package/dist/index.js CHANGED
@@ -118,15 +118,35 @@ function formatResult(data) {
118
118
  }
119
119
  // --- MCP Server ---
120
120
  const server = new McpServer({
121
- name: 'ShieldAPI',
122
- version: '2.0.0',
121
+ name: 'shieldapi-mcp',
122
+ title: 'ShieldAPI — Security Intelligence for AI Agents',
123
+ version: '2.1.0',
124
+ description: '9 security tools for AI agents: breach checks, domain/IP/URL reputation, prompt injection detection, skill supply chain scanning. Pay-per-request via x402 USDC micropayments. Demo mode available.',
125
+ websiteUrl: 'https://shield.vainplex.dev',
126
+ icons: [{ src: 'https://shield.vainplex.dev/icon.svg', mimeType: 'image/svg+xml' }],
123
127
  });
128
+ // Annotations for read-only lookup tools
129
+ const readOnlyAnnotations = {
130
+ title: '', // will be set per-tool
131
+ readOnlyHint: true,
132
+ destructiveHint: false,
133
+ idempotentHint: true,
134
+ openWorldHint: true,
135
+ };
136
+ const TOOL_TITLES = {
137
+ check_url: 'Check URL Safety',
138
+ check_password: 'Check Password Breach',
139
+ check_password_range: 'Password Range Lookup',
140
+ check_domain: 'Check Domain Reputation',
141
+ check_ip: 'Check IP Reputation',
142
+ check_email: 'Check Email Breach',
143
+ };
124
144
  // Register standard GET tools from config
125
145
  for (const [name, def] of Object.entries(TOOLS)) {
126
- server.tool(name, def.description, { [def.param]: z.string().describe(def.paramDesc) }, async (params) => formatResult(await callShieldApi(def.endpoint, params)));
146
+ server.tool(name, def.description, { [def.param]: z.string().describe(def.paramDesc) }, { ...readOnlyAnnotations, title: TOOL_TITLES[name] || name }, async (params) => formatResult(await callShieldApi(def.endpoint, params)));
127
147
  }
128
148
  // full_scan — single 'target' param mapped to the correct server param
129
- server.tool('full_scan', 'Run all security checks on a target (URL, domain, IP, or email). Most comprehensive scan.', { target: z.string().describe('Target to scan — URL, domain, IP address, or email') }, async ({ target }) => formatResult(await callShieldApi('full-scan', detectTargetType(target))));
149
+ server.tool('full_scan', 'Run all security checks on a target (URL, domain, IP, or email). Most comprehensive scan.', { target: z.string().describe('Target to scan — URL, domain, IP address, or email') }, { title: 'Full Security Scan', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ target }) => formatResult(await callShieldApi('full-scan', detectTargetType(target))));
130
150
  // ================================================================
131
151
  // Phase 2 Tools (POST endpoints)
132
152
  // ================================================================
@@ -137,7 +157,7 @@ server.tool('scan_skill', 'Scan an AI agent skill/plugin for security issues acr
137
157
  name: z.string().describe('Filename including extension'),
138
158
  content: z.string().describe('File content as string'),
139
159
  })).optional().describe('Additional code files to analyze (max 20 files)'),
140
- }, async (params) => {
160
+ }, { title: 'Scan AI Skill/Plugin', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, async (params) => {
141
161
  const body = {};
142
162
  if (params.skill)
143
163
  body.skill = params.skill;
@@ -150,7 +170,7 @@ server.tool('check_prompt', 'Detect prompt injection in text. Analyzes across 4
150
170
  prompt: z.string().describe('The text to analyze for prompt injection'),
151
171
  context: z.enum(['user-input', 'skill-prompt', 'system-prompt']).optional()
152
172
  .describe('Context hint for sensitivity: user-input (default), skill-prompt (higher tolerance), system-prompt (highest sensitivity)'),
153
- }, async (params) => {
173
+ }, { title: 'Detect Prompt Injection', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, async (params) => {
154
174
  const body = { prompt: params.prompt };
155
175
  if (params.context)
156
176
  body.context = params.context;
@@ -0,0 +1,40 @@
1
+ ## Security intelligence for AI agents
2
+
3
+ ShieldAPI provides 9 security tools via MCP — from password breach checks to prompt injection detection. All tools work in **free demo mode** out of the box. Paid mode uses x402 USDC micropayments on Base.
4
+
5
+ ### Tools
6
+
7
+ | Tool | What it does | Price |
8
+ |---|---|---|
9
+ | `check_password` | SHA-1 hash against 900M+ breached passwords (HIBP) | $0.001 |
10
+ | `check_password_range` | k-Anonymity password range lookup | $0.001 |
11
+ | `check_email` | Email breach exposure via HIBP | $0.005 |
12
+ | `check_domain` | DNS, SPF/DMARC, SSL, blacklist reputation | $0.003 |
13
+ | `check_ip` | Blacklists, Tor exit detection, reverse DNS | $0.002 |
14
+ | `check_url` | Phishing, malware, brand impersonation | $0.003 |
15
+ | `full_scan` | All checks combined in one call | $0.010 |
16
+ | **`check_prompt`** | Prompt injection detection — 200+ patterns, <100ms | $0.005 |
17
+ | **`scan_skill`** | AI skill/plugin supply chain scanner — 8 risk categories | $0.020 |
18
+
19
+ ### Quick Start
20
+
21
+ ```bash
22
+ npx shieldapi-mcp
23
+ ```
24
+
25
+ All tools work immediately in demo mode — no wallet, no API key needed.
26
+
27
+ ### Highlights
28
+
29
+ - **Prompt Injection Detection:** 200+ patterns including Base64, ROT13, Unicode homoglyphs, DAN/jailbreak, exfiltration attempts
30
+ - **Skill Supply Chain Security:** Scans for malicious code, credential leaks, suspicious downloads — based on Snyk ToxicSkills taxonomy
31
+ - **Real Breach Data:** 900M+ password hashes from Have I Been Pwned
32
+ - **x402 Native:** First security MCP server with pay-per-request USDC micropayments
33
+ - **No API Key:** Works out of the box in demo mode, add a wallet for paid mode
34
+
35
+ ### Links
36
+
37
+ - [Live API](https://shield.vainplex.dev)
38
+ - [x402scan Listing](https://www.x402scan.com/server/55c99a38-34b3-4b2c-8987-f58ebd88a7df)
39
+ - [npm](https://www.npmjs.com/package/shieldapi-mcp)
40
+ - [GitHub](https://github.com/alberthild/shieldapi-mcp)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldapi-mcp",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "MCP server for ShieldAPI — URL scanning, breach detection, domain/IP reputation as AI agent tools. Pay-per-request with USDC micropayments via x402.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -149,16 +149,39 @@ function formatResult(data: unknown): { content: Array<{ type: 'text'; text: str
149
149
  // --- MCP Server ---
150
150
 
151
151
  const server = new McpServer({
152
- name: 'ShieldAPI',
153
- version: '2.0.0',
152
+ name: 'shieldapi-mcp',
153
+ title: 'ShieldAPI — Security Intelligence for AI Agents',
154
+ version: '2.1.0',
155
+ description: '9 security tools for AI agents: breach checks, domain/IP/URL reputation, prompt injection detection, skill supply chain scanning. Pay-per-request via x402 USDC micropayments. Demo mode available.',
156
+ websiteUrl: 'https://shield.vainplex.dev',
157
+ icons: [{ src: 'https://shield.vainplex.dev/icon.svg', mimeType: 'image/svg+xml' }],
154
158
  });
155
159
 
160
+ // Annotations for read-only lookup tools
161
+ const readOnlyAnnotations = {
162
+ title: '', // will be set per-tool
163
+ readOnlyHint: true,
164
+ destructiveHint: false,
165
+ idempotentHint: true,
166
+ openWorldHint: true,
167
+ } as const;
168
+
169
+ const TOOL_TITLES: Record<string, string> = {
170
+ check_url: 'Check URL Safety',
171
+ check_password: 'Check Password Breach',
172
+ check_password_range: 'Password Range Lookup',
173
+ check_domain: 'Check Domain Reputation',
174
+ check_ip: 'Check IP Reputation',
175
+ check_email: 'Check Email Breach',
176
+ };
177
+
156
178
  // Register standard GET tools from config
157
179
  for (const [name, def] of Object.entries(TOOLS)) {
158
180
  server.tool(
159
181
  name,
160
182
  def.description,
161
183
  { [def.param]: z.string().describe(def.paramDesc) },
184
+ { ...readOnlyAnnotations, title: TOOL_TITLES[name] || name },
162
185
  async (params) => formatResult(await callShieldApi(def.endpoint, params as Record<string, string>))
163
186
  );
164
187
  }
@@ -168,6 +191,7 @@ server.tool(
168
191
  'full_scan',
169
192
  'Run all security checks on a target (URL, domain, IP, or email). Most comprehensive scan.',
170
193
  { target: z.string().describe('Target to scan — URL, domain, IP address, or email') },
194
+ { title: 'Full Security Scan', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
171
195
  async ({ target }) => formatResult(await callShieldApi('full-scan', detectTargetType(target)))
172
196
  );
173
197
 
@@ -186,6 +210,7 @@ server.tool(
186
210
  content: z.string().describe('File content as string'),
187
211
  })).optional().describe('Additional code files to analyze (max 20 files)'),
188
212
  },
213
+ { title: 'Scan AI Skill/Plugin', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
189
214
  async (params) => {
190
215
  const body: Record<string, unknown> = {};
191
216
  if (params.skill) body.skill = params.skill;
@@ -203,6 +228,7 @@ server.tool(
203
228
  context: z.enum(['user-input', 'skill-prompt', 'system-prompt']).optional()
204
229
  .describe('Context hint for sensitivity: user-input (default), skill-prompt (higher tolerance), system-prompt (highest sensitivity)'),
205
230
  },
231
+ { title: 'Detect Prompt Injection', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
206
232
  async (params) => {
207
233
  const body: Record<string, unknown> = { prompt: params.prompt };
208
234
  if (params.context) body.context = params.context;