copyseeker-mcp-server 1.0.4 → 2.0.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 CopySeeker
3
+ Copyright (c) 2025 Copyseeker
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,159 +1,131 @@
1
1
  # Copyseeker MCP Server
2
2
 
3
- A Model Context Protocol (MCP) server that integrates Copyseeker's powerful reverse image search API with Claude and other MCP-compatible AI assistants.
3
+ Give Claude, Cursor, VS Code Copilot, Windsurf, OpenAI Codex, Gemini CLI and any other [MCP](https://modelcontextprotocol.io) client three image tools from [Copyseeker](https://copyseeker.net):
4
4
 
5
- ## Features
5
+ | Tool | What it does | Cost |
6
+ |---|---|---|
7
+ | `reverse_image_search` | Finds the web pages that show an image, ranked by prominence, with the copies each page uses | 1 search |
8
+ | `detect_ai_image` | Tells whether an image is AI-generated, with a confidence score | 0.01 searches |
9
+ | `detect_nsfw` | Tells whether an image contains nudity or sexual content, with a confidence score | 0.01 searches |
6
10
 
7
- - 🔍 **Reverse Image Search**: Find similar images and their sources across the web
8
- - 🖼️ **Multiple Input Methods**: Search by URL or upload images directly
9
- - 📊 **Detailed Results**: Get comprehensive metadata about found images
10
- - ⚡ **Fast & Reliable**: Powered by Copyseeker's robust API infrastructure
11
- - 🔒 **Secure**: Your API key stays local, never shared
11
+ Each tool takes a direct image URL or the path to a local image file (up to 20 MB). Calls draw from the same search balance as the website, Monitor and the [Copyseeker API](https://copyseeker.net/apis).
12
12
 
13
- ## Quick Start
13
+ ## Requirements
14
14
 
15
- ### 1. Install the MCP Server
15
+ - Node.js 20 or newer
16
+ - A paid Copyseeker plan and an API key: create one under **Account → Developers** at [copyseeker.net/account](https://copyseeker.net/account#api)
16
17
 
17
- ```bash
18
- npm install -g copyseeker-mcp-server
19
- ```
20
-
21
- ### 2. Get Your API Key
18
+ ## Setup
22
19
 
23
- 1. Visit [RapidAPI Copyseeker](https://rapidapi.com/copyseeker1-copyseeker-default/api/reverse-image-search-by-copyseeker/)
24
- 2. Subscribe to a plan (free tier available)
25
- 3. Copy your RapidAPI key
20
+ ### Claude Code
26
21
 
27
- ### 3. Configure Claude Desktop
22
+ ```bash
23
+ claude mcp add copyseeker -e COPYSEEKER_API_KEY=your_api_key -- npx -y copyseeker-mcp-server
24
+ ```
28
25
 
29
- Add this to your Claude Desktop configuration file:
26
+ ### Claude Desktop
30
27
 
31
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
32
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
28
+ Add this to `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/`, Windows: `%APPDATA%\Claude\`), then restart Claude Desktop:
33
29
 
34
30
  ```json
35
31
  {
36
32
  "mcpServers": {
37
33
  "copyseeker": {
38
- "command": "copyseeker-mcp",
34
+ "command": "npx",
35
+ "args": ["-y", "copyseeker-mcp-server"],
39
36
  "env": {
40
- "COPYSEEKER_RAPIDAPI_KEY": "your_rapidapi_key_here"
37
+ "COPYSEEKER_API_KEY": "your_api_key"
41
38
  }
42
39
  }
43
40
  }
44
41
  }
45
42
  ```
46
43
 
47
- ### 4. Restart Claude Desktop
44
+ ### Cursor
48
45
 
49
- The Copyseeker tools will now be available in Claude!
46
+ Add the same `mcpServers` entry as for Claude Desktop to `~/.cursor/mcp.json` (all projects) or `.cursor/mcp.json` (one project).
50
47
 
51
- ## Usage Examples
48
+ ### VS Code (GitHub Copilot)
52
49
 
53
- ### Complete Reverse Image Search
54
- ```
55
- Can you do a complete reverse search on: https://copyseeker.net/assets/img/pc.png
56
- ```
50
+ Add this to `.vscode/mcp.json` in your project. VS Code asks for the key on first use and stores it securely:
57
51
 
58
- ### Copyright & Source Verification
59
- ```
60
- I need to check if I can legally use this image. Please analyze: [image URL]
61
- ```
62
-
63
- ### Find Exact Matches
64
- ```
65
- Where exactly does this image appear online? [image URL]
66
- ```
67
-
68
- ### Find Design Inspiration
69
- ```
70
- Show me images that look similar to this design for inspiration: [image URL]
71
- ```
72
-
73
- ### Page Authority Assessment
74
- ```
75
- Which website is the most credible source for this image? [image URL]
52
+ ```json
53
+ {
54
+ "inputs": [
55
+ {
56
+ "type": "promptString",
57
+ "id": "copyseeker-api-key",
58
+ "description": "Copyseeker API key",
59
+ "password": true
60
+ }
61
+ ],
62
+ "servers": {
63
+ "copyseeker": {
64
+ "type": "stdio",
65
+ "command": "npx",
66
+ "args": ["-y", "copyseeker-mcp-server"],
67
+ "env": {
68
+ "COPYSEEKER_API_KEY": "${input:copyseeker-api-key}"
69
+ }
70
+ }
71
+ }
72
+ }
76
73
  ```
77
74
 
78
- ## Available Tools
75
+ Then use the tools from Copilot Chat in agent mode.
79
76
 
80
- ### `reverse_image_search`
81
- Complete reverse image search with all results formatted clearly.
77
+ ### Windsurf
82
78
 
83
- **Parameters:**
84
- - `image_url` (required): Direct URL to the image
79
+ Add the same `mcpServers` entry as for Claude Desktop to `~/.codeium/windsurf/mcp_config.json`.
85
80
 
86
- **Returns:**
87
- - AI analysis of what the image represents
88
- - Exact matches (websites containing the same image)
89
- - Visually similar images (different images that look alike)
90
- - Page authority scores for credibility assessment
91
- - AI-detected categories with confidence scores
81
+ ### OpenAI Codex CLI
92
82
 
93
- ### `analyze_image_copyright`
94
- Specialized copyright and usage rights analysis.
83
+ Add this to `~/.codex/config.toml`:
95
84
 
96
- **Parameters:**
97
- - `image_url` (required): URL of the image to analyze
85
+ ```toml
86
+ [mcp_servers.copyseeker]
87
+ command = "npx"
88
+ args = ["-y", "copyseeker-mcp-server"]
89
+ env = { COPYSEEKER_API_KEY = "your_api_key" }
90
+ ```
98
91
 
99
- **Returns:**
100
- - Copyright risk assessment based on where image appears
101
- - Source credibility ranking by page authority
102
- - Usage recommendations and next steps
103
- - Likely original source identification
92
+ ### Gemini CLI
104
93
 
105
- ### `find_exact_matches`
106
- Find websites containing the exact same image.
94
+ Add the same `mcpServers` entry as for Claude Desktop to `~/.gemini/settings.json`.
107
95
 
108
- **Parameters:**
109
- - `image_url` (required): URL of the image to find matches for
96
+ ### Other clients
110
97
 
111
- **Returns:**
112
- - List of websites with the exact same image
113
- - Page authority scores (higher = more credible source)
114
- - Direct URLs to image files on each site
115
- - Summary of distribution patterns
98
+ Any MCP client that can launch a local (stdio) server works. Configure it to run `npx -y copyseeker-mcp-server` with the `COPYSEEKER_API_KEY` environment variable set.
116
99
 
117
- ### `find_similar_images`
118
- Discover visually similar images for inspiration and alternatives.
100
+ ChatGPT connectors only accept remote MCP servers reached over HTTPS, so this local server does not work there.
119
101
 
120
- **Parameters:**
121
- - `image_url` (required): URL of the image to find similarities for
102
+ ## Examples
122
103
 
123
- **Returns:**
124
- - URLs to different images that look visually similar
125
- - Common visual elements and themes
126
- - Use cases for similar images
127
- - Style and category analysis
104
+ - "Where else on the web does https://example.com/photo.jpg appear? Who published it first?"
105
+ - "Is ~/Downloads/portrait.png AI-generated?"
106
+ - "Check these five product images for NSFW content before I upload them."
128
107
 
129
- ## Pricing
108
+ ## Errors
130
109
 
131
- [View all pricing plans →](https://rapidapi.com/copyseeker1-copyseeker-default/api/reverse-image-search-by-copyseeker/pricing)
110
+ Failures come back to the assistant as plain explanations it can act on: an invalid key, a missing plan, an empty balance (with the top-up link), the rate limit of 60 calls per minute (with how long to wait), or a URL that points to a web page instead of an image. A search that fails on Copyseeker's side is refunded.
132
111
 
133
- ## Troubleshooting
112
+ ## Upgrading from 1.x
134
113
 
135
- ### "API key required" error
136
- Make sure you've set the `COPYSEEKER_RAPIDAPI_KEY` environment variable in your Claude configuration.
114
+ Version 2 calls the Copyseeker API directly instead of RapidAPI:
137
115
 
138
- ### "Rate limit exceeded"
139
- Check your usage on the [RapidAPI dashboard](https://rapidapi.com/developer/dashboard) and consider upgrading your plan.
116
+ - Replace `COPYSEEKER_RAPIDAPI_KEY` with `COPYSEEKER_API_KEY`, a key from your Copyseeker account.
117
+ - The tools are now `reverse_image_search`, `detect_ai_image` and `detect_nsfw`. `analyze_image_copyright`, `find_exact_matches` and `find_similar_images` are gone: `reverse_image_search` covers them.
118
+ - Node.js 20 or newer is required.
140
119
 
141
- ### "Image not found" error
142
- Ensure the image URL is directly accessible and points to a valid image file (not a webpage containing an image).
120
+ ## Development
143
121
 
144
- ## Support
122
+ ```bash
123
+ npm install
124
+ npm test # builds, then runs the server against a fake Copyseeker API
125
+ ```
145
126
 
146
- - 🌐 Website: [copyseeker.net](https://copyseeker.net)
147
- - 📚 API Documentation: [RapidAPI Docs](https://rapidapi.com/copyseeker1-copyseeker-default/api/reverse-image-search-by-copyseeker/)
127
+ `COPYSEEKER_API_URL` points the server at another API base URL (default `https://api.copyseeker.net`).
148
128
 
149
129
  ## License
150
130
 
151
- MIT License - see LICENSE file for details.
152
-
153
- ## Contributing
154
-
155
- We welcome contributions! Please see our contributing guidelines and submit pull requests to our GitHub repository.
156
-
157
- ---
158
-
159
- **Made with ❤️ by the Copyseeker team**
131
+ MIT
@@ -0,0 +1,121 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { basename, extname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ export const DEFAULT_API_URL = "https://api.copyseeker.net";
5
+ export const MAX_FILE_BYTES = 20 * 1024 * 1024;
6
+ // Reverse image search can take tens of seconds on images found on many pages.
7
+ const REQUEST_TIMEOUT_MS = 120_000;
8
+ const MIME_TYPES = {
9
+ ".jpg": "image/jpeg",
10
+ ".jpeg": "image/jpeg",
11
+ ".png": "image/png",
12
+ ".gif": "image/gif",
13
+ ".webp": "image/webp",
14
+ ".bmp": "image/bmp",
15
+ ".tif": "image/tiff",
16
+ ".tiff": "image/tiff",
17
+ ".heic": "image/heic",
18
+ ".heif": "image/heif",
19
+ ".avif": "image/avif",
20
+ };
21
+ // A failure the assistant can explain to the user and often fix (new key, top-up, other image).
22
+ export class CopyseekerError extends Error {
23
+ code;
24
+ constructor(message, code) {
25
+ super(message);
26
+ this.code = code;
27
+ this.name = "CopyseekerError";
28
+ }
29
+ }
30
+ export class CopyseekerClient {
31
+ apiKey;
32
+ apiUrl;
33
+ fetchImpl;
34
+ constructor(apiKey, apiUrl = DEFAULT_API_URL, fetchImpl = fetch) {
35
+ this.apiKey = apiKey;
36
+ this.apiUrl = apiUrl;
37
+ this.fetchImpl = fetchImpl;
38
+ }
39
+ async call(endpoint, image) {
40
+ const source = image.trim();
41
+ const headers = { "X-API-Key": this.apiKey, Accept: "application/json" };
42
+ let response;
43
+ try {
44
+ if (isHttpUrl(source)) {
45
+ const url = `${this.apiUrl}/${endpoint}?imageUrl=${encodeURIComponent(source)}`;
46
+ response = await this.fetchImpl(url, { headers, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
47
+ }
48
+ else {
49
+ const body = new FormData();
50
+ const file = await readImageFile(source);
51
+ body.append("file", new Blob([file.bytes], { type: file.mimeType }), file.name);
52
+ response = await this.fetchImpl(`${this.apiUrl}/${endpoint}`, { method: "POST", headers, body, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
53
+ }
54
+ }
55
+ catch (error) {
56
+ if (error instanceof CopyseekerError) {
57
+ throw error;
58
+ }
59
+ if (error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError")) {
60
+ throw new CopyseekerError(`Copyseeker did not answer within ${REQUEST_TIMEOUT_MS / 1000} seconds. Try again in a moment.`, "TIMEOUT");
61
+ }
62
+ throw new CopyseekerError(`Could not reach Copyseeker (${error instanceof Error ? error.message : String(error)}). Check the internet connection.`, "NETWORK_ERROR");
63
+ }
64
+ if (response.ok) {
65
+ return (await response.json());
66
+ }
67
+ throw await toError(response);
68
+ }
69
+ }
70
+ export function isHttpUrl(value) {
71
+ return /^https?:\/\//i.test(value);
72
+ }
73
+ async function readImageFile(source) {
74
+ const path = source.toLowerCase().startsWith("file://") ? fileURLToPath(source) : source;
75
+ let size;
76
+ try {
77
+ const info = await stat(path);
78
+ if (!info.isFile()) {
79
+ throw new CopyseekerError(`"${source}" is not a file. Pass a direct image URL (http/https) or the path to a local image file.`, "INVALID_IMAGE");
80
+ }
81
+ size = info.size;
82
+ }
83
+ catch (error) {
84
+ if (error instanceof CopyseekerError) {
85
+ throw error;
86
+ }
87
+ throw new CopyseekerError(`"${source}" is neither an http(s) image URL nor a readable local file.`, "INVALID_IMAGE");
88
+ }
89
+ if (size === 0 || size > MAX_FILE_BYTES) {
90
+ throw new CopyseekerError(`"${source}" is ${size === 0 ? "empty" : "larger than 20 MB"}. Copyseeker accepts images up to 20 MB.`, "INVALID_IMAGE");
91
+ }
92
+ const name = basename(path);
93
+ return { bytes: new Uint8Array(await readFile(path)), name, mimeType: MIME_TYPES[extname(name).toLowerCase()] ?? "application/octet-stream" };
94
+ }
95
+ async function toError(response) {
96
+ let code = "";
97
+ try {
98
+ code = (await response.json())?.error ?? "";
99
+ }
100
+ catch {
101
+ // Not JSON (a gateway error page); the status code still tells what happened.
102
+ }
103
+ switch (code) {
104
+ case "INVALID_API_KEY":
105
+ return new CopyseekerError("The Copyseeker API key is missing or invalid. Create one at https://copyseeker.net/account#api and set it as COPYSEEKER_API_KEY in the MCP server config.", code);
106
+ case "PLAN_REQUIRED":
107
+ return new CopyseekerError("API access needs a paid Copyseeker plan. See https://copyseeker.net/pricing.", code);
108
+ case "QUOTA_EXHAUSTED":
109
+ return new CopyseekerError("The Copyseeker account has no searches left for this call. Top up at https://copyseeker.net/account#searches or wait for the monthly reset.", code);
110
+ case "RATE_LIMITED": {
111
+ const retryAfter = response.headers.get("Retry-After");
112
+ return new CopyseekerError(`Copyseeker's rate limit (60 calls per minute) was hit. Retry after ${retryAfter ?? "a few"} seconds.`, code);
113
+ }
114
+ case "INVALID_IMAGE":
115
+ return new CopyseekerError("Copyseeker could not read an image there. Use a direct link to the image file itself (not a web page that shows it), or a local file path. Nothing was charged.", code);
116
+ case "SEARCH_FAILED":
117
+ return new CopyseekerError("The search failed on Copyseeker's side and its searches were refunded. Try again.", code);
118
+ default:
119
+ return new CopyseekerError(`Copyseeker answered HTTP ${response.status}${code ? ` (${code})` : ""}.`, code || `HTTP_${response.status}`);
120
+ }
121
+ }
package/build/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
3
+ import { CopyseekerClient, DEFAULT_API_URL } from "./client.js";
4
+ import { createServer } from "./server.js";
5
+ const apiKey = process.env.COPYSEEKER_API_KEY?.trim();
6
+ if (!apiKey) {
7
+ // stdout carries the protocol, so everything for people goes to stderr.
8
+ console.error("COPYSEEKER_API_KEY is not set. Create an API key at https://copyseeker.net/account#api and add it to this server's env in your MCP client config.");
9
+ process.exit(1);
10
+ }
11
+ const client = new CopyseekerClient(apiKey, process.env.COPYSEEKER_API_URL?.trim() || DEFAULT_API_URL);
12
+ // One factory serves both clients that open with the 2025 initialize handshake and stateless 2026-07-28 clients.
13
+ serveStdio(() => createServer(client), {
14
+ onerror: (error) => {
15
+ console.error(`[copyseeker-mcp] ${error.message}`);
16
+ },
17
+ });
@@ -0,0 +1,84 @@
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
+ import { z } from "zod";
3
+ import { CopyseekerError, } from "./client.js";
4
+ export const SERVER_NAME = "copyseeker";
5
+ export const SERVER_VERSION = "2.0.1";
6
+ const DEFAULT_MAX_RESULTS = 25;
7
+ const INSTRUCTIONS = `Copyseeker tools work on one image each, given as a direct image URL (http/https) or the path to a local image file.
8
+ Each call is charged to the user's Copyseeker searches: reverse_image_search 1, detect_ai_image 0.01, detect_nsfw 0.01.
9
+ Call a tool once per image and question; do not repeat a call that already succeeded.`;
10
+ const imageInput = z
11
+ .string()
12
+ .min(1)
13
+ .describe("Direct URL of the image file (http or https, not the web page showing it), or the absolute path to a local image file up to 20 MB.");
14
+ const SEARCH_ANNOTATIONS = { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: true };
15
+ export function createServer(client) {
16
+ const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, { instructions: INSTRUCTIONS });
17
+ server.registerTool("reverse_image_search", {
18
+ title: "Reverse image search",
19
+ description: "Find the web pages that show this image, with the copies of it each page uses, ranked by how prominent the page is. " +
20
+ "Use it to find where an image came from, who published it first, or where it is reused without permission. Costs 1 search.",
21
+ inputSchema: z.object({
22
+ image: imageInput,
23
+ max_results: z.number().int().min(1).max(100).default(DEFAULT_MAX_RESULTS).describe("Most pages to return, best ranked first."),
24
+ }),
25
+ outputSchema: z.object({
26
+ totalPages: z.number().int().describe("Pages Copyseeker found, before max_results."),
27
+ pages: z.array(z.object({
28
+ url: z.string(),
29
+ title: z.string().nullable(),
30
+ rank: z.number().describe("Page prominence; lower is more prominent."),
31
+ matchingImages: z.array(z.string()).describe("URLs of the copies of the image on this page."),
32
+ })),
33
+ }),
34
+ annotations: { ...SEARCH_ANNOTATIONS, title: "Reverse image search" },
35
+ }, async ({ image, max_results }) => {
36
+ return run(async () => {
37
+ const result = await client.call("reverse-image-search", image);
38
+ const pages = result.pages ?? [];
39
+ return { totalPages: pages.length, pages: pages.slice(0, max_results) };
40
+ });
41
+ });
42
+ server.registerTool("detect_ai_image", {
43
+ title: "Detect AI-generated image",
44
+ description: "Tell whether an image was generated by AI (Midjourney, DALL-E, Stable Diffusion, Flux and similar) or is a real photo or artwork. Costs 0.01 searches.",
45
+ inputSchema: z.object({ image: imageInput }),
46
+ outputSchema: z.object({
47
+ isAiGenerated: z.boolean(),
48
+ confidence: z.number().min(0).max(1).describe("How sure the verdict is, from 0 to 1."),
49
+ }),
50
+ annotations: { ...SEARCH_ANNOTATIONS, title: "Detect AI-generated image" },
51
+ }, async ({ image }) => {
52
+ return run(async () => {
53
+ const result = await client.call("ai-detection", image);
54
+ return { isAiGenerated: result.isAiGenerated, confidence: result.confidence };
55
+ });
56
+ });
57
+ server.registerTool("detect_nsfw", {
58
+ title: "Detect NSFW image",
59
+ description: "Tell whether an image contains nudity or sexual content that is not safe for work. Costs 0.01 searches.",
60
+ inputSchema: z.object({ image: imageInput }),
61
+ outputSchema: z.object({
62
+ isNsfw: z.boolean(),
63
+ confidence: z.number().min(0).max(1).describe("How sure the verdict is, from 0 to 1."),
64
+ }),
65
+ annotations: { ...SEARCH_ANNOTATIONS, title: "Detect NSFW image" },
66
+ }, async ({ image }) => {
67
+ return run(async () => {
68
+ const result = await client.call("nsfw-detection", image);
69
+ return { isNsfw: result.isNsfw, confidence: result.confidence };
70
+ });
71
+ });
72
+ return server;
73
+ }
74
+ // Copyseeker failures go back to the model as tool errors it can read and act on, not as protocol errors.
75
+ async function run(call) {
76
+ try {
77
+ const output = await call();
78
+ return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }], structuredContent: output };
79
+ }
80
+ catch (error) {
81
+ const message = error instanceof CopyseekerError ? error.message : `Unexpected error: ${error instanceof Error ? error.message : String(error)}`;
82
+ return { content: [{ type: "text", text: message }], isError: true };
83
+ }
84
+ }
package/package.json CHANGED
@@ -1,55 +1,57 @@
1
1
  {
2
- "name": "copyseeker-mcp-server",
3
- "version": "1.0.4",
4
- "description": "MCP server for CopySeeker reverse image search API - find similar images and sources",
5
- "main": "build/index.js",
6
- "bin": {
7
- "copyseeker-mcp": "build/index.js"
8
- },
9
- "type": "module",
10
- "scripts": {
11
- "build": "tsc",
12
- "start": "node build/index.js",
13
- "dev": "tsx src/index.ts",
14
- "prepublishOnly": "npm run build"
15
- },
16
- "dependencies": {
17
- "@modelcontextprotocol/sdk": "^0.4.0",
18
- "axios": "^1.6.0"
19
- },
20
- "devDependencies": {
21
- "@types/node": "^20.0.0",
22
- "typescript": "^5.0.0",
23
- "tsx": "^4.0.0"
24
- },
25
- "keywords": [
26
- "mcp",
27
- "model-context-protocol",
28
- "reverse-image-search",
29
- "copyseeker",
30
- "claude",
31
- "image-search",
32
- "similar-images",
33
- "reverse-search",
34
- "copyright-check",
35
- "image-analysis"
36
- ],
37
- "author": "CopySeeker <support@copyseeker.net>",
38
- "license": "MIT",
39
- "homepage": "https://copyseeker.net",
40
- "repository": {
41
- "type": "git",
42
- "url": "https://github.com/copyseeker/copyseeker-mcp-server.git"
43
- },
44
- "bugs": {
45
- "url": "https://github.com/copyseeker/copyseeker-mcp-server/issues"
46
- },
47
- "engines": {
48
- "node": ">=18.0.0"
49
- },
50
- "files": [
51
- "build/**/*",
52
- "README.md",
53
- "LICENSE"
54
- ]
2
+ "name": "copyseeker-mcp-server",
3
+ "version": "2.0.1",
4
+ "description": "MCP server for Copyseeker: reverse image search, AI image detection and NSFW detection for Claude, Cursor, VS Code Copilot, Codex, Gemini CLI and other AI assistants",
5
+ "type": "module",
6
+ "bin": {
7
+ "copyseeker-mcp": "build/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc -p tsconfig.build.json",
11
+ "typecheck": "tsc --noEmit",
12
+ "test": "npm run build && node --test --import tsx \"test/**/*.test.ts\"",
13
+ "start": "node build/index.js",
14
+ "prepublishOnly": "npm test"
15
+ },
16
+ "dependencies": {
17
+ "@modelcontextprotocol/server": "^2.4.0",
18
+ "zod": "^4.2.0"
19
+ },
20
+ "devDependencies": {
21
+ "@modelcontextprotocol/client": "^2.4.0",
22
+ "@types/node": "^20.19.0",
23
+ "tsx": "^4.23.0",
24
+ "typescript": "^5.9.3"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "copyseeker",
30
+ "reverse-image-search",
31
+ "ai-image-detection",
32
+ "nsfw-detection",
33
+ "image-search",
34
+ "copyright",
35
+ "mcp-server",
36
+ "claude",
37
+ "cursor",
38
+ "vscode",
39
+ "copilot",
40
+ "codex",
41
+ "gemini",
42
+ "ai-detection",
43
+ "deepfake-detection"
44
+ ],
45
+ "author": "Copyseeker <support@copyseeker.net>",
46
+ "license": "MIT",
47
+ "homepage": "https://copyseeker.net/apis",
48
+ "engines": {
49
+ "node": ">=20"
50
+ },
51
+ "files": [
52
+ "build/**/*",
53
+ "README.md",
54
+ "LICENSE"
55
+ ],
56
+ "mcpName": "net.copyseeker/mcp"
55
57
  }