// npm 패키지
mcp-echarts
❤️ Generate visual charts using Apache ECharts with AI MCP dynamically.
주간
667
월간
2,051
버전
10
메인테이너
1
라이선스
MIT
최초 publish
2025-06-13
publisher
atool
tarball
7,495,734 B
AUTO-PUBLISHED·1개 버전 인덱싱됨·최근 publish: 2026-01-30
// publisher 캠페인by atool
이 계정에서 catch된 패키지 9건고립된 catch가 아닙니다. 동일 publisher가 8개의 다른 패키지를 추가로 발행했고, 모두 파이프라인이 catch했습니다 — 일회성이 아닌 조직적 캠페인의 형태. 아래 링크는 각 형제 catch의 분석으로 이동합니다.
// offending code· @0.7.1· no static-pattern hits
llm: benign · 0.85→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
- @0.7.1··AUTO-PUBLISHED·publisher: atoolheuristic 75/100static flags 0llm benign (0.85) via ollamamature-packagepublisher-multi-name-burst:5osv-flagged:MAL-2026-4146
→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
// offending code· no static-pattern hits
--- install scripts --- ### prepare husky && npm run build ### prepublishOnly npm run build --- package.json (entry) --- { "name": "mcp-echarts", "description": "❤️ Generate visual charts using Apache ECharts with AI MCP dynamically.", "version": "0.7.1", "main": "build/index.js", "scripts": { "test": "vitest", "prebuild": "rm -rf build/*", "build": "tsc && tsc-alias -p tsconfig.json", "start": "npm run build && npx @modelcontextprotocol/inspector node build/index.js", "prepare": "husky && npm run build", "prepublishOnly": "npm run build" }, "bin": { "mcp-echarts": "./build/index.js" }, "files": ["build", "fonts"], "keywords": ["mcp", "echarts", "visualization", "chart", "mcp-echarts"], "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", "@napi-rs/canvas": "^0.1.73", "dotenv": "^17.2.1", "echarts": "^6.0.0", "express": "^5.1.0", "minio": "^8.0.5", "zod": "^3.25.16" }, "devDependencies": { "@biomejs/biome": "1.9.4", "@modelcontextprotocol/inspector": "^0.15.0", "@types/express": "^5.0.3", "@types/node": "^22.15.21", "@types/pixelmatch": "^5.2.6", "@types/pngjs": "^6.0.5", "husky": "^9.1.7", "lint-staged": "^15.5.2", "pixelmatch": "^7.1.0", "pngjs": "^7.0.0", "tsc-alias": --- index.js (entry) --- #!/usr/bin/env node "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_crypto_1 = require("node:crypto"); const node_process_1 = __importDefault(require("node:process")); const node_util_1 = require("node:util"); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const sse_js_1 = require("@modelcontextprotocol/sdk/server/ss --- bundled output (OSV-MAL flagged — LLM scope expansion) --- --- build/index.js (bundled) --- #!/usr/bin/env node "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_crypto_1 = require("node:crypto"); const node_process_1 = __importDefault(require("node:process")); const node_util_1 = require("node:util"); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js"); const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); const dotenv_1 = require("dotenv"); const express_1 = __importDefault(require("express")); const tools_1 = require("./tools/index.js"); // Load environment variables from .env file (completely silent to avoid stdout contamination) node_process_1.default.env.DOTENV_CONFIG_QUIET = "true"; (0, dotenv_1.config)({ override: false, debug: false }); /** * MCP Server for ECharts. * This server provides tools for generating ECharts visualizations and validate ECharts configurations. */ function createEChartsServer() { const server = new mcp_js_1.McpServer({ --- build/utils/imageHandler.js (bundled) --- "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateChartImage = generateChartImage; const minio_1 = require("./minio.js"); const render_1 = require("./render.js"); /** * Unified chart image generation method * Automatically decides whether to return Base64 image data or MinIO URL based on configuration * * @param echartsOption ECharts configuration options * @param width Image width, default 800 * @param height Image height, default 600 * @param theme Theme, default 'default' * @param outputType Output type, default 'png' * @param toolName Tool name (for debug logging) * @returns Unified MCP response content format */ function generateChartImage(echartsOption_1) { return __awaiter(this, arguments, void 0, function* (echartsOption, width = 800, height = 600, theme = "default", outputType = "png", toolName = "unknown") { // Debug logging if (process.env.DEBUG_MCP_ECHARTS) { console.error(`[DEBUG] ${toolName} generating chart:`, { width, height, theme, outputType, optionKeys: Object.keys(echartsOption), }); } try { // Render chart const result = yield (0, render_1.renderECharts)(echartsOp --- build/utils/index.js (bundled) --- "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateChartImage = exports.renderECharts = exports.zodToJsonSchema = void 0; var schema_1 = require("./schema.js"); Object.defineProperty(exports, "zodToJsonSchema", { enumerable: true, get: function () { return schema_1.zodToJsonSchema; } }); var render_1 = require("./render.js"); Object.defineProperty(exports, "renderECharts", { enumerable: true, get: function () { return render_1.renderECharts; } }); var imageHandler_1 = require("./imageHandler.js"); Object.defineProperty(exports, "generateChartImage", { enumerable: true, get: function () { return imageHandler_1.generateChartImage; } }); --- build/utils/minio.js (bundled) --- "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMinIOConfigured = isMinIOConfigured; exports.storeBufferToMinIO = storeBufferToMinIO; const node_fs_1 = __importDefault(require("node:fs")); const node_os_1 = __importDefault(require("node:os")); const node_path_1 = __importDefault(require("node:path")); const minio_1 = require("minio"); const BUCKET_NAME = process.env.MINIO_BUCKET_NAME || "mcp-echarts"; /** * Check if MinIO is properly configured */ function isMinIOConfigured() { return !!(process.env.MINIO_ACCESS_KEY && process.env.MINIO_SECRET_KEY && process.env.MINIO_ENDPOINT); } /** * Get MinIO client (only create when properly configured) */ function getMinIOClient() { if (!isMinIOConfigured()) { return null; } const endpoint = process.env.MINIO_ENDPOINT; const accessKey = process.env.MINIO_ACCESS_KEY; const secretKey = process.env.MINIO_SECRET_KEY; if (!endpoint || !accessKey || !secretKey) { return null; } return new minio_1.Client({ endPoint: endpoint, port: Number.parseInt(process.env.MINIO_PORT || "9000"), useSSL: process --- build/utils/render.js (bundled) --- "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModul
