@smallpict/mcp 0.0.2

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 ADDED
@@ -0,0 +1,72 @@
1
+ # @smallpict/mcp
2
+
3
+ Official **Model Context Protocol (MCP)** server for [SmallPict](https://smallpict.app), the high-performance image optimization and AVIF/WebP transcoding platform.
4
+
5
+ This MCP server equips AI coding assistants (such as **Claude Desktop**, **Cursor**, **Windsurf**, and **Antigravity**) with direct capabilities to compress, transcode, and maintain web image assets.
6
+
7
+ ---
8
+
9
+ ## Capabilities / Tools
10
+
11
+ 1. **`smallpict_optimize_image`**:
12
+ - Compresses local image files or remote URLs to **WebP** or **AVIF**.
13
+ - Supports **Lossy** (`quality: 1-100`) and **Lossless** (`lossless: true`) modes.
14
+ - Downscaling constraints: `maxDimension` (longest edge), `maxWidth`, and `maxHeight`.
15
+ - Automatically writes the optimized image back to the workspace if `outputPath` is provided.
16
+ - Outputs full telemetry: original size, compressed size, and percentage saved (up to 85%).
17
+ 2. **`smallpict_get_quota`**:
18
+ - Inspects the account's active plan, processed bytes, and remaining monthly quota.
19
+ 3. **`smallpict_purge_cdn_cache`**:
20
+ - Invalidates cached asset URLs on Cloudflare Edge CDN PoPs globally.
21
+
22
+ ---
23
+
24
+ ## Installation & Setup
25
+
26
+ ### 1. Build from Source
27
+ ```bash
28
+ cd /Users/ariefjr/Documents/hermoves-id/wordpres-plugins/smallpict-mcp
29
+ npm install
30
+ npm run build
31
+ ```
32
+
33
+ ### 2. Configure in Claude Desktop
34
+ Add the following to your `claude_desktop_config.json`:
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "smallpict": {
40
+ "command": "node",
41
+ "args": ["/Users/ariefjr/Documents/hermoves-id/wordpres-plugins/smallpict-mcp/dist/index.js"],
42
+ "env": {
43
+ "SMALLPICT_API_KEY": "sp_sdk_live_...",
44
+ "SMALLPICT_SECRET_KEY": "sp_sec_..."
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### 3. Configure in Cursor (`~/.cursor/mcp.json`)
52
+ ```json
53
+ {
54
+ "mcpServers": {
55
+ "smallpict": {
56
+ "command": "node",
57
+ "args": ["/Users/ariefjr/Documents/hermoves-id/wordpres-plugins/smallpict-mcp/dist/index.js"],
58
+ "env": {
59
+ "SMALLPICT_API_KEY": "sp_sdk_live_...",
60
+ "SMALLPICT_SECRET_KEY": "sp_sec_..."
61
+ }
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Environment Variables
70
+ - `SMALLPICT_API_KEY` (Required): Your API key (`sp_sdk_...` or sandbox evaluation key `sp_test_...`).
71
+ - `SMALLPICT_SECRET_KEY` (Required for HMAC): Your API secret key.
72
+ - `SMALLPICT_BASE_URL` (Optional): API endpoint URL (default: `https://api.smallpict.app`).
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+
7
+ // src/tools/optimize.ts
8
+ import { z } from "zod";
9
+ import fs from "fs/promises";
10
+ import path from "path";
11
+
12
+ // src/client.ts
13
+ import { SmallPictClient } from "@smallpict/sdk";
14
+ var clientInstance = null;
15
+ function getSmallPictClient() {
16
+ if (clientInstance) {
17
+ return clientInstance;
18
+ }
19
+ const apiKey = process.env.SMALLPICT_API_KEY;
20
+ const secretKey = process.env.SMALLPICT_SECRET_KEY;
21
+ const baseUrl = process.env.SMALLPICT_BASE_URL || "https://api.smallpict.app";
22
+ if (!apiKey) {
23
+ throw new Error(
24
+ "Missing required environment variable SMALLPICT_API_KEY. Please provide SMALLPICT_API_KEY in MCP server configuration."
25
+ );
26
+ }
27
+ clientInstance = new SmallPictClient({
28
+ apiKey,
29
+ secretKey,
30
+ baseUrl
31
+ });
32
+ return clientInstance;
33
+ }
34
+
35
+ // src/tools/optimize.ts
36
+ var optimizeSchema = {
37
+ filePath: z.string().describe("Local file path or remote image URL (http/https) to optimize"),
38
+ format: z.enum(["webp", "avif", "auto"]).default("webp").describe("Target image format (webp, avif, or auto)"),
39
+ quality: z.number().min(1).max(100).default(80).optional().describe("Compression quality (1-100, default: 80)"),
40
+ maxDimension: z.number().positive().optional().describe("Optional maximum bounding dimension (longest edge) in pixels for image downscaling"),
41
+ maxWidth: z.number().positive().optional().describe("Optional maximum width in pixels for image resizing"),
42
+ maxHeight: z.number().positive().optional().describe("Optional maximum height in pixels for image resizing"),
43
+ lossless: z.boolean().default(false).optional().describe("Enable lossless compression mode (pixel-perfect fidelity, ignores quality)"),
44
+ outputPath: z.string().optional().describe("Optional local path where the optimized image should be saved")
45
+ };
46
+ function detectMimeType(filePath) {
47
+ const ext = path.extname(filePath).toLowerCase();
48
+ switch (ext) {
49
+ case ".png":
50
+ return "image/png";
51
+ case ".webp":
52
+ return "image/webp";
53
+ case ".avif":
54
+ return "image/avif";
55
+ case ".gif":
56
+ return "image/gif";
57
+ case ".jpg":
58
+ case ".jpeg":
59
+ default:
60
+ return "image/jpeg";
61
+ }
62
+ }
63
+ async function handleOptimize(args) {
64
+ const client = getSmallPictClient();
65
+ const format = args.format || "webp";
66
+ const quality = args.quality ?? 80;
67
+ const lossless = args.lossless ?? false;
68
+ console.error(
69
+ `[smallpict-mcp] Optimizing image: ${args.filePath} -> ${format} (q=${quality}, lossless=${lossless}${args.maxDimension ? `, maxDim=${args.maxDimension}` : ""})`
70
+ );
71
+ let isRemote = args.filePath.startsWith("http://") || args.filePath.startsWith("https://");
72
+ let source;
73
+ let filename = path.basename(args.filePath);
74
+ let mimeType = detectMimeType(args.filePath);
75
+ if (isRemote) {
76
+ source = args.filePath;
77
+ } else {
78
+ const resolvedPath = path.resolve(process.cwd(), args.filePath);
79
+ const fileBuffer = await fs.readFile(resolvedPath);
80
+ source = new Uint8Array(fileBuffer);
81
+ filename = path.basename(resolvedPath);
82
+ mimeType = detectMimeType(resolvedPath);
83
+ }
84
+ const result = await client.optimize(source, {
85
+ filename,
86
+ mimeType,
87
+ format,
88
+ quality,
89
+ maxWidth: args.maxWidth,
90
+ maxHeight: args.maxHeight,
91
+ lossless,
92
+ ...args.maxDimension ? { maxDimension: args.maxDimension } : {}
93
+ });
94
+ let savedMessage = "";
95
+ if (args.outputPath && result.url) {
96
+ const targetPath = path.resolve(process.cwd(), args.outputPath);
97
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
98
+ console.error(`[smallpict-mcp] Downloading optimized image from ${result.url} to ${targetPath}`);
99
+ const res = await fetch(result.url);
100
+ if (!res.ok) {
101
+ throw new Error(`Failed to download optimized asset from ${result.url}: ${res.statusText}`);
102
+ }
103
+ const arrayBuffer = await res.arrayBuffer();
104
+ await fs.writeFile(targetPath, Buffer.from(arrayBuffer));
105
+ savedMessage = `
106
+ - **Saved to**: \`${targetPath}\``;
107
+ }
108
+ const formattedOriginal = (result.originalSize / 1024).toFixed(1) + " KB";
109
+ const formattedCompressed = (result.compressedSize / 1024).toFixed(1) + " KB";
110
+ return {
111
+ content: [
112
+ {
113
+ type: "text",
114
+ text: `### \u2705 SmallPict Image Optimization Succeeded
115
+ - **File**: \`${filename}\`
116
+ - **Output Format**: \`${result.format}\`
117
+ - **Compression Mode**: \`${lossless ? "Lossless (Pixel-Perfect)" : `Lossy (q=${quality})`}\`${args.maxDimension ? `
118
+ - **Max Dimension Constraint**: \`${args.maxDimension}px\`` : ""}
119
+ - **Original Size**: ${formattedOriginal}
120
+ - **Optimized Size**: ${formattedCompressed}
121
+ - **Bandwidth Savings**: **-${result.savingsPercentage}%** (${(result.bytesSaved / 1024).toFixed(1)} KB saved)
122
+ - **Job ID**: \`${result.jobId}\`
123
+ - **CDN Delivery URL**: ${result.url || "N/A"}${savedMessage}
124
+ `
125
+ }
126
+ ]
127
+ };
128
+ }
129
+
130
+ // src/tools/quota.ts
131
+ var quotaSchema = {};
132
+ async function handleGetQuota() {
133
+ const client = getSmallPictClient();
134
+ console.error("[smallpict-mcp] Fetching SmallPict account quota...");
135
+ const quota = await client.getQuota();
136
+ const formatBytes = (bytes) => {
137
+ if (bytes >= 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB";
138
+ if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + " MB";
139
+ return (bytes / 1024).toFixed(1) + " KB";
140
+ };
141
+ return {
142
+ content: [
143
+ {
144
+ type: "text",
145
+ text: `### \u{1F4CA} SmallPict Quota & Plan Status
146
+ - **Current Plan**: \`${quota.plan.toUpperCase()}\`
147
+ - **Monthly Usage**: ${formatBytes(quota.bytesUsed)} / ${formatBytes(quota.quotaLimit)} (**${quota.quotaPercentage}%**)
148
+ - **CDN Egress Used**: ${formatBytes(quota.cdnEgressUsedBytes || 0)}
149
+ - **Active API Keys**: ${quota.activeKeysCount ?? "N/A"}
150
+ - **Registered Sites**: ${quota.activeSitesCount ?? "N/A"}
151
+ `
152
+ }
153
+ ]
154
+ };
155
+ }
156
+
157
+ // src/tools/purge.ts
158
+ import { z as z2 } from "zod";
159
+ var purgeSchema = {
160
+ urls: z2.array(z2.string()).describe("List of asset URLs to invalidate on Cloudflare Edge CDN"),
161
+ purgeType: z2.enum(["url", "all"]).default("url").optional().describe("Purge scope: url or all (default: url)")
162
+ };
163
+ async function handlePurge(args) {
164
+ const client = getSmallPictClient();
165
+ console.error(`[smallpict-mcp] Purging ${args.urls.length} asset(s) from CDN edge cache...`);
166
+ const response = await client.purgeCdn({
167
+ urls: args.urls,
168
+ purgeType: args.purgeType || "url"
169
+ });
170
+ return {
171
+ content: [
172
+ {
173
+ type: "text",
174
+ text: `### \u{1F680} SmallPict CDN Cache Purged
175
+ - **Status**: \`success\`
176
+ - **Purged URLs**:
177
+ ${args.urls.map((u) => ` - \`${u}\``).join("\n")}
178
+ - **Message**: ${response.message || "Assets successfully purged from Cloudflare edge locations"}
179
+ `
180
+ }
181
+ ]
182
+ };
183
+ }
184
+
185
+ // src/index.ts
186
+ var server = new McpServer({
187
+ name: "smallpict-mcp",
188
+ version: "0.0.2"
189
+ });
190
+ server.tool(
191
+ "smallpict_optimize_image",
192
+ "Compress and convert local or remote images (JPEG, PNG, GIF) into modern WebP/AVIF using SmallPict API with up to 85% bandwidth reduction",
193
+ optimizeSchema,
194
+ handleOptimize
195
+ );
196
+ server.tool(
197
+ "smallpict_get_quota",
198
+ "Inspect active SmallPict subscription plan, monthly bytes consumed, and remaining bandwidth quota",
199
+ quotaSchema,
200
+ handleGetQuota
201
+ );
202
+ server.tool(
203
+ "smallpict_purge_cdn_cache",
204
+ "Invalidate cached image URLs across Cloudflare Edge CDN PoPs",
205
+ purgeSchema,
206
+ handlePurge
207
+ );
208
+ async function main() {
209
+ const transport = new StdioServerTransport();
210
+ await server.connect(transport);
211
+ console.error("\u2705 [smallpict-mcp] Server running on stdio transport");
212
+ }
213
+ main().catch((error) => {
214
+ console.error("\u274C [smallpict-mcp] Fatal error:", error);
215
+ process.exit(1);
216
+ });
217
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/tools/optimize.ts","../src/client.ts","../src/tools/quota.ts","../src/tools/purge.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { optimizeSchema, handleOptimize } from './tools/optimize.js';\nimport { quotaSchema, handleGetQuota } from './tools/quota.js';\nimport { purgeSchema, handlePurge } from './tools/purge.js';\n\nconst server = new McpServer({\n name: 'smallpict-mcp',\n version: '0.0.2',\n});\n\n// 1. Tool: Optimize Image\nserver.tool(\n 'smallpict_optimize_image',\n 'Compress and convert local or remote images (JPEG, PNG, GIF) into modern WebP/AVIF using SmallPict API with up to 85% bandwidth reduction',\n optimizeSchema,\n handleOptimize\n);\n\n// 2. Tool: Get Quota\nserver.tool(\n 'smallpict_get_quota',\n 'Inspect active SmallPict subscription plan, monthly bytes consumed, and remaining bandwidth quota',\n quotaSchema,\n handleGetQuota\n);\n\n// 3. Tool: Purge CDN Cache\nserver.tool(\n 'smallpict_purge_cdn_cache',\n 'Invalidate cached image URLs across Cloudflare Edge CDN PoPs',\n purgeSchema,\n handlePurge\n);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('✅ [smallpict-mcp] Server running on stdio transport');\n}\n\nmain().catch((error) => {\n console.error('❌ [smallpict-mcp] Fatal error:', error);\n process.exit(1);\n});\n","import { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { getSmallPictClient } from '../client.js';\n\nexport const optimizeSchema = {\n filePath: z.string().describe('Local file path or remote image URL (http/https) to optimize'),\n format: z.enum(['webp', 'avif', 'auto']).default('webp').describe('Target image format (webp, avif, or auto)'),\n quality: z.number().min(1).max(100).default(80).optional().describe('Compression quality (1-100, default: 80)'),\n maxDimension: z.number().positive().optional().describe('Optional maximum bounding dimension (longest edge) in pixels for image downscaling'),\n maxWidth: z.number().positive().optional().describe('Optional maximum width in pixels for image resizing'),\n maxHeight: z.number().positive().optional().describe('Optional maximum height in pixels for image resizing'),\n lossless: z.boolean().default(false).optional().describe('Enable lossless compression mode (pixel-perfect fidelity, ignores quality)'),\n outputPath: z.string().optional().describe('Optional local path where the optimized image should be saved'),\n};\n\nfunction detectMimeType(filePath: string): string {\n const ext = path.extname(filePath).toLowerCase();\n switch (ext) {\n case '.png':\n return 'image/png';\n case '.webp':\n return 'image/webp';\n case '.avif':\n return 'image/avif';\n case '.gif':\n return 'image/gif';\n case '.jpg':\n case '.jpeg':\n default:\n return 'image/jpeg';\n }\n}\n\nexport async function handleOptimize(args: {\n filePath: string;\n format?: 'webp' | 'avif' | 'auto';\n quality?: number;\n maxDimension?: number;\n maxWidth?: number;\n maxHeight?: number;\n lossless?: boolean;\n outputPath?: string;\n}) {\n const client = getSmallPictClient();\n const format = args.format || 'webp';\n const quality = args.quality ?? 80;\n const lossless = args.lossless ?? false;\n\n console.error(\n `[smallpict-mcp] Optimizing image: ${args.filePath} -> ${format} (q=${quality}, lossless=${lossless}${args.maxDimension ? `, maxDim=${args.maxDimension}` : ''})`\n );\n\n let isRemote = args.filePath.startsWith('http://') || args.filePath.startsWith('https://');\n let source: string | Uint8Array;\n let filename = path.basename(args.filePath);\n let mimeType = detectMimeType(args.filePath);\n\n if (isRemote) {\n source = args.filePath;\n } else {\n const resolvedPath = path.resolve(process.cwd(), args.filePath);\n const fileBuffer = await fs.readFile(resolvedPath);\n source = new Uint8Array(fileBuffer);\n filename = path.basename(resolvedPath);\n mimeType = detectMimeType(resolvedPath);\n }\n\n const result = await client.optimize(source, {\n filename,\n mimeType,\n format,\n quality,\n maxWidth: args.maxWidth,\n maxHeight: args.maxHeight,\n lossless,\n ...(args.maxDimension ? { maxDimension: args.maxDimension } : {}),\n } as any);\n\n let savedMessage = '';\n if (args.outputPath && result.url) {\n const targetPath = path.resolve(process.cwd(), args.outputPath);\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n \n console.error(`[smallpict-mcp] Downloading optimized image from ${result.url} to ${targetPath}`);\n const res = await fetch(result.url);\n if (!res.ok) {\n throw new Error(`Failed to download optimized asset from ${result.url}: ${res.statusText}`);\n }\n const arrayBuffer = await res.arrayBuffer();\n await fs.writeFile(targetPath, Buffer.from(arrayBuffer));\n savedMessage = `\\n- **Saved to**: \\`${targetPath}\\``;\n }\n\n const formattedOriginal = (result.originalSize / 1024).toFixed(1) + ' KB';\n const formattedCompressed = (result.compressedSize / 1024).toFixed(1) + ' KB';\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `### ✅ SmallPict Image Optimization Succeeded\n- **File**: \\`${filename}\\`\n- **Output Format**: \\`${result.format}\\`\n- **Compression Mode**: \\`${lossless ? 'Lossless (Pixel-Perfect)' : `Lossy (q=${quality})`}\\`${args.maxDimension ? `\\n- **Max Dimension Constraint**: \\`${args.maxDimension}px\\`` : ''}\n- **Original Size**: ${formattedOriginal}\n- **Optimized Size**: ${formattedCompressed}\n- **Bandwidth Savings**: **-${result.savingsPercentage}%** (${((result.bytesSaved) / 1024).toFixed(1)} KB saved)\n- **Job ID**: \\`${result.jobId}\\`\n- **CDN Delivery URL**: ${result.url || 'N/A'}${savedMessage}\n`,\n },\n ],\n };\n}\n","import { SmallPictClient } from '@smallpict/sdk';\n\nlet clientInstance: SmallPictClient | null = null;\n\nexport function getSmallPictClient(): SmallPictClient {\n if (clientInstance) {\n return clientInstance;\n }\n\n const apiKey = process.env.SMALLPICT_API_KEY;\n const secretKey = process.env.SMALLPICT_SECRET_KEY;\n const baseUrl = process.env.SMALLPICT_BASE_URL || 'https://api.smallpict.app';\n\n if (!apiKey) {\n throw new Error(\n 'Missing required environment variable SMALLPICT_API_KEY. Please provide SMALLPICT_API_KEY in MCP server configuration.'\n );\n }\n\n clientInstance = new SmallPictClient({\n apiKey,\n secretKey,\n baseUrl,\n });\n\n return clientInstance;\n}\n","import { getSmallPictClient } from '../client.js';\n\nexport const quotaSchema = {};\n\nexport async function handleGetQuota() {\n const client = getSmallPictClient();\n\n console.error('[smallpict-mcp] Fetching SmallPict account quota...');\n const quota = await client.getQuota();\n\n const formatBytes = (bytes: number) => {\n if (bytes >= 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB';\n if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + ' MB';\n return (bytes / 1024).toFixed(1) + ' KB';\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `### 📊 SmallPict Quota & Plan Status\n- **Current Plan**: \\`${quota.plan.toUpperCase()}\\`\n- **Monthly Usage**: ${formatBytes(quota.bytesUsed)} / ${formatBytes(quota.quotaLimit)} (**${quota.quotaPercentage}%**)\n- **CDN Egress Used**: ${formatBytes(quota.cdnEgressUsedBytes || 0)}\n- **Active API Keys**: ${quota.activeKeysCount ?? 'N/A'}\n- **Registered Sites**: ${quota.activeSitesCount ?? 'N/A'}\n`,\n },\n ],\n };\n}\n","import { z } from 'zod';\nimport { getSmallPictClient } from '../client.js';\n\nexport const purgeSchema = {\n urls: z.array(z.string()).describe('List of asset URLs to invalidate on Cloudflare Edge CDN'),\n purgeType: z.enum(['url', 'all']).default('url').optional().describe('Purge scope: url or all (default: url)'),\n};\n\nexport async function handlePurge(args: { urls: string[]; purgeType?: 'url' | 'all' }) {\n const client = getSmallPictClient();\n\n console.error(`[smallpict-mcp] Purging ${args.urls.length} asset(s) from CDN edge cache...`);\n const response = await client.purgeCdn({\n urls: args.urls,\n purgeType: args.purgeType || 'url',\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `### 🚀 SmallPict CDN Cache Purged\n- **Status**: \\`success\\`\n- **Purged URLs**:\n${args.urls.map((u) => ` - \\`${u}\\``).join('\\n')}\n- **Message**: ${response.message || 'Assets successfully purged from Cloudflare edge locations'}\n`,\n },\n ],\n };\n}\n"],"mappings":"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","names":["z","z"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@smallpict/mcp",
3
+ "version": "0.0.2",
4
+ "description": "Official Model Context Protocol (MCP) server for SmallPict Image Optimization",
5
+ "type": "module",
6
+ "bin": {
7
+ "smallpict-mcp": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "typecheck": "tsc --noEmit",
19
+ "prepublishOnly": "npm run typecheck && npm run build",
20
+ "start": "node dist/index.js"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "smallpict",
26
+ "image-optimization",
27
+ "webp",
28
+ "avif",
29
+ "ai-agent"
30
+ ],
31
+ "author": "SmallPict Engineering <support@smallpict.app>",
32
+ "license": "MIT",
33
+ "homepage": "https://smallpict.app",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/tuxnoob/smallpict-mcp.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/tuxnoob/smallpict-mcp/issues"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "provenance": true
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.6.1",
47
+ "@smallpict/sdk": "^0.0.2",
48
+ "zod": "^3.24.2"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.17.0",
52
+ "tsup": "^8.3.6",
53
+ "typescript": "^5.7.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ }
58
+ }