Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@atlisp/mcp

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@atlisp/mcp - npm Package Compare versions

Comparing version
1.8.12
to
1.8.13
+66
dist/html/api-docs.html
<!DOCTYPE html>
<html>
<head>
<title>@lisp MCP Server API Docs</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; }
h1 { color: #333; }
h2 { color: #666; margin-top: 30px; }
.endpoint { background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; }
.method { display: inline-block; padding: 3px 8px; border-radius: 3px; font-weight: bold; font-size: 12px; }
.get { background: #61affe; color: white; }
.post { background: #49cc90; color: white; }
code { background: #eee; padding: 2px 5px; border-radius: 3px; }
.info { background: #f0f0f0; padding: 10px; margin: 10px 0; }
</style>
</head>
<body>
<h1>@lisp MCP Server API</h1>
<div class="info">
<strong>Version:</strong> __VERSION__ |
<strong>Tools:</strong> __TOOLS_COUNT__ |
<strong>Resources:</strong> 11
</div>
<h2>Endpoints</h2>
<div class="endpoint">
<span class="method get">GET</span> <code>/health</code> - Health check
</div>
<div class="endpoint">
<span class="method get">GET</span> <code>/metrics</code> - Prometheus metrics
</div>
<div class="endpoint">
<span class="method post">POST</span> <code>/mcp</code> - MCP JSON-RPC endpoint
</div>
<div class="endpoint">
<span class="method get">GET</span> <code>/sse</code> - Server-Sent Events
</div>
<div class="endpoint">
<span class="method post">POST</span> <code>/message</code> - SSE message
</div>
<div class="endpoint">
<span class="method get">GET</span> <code>/debug</code> - Debug panel
</div>
<div class="endpoint">
<span class="method post">POST</span> <code>/config/reload</code> - Reload configuration
</div>
<div class="endpoint">
<span class="method get">GET</span> <code>/rate-limit/status</code> - Rate limit status
</div>
<div class="endpoint">
<span class="method post">POST</span> <code>/rate-limit/reset</code> - Reset rate limit
</div>
<h2>Quick Start</h2>
<pre>
# Health check
curl http://localhost:8110/health
# Call MCP tool
curl -X POST http://localhost:8110/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_cad_info","arguments":{}}}'
</pre>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>@lisp MCP Debug Panel</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background: #1a1a2e; color: #eee; }
h1 { color: #00d4ff; }
h2 { color: #00d4ff; border-bottom: 1px solid #333; padding-bottom: 10px; }
.card { background: #16213e; padding: 20px; margin: 10px 0; border-radius: 8px; }
.stat { display: inline-block; margin: 10px 20px; }
.stat-label { color: #888; font-size: 12px; }
.stat-value { font-size: 24px; color: #00d4ff; }
.status-ok { color: #49cc90; }
.status-error { color: #f93e3e; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #333; }
th { color: #888; }
code { background: #0f0f23; padding: 3px 8px; border-radius: 3px; color: #00d4ff; }
.refresh { background: #00d4ff; color: #1a1a2e; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; margin: 10px 0; }
</style>
</head>
<body>
<h1>🛠️ @lisp MCP Debug Panel</h1>
<button class="refresh" onclick="location.reload()">🔄 Refresh</button>
<h2>System</h2>
<div class="card">
<div class="stat">
<div class="stat-label">Uptime</div>
<div class="stat-value">__UPTIME_MIN__m</div>
</div>
<div class="stat">
<div class="stat-label">Memory RSS</div>
<div class="stat-value">__MEMORY_RSS_MB__ MB</div>
</div>
<div class="stat">
<div class="stat-label">Heap Used</div>
<div class="stat-value">__HEAP_USED_MB__ MB</div>
</div>
<div class="stat">
<div class="stat-label">MCP Sessions</div>
<div class="stat-value">__SESSIONS_COUNT__</div>
</div>
</div>
<h2>CAD Status</h2>
<div class="card">
<span class="__CAD_STATUS_CLASS__">
__CAD_STATUS_TEXT__
</span>
</div>
<h2>Endpoints</h2>
<div class="card">
<table>
<tr><th>Endpoint</th><th>Method</th><th>Description</th></tr>
<tr><td><code>/health</code></td><td>GET</td><td>Health check</td></tr>
<tr><td><code>/metrics</code></td><td>GET</td><td>Prometheus metrics</td></tr>
<tr><td><code>/mcp</code></td><td>POST</td><td>MCP JSON-RPC</td></tr>
<tr><td><code>/sse</code></td><td>GET</td><td>Server-Sent Events</td></tr>
<tr><td><code>/debug</code></td><td>GET</td><td>This panel</td></tr>
<tr><td><code>/api/docs</code></td><td>GET</td><td>API Documentation</td></tr>
</table>
</div>
<h2>Tools (__TOOLS_COUNT__)</h2>
<div class="card">
<p>Use <code>tools/list</code> MCP method to get full tool list.</p>
</div>
<script>
setTimeout(() => location.reload(), 30000);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>@lisp MCP Tool Playground</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: #eee; padding: 20px; }
h1 { color: #00d4ff; margin-bottom: 20px; font-size: 24px; }
.header { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; margin-bottom: 20px; }
.search-box { flex: 1; min-width: 200px; background: #16213e; border: 1px solid #333; color: #eee; padding: 10px 14px; border-radius: 6px; font-size: 14px; outline: none; }
.search-box:focus { border-color: #00d4ff; }
.category-filter { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 20px; }
.cat-btn { background: #16213e; border: 1px solid #333; color: #888; padding: 6px 14px; border-radius: 16px; cursor: pointer; font-size: 13px; transition: all .15s; }
.cat-btn:hover { border-color: #00d4ff; color: #eee; }
.cat-btn.active { background: #00d4ff; color: #1a1a2e; border-color: #00d4ff; }
.tool-count { color: #888; font-size: 13px; margin-bottom: 12px; }
.category-group { margin-bottom: 24px; }
.category-title { color: #00d4ff; font-size: 16px; font-weight: 600; padding: 10px 0 8px; border-bottom: 1px solid #333; margin-bottom: 8px; cursor: pointer; display: flex; align-items: center; gap: 8px; }
.category-title .arrow { color: #555; transition: transform .15s; font-size: 12px; }
.category-title.collapsed .arrow { transform: rotate(-90deg); }
.category-title .count { color: #888; font-size: 12px; font-weight: 400; }
.tool-card { background: #16213e; border: 1px solid #333; border-radius: 6px; padding: 12px 16px; margin-bottom: 6px; cursor: pointer; transition: border-color .15s; }
.tool-card:hover { border-color: #00d4ff44; }
.tool-card.expanded { border-color: #00d4ff; }
.tool-name { color: #49cc90; font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; font-size: 14px; }
.tool-desc { color: #999; font-size: 13px; margin-top: 4px; line-height: 1.4; }
.tool-meta { display: flex; gap: 12px; margin-top: 6px; font-size: 12px; color: #666; }
.tool-meta span { background: #0f0f23; padding: 2px 8px; border-radius: 3px; }
.tool-details { display: none; margin-top: 12px; padding-top: 12px; border-top: 1px solid #333; }
.tool-card.expanded .tool-details { display: block; }
.params-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 12px; }
.params-table th { color: #888; text-align: left; padding: 6px 8px; border-bottom: 1px solid #333; font-weight: 500; }
.params-table td { padding: 6px 8px; border-bottom: 1px solid #222; color: #ccc; }
.params-table .required { color: #f93e3e; margin-left: 4px; }
.param-input { width: 100%; background: #0f0f23; border: 1px solid #333; color: #eee; padding: 6px 10px; border-radius: 4px; font-size: 13px; font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; }
.param-input:focus { border-color: #00d4ff; outline: none; }
.param-input.array-input { min-height: 60px; resize: vertical; }
.btn { background: #00d4ff; color: #1a1a2e; border: none; padding: 8px 18px; border-radius: 5px; cursor: pointer; font-size: 13px; font-weight: 600; transition: opacity .15s; }
.btn:hover { opacity: .85; }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn.execute { background: #49cc90; }
.btn.execute.running { background: #888; }
.response-area { display: none; margin-top: 12px; }
.response-area.visible { display: block; }
.response-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.response-header label { color: #888; font-size: 12px; font-weight: 500; }
.response-status { font-size: 12px; padding: 2px 8px; border-radius: 3px; }
.response-status.ok { background: #49cc9033; color: #49cc90; }
.response-status.err { background: #f93e3e33; color: #f93e3e; }
.response-json { background: #0f0f23; border: 1px solid #333; border-radius: 4px; padding: 12px; font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; font-size: 12px; color: #00d4ff; white-space: pre-wrap; word-break: break-all; max-height: 400px; overflow: auto; }
.no-results { color: #666; text-align: center; padding: 40px; font-size: 14px; }
.toolbar { display: flex; gap: 8px; align-items: center; }
.expand-all-btn { background: none; border: 1px solid #333; color: #888; padding: 6px 14px; border-radius: 5px; cursor: pointer; font-size: 12px; }
.expand-all-btn:hover { border-color: #00d4ff44; color: #eee; }
.scroll-top { position: fixed; bottom: 20px; right: 20px; width: 40px; height: 40px; background: #16213e; border: 1px solid #333; border-radius: 50%; color: #00d4ff; font-size: 18px; cursor: pointer; display: none; align-items: center; justify-content: center; }
.scroll-top.visible { display: flex; }
.scroll-top:hover { border-color: #00d4ff; }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: #0f0f23; }
::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #555; }
@media (max-width: 600px) {
body { padding: 10px; }
.header { flex-direction: column; }
.search-box { width: 100%; }
}
</style>
</head>
<body>
<h1>🧰 @lisp MCP Tool Playground</h1>
<div class="header">
<input class="search-box" id="search" placeholder="Search tools by name or description..." oninput="filterTools()">
<div class="toolbar">
<button class="expand-all-btn" onclick="expandAll()">Expand All</button>
<button class="expand-all-btn" onclick="collapseAll()">Collapse All</button>
</div>
</div>
<div class="category-filter" id="categoryFilter"></div>
<div class="tool-count" id="toolCount"></div>
<div id="toolList"></div>
<button class="scroll-top" id="scrollTop" onclick="window.scrollTo({top:0,behavior:'smooth'})">↑</button>
<script>
var TOOLS = __TOOLS_JSON__;
var activeCategory = null;
var searchQuery = '';
function categorize(name) {
if (/^batch_/.test(name)) return 'Batch';
if (/^boolean_/.test(name)) return 'Boolean';
if (/^(create_3d_|create_box|create_cone|create_cylinder|create_sphere|create_torus|create_wedge|extrude_|revolve_|slice_|thicken_|offset_surface|create_loft_|get_3d_)/.test(name)) return '3D';
if (/xdata/i.test(name)) return 'Xdata';
if (/sheet/i.test(name)) return 'Sheet Set';
if (/pdf/i.test(name)) return 'PDF';
if (/^(xref|dgn|dwf)/i.test(name)) return 'Xref';
if (/constraint/i.test(name)) return 'Constraint';
if (/parametric/i.test(name)) return 'Parametric';
if (/pipeline/i.test(name)) return 'Pipeline';
if (/trigger/i.test(name)) return 'Trigger';
if (/repl/i.test(name)) return 'REPL';
if (/^(plot_|publish_|save_pdf_layout)/.test(name)) return 'Plot';
if (/^(connect_cad|eval_lisp|install_|init_|get_cad_info|get_platform_info|at_command|new_document|bring_to_front|get_system_status)/.test(name)) return 'System';
if (/^(list_|search_|measure_|import_funlib)/.test(name)) return 'Query';
if (/^(import_|export_)/.test(name)) return 'Import/Export';
if (/^(create_layer|delete_layer|set_layer|set_current_layer)/.test(name)) return 'Layer';
if (/^(create_block|insert_block|explode_block|get_block|set_block)/.test(name)) return 'Block';
if (/^(create_dim|list_dim|set_dim|create_hatch|set_hatch)/.test(name)) return 'Dimension & Hatch';
if (/^(create_ucs|set_ucs|delete_ucs|list_ucs|get_current_ucs|create_layout|delete_layout|rename_layout|set_layout|list_layouts|get_current_layout|create_named_view|list_named_views|restore_named_view)/.test(name)) return 'UCS & Layout';
if (/^(open_dwg|save_dwg|close_dwg)/.test(name)) return 'Drawing';
if (/^(create_text|list_text|create_mleader|list_mleader|set_mleader|create_linetype|list_linetypes|load_linetype)/.test(name)) return 'Style';
if (/^(attach_|detach_)/.test(name)) return 'Underlay';
if (/^(create_group|delete_group|list_groups|get_group)/.test(name)) return 'Group';
if (/^(create_entity|delete_entity|get_entity|set_entity|select_entities)/.test(name)) return 'Entity';
return 'Other';
}
function getCategories() {
var cats = {};
TOOLS.forEach(function(t) {
var c = categorize(t.name);
if (!cats[c]) cats[c] = [];
cats[c].push(t);
});
var order = ['System','Query','Entity','Layer','Block','Drawing','Dimension & Hatch','UCS & Layout','3D','Batch','Boolean','Group','Style','Xdata','Sheet Set','PDF','Xref','Underlay','Import/Export','Constraint','Parametric','Plot','Pipeline','Trigger','REPL','Other'];
var sorted = {};
order.forEach(function(c) { if (cats[c]) sorted[c] = cats[c]; });
Object.keys(cats).filter(function(c) { return !order.includes(c); }).forEach(function(c) { sorted[c] = cats[c]; });
return sorted;
}
function escapeHtml(s) {
var d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
function buildForm(inputSchema) {
var props = inputSchema.properties || {};
var required = inputSchema.required || [];
var keys = Object.keys(props);
if (keys.length === 0) return '<p style="color:#666;font-size:13px;padding:6px 0">No parameters required.</p>';
var html = '<table class="params-table"><tr><th>Parameter</th><th>Type</th><th>Description</th><th>Value</th></tr>';
keys.forEach(function(k) {
var p = props[k];
var isReq = required.includes(k);
var typeLabel = p.type || 'string';
var inputHtml = '';
if (p.enum) {
inputHtml = '<select class="param-input" data-param="' + k + '" data-type="string"><option value="">-- select --</option>';
p.enum.forEach(function(v) {
inputHtml += '<option value="' + escapeHtml(v) + '">' + escapeHtml(v) + '</option>';
});
inputHtml += '</select>';
} else if (p.type === 'boolean') {
inputHtml = '<select class="param-input" data-param="' + k + '" data-type="boolean"><option value="">-- select --</option><option value="true">true</option><option value="false">false</option></select>';
} else if (p.type === 'integer' || p.type === 'number') {
inputHtml = '<input class="param-input" data-param="' + k + '" data-type="' + p.type + '" placeholder="' + typeLabel + '" step="any">';
} else if (p.type === 'array' || (p.type === 'object' && !p.properties)) {
inputHtml = '<textarea class="param-input array-input" data-param="' + k + '" data-type="json" placeholder=\'JSON array/object, e.g. ["a","b"] or {"key":"val"}\' rows="2"></textarea>';
} else if (p.type === 'object' && p.properties) {
inputHtml = '<textarea class="param-input array-input" data-param="' + k + '" data-type="json" placeholder=\'JSON object\' rows="2"></textarea>';
} else {
inputHtml = '<input class="param-input" data-param="' + k + '" data-type="string" placeholder="' + escapeHtml(p.description || '') + '">';
}
html += '<tr><td><code>' + escapeHtml(k) + '</code>' + (isReq ? '<span class="required">*</span>' : '') + '</td><td style="color:#888">' + typeLabel + '</td><td>' + escapeHtml(p.description || '-') + '</td><td>' + inputHtml + '</td></tr>';
});
html += '</table>';
return html;
}
function collectParams(card) {
var params = {};
card.querySelectorAll('.param-input').forEach(function(el) {
var key = el.dataset.param;
var val = el.value.trim();
if (val === '') return;
var type = el.dataset.type;
if (type === 'number' || type === 'integer') val = Number(val);
else if (type === 'boolean') val = val === 'true';
else if (type === 'json') { try { val = JSON.parse(val); } catch(e) { return; } }
params[key] = val;
});
return params;
}
function renderTools() {
var categories = getCategories();
var container = document.getElementById('toolList');
var filterEl = document.getElementById('categoryFilter');
container.innerHTML = '';
filterEl.innerHTML = '<button class="cat-btn active" data-cat="" onclick="setCategory(this,\'\')">All</button>';
var totalCount = 0;
var catKeys = Object.keys(categories);
catKeys.forEach(function(c) {
var count = categories[c].length;
if (activeCategory && activeCategory !== c) count = 0;
else if (searchQuery) {
var q = searchQuery.toLowerCase();
count = categories[c].filter(function(t) { return t.name.toLowerCase().includes(q) || (t.description && t.description.toLowerCase().includes(q)); }).length;
}
totalCount += count;
filterEl.innerHTML += '<button class="cat-btn' + (activeCategory === c ? ' active' : '') + '" data-cat="' + c + '" onclick="setCategory(this,\'' + c + '\')">' + c + '</button>';
});
var countText = totalCount + ' tool' + (totalCount !== 1 ? 's' : '');
if (searchQuery) countText += ' matching "' + searchQuery + '"';
document.getElementById('toolCount').textContent = countText;
var hasResults = false;
catKeys.forEach(function(c) {
var tools = categories[c];
if (searchQuery) {
var q = searchQuery.toLowerCase();
tools = tools.filter(function(t) { return t.name.toLowerCase().includes(q) || (t.description && t.description.toLowerCase().includes(q)); });
}
if (activeCategory && activeCategory !== c) tools = [];
if (tools.length === 0) return;
hasResults = true;
var groupHtml = '<div class="category-group"><div class="category-title collapsed" onclick="toggleCategory(this)"><span class="arrow">▼</span> ' + c + ' <span class="count">(' + tools.length + ')</span></div>';
tools.forEach(function(t) {
var hasParams = t.inputSchema && t.inputSchema.properties && Object.keys(t.inputSchema.properties).length > 0;
var paramsCount = hasParams ? Object.keys(t.inputSchema.properties).length + ' params' : 'no params';
var reqCount = (t.inputSchema.required && t.inputSchema.required.length) ? '<span>' + t.inputSchema.required.length + ' required</span>' : '';
groupHtml += '<div class="tool-card" id="tool-' + t.name + '" onclick="toggleCard(this)">';
groupHtml += '<div class="tool-name">' + escapeHtml(t.name) + '</div>';
groupHtml += '<div class="tool-desc">' + escapeHtml(t.description || '') + '</div>';
groupHtml += '<div class="tool-meta"><span>' + paramsCount + '</span>' + reqCount + '</div>';
groupHtml += '<div class="tool-details">';
if (hasParams) {
groupHtml += buildForm(t.inputSchema);
} else {
groupHtml += '<p style="color:#666;font-size:13px;padding:6px 0">No parameters required.</p>';
}
groupHtml += '<button class="btn execute" onclick="event.stopPropagation();executeTool(this,\'' + t.name + '\')">▶ Execute</button>';
groupHtml += '<div class="response-area" id="response-' + t.name + '">';
groupHtml += '<div class="response-header"><label>Response</label><span class="response-status" id="status-' + t.name + '"></span></div>';
groupHtml += '<div class="response-json" id="result-' + t.name + '"></div>';
groupHtml += '</div></div></div>';
});
groupHtml += '</div>';
container.innerHTML += groupHtml;
});
if (!hasResults) {
container.innerHTML = '<div class="no-results">No tools found matching your search.</div>';
}
if (searchQuery) {
container.querySelectorAll('.category-group').forEach(function(g) {
var visibleCards = g.querySelectorAll('.tool-card');
if (visibleCards.length <= 3) {
var title = g.querySelector('.category-title');
if (title) title.classList.remove('collapsed');
}
});
}
}
function toggleCategory(el) {
el.classList.toggle('collapsed');
var group = el.parentElement;
var cards = group.querySelectorAll('.tool-card');
cards.forEach(function(c) { c.style.display = el.classList.contains('collapsed') ? 'none' : ''; });
}
function toggleCard(el) {
if (event && (event.target.closest('.param-input') || event.target.closest('.btn') || event.target.closest('.response-area'))) return;
el.classList.toggle('expanded');
}
async function executeTool(btn, toolName) {
if (btn.disabled) return;
var card = btn.closest('.tool-card');
var responseArea = document.getElementById('response-' + toolName);
var statusEl = document.getElementById('status-' + toolName);
var resultEl = document.getElementById('result-' + toolName);
btn.disabled = true;
btn.textContent = '⏳ Running...';
btn.classList.add('running');
responseArea.classList.remove('visible');
statusEl.textContent = '';
statusEl.className = 'response-status';
resultEl.textContent = '';
var arguments = collectParams(card);
var body = { jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: toolName, arguments: arguments } };
try {
var res = await fetch('/mcp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
var data = await res.json();
responseArea.classList.add('visible');
if (res.ok) {
statusEl.textContent = res.status + ' OK';
statusEl.className = 'response-status ok';
} else {
statusEl.textContent = res.status + ' Error';
statusEl.className = 'response-status err';
}
resultEl.textContent = JSON.stringify(data, null, 2);
} catch (err) {
responseArea.classList.add('visible');
statusEl.textContent = 'Network Error';
statusEl.className = 'response-status err';
resultEl.textContent = err.message;
} finally {
btn.disabled = false;
btn.textContent = '▶ Execute';
btn.classList.remove('running');
}
}
function setCategory(el, cat) {
document.querySelectorAll('.cat-btn').forEach(function(b) { b.classList.remove('active'); });
el.classList.add('active');
activeCategory = cat || null;
renderTools();
}
function filterTools() {
searchQuery = document.getElementById('search').value;
renderTools();
}
function expandAll() {
document.querySelectorAll('.category-title').forEach(function(t) { t.classList.remove('collapsed'); });
document.querySelectorAll('.tool-card').forEach(function(c) { c.style.display = ''; });
}
function collapseAll() {
document.querySelectorAll('.category-title').forEach(function(t) { t.classList.add('collapsed'); });
}
window.addEventListener('scroll', function() {
document.getElementById('scrollTop').classList.toggle('visible', window.scrollY > 400);
});
renderTools();
</script>
</body>
</html>
+2
-2
{
"name": "@atlisp/mcp",
"version": "1.8.12",
"version": "1.8.13",
"description": "MCP Server for @lisp on CAD,support AutoCAD/GstarCAD/ZWCAD/BricsCAD or CAD platform compatible with AutoLISP",

@@ -21,3 +21,3 @@ "type": "module",

"build:main": "esbuild src/atlisp-mcp.js --bundle --platform=node --target=node18 --format=esm --outdir=dist --external:edge-js --packages=external --banner:js=\"#!/usr/bin/env node\"",
"build:worker": "node -e \"const fs=require('fs');for(const f of ['cad-worker.js','lisp-security.js','logger.js','config.js'])fs.copyFileSync('src/'+f,'dist/'+f)\"",
"build:worker": "node -e \"const fs=require('fs');const path=require('path');for(const f of ['cad-worker.js','lisp-security.js','logger.js','config.js'])fs.copyFileSync('src/'+f,'dist/'+f);if(!fs.existsSync('dist/html'))fs.mkdirSync('dist/html');for(const f of fs.readdirSync('src/html'))fs.copyFileSync('src/html/'+f,'dist/html/'+f)\"",
"prepublishOnly": "npm run build",

@@ -24,0 +24,0 @@ "test": "vitest run",