Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "isketch",
"owner": { "name": "raj-khan", "url": "https://github.com/raj-khan" },
"description": "isketch for Claude Code: diagrams your agent reads exactly and edits back.",
"plugins": [
{
"name": "isketch",
"source": "./plugin",
"description": "Read, write and draw isketch .flow diagrams, with an MCP server that lists, reads, validates, renders and diffs them."
}
]
}
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ jobs:
for file in examples/*.flow; do npm run -s isketch -- render "$file" -o "${file%.flow}.svg"; done
git diff --exit-code examples/

# The Claude Code plugin ships a bundled MCP server: it must match the source.
- name: Claude Code plugin
if: '!cancelled()'
run: |
npm run -s plugin
git diff --exit-code plugin/

- name: VS Code extension builds
if: '!cancelled()'
run: npm run -s vscode

server:
name: Server
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
public/landing.html
public/landing-diagram.svg
public/demo.webm
# Bundles, built from formatted source.
plugin/server/
vscode/dist/
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,20 @@ a screenshot. It has five tools:
| `render_diagram` | Draw one as SVG |
| `diff_diagrams` | Compare a diagram with a proposed version |

It needs only Node, and only reads and writes inside the folder you give it. isketch is not on npm
yet, so point at a clone:
**In Claude Code, the plugin is the quickest way:** it adds the MCP server (bundled, nothing to
install) and a skill that teaches Claude the `.flow` format and when to read or update a diagram.

```text
/plugin marketplace add raj-khan/flow
/plugin install isketch@isketch
```

**In VS Code**, the extension in `vscode/` previews a `.flow` file beside the text as you type,
underlines errors by line, colours the syntax and opens the diagram in isketch
(`npm run vscode`, then `npx @vscode/vsce package` in `vscode/` for a `.vsix`).

To add the server by hand instead, it needs only Node, and only reads and writes inside the folder
you give it. isketch is not on npm yet, so point at a clone:

```bash
# Claude Code, from your project
Expand Down
31 changes: 27 additions & 4 deletions backlog/tasks/fl-89 - Meet-agents-where-they-are.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
id: FL-89
title: Meet agents where they are
status: To Do
assignee: []
status: In Progress
assignee:
- '@raj-khan'
created_date: '2026-09-25 17:39'
updated_date: '2026-09-27 14:36'
labels:
- mcp
- growth
Expand All @@ -25,8 +27,29 @@ Distribution to where coding agents already run.

<!-- AC:BEGIN -->

- [ ] #1 A Claude Code plugin with a skill that teaches the .flow format and sets up the MCP server
- [x] #1 A Claude Code plugin with a skill that teaches the .flow format and sets up the MCP server
- [ ] #2 Listed in the MCP registry and the main MCP directories
- [ ] #3 A VS Code extension previews and edits .flow files beside the code
- [x] #3 A VS Code extension previews and edits .flow files beside the code

<!-- AC:END -->

## Implementation Plan

<!-- SECTION:PLAN:BEGIN -->

1. Claude Code plugin in plugin/, with .claude-plugin/marketplace.json at the root so the repo is its own marketplace: a skill that teaches the .flow format and when to read or update a diagram, and .mcp.json running the MCP server bundled into plugin/server/ (rolldown, one file plus the font) so a clone needs no install. CI checks the bundle matches the source.
2. VS Code extension in vscode/: a flow language with a TextMate grammar, a live preview beside the editor (the apps own renderer, dark with VS Code), errors as diagnostics by line, and Open in isketch. Bundled by scripts/make-vscode.mjs; tested against a fake of the vscode API.
3. Listings: server.json for the official MCP registry (the hosted /mcp endpoint) and docs/listings.md with each step, for the owner to run once isketch.online is live.

<!-- SECTION:PLAN:END -->

## Implementation Notes

<!-- SECTION:NOTES:BEGIN -->

Verified plugin: claude plugin validate passes for ./plugin and the marketplace; the bundled server run from a copy of plugin/ alone (no node_modules) answers initialize, lists its five tools, reads a brief and renders a sketch with the font embedded. sketchFont no longer throws when the font package is absent (require.resolve was outside the catch).

Verified VS Code: vscode/src/**tests**/extension.spec.js (5, through a fake vscode API aliased in the test config: commands registered, preview follows edits, errors underlined on their line with the last good drawing kept, Open in isketch link, escaping and CSP); npx @vscode/vsce package builds a 60 KB .vsix with the bundle, font, grammar and README. vitest 305, e2e 144, lint and typecheck.

Open: AC #2 (listing in the MCP registry and directories) is prepared (server.json, docs/listings.md) but publishing needs the owners GitHub, registry, directory and marketplace accounts and the hosted server at isketch.online, so it is left for the owner.
<!-- SECTION:NOTES:END -->
8 changes: 8 additions & 0 deletions bin/mcp-plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// The Claude Code plugin's MCP server: the same server as `isketch mcp`, for
// the folder Claude Code runs it in. scripts/make-plugin.mjs bundles it, with
// everything it needs, into plugin/server/.
import process from 'node:process'

