Compare commits

..

3 Commits

Author SHA1 Message Date
dayuan.jiang
6ed05ed24d chore: always bundle latest draw.io version in Electron builds
Remove pinned v29.3.5 tag so the build always clones the latest draw.io.
This adds the Animated GIF export and other new features to the Electron app.

Closes #770
2026-04-06 10:13:40 +09:00
Dayuan Jiang
31819f413c fix: add 10MB body size limit to MCP HTTP endpoints (#791)
All three POST handlers (/api/state, /api/restore, /api/history-svg)
now use a shared readBody() helper that enforces a 10MB limit and
returns 413 if exceeded, preventing memory exhaustion from oversized
requests.

Bumps @next-ai-drawio/mcp-server to 0.1.19.
2026-04-06 09:14:20 +09:00
Dayuan Jiang
41c410c2ba fix: bind MCP server HTTP to 127.0.0.1 only (#787)
The embedded HTTP sidecar was using server.listen(port) without a host
argument, which defaults to 0.0.0.0 (all interfaces). This exposed the
server to the local network. Now explicitly binds to 127.0.0.1.

Also excludes release/ from tsconfig to fix pre-existing TS errors.

Bumps @next-ai-drawio/mcp-server to 0.1.18.
2026-04-06 09:04:38 +09:00
3 changed files with 29 additions and 18 deletions

View File

@@ -37,7 +37,7 @@ jobs:
- name: Download draw.io static files for offline use - name: Download draw.io static files for offline use
run: | run: |
rm -rf public/drawio rm -rf public/drawio
git clone --depth 1 --branch v29.3.5 https://github.com/jgraph/drawio.git /tmp/drawio git clone --depth 1 https://github.com/jgraph/drawio.git /tmp/drawio
mkdir -p public/drawio mkdir -p public/drawio
cp -r /tmp/drawio/src/main/webapp/* public/drawio/ cp -r /tmp/drawio/src/main/webapp/* public/drawio/
rm -rf public/drawio/WEB-INF rm -rf public/drawio/WEB-INF
@@ -70,7 +70,7 @@ jobs:
shell: bash shell: bash
run: | run: |
rm -rf public/drawio rm -rf public/drawio
git clone --depth 1 --branch v29.3.5 https://github.com/jgraph/drawio.git /tmp/drawio git clone --depth 1 https://github.com/jgraph/drawio.git /tmp/drawio
mkdir -p public/drawio mkdir -p public/drawio
cp -r /tmp/drawio/src/main/webapp/* public/drawio/ cp -r /tmp/drawio/src/main/webapp/* public/drawio/
rm -rf public/drawio/WEB-INF rm -rf public/drawio/WEB-INF

View File

@@ -1,6 +1,6 @@
{ {
"name": "@next-ai-drawio/mcp-server", "name": "@next-ai-drawio/mcp-server",
"version": "0.1.18", "version": "0.1.19",
"description": "MCP server for Next AI Draw.io - AI-powered diagram generation with real-time browser preview", "description": "MCP server for Next AI Draw.io - AI-powered diagram generation with real-time browser preview",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",

View File

@@ -4,6 +4,29 @@
*/ */
import http from "node:http" import http from "node:http"
const MAX_BODY_BYTES = 10 * 1024 * 1024 // 10 MiB
function readBody(
req: http.IncomingMessage,
res: http.ServerResponse,
cb: (body: string) => void,
): void {
let body = ""
let size = 0
req.on("data", (chunk: Buffer) => {
size += chunk.length
if (size > MAX_BODY_BYTES) {
res.writeHead(413, { "Content-Type": "application/json" })
res.end(JSON.stringify({ error: "Payload too large" }))
req.destroy()
return
}
body += chunk
})
req.on("end", () => cb(body))
}
import { import {
addHistory, addHistory,
clearHistory, clearHistory,
@@ -266,11 +289,7 @@ function handleStateApi(
}), }),
) )
} else if (req.method === "POST") { } else if (req.method === "POST") {
let body = "" readBody(req, res, (body) => {
req.on("data", (chunk) => {
body += chunk
})
req.on("end", () => {
try { try {
const data = JSON.parse(body) const data = JSON.parse(body)
const { sessionId } = data const { sessionId } = data
@@ -347,11 +366,7 @@ function handleRestoreApi(
return return
} }
let body = "" readBody(req, res, (body) => {
req.on("data", (chunk) => {
body += chunk
})
req.on("end", () => {
try { try {
const { sessionId, index } = JSON.parse(body) const { sessionId, index } = JSON.parse(body)
if (!sessionId || index === undefined) { if (!sessionId || index === undefined) {
@@ -393,11 +408,7 @@ function handleHistorySvgApi(
return return
} }
let body = "" readBody(req, res, (body) => {
req.on("data", (chunk) => {
body += chunk
})
req.on("end", () => {
try { try {
const { sessionId, svg } = JSON.parse(body) const { sessionId, svg } = JSON.parse(body)
if (!sessionId || !svg) { if (!sessionId || !svg) {