chore: rename project to excalidraw-mcp-sentinel
- Package name: @sanjibdevnath/mcp-excalidraw-local → excalidraw-mcp-sentinel - GitHub repo: celstnblacc/mcp-excalidraw-local → celstnblacc/excalidraw-mcp-sentinel - Docker images, CLI binary, CI workflows, docs all updated - Version reset to 1.0.0 for independent release track - Added "Why this fork?" section to README - Removed superseded planning docs (PLAN.md, PLAN_v2.md, REVIEW.md, HANDOFF.md) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
8f9fe3fa08
commit
9fb8ce34ec
@@ -17,8 +17,8 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IMAGE_NAME_MCP: sanjibdevnath/mcp-excalidraw-local
|
IMAGE_NAME_MCP: celstnblacc/excalidraw-mcp-sentinel
|
||||||
IMAGE_NAME_CANVAS: sanjibdevnath/mcp-excalidraw-local-canvas
|
IMAGE_NAME_CANVAS: celstnblacc/excalidraw-mcp-sentinel-canvas
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-changes:
|
check-changes:
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
- name: Check if version exists on NPM
|
- name: Check if version exists on NPM
|
||||||
id: check
|
id: check
|
||||||
run: |
|
run: |
|
||||||
if npm view @sanjibdevnath/mcp-excalidraw-local@${{ steps.version.outputs.version }} version 2>/dev/null; then
|
if npm view excalidraw-mcp-sentinel@${{ steps.version.outputs.version }} version 2>/dev/null; then
|
||||||
echo "exists=true" >> "$GITHUB_OUTPUT"
|
echo "exists=true" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||||
|
|||||||
@@ -140,8 +140,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure git
|
- name: Configure git
|
||||||
run: |
|
run: |
|
||||||
git config user.name "sanjibdevnathlabs-release-bot[bot]"
|
git config user.name "excalidraw-sentinel-release-bot[bot]"
|
||||||
git config user.email "${{ secrets.APP_ID }}+sanjibdevnathlabs-release-bot[bot]@users.noreply.github.com"
|
git config user.email "${{ secrets.APP_ID }}+excalidraw-sentinel-release-bot[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
- name: Bump version in package.json
|
- name: Bump version in package.json
|
||||||
run: |
|
run: |
|
||||||
@@ -170,7 +170,7 @@ jobs:
|
|||||||
|
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
npm install @sanjibdevnath/mcp-excalidraw-local@${{ needs.check.outputs.new_version }}
|
npm install excalidraw-mcp-sentinel@${{ needs.check.outputs.new_version }}
|
||||||
```
|
```
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
@@ -208,7 +208,7 @@ jobs:
|
|||||||
id: check-npm
|
id: check-npm
|
||||||
run: |
|
run: |
|
||||||
VERSION=$(node -p "require('./package.json').version")
|
VERSION=$(node -p "require('./package.json').version")
|
||||||
if npm view @sanjibdevnath/mcp-excalidraw-local@$VERSION version 2>/dev/null; then
|
if npm view excalidraw-mcp-sentinel@$VERSION version 2>/dev/null; then
|
||||||
echo "exists=true" >> "$GITHUB_OUTPUT"
|
echo "exists=true" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||||
@@ -253,8 +253,8 @@ jobs:
|
|||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
sanjibdevnath/mcp-excalidraw-local:latest
|
celstnblacc/excalidraw-mcp-sentinel:latest
|
||||||
sanjibdevnath/mcp-excalidraw-local:v${{ needs.release.outputs.version }}
|
celstnblacc/excalidraw-mcp-sentinel:v${{ needs.release.outputs.version }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
@@ -266,8 +266,8 @@ jobs:
|
|||||||
file: ./Dockerfile.canvas
|
file: ./Dockerfile.canvas
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
sanjibdevnath/mcp-excalidraw-local-canvas:latest
|
celstnblacc/excalidraw-mcp-sentinel-canvas:latest
|
||||||
sanjibdevnath/mcp-excalidraw-local-canvas:v${{ needs.release.outputs.version }}
|
celstnblacc/excalidraw-mcp-sentinel-canvas:v${{ needs.release.outputs.version }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# AGENTS.md
|
# AGENTS.md
|
||||||
|
|
||||||
Agent instructions for mcp-excalidraw-local. Read this before starting any task.
|
Agent instructions for excalidraw-mcp-sentinel. Read this before starting any task.
|
||||||
|
|
||||||
## What This Is
|
## What This Is
|
||||||
|
|
||||||
A fully local, self-hosted Excalidraw MCP server. Single Node.js/TypeScript process
|
A hardened, self-hosted Excalidraw MCP server (`excalidraw-mcp-sentinel`). Single Node.js/TypeScript process
|
||||||
running an MCP server (stdio, 32 tools), an Express+WebSocket canvas server, and
|
running an MCP server (stdio, 32 tools), an Express+WebSocket canvas server, and
|
||||||
SQLite persistence with multi-tenancy.
|
SQLite persistence with multi-tenancy. Forked from [sanjibdevnathlabs/mcp-excalidraw-local](https://github.com/sanjibdevnathlabs/mcp-excalidraw-local).
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ All middleware lives here — do not duplicate in routes:
|
|||||||
|
|
||||||
## Before `npm publish`
|
## Before `npm publish`
|
||||||
|
|
||||||
- [ ] Bump `version` in `package.json` (current: `1.6.2`, next: `1.6.3`)
|
- [ ] Bump `version` in `package.json` (current: `1.0.0`)
|
||||||
- [ ] `npm test` → 369/369
|
- [ ] `npm test` → 369/369
|
||||||
- [ ] `npm run build` → zero errors
|
- [ ] `npm run build` → zero errors
|
||||||
- [ ] `shipguard scan .` → 0 CRITICAL
|
- [ ] `shipguard scan .` → 0 CRITICAL
|
||||||
|
|||||||
@@ -5,6 +5,20 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.0.0] - 2026-03-29
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Renamed project from `@sanjibdevnath/mcp-excalidraw-local` to `excalidraw-mcp-sentinel`
|
||||||
|
- New npm package name: `excalidraw-mcp-sentinel` (unscoped)
|
||||||
|
- GitHub repo: `celstnblacc/excalidraw-mcp-sentinel`
|
||||||
|
- Docker images: `celstnblacc/excalidraw-mcp-sentinel` and `celstnblacc/excalidraw-mcp-sentinel-canvas`
|
||||||
|
- CLI binary renamed: `excalidraw-mcp-sentinel`
|
||||||
|
- Version reset to 1.0.0 for independent release track
|
||||||
|
- Added "Why this fork?" section to README with full attribution
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Superseded planning docs (PLAN.md, PLAN_v2.md, REVIEW.md, HANDOFF.md)
|
||||||
|
|
||||||
## [1.6.3] - 2026-03-29
|
## [1.6.3] - 2026-03-29
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## What This Is
|
## What This Is
|
||||||
|
|
||||||
A fully local, self-hosted Excalidraw MCP server. Single Node.js process that runs an MCP server (stdio, 32 tools), an embedded Express+WebSocket canvas server, and SQLite persistence with multi-tenancy. Forked from [yctimlin/mcp_excalidraw](https://github.com/yctimlin/mcp_excalidraw).
|
A hardened, self-hosted Excalidraw MCP server (`excalidraw-mcp-sentinel`). Single Node.js process that runs an MCP server (stdio, 32 tools), an embedded Express+WebSocket canvas server, and SQLite persistence with multi-tenancy. Forked from [sanjibdevnathlabs/mcp-excalidraw-local](https://github.com/sanjibdevnathlabs/mcp-excalidraw-local) (itself from [yctimlin/mcp_excalidraw](https://github.com/yctimlin/mcp_excalidraw)).
|
||||||
|
|
||||||
## Build & Development Commands
|
## Build & Development Commands
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ node dist/server.js
|
|||||||
curl http://localhost:3000/health
|
curl http://localhost:3000/health
|
||||||
```
|
```
|
||||||
|
|
||||||
There are no unit tests. Validation is done via type checking (`pnpm run type-check`) and build verification. The CI runs `type-check` then `build` across Node 18/20/22.
|
369 tests across unit, API, WebSocket, and regression suites. Run `npm test` or `pnpm test`. CI runs `type-check` then `build` then `test` across Node 18/20/22.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ Two Dockerfiles: `Dockerfile` (MCP server only), `Dockerfile.canvas` (canvas wit
|
|||||||
- Docker: non-root user, resource limits, hardened `.dockerignore`
|
- Docker: non-root user, resource limits, hardened `.dockerignore`
|
||||||
|
|
||||||
### Before running `npm publish`
|
### Before running `npm publish`
|
||||||
- [ ] Bump `version` in `package.json` to match `CHANGELOG.md` entry (currently `1.6.2` — next is `1.6.3`)
|
- [ ] Bump `version` in `package.json` to match `CHANGELOG.md` entry (currently `1.0.0`)
|
||||||
- [ ] Run `npm test` — must be 369/369
|
- [ ] Run `npm test` — must be 369/369
|
||||||
- [ ] Run `npm run build` — must be zero TS errors
|
- [ ] Run `npm run build` — must be zero TS errors
|
||||||
- [ ] Run `shipguard scan .` — must be 0 CRITICAL findings
|
- [ ] Run `shipguard scan .` — must be 0 CRITICAL findings
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# MCP Excalidraw Local
|
# Excalidraw MCP Sentinel
|
||||||
|
|
||||||
[](https://github.com/sanjibdevnathlabs/mcp-excalidraw-local/actions/workflows/ci.yml)
|
[](https://github.com/celstnblacc/excalidraw-mcp-sentinel/actions/workflows/ci.yml)
|
||||||
[](https://github.com/sanjibdevnathlabs/mcp-excalidraw-local/actions/workflows/release.yml)
|
[](https://github.com/celstnblacc/excalidraw-mcp-sentinel/actions/workflows/release.yml)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
A fully local, self-hosted Excalidraw MCP server with **SQLite persistence**, **multi-tenancy**, and **auto-sync** — designed to run entirely on your machine without depending on `excalidraw.com`.
|
A **hardened**, fully local, self-hosted Excalidraw MCP server with **SQLite persistence**, **multi-tenancy**, **auto-sync**, and **production-grade security** — designed to run entirely on your machine without depending on `excalidraw.com`.
|
||||||
|
|
||||||
Run a live Excalidraw canvas and control it from any AI agent. This repo provides:
|
Run a live Excalidraw canvas and control it from any AI agent. This repo provides:
|
||||||
|
|
||||||
@@ -13,10 +13,23 @@ Run a live Excalidraw canvas and control it from any AI agent. This repo provide
|
|||||||
- **Live Canvas**: Real-time Excalidraw UI synced via WebSocket
|
- **Live Canvas**: Real-time Excalidraw UI synced via WebSocket
|
||||||
- **SQLite Persistence**: Elements survive restarts, with versioning and search
|
- **SQLite Persistence**: Elements survive restarts, with versioning and search
|
||||||
- **Multi-Tenancy**: Isolated canvases per workspace, auto-detected
|
- **Multi-Tenancy**: Isolated canvases per workspace, auto-detected
|
||||||
|
- **Security Hardened**: Helmet, rate limiting, API key auth, prototype pollution guard, WS challenge-response
|
||||||
|
- **369 Tests**: Full test coverage across unit, API, WebSocket, and regression tests
|
||||||
|
|
||||||
> **Fork notice:** This project is forked from [yctimlin/mcp_excalidraw](https://github.com/yctimlin/mcp_excalidraw) and extends it with persistence, multi-workspace support, and numerous UX improvements. Full credit to the original author for the excellent foundation. See [What Changed From Upstream](#what-changed-from-upstream) for details.
|
## Why this fork?
|
||||||
|
|
||||||
Keywords: Excalidraw MCP server, AI diagramming, local Excalidraw, self-hosted, SQLite persistence, multi-tenant, Mermaid to Excalidraw.
|
Forked from [celstnblacc/excalidraw-mcp-sentinel](https://github.com/celstnblacc/excalidraw-mcp-sentinel) (itself a fork of [yctimlin/mcp_excalidraw](https://github.com/yctimlin/mcp_excalidraw)) with production hardening:
|
||||||
|
|
||||||
|
- **369 tests** (upstream has none) — unit, API, WebSocket, and regression
|
||||||
|
- **Security middleware** (`src/security.ts`): helmet, CORS allowlist, timing-safe API key auth, prototype pollution guard, input sanitization
|
||||||
|
- **3-tier rate limiting**: general, destructive, and write-burst ceilings
|
||||||
|
- **WebSocket challenge-response authentication**
|
||||||
|
- **Docker hardening**: non-root user, resource limits, hardened `.dockerignore`
|
||||||
|
- **Full gauntlet security audit pass**
|
||||||
|
|
||||||
|
Full credit to [@sanjibdevnathlabs](https://github.com/sanjibdevnathlabs) and [@yctimlin](https://github.com/yctimlin) for the excellent foundation. See [What Changed From Upstream](#what-changed-from-upstream) for the full diff.
|
||||||
|
|
||||||
|
Keywords: Excalidraw MCP server, AI diagramming, local Excalidraw, self-hosted, SQLite persistence, multi-tenant, Mermaid to Excalidraw, security hardened.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
@@ -87,14 +100,14 @@ Install "Desktop development with C++" from [Visual Studio Build Tools](https://
|
|||||||
The setup wizard checks your environment, optionally installs the agent skill, and configures MCP clients — all interactively. Every step is skippable.
|
The setup wizard checks your environment, optionally installs the agent skill, and configures MCP clients — all interactively. Every step is skippable.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx @sanjibdevnath/mcp-excalidraw-local setup
|
npx excalidraw-mcp-sentinel setup
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Example session</summary>
|
<summary>Example session</summary>
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npx @sanjibdevnath/mcp-excalidraw-local setup
|
$ npx excalidraw-mcp-sentinel setup
|
||||||
|
|
||||||
Excalidraw MCP — Setup
|
Excalidraw MCP — Setup
|
||||||
|
|
||||||
@@ -136,8 +149,8 @@ $ npx @sanjibdevnath/mcp-excalidraw-local setup
|
|||||||
### Path B: From Source
|
### Path B: From Source
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/sanjibdevnathlabs/mcp-excalidraw-local.git
|
git clone https://github.com/celstnblacc/excalidraw-mcp-sentinel.git
|
||||||
cd mcp-excalidraw-local
|
cd excalidraw-mcp-sentinel
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
@@ -156,7 +169,7 @@ Open `http://localhost:3000` in your browser.
|
|||||||
|
|
||||||
Canvas server:
|
Canvas server:
|
||||||
```bash
|
```bash
|
||||||
docker run -d -p 3000:3000 --name mcp-excalidraw-canvas sanjibdevnath/mcp-excalidraw-local-canvas:latest
|
docker run -d -p 3000:3000 --name mcp-excalidraw-canvas celstnblacc/excalidraw-mcp-sentinel-canvas:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
MCP server (stdio) is typically launched by your MCP client:
|
MCP server (stdio) is typically launched by your MCP client:
|
||||||
@@ -168,7 +181,7 @@ MCP server (stdio) is typically launched by your MCP client:
|
|||||||
"args": [
|
"args": [
|
||||||
"run", "-i", "--rm",
|
"run", "-i", "--rm",
|
||||||
"-e", "CANVAS_PORT=3000",
|
"-e", "CANVAS_PORT=3000",
|
||||||
"sanjibdevnath/mcp-excalidraw-local:latest"
|
"celstnblacc/excalidraw-mcp-sentinel:latest"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +203,7 @@ Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per-project):
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local"],
|
"args": ["-y", "excalidraw-mcp-sentinel"],
|
||||||
"env": {
|
"env": {
|
||||||
"CANVAS_PORT": "3000"
|
"CANVAS_PORT": "3000"
|
||||||
}
|
}
|
||||||
@@ -224,7 +237,7 @@ Add to `claude_desktop_config.json`:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local"],
|
"args": ["-y", "excalidraw-mcp-sentinel"],
|
||||||
"env": {
|
"env": {
|
||||||
"CANVAS_PORT": "3000"
|
"CANVAS_PORT": "3000"
|
||||||
}
|
}
|
||||||
@@ -238,7 +251,7 @@ Add to `claude_desktop_config.json`:
|
|||||||
```bash
|
```bash
|
||||||
claude mcp add excalidraw-canvas --scope user \
|
claude mcp add excalidraw-canvas --scope user \
|
||||||
-e CANVAS_PORT=3000 \
|
-e CANVAS_PORT=3000 \
|
||||||
-- npx -y @sanjibdevnath/mcp-excalidraw-local
|
-- npx -y excalidraw-mcp-sentinel
|
||||||
```
|
```
|
||||||
|
|
||||||
### Codex CLI
|
### Codex CLI
|
||||||
@@ -250,7 +263,7 @@ Add to `~/.codex/mcp.json`:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local"],
|
"args": ["-y", "excalidraw-mcp-sentinel"],
|
||||||
"env": {
|
"env": {
|
||||||
"CANVAS_PORT": "3000"
|
"CANVAS_PORT": "3000"
|
||||||
}
|
}
|
||||||
@@ -288,14 +301,14 @@ Already installed a previous version? The interactive update wizard is the easie
|
|||||||
### Interactive Update (recommended)
|
### Interactive Update (recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx @sanjibdevnath/mcp-excalidraw-local@latest update
|
npx excalidraw-mcp-sentinel@latest update
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Example session</summary>
|
<summary>Example session</summary>
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npx @sanjibdevnath/mcp-excalidraw-local@latest update
|
$ npx excalidraw-mcp-sentinel@latest update
|
||||||
|
|
||||||
Excalidraw MCP — Update v1.2.0
|
Excalidraw MCP — Update v1.2.0
|
||||||
|
|
||||||
@@ -333,7 +346,7 @@ If you prefer to update manually, follow the steps for your installation method,
|
|||||||
|
|
||||||
#### npx users
|
#### npx users
|
||||||
|
|
||||||
If your MCP config uses `npx -y @sanjibdevnath/mcp-excalidraw-local`, npx caches the package locally and won't automatically fetch new versions.
|
If your MCP config uses `npx -y excalidraw-mcp-sentinel`, npx caches the package locally and won't automatically fetch new versions.
|
||||||
|
|
||||||
**Option A — Clear the cache (one-time):**
|
**Option A — Clear the cache (one-time):**
|
||||||
```bash
|
```bash
|
||||||
@@ -349,7 +362,7 @@ Update the `args` in your MCP config to include `@latest`:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local@latest"],
|
"args": ["-y", "excalidraw-mcp-sentinel@latest"],
|
||||||
"env": { "CANVAS_PORT": "3000" }
|
"env": { "CANVAS_PORT": "3000" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,8 +383,8 @@ npm run build
|
|||||||
#### Docker users
|
#### Docker users
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull sanjibdevnath/mcp-excalidraw-local:latest
|
docker pull celstnblacc/excalidraw-mcp-sentinel:latest
|
||||||
docker pull sanjibdevnath/mcp-excalidraw-local-canvas:latest
|
docker pull celstnblacc/excalidraw-mcp-sentinel-canvas:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Then recreate your containers (`docker compose up -d` or `docker run` again).
|
Then recreate your containers (`docker compose up -d` or `docker run` again).
|
||||||
@@ -391,7 +404,7 @@ cp -R skills/excalidraw-skill ~/.claude/skills/excalidraw-skill
|
|||||||
curl -s http://localhost:3000/health
|
curl -s http://localhost:3000/health
|
||||||
|
|
||||||
# Or check the installed package version
|
# Or check the installed package version
|
||||||
npx @sanjibdevnath/mcp-excalidraw-local --version
|
npx excalidraw-mcp-sentinel --version
|
||||||
```
|
```
|
||||||
|
|
||||||
## How We Differ from the Official Excalidraw MCP
|
## How We Differ from the Official Excalidraw MCP
|
||||||
@@ -503,7 +516,7 @@ This repo includes a skill at `skills/excalidraw-skill/` that provides:
|
|||||||
The easiest way to install the skill:
|
The easiest way to install the skill:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx @sanjibdevnath/mcp-excalidraw-local setup
|
npx excalidraw-mcp-sentinel setup
|
||||||
```
|
```
|
||||||
|
|
||||||
The wizard detects your installed agents and lets you choose which ones get the skill.
|
The wizard detects your installed agents and lets you choose which ones get the skill.
|
||||||
@@ -589,7 +602,7 @@ This is the most common installation issue. `better-sqlite3` is a native Node.js
|
|||||||
```
|
```
|
||||||
3. Or run the setup wizard which handles this automatically:
|
3. Or run the setup wizard which handles this automatically:
|
||||||
```bash
|
```bash
|
||||||
npx @sanjibdevnath/mcp-excalidraw-local setup
|
npx excalidraw-mcp-sentinel setup
|
||||||
```
|
```
|
||||||
|
|
||||||
### EADDRINUSE (port already in use)
|
### EADDRINUSE (port already in use)
|
||||||
@@ -619,7 +632,7 @@ node dist/index.js # restart
|
|||||||
|
|
||||||
### NVM / path issues with npx
|
### NVM / path issues with npx
|
||||||
|
|
||||||
**Symptom:** `npx @sanjibdevnath/mcp-excalidraw-local` hangs or uses the wrong Node version.
|
**Symptom:** `npx excalidraw-mcp-sentinel` hangs or uses the wrong Node version.
|
||||||
|
|
||||||
**Fix:**
|
**Fix:**
|
||||||
```bash
|
```bash
|
||||||
@@ -639,7 +652,7 @@ Then use the full path in your MCP config:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "/Users/you/.nvm/versions/node/v22.12.0/bin/npx",
|
"command": "/Users/you/.nvm/versions/node/v22.12.0/bin/npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local"],
|
"args": ["-y", "excalidraw-mcp-sentinel"],
|
||||||
"env": { "CANVAS_PORT": "3000" }
|
"env": { "CANVAS_PORT": "3000" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "node",
|
"command": "node",
|
||||||
"args": ["/absolute/path/to/mcp-excalidraw-local/dist/index.js"],
|
"args": ["/absolute/path/to/excalidraw-mcp-sentinel/dist/index.js"],
|
||||||
"env": {
|
"env": {
|
||||||
"CANVAS_PORT": "3000"
|
"CANVAS_PORT": "3000"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.canvas
|
dockerfile: Dockerfile.canvas
|
||||||
image: sanjibdevnath/mcp-excalidraw-local-canvas:latest
|
image: celstnblacc/excalidraw-mcp-sentinel-canvas:latest
|
||||||
container_name: mcp-excalidraw-canvas
|
container_name: mcp-excalidraw-canvas
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
@@ -51,7 +51,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
image: sanjibdevnath/mcp-excalidraw-local:latest
|
image: celstnblacc/excalidraw-mcp-sentinel:latest
|
||||||
container_name: mcp-excalidraw-mcp
|
container_name: mcp-excalidraw-mcp
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: true
|
tty: true
|
||||||
|
|||||||
Generated
+25
-9
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@sanjibdevnath/mcp-excalidraw-local",
|
"name": "excalidraw-mcp-sentinel",
|
||||||
"version": "1.6.2",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@sanjibdevnath/mcp-excalidraw-local",
|
"name": "excalidraw-mcp-sentinel",
|
||||||
"version": "1.6.2",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@excalidraw/excalidraw": "^0.18.0",
|
"@excalidraw/excalidraw": "^0.18.0",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"zod-to-json-schema": "^3.22.3"
|
"zod-to-json-schema": "^3.22.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"mcp-excalidraw-local": "dist/index.js"
|
"excalidraw-mcp-sentinel": "dist/index.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.58.2",
|
"@playwright/test": "^1.58.2",
|
||||||
@@ -119,6 +119,7 @@
|
|||||||
"integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
|
"integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
@@ -3212,7 +3213,7 @@
|
|||||||
"version": "15.7.15",
|
"version": "15.7.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
||||||
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
|
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
@@ -3233,8 +3234,9 @@
|
|||||||
"version": "18.3.23",
|
"version": "18.3.23",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
|
||||||
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
|
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
@@ -3244,8 +3246,9 @@
|
|||||||
"version": "18.3.7",
|
"version": "18.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
|
||||||
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
|
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": "^18.0.0"
|
"@types/react": "^18.0.0"
|
||||||
}
|
}
|
||||||
@@ -3835,6 +3838,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001726",
|
"caniuse-lite": "^1.0.30001726",
|
||||||
"electron-to-chromium": "^1.5.173",
|
"electron-to-chromium": "^1.5.173",
|
||||||
@@ -3979,6 +3983,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz",
|
||||||
"integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==",
|
"integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chevrotain/cst-dts-gen": "11.1.2",
|
"@chevrotain/cst-dts-gen": "11.1.2",
|
||||||
"@chevrotain/gast": "11.1.2",
|
"@chevrotain/gast": "11.1.2",
|
||||||
@@ -4327,7 +4332,7 @@
|
|||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/cytoscape": {
|
"node_modules/cytoscape": {
|
||||||
@@ -4335,6 +4340,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz",
|
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz",
|
||||||
"integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==",
|
"integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
@@ -4735,6 +4741,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
@@ -5727,6 +5734,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
|
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
|
||||||
"integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==",
|
"integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.9.0"
|
"node": ">=16.9.0"
|
||||||
}
|
}
|
||||||
@@ -5973,6 +5981,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.11.0.tgz",
|
||||||
"integrity": "sha512-zKfoBBD1uDw3rljwHkt0fWuja1B76R7CjznuBO+mSX6jpsO1EBeWNRKpeaQho9yPI/pvCv4recGfgOXGxwPZvQ==",
|
"integrity": "sha512-zKfoBBD1uDw3rljwHkt0fWuja1B76R7CjznuBO+mSX6jpsO1EBeWNRKpeaQho9yPI/pvCv4recGfgOXGxwPZvQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.20.0"
|
"node": ">=12.20.0"
|
||||||
},
|
},
|
||||||
@@ -7527,6 +7536,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
@@ -7539,6 +7549,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
@@ -8401,6 +8412,7 @@
|
|||||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -8700,6 +8712,7 @@
|
|||||||
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.4.4",
|
"fdir": "^6.4.4",
|
||||||
@@ -8790,6 +8803,7 @@
|
|||||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -8803,6 +8817,7 @@
|
|||||||
"integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==",
|
"integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/expect": "4.1.0",
|
"@vitest/expect": "4.1.0",
|
||||||
"@vitest/mocker": "4.1.0",
|
"@vitest/mocker": "4.1.0",
|
||||||
@@ -9126,6 +9141,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.5.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.5.tgz",
|
||||||
"integrity": "sha512-ualArhgJydGAKkSdtxQyu6RXFW8nHFKWaw20jey8UFXU9uzkHYqWXJ93Iz+hUVVJb37VpF4LCCsOOfj6xaCVRQ==",
|
"integrity": "sha512-ualArhgJydGAKkSdtxQyu6RXFW8nHFKWaw20jey8UFXU9uzkHYqWXJ93Iz+hUVVJb37VpF4LCCsOOfj6xaCVRQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-8
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@sanjibdevnath/mcp-excalidraw-local",
|
"name": "excalidraw-mcp-sentinel",
|
||||||
"version": "1.6.2",
|
"version": "1.0.0",
|
||||||
"description": "Fully local MCP server for Excalidraw with SQLite persistence, multi-tenancy, auto-sync, real-time canvas, and 32 tools",
|
"description": "Hardened, self-hosted Excalidraw MCP server with SQLite persistence, multi-tenancy, auto-sync, security middleware, and 369 tests",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
"mcp-excalidraw-local": "dist/index.js"
|
"excalidraw-mcp-sentinel": "dist/index.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm run build:server && node dist/index.js",
|
"start": "npm run build:server && node dist/index.js",
|
||||||
@@ -84,9 +84,14 @@
|
|||||||
"local"
|
"local"
|
||||||
],
|
],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "sanjibdevnathlabs"
|
"name": "celstnblacc",
|
||||||
|
"url": "https://github.com/celstnblacc"
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "sanjibdevnathlabs",
|
||||||
|
"url": "https://github.com/sanjibdevnathlabs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "yctimlin",
|
"name": "yctimlin",
|
||||||
"email": "c22647809@gmail.com",
|
"email": "c22647809@gmail.com",
|
||||||
@@ -96,11 +101,11 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sanjibdevnathlabs/mcp-excalidraw-local.git"
|
"url": "https://github.com/celstnblacc/excalidraw-mcp-sentinel.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/sanjibdevnathlabs/mcp-excalidraw-local#readme",
|
"homepage": "https://github.com/celstnblacc/excalidraw-mcp-sentinel#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/sanjibdevnathlabs/mcp-excalidraw-local/issues"
|
"url": "https://github.com/celstnblacc/excalidraw-mcp-sentinel/issues"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Run these checks **in order**:
|
|||||||
|
|
||||||
1. **MCP Server** (best): If tools like `batch_create_elements` are available → use MCP mode.
|
1. **MCP Server** (best): If tools like `batch_create_elements` are available → use MCP mode.
|
||||||
2. **REST API** (fallback): `curl -s http://localhost:3000/health` returns `{"status":"ok"}` → use REST API mode.
|
2. **REST API** (fallback): `curl -s http://localhost:3000/health` returns `{"status":"ok"}` → use REST API mode.
|
||||||
3. **Nothing works**: Guide user to install (clone `sanjibdevnathlabs/mcp-excalidraw-local`, build, configure MCP).
|
3. **Nothing works**: Guide user to install (clone `celstnblacc/excalidraw-mcp-sentinel`, build, configure MCP).
|
||||||
|
|
||||||
See `references/cheatsheet.md` for the full MCP-vs-REST mapping and REST API gotchas.
|
See `references/cheatsheet.md` for the full MCP-vs-REST mapping and REST API gotchas.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2923,7 +2923,7 @@ if (isMainModule()) {
|
|||||||
try {
|
try {
|
||||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
||||||
if (arg === '--help' || arg === '-h') {
|
if (arg === '--help' || arg === '-h') {
|
||||||
process.stdout.write(`${pkg.name} v${pkg.version}\n\nUsage:\n mcp-excalidraw-local Start MCP server (stdio transport)\n mcp-excalidraw-local setup Interactive setup wizard\n mcp-excalidraw-local update Update agent skills and MCP config\n mcp-excalidraw-local --help Show this help\n mcp-excalidraw-local --version Show version\n`);
|
process.stdout.write(`${pkg.name} v${pkg.version}\n\nUsage:\n excalidraw-mcp-sentinel Start MCP server (stdio transport)\n excalidraw-mcp-sentinel setup Interactive setup wizard\n excalidraw-mcp-sentinel update Update agent skills and MCP config\n excalidraw-mcp-sentinel --help Show this help\n excalidraw-mcp-sentinel --version Show version\n`);
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(`${pkg.version}\n`);
|
process.stdout.write(`${pkg.version}\n`);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Security middleware for mcp-excalidraw-local.
|
* Security middleware for excalidraw-mcp-sentinel.
|
||||||
*
|
*
|
||||||
* All env vars are read at request/connection time (not at module init)
|
* All env vars are read at request/connection time (not at module init)
|
||||||
* so that tests can mutate process.env between cases.
|
* so that tests can mutate process.env between cases.
|
||||||
|
|||||||
+6
-6
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interactive setup wizard for mcp-excalidraw-local.
|
* Interactive setup wizard for excalidraw-mcp-sentinel.
|
||||||
* Runs via: npx @sanjibdevnath/mcp-excalidraw-local setup
|
* Runs via: npx excalidraw-mcp-sentinel setup
|
||||||
*
|
*
|
||||||
* Uses only Node.js built-ins — no third-party dependencies.
|
* Uses only Node.js built-ins — no third-party dependencies.
|
||||||
* Every phase is optional and skippable.
|
* Every phase is optional and skippable.
|
||||||
@@ -92,7 +92,7 @@ function getAgents(): AgentDef[] {
|
|||||||
},
|
},
|
||||||
mcpConfigType: 'cli-command',
|
mcpConfigType: 'cli-command',
|
||||||
mcpCliRemove: 'claude mcp remove excalidraw-canvas --scope user',
|
mcpCliRemove: 'claude mcp remove excalidraw-canvas --scope user',
|
||||||
mcpCliCommand: 'claude mcp add excalidraw-canvas --scope user -e CANVAS_PORT=3000 -- npx -y @sanjibdevnath/mcp-excalidraw-local@latest',
|
mcpCliCommand: 'claude mcp add excalidraw-canvas --scope user -e CANVAS_PORT=3000 -- npx -y excalidraw-mcp-sentinel@latest',
|
||||||
instructionConfig: {
|
instructionConfig: {
|
||||||
global: path.join(home, '.claude', 'CLAUDE.md'),
|
global: path.join(home, '.claude', 'CLAUDE.md'),
|
||||||
local: path.join(process.cwd(), 'CLAUDE.md'),
|
local: path.join(process.cwd(), 'CLAUDE.md'),
|
||||||
@@ -493,7 +493,7 @@ async function phaseMcpConfig(rl: readline.Interface): Promise<void> {
|
|||||||
function mergeJsonConfig(configPath: string): void {
|
function mergeJsonConfig(configPath: string): void {
|
||||||
const mcpEntry = {
|
const mcpEntry = {
|
||||||
command: 'npx',
|
command: 'npx',
|
||||||
args: ['-y', '@sanjibdevnath/mcp-excalidraw-local@latest'],
|
args: ['-y', 'excalidraw-mcp-sentinel@latest'],
|
||||||
env: { CANVAS_PORT: '3000' },
|
env: { CANVAS_PORT: '3000' },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -549,7 +549,7 @@ function printManualConfig(): void {
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"excalidraw-canvas": {
|
"excalidraw-canvas": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "@sanjibdevnath/mcp-excalidraw-local@latest"],
|
"args": ["-y", "excalidraw-mcp-sentinel@latest"],
|
||||||
"env": { "CANVAS_PORT": "3000" }
|
"env": { "CANVAS_PORT": "3000" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,7 +619,7 @@ export async function runUpdate(): Promise<void> {
|
|||||||
const skillSource = path.resolve(__dirname, '..', 'skills', 'excalidraw-skill');
|
const skillSource = path.resolve(__dirname, '..', 'skills', 'excalidraw-skill');
|
||||||
if (!fs.existsSync(skillSource)) {
|
if (!fs.existsSync(skillSource)) {
|
||||||
fail(`Skill source not found at ${skillSource}`);
|
fail(`Skill source not found at ${skillSource}`);
|
||||||
fail('This can happen with corrupted installs. Try: npx @sanjibdevnath/mcp-excalidraw-local@latest setup');
|
fail('This can happen with corrupted installs. Try: npx excalidraw-mcp-sentinel@latest setup');
|
||||||
rl.close();
|
rl.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user