import { serve } from './mcp.mjs'

serve(process.argv[2] ?? '.')
32 changes: 26 additions & 6 deletions bin/sketchFont.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,35 @@
// server looks the same wherever the SVG is opened.
import { readFile } from 'node:fs/promises'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'

const require = createRequire(import.meta.url)
const FILE = 'patrick-hand-latin-400-normal.woff2'
let loaded

/**
* Where the font may be: beside this file, as the bundled Claude Code plugin
* ships it, or in the installed package.
*/
function candidates() {
const found = [fileURLToPath(new URL(`./${FILE}`, import.meta.url))]
try {
found.push(createRequire(import.meta.url).resolve(`@fontsource/patrick-hand/files/${FILE}`))
} catch {
// Not installed, as in the plugin: the copy beside this file is the one.
}
return found
}

export function sketchFont() {
loaded ??= readFile(
require.resolve('@fontsource/patrick-hand/files/patrick-hand-latin-400-normal.woff2'),
)
.then((bytes) => `data:font/woff2;base64,${bytes.toString('base64')}`)
.catch(() => '')
loaded ??= (async () => {
for (const path of candidates()) {
try {
return `data:font/woff2;base64,${(await readFile(path)).toString('base64')}`
} catch {
// Try the next place.
}
}
return ''
})()
return loaded
}
51 changes: 51 additions & 0 deletions docs/listings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Getting isketch listed

Everything below is ready in the repository; each step publishes under the owner's own accounts,
so it is the owner's to run. Do them after isketch.online serves the hosted server (FL-71), since
the listings point at it.

## Claude Code plugin

Already installable from this repository, which is its own marketplace:

```text
/plugin marketplace add raj-khan/flow
/plugin install isketch@isketch
```

It adds the `isketch` skill (the `.flow` format, and when to read or update a diagram) and the local
MCP server, bundled in `plugin/server/` so nothing needs installing. `claude plugin validate ./plugin`
and `claude plugin validate .` both pass. To reach more people, submit it to a community plugin
directory as that directory asks.

## Official MCP registry

`server.json` describes the hosted server's `/mcp` endpoint under `io.github.raj-khan/isketch`,
which the registry verifies through GitHub.

```bash
brew install mcp-publisher # or download it from the registry's releases
mcp-publisher login github
mcp-publisher publish # reads server.json
```

## MCP directories

With the registry entry live, add isketch to the directories that list servers by hand, each with
the one-line description from `server.json` and a link to the README:

- Smithery, Glama, PulseMCP and mcp.so, through their submit forms
- awesome-mcp-servers, by pull request, under diagramming or developer tools

## VS Code Marketplace

```bash
npm run vscode # builds vscode/dist
cd vscode && npx @vscode/vsce login raj-khan # a Personal Access Token from Azure DevOps
npx @vscode/vsce publish
```

The publisher id in `vscode/package.json` is `raj-khan`; create it at
marketplace.visualstudio.com/manage first. `npx @vscode/vsce package` makes a `.vsix` to try
locally with _Extensions: Install from VSIX_. Publish to Open VSX too (`npx ovsx publish`), for
Cursor, Windsurf and VSCodium.
5 changes: 5 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export default [
'playwright-report/**',
// The server is TypeScript, checked by its own compiler.
'server/**',
// Bundles, built from source that is linted.
'plugin/server/**',
'vscode/dist/**',
],
},

Expand All @@ -27,6 +30,8 @@ export default [
'.claude/hooks/*.mjs',
'scripts/*.mjs',
'bin/*.mjs',
'vscode/src/**/*.js',
'vscode/test/*.js',
'.github/actions/**/*.mjs',
],
languageOptions: {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
"landing": "node scripts/make-landing.mjs",
"clip": "npm run build && node scripts/make-demo-clip.mjs",
"docs": "node scripts/make-docs.mjs",
"pages": "node scripts/make-pages.mjs"
"pages": "node scripts/make-pages.mjs",
"plugin": "node scripts/make-plugin.mjs",
"vscode": "node scripts/make-vscode.mjs"
},
"dependencies": {
"@fontsource/patrick-hand": "^5.3.0",
Expand Down
10 changes: 10 additions & 0 deletions plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "isketch",
"description": "Read, write and draw isketch diagrams: .flow files your agent reads exactly and edits back, with an MCP server to list, read, validate, render and diff them.",
"version": "0.1.0",
"author": { "name": "raj-khan", "url": "https://github.com/raj-khan" },
"homepage": "https://isketch.online",
"repository": "https://github.com/raj-khan/flow",
"license": "MIT",
"keywords": ["diagram", "architecture", "mcp", "flow", "excalidraw", "drawio"]
}
8 changes: 8 additions & 0 deletions plugin/.mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"isketch": {
"command": "node",
"args": ["${CLAUDE_PLUGIN_ROOT}/server/isketch-mcp.mjs", "."]
}
}
}
Loading
Loading