npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@atomos-web/structura-mcp

v2.0.0

Published

**Node.js MCP server** that exposes Atomos Structura schema designer over the [Model Context Protocol](https://modelcontextprotocol.io).

Readme

@atomos-web/structura-mcp

Node.js MCP server that exposes Atomos Structura schema designer over the Model Context Protocol.

🤖 20+ AI Tools for Claude, GPT, Cursor, and other AI agents to create, manipulate, and manage schema workspaces in real-time.

✨ New AI Capabilities

  • 🎛️ Viewport Control — AI can zoom, pan, center, and fit schemas to screen
  • 🔒 Availability Guards — Fine-grained permission system for menu features
  • 🔄 Session Management — Clean memory wipe and graceful session termination
  • 📊 Menu Configuration — Runtime enable/disable of UI features
  • 🎯 Advanced Layout — Smart centering and fit-to-screen algorithms

Install

pnpm add @atomos-web/structura-mcp
# or
npm i @atomos-web/structura-mcp

Quick Start

# Start MCP server
npx @atomos-web/structura-mcp

# Custom port and configuration
PORT=3001 npx @atomos-web/structura-mcp

Embedded Server

import { createServer } from 'http';
import { VbsMcpServer } from '@atomos-web/structura-mcp';

const mcp = new VbsMcpServer({
  initialConfig: {
    headless: true,
    allow_multiple_schemas: true,
    menu: {
      zoom: { available: true },
      center_on_screen: { available: true },
      export: { available: false } // Disable export by default
    }
  },
  onSessionClose: () => console.log('AI session ended'),
  onClearMemory: () => console.log('Memory cleared')
});

createServer((req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  if (req.method === 'GET' && req.url === '/events') {
    mcp.handleSSE(req, res);   // Real-time updates
  } else {
    mcp.handleRequest(req, res); // JSON-RPC tools
  }
}).listen(3001);

🤖 AI Tools Reference

Entity Management

| Tool | Purpose | |------|---------| | atomos-structura/create-entity | Create new entity with properties, position, dimensions | | atomos-structura/get-entity | Retrieve entity by ID with all properties |
| atomos-structura/update-entity | Replace entity properties and metadata | | atomos-structura/delete-entity | Remove entity (cascades to delete related links) |

Relationship Management

| Tool | Purpose | |------|---------| | atomos-structura/create-link | Create relationship between entities with cardinality | | atomos-structura/get-schema | Get all entities and links in active schema |


Targeting a specific schema

All entity and link tools require an explicit schema_id parameter (introduced in v1.2.0).
get-entity falls back to the active schema when schema_id is omitted for backwards compatibility.

// Create a schema first and note the returned ID
const { result: { id: schemaId } } = await fetch('http://localhost:9743', {
  method: 'POST',
  body: JSON.stringify({ method: 'atomos-structura/create-schema', params: { name: 'Orders' }, id: 1 }),
}).then(r => r.json())

// All subsequent calls must supply schema_id
await fetch('http://localhost:9743', {
  method: 'POST',
  body: JSON.stringify({
    method: 'atomos-structura/create-entity',
    params: {
      schema_id: schemaId,   // ← required
      id: 'entity-order',
      name: 'Order',
      position: { x: 100, y: 100 },
      dimensions: { width: 200, height: 60 },
      properties: [],
    },
    id: 2,
  }),
}).then(r => r.json())

The change SSE event now includes schema_id in the payload so consumers can route updates to the correct canvas instance:

eventSource.addEventListener('change', (e) => {
  const { schema_id, entities, links } = JSON.parse(e.data)
  // Route to the canvas that owns schema_id
  getCanvasAdapterFor(schema_id)?.updateEntities(entities)
})

| Tool | Purpose | Availability Guard | |------|---------|-------------------| | atomos-structura/viewport/get | Get current zoom and pan state | None | | atomos-structura/viewport/set-zoom | Set zoom level (0.1x to 4x) | menu.zoom.available | | atomos-structura/viewport/set-pan | Set pan position {x, y} | None |
| atomos-structura/viewport/center | Center view on entity centroids | menu.center_on_screen.available | | atomos-structura/viewport/fit-to-screen | Fit all entities in viewport (zoom ≤2) | menu.fit_to_screen.available |

🆕 Session Lifecycle

| Tool | Purpose |
|------|---------| | atomos-structura/session/close | End session, call onSessionClose hook, clear SSE clients | | atomos-structura/session/clear-memory | Reset all data, call onClearMemory hook, preserve config |

Schema Management

| Tool | Purpose | |------|---------|
| atomos-structura/create-schema | Create new schema tab/workspace | | atomos-structura/list-schemas | List all schemas with entity counts | | atomos-structura/rename-schema | Update schema name | | atomos-structura/delete-schema | Remove schema (if not active) | | atomos-structura/activate-schema | Switch to different schema |

State Management

| Tool | Purpose | |------|---------| | atomos-structura/sync-state | Bulk update entities, links, settings, menu config | | atomos-structura/get-settings | Retrieve workspace settings | | atomos-structura/update-settings | Merge new settings | | atomos-structura/get-workspace | Export complete workspace (all schemas + settings) | | atomos-structura/load-workspace | Import complete workspace |


🔒 Availability Guards

AI tools respect menu configuration - if a feature is disabled, the tool returns 403 Forbidden:

// Configure availability
await mcp.call('atomos-structura/sync-state', {
  entities: [],
  links: [],
  menu_config: {
    zoom: { available: false },               // Blocks viewport/set-zoom  
    center_on_screen: { available: false },   // Blocks viewport/center
    fit_to_screen: { available: false },      // Blocks viewport/fit-to-screen
    export: { available: true }               // Allow export
  }
});

// This will now return: { error: { code: 403, message: "Feature not available" } }
await mcp.call('atomos-structura/viewport/set-zoom', { level: 2.0 });

📡 Real-Time Updates

SSE events keep AI agents synchronized with workspace changes:

| Event | Payload | Triggered By | |-------|---------|-------------| | change | { entities: [...], links: [...] } | Entity/link modifications | | workspace | { type: "schema-created", id: "...", name: "..." } | Schema operations |
| settings-updated | { settings: {...} } | Settings changes | | viewport-updated | { viewport: { zoom, pan } } | Viewport changes | | menu-config | { zoom: { available, value }, ... } | Menu configuration | | state-reset | { success: true } | Memory clear operations |

📚 Example Usage

Complete Schema Creation

// 1. Create schema  
await mcp.call('atomos-structura/create-schema', {
  id: 'ecommerce', 
  name: 'E-commerce System'
});

// 2. Add entities
await mcp.call('atomos-structura/create-entity', {
  id: 'user',
  name: 'User',
  position: { x: 100, y: 100 },
  properties: [
    { key: 'id', value: 'UUID', type: 'text' },
    { key: 'email', value: 'string', type: 'email' }
  ]
});

// 3. Create relationships
await mcp.call('atomos-structura/create-link', {
  id: 'user-orders',
  leftEntityId: 'user',
  rightEntityId: 'order',
  leftCardinality: '1',
  rightCardinality: '*'
});

// 4. Auto-layout
await mcp.call('atomos-structura/viewport/center', { width: 1200, height: 800 });
await mcp.call('atomos-structura/viewport/fit-to-screen', { width: 1200, height: 800 });

Built with battle-tested reliability - 157/162 tests passing 🎯 |---|---|---| | Tool calls → server | HTTP POST | / | | Server → client (push) | SSE | GET /events |

Every POST body is { method, params, id }. Every response is { result?, error?, id }.


MCP methods

Entity operations

| Method | Params | Returns | |---|---|---| | atomos-structura/create-entity | Entity | { success, entity } | | atomos-structura/get-entity | { entityId } | { entity } | | atomos-structura/update-entity | Entity | { success, entity } | | atomos-structura/delete-entity | { entityId } | { success } | | atomos-structura/create-link | LinkProps | { success, link } |

Schema operations

| Method | Params | Returns | |---|---|---| | atomos-structura/list-schemas | — | { schemas[], active_schema_id } | | atomos-structura/create-schema | { name, id? } | { success, id, name } or 403 | | atomos-structura/rename-schema | { id, name } | { success } | | atomos-structura/delete-schema | { id } | { success } | | atomos-structura/activate-schema | { id } | { success, id } | | atomos-structura/get-schema | { schemaId? } | { schema } |

Settings

| Method | Params | Returns | |---|---|---| | atomos-structura/get-settings | — | { settings } | | atomos-structura/update-settings | { settings } | { success, settings } |

Workspace persistence

| Method | Params | Returns | |---|---|---| | atomos-structura/get-workspace | — | { workspace: McpWorkspaceState } | | atomos-structura/load-workspace | { workspace: McpWorkspaceState } | { success } | | atomos-structura/sync-state | { entities?, links?, settings? } | { success } |

get-workspace and load-workspace are fully round-trippable — the payload from get-workspace can be passed verbatim to load-workspace.


SSE events

Subscribe via GET /events. The server sends two event types:

change

Fired after any entity or link mutation.

{ "entities": [...], "links": [...] }

workspace

Fired after schema, canvas, or settings mutations.

{
  "type": "schema-created | schema-deleted | schema-activated | settings-updated | state-loaded | ...",
  "id": "schema-abc",
  "name": "My Schema",
  "state": { ... }
}

Session policy

createVbsMcpServer({
  initialConfig: {
    /** Block multi-schema sessions. create-schema returns 403 when a schema already exists. */
    allow_multiple_schemas: false,
  },
});

Browser sync

The matching browser-side connector in @atomos-web/structura keeps the Redux store in sync with the MCP server automatically:

import { createSchemaBuilder } from '@atomos-web/structura';

const builder = createSchemaBuilder({ mcpUrl: 'http://localhost:3001' });

Manual wiring:

import { createMcpSync } from '@atomos-web/structura';

const { disconnect } = createMcpSync(store, 'http://localhost:3001');

Error codes

| Code | Meaning | |---|---| | 403 | Operation blocked by session policy (allow_multiple_schemas: false) | | 404 | Entity, schema, or canvas not found | | 405 | Non-POST request on the command endpoint | | 409 | Duplicate id (schema already exists) | | 500 | Internal server error | | -32601 | Method not found |


License

MIT