@symbo.ls/mcp-server 3.8.1 → 3.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/mcp-handler.js +229 -15
package/package.json
CHANGED
package/src/mcp-handler.js
CHANGED
|
@@ -741,6 +741,7 @@ const TOOLS = [
|
|
|
741
741
|
token: { type: 'string' },
|
|
742
742
|
api_key: { type: 'string' },
|
|
743
743
|
visibility: { type: 'string', default: 'private' },
|
|
744
|
+
language: { type: 'string', default: 'javascript' },
|
|
744
745
|
},
|
|
745
746
|
required: ['name'],
|
|
746
747
|
},
|
|
@@ -866,6 +867,7 @@ async function callTool(name, args = {}) {
|
|
|
866
867
|
'RULES.md',
|
|
867
868
|
'COMMON_MISTAKES.md',
|
|
868
869
|
'PROJECT_STRUCTURE.md',
|
|
870
|
+
'SHARED_LIBRARIES.md',
|
|
869
871
|
'PATTERNS.md',
|
|
870
872
|
'SNIPPETS.md',
|
|
871
873
|
'DEFAULT_LIBRARY.md',
|
|
@@ -975,8 +977,71 @@ async function callTool(name, args = {}) {
|
|
|
975
977
|
confidence = 'medium';
|
|
976
978
|
}
|
|
977
979
|
}
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
+
const fullGuide = readSkill('RUNNING_APPS.md');
|
|
981
|
+
let output = `# Environment Detection\n\n**Detected: ${envType}** (confidence: ${confidence})\n\n`;
|
|
982
|
+
|
|
983
|
+
if (envType === 'local_project') {
|
|
984
|
+
const structureGuide = readSkill('PROJECT_STRUCTURE.md');
|
|
985
|
+
const sharedLibsGuide = readSkill('SHARED_LIBRARIES.md');
|
|
986
|
+
output += '## Your Environment: Local Project\n\n';
|
|
987
|
+
output += "You're working in a standard Symbols project with file-based structure.\n\n";
|
|
988
|
+
output += '### Code Format\n';
|
|
989
|
+
output += "- Components: `export const Name = { extends: 'Flex', ... }` in `components/`\n";
|
|
990
|
+
output += "- Pages: `export const pageName = { extends: 'Page', ... }` in `pages/`\n";
|
|
991
|
+
output += '- State: `export default { key: value }` in `state.js`\n';
|
|
992
|
+
output += '- Functions: `export const fn = function() {}` in `functions/`\n';
|
|
993
|
+
output += '- No imports between files (except pages/index.js)\n\n';
|
|
994
|
+
output += '### Commands\n';
|
|
995
|
+
output +=
|
|
996
|
+
'```bash\nnpm start # dev server\nsmbls build # production build\nsmbls push # deploy to platform\nsmbls deploy # deploy to provider\n```\n\n';
|
|
997
|
+
output += `### Full Project Structure Reference\n\n${structureGuide}`;
|
|
998
|
+
output += `\n\n### Shared Libraries Reference\n\n${sharedLibsGuide}`;
|
|
999
|
+
} else if (envType === 'cdn') {
|
|
1000
|
+
output += '## Your Environment: CDN (Browser-Only)\n\n';
|
|
1001
|
+
output += "You're running Symbols directly in the browser via CDN import.\n\n";
|
|
1002
|
+
output += '### Code Format\n';
|
|
1003
|
+
output += '- Single HTML file with `<script type="module">`\n';
|
|
1004
|
+
output += "- Import: `import { create } from 'https://esm.sh/smbls'`\n";
|
|
1005
|
+
output += '- Define app as inline object tree\n';
|
|
1006
|
+
output += '- Mount: `create(App, { designSystem, components, functions, state })`\n';
|
|
1007
|
+
output += '- Components defined as JS variables (no file-based registry)\n\n';
|
|
1008
|
+
output += '### Limitations\n';
|
|
1009
|
+
output += '- No file-based routing (use tab/view switching)\n';
|
|
1010
|
+
output += '- No SSR\n';
|
|
1011
|
+
output += "- `childExtends: 'Name'` needs components passed to `create()`\n\n";
|
|
1012
|
+
output += `### Full CDN Reference\n\n${fullGuide}`;
|
|
1013
|
+
} else if (envType === 'json_runtime') {
|
|
1014
|
+
output += '## Your Environment: JSON Runtime (Frank)\n\n';
|
|
1015
|
+
output += "You're running Symbols from serialized JSON project data.\n\n";
|
|
1016
|
+
output += '### Code Format\n';
|
|
1017
|
+
output +=
|
|
1018
|
+
'- Project data is a JSON object with components, pages, designSystem, state, functions\n';
|
|
1019
|
+
output += '- Functions are serialized as strings\n';
|
|
1020
|
+
output +=
|
|
1021
|
+
"- Convert with: `smbls frank to-json ./symbols` or `toJSON({ entry: './symbols' })`\n";
|
|
1022
|
+
output +=
|
|
1023
|
+
"- Reverse with: `smbls frank to-fs data.json -o ./output` or `toFS(data, './output')`\n";
|
|
1024
|
+
output += '- Can be loaded by Mermaid server via JSON_PATH env var\n\n';
|
|
1025
|
+
output += `### Full Reference\n\n${fullGuide}`;
|
|
1026
|
+
} else if (envType === 'remote_server') {
|
|
1027
|
+
output += '## Your Environment: Remote Symbols Server (Mermaid)\n\n';
|
|
1028
|
+
output += "You're working with the Mermaid rendering server for hosted Symbols apps.\n\n";
|
|
1029
|
+
output += '### URL Patterns\n';
|
|
1030
|
+
output += '- Production: `https://app.user.preview.symbols.app/`\n';
|
|
1031
|
+
output += '- Development: `https://app.user.preview.dev.symbols.app/`\n';
|
|
1032
|
+
output += '- Staging: `https://app.user.preview.staging.symbols.app/`\n';
|
|
1033
|
+
output += '- Legacy: `https://app.symbo.ls/`\n';
|
|
1034
|
+
output += '- Custom domains supported\n\n';
|
|
1035
|
+
output += '### Deployment\n';
|
|
1036
|
+
output += '```bash\nsmbls push # deploy to Symbols platform\n```\n\n';
|
|
1037
|
+
output += `### Full Reference\n\n${fullGuide}`;
|
|
1038
|
+
} else {
|
|
1039
|
+
output += '## Could Not Determine Environment\n\n';
|
|
1040
|
+
output += 'Provide more details about your project files to get specific guidance.\n\n';
|
|
1041
|
+
output += `### All 4 Ways to Run Symbols Apps\n\n${fullGuide}`;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
return output;
|
|
980
1045
|
}
|
|
981
1046
|
|
|
982
1047
|
if (name === 'login') {
|
|
@@ -1026,7 +1091,7 @@ async function callTool(name, args = {}) {
|
|
|
1026
1091
|
const body = {
|
|
1027
1092
|
name: args.name,
|
|
1028
1093
|
visibility: args.visibility || 'private',
|
|
1029
|
-
language: 'javascript',
|
|
1094
|
+
language: args.language || 'javascript',
|
|
1030
1095
|
};
|
|
1031
1096
|
if (args.key) body.key = args.key;
|
|
1032
1097
|
const result = await apiRequest('POST', '/core/projects', {
|
|
@@ -1051,15 +1116,22 @@ async function callTool(name, args = {}) {
|
|
|
1051
1116
|
const result = await apiRequest('GET', path, { token: args.token, api_key: args.api_key });
|
|
1052
1117
|
if (result.success) {
|
|
1053
1118
|
const data = result.data || {};
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1119
|
+
const components = data.components || {};
|
|
1120
|
+
const pages = data.pages || {};
|
|
1121
|
+
const ds = data.designSystem || {};
|
|
1122
|
+
const state = data.state || {};
|
|
1123
|
+
const functions = data.functions || {};
|
|
1124
|
+
return `# Project Data (branch: ${branch})\n\n**Components (${Object.keys(components).length}):** ${
|
|
1125
|
+
Object.keys(components).slice(0, 20).join(', ') || 'none'
|
|
1126
|
+
}\n**Pages (${Object.keys(pages).length}):** ${
|
|
1127
|
+
Object.keys(pages).slice(0, 20).join(', ') || 'none'
|
|
1128
|
+
}\n**Design System keys:** ${
|
|
1129
|
+
Object.keys(ds).slice(0, 15).join(', ') || 'none'
|
|
1130
|
+
}\n**State keys:** ${
|
|
1131
|
+
Object.keys(state).slice(0, 15).join(', ') || 'none'
|
|
1132
|
+
}\n**Functions (${Object.keys(functions).length}):** ${
|
|
1133
|
+
Object.keys(functions).slice(0, 15).join(', ') || 'none'
|
|
1134
|
+
}\n\n---\n\nFull data:\n\`\`\`json\n${JSON.stringify(data, null, 2).slice(0, 8000)}\n\`\`\``;
|
|
1063
1135
|
}
|
|
1064
1136
|
return `Failed to get project: ${result.error || 'Unknown error'}`;
|
|
1065
1137
|
}
|
|
@@ -1171,6 +1243,7 @@ const SKILL_RESOURCES = {
|
|
|
1171
1243
|
'symbols://skills/running-apps': 'RUNNING_APPS.md',
|
|
1172
1244
|
'symbols://skills/cli': 'CLI.md',
|
|
1173
1245
|
'symbols://skills/sdk': 'SDK.md',
|
|
1246
|
+
'symbols://skills/shared-libraries': 'SHARED_LIBRARIES.md',
|
|
1174
1247
|
'symbols://skills/common-mistakes': 'COMMON_MISTAKES.md',
|
|
1175
1248
|
'symbols://skills/brand-identity': 'BRAND_IDENTITY.md',
|
|
1176
1249
|
'symbols://skills/design-critique': 'DESIGN_CRITIQUE.md',
|
|
@@ -1181,13 +1254,110 @@ const SKILL_RESOURCES = {
|
|
|
1181
1254
|
'symbols://skills/presentation': 'PRESENTATION.md',
|
|
1182
1255
|
};
|
|
1183
1256
|
|
|
1257
|
+
const INLINE_RESOURCES = {
|
|
1258
|
+
'symbols://reference/spacing-tokens': `# Symbols Spacing Tokens
|
|
1259
|
+
|
|
1260
|
+
Ratio-based system (base 16px, ratio 1.618 golden ratio):
|
|
1261
|
+
|
|
1262
|
+
| Token | ~px | Token | ~px | Token | ~px |
|
|
1263
|
+
|-------|------|-------|------|-------|------|
|
|
1264
|
+
| X | 3 | A | 16 | D | 67 |
|
|
1265
|
+
| Y | 6 | A1 | 20 | E | 109 |
|
|
1266
|
+
| Z | 10 | A2 | 22 | F | 177 |
|
|
1267
|
+
| Z1 | 12 | B | 26 | | |
|
|
1268
|
+
| Z2 | 14 | B1 | 32 | | |
|
|
1269
|
+
| | | B2 | 36 | | |
|
|
1270
|
+
| | | C | 42 | | |
|
|
1271
|
+
| | | C1 | 52 | | |
|
|
1272
|
+
| | | C2 | 55 | | |
|
|
1273
|
+
|
|
1274
|
+
Usage: padding: 'A B', gap: 'C', borderRadius: 'Z', fontSize: 'B1'
|
|
1275
|
+
Tokens work with padding, margin, gap, width, height, borderRadius, position, and any spacing property.
|
|
1276
|
+
Negative values: margin: '-Y1 -Z2 - auto'
|
|
1277
|
+
Math: padding: 'A+V2'
|
|
1278
|
+
`,
|
|
1279
|
+
'symbols://reference/atom-components': `# Symbols Atom Components (Primitives)
|
|
1280
|
+
|
|
1281
|
+
| Atom | HTML Tag | Description |
|
|
1282
|
+
|------------|------------|-------------------------------|
|
|
1283
|
+
| Text | <span> | Text content |
|
|
1284
|
+
| Box | <div> | Generic container |
|
|
1285
|
+
| Flex | <div> | Flexbox container |
|
|
1286
|
+
| Grid | <div> | CSS Grid container |
|
|
1287
|
+
| Link | <a> | Anchor with built-in router |
|
|
1288
|
+
| Input | <input> | Form input |
|
|
1289
|
+
| Radio | <input> | Radio button |
|
|
1290
|
+
| Checkbox | <input> | Checkbox |
|
|
1291
|
+
| Svg | <svg> | SVG container |
|
|
1292
|
+
| Icon | <svg> | Icon from icon sprite |
|
|
1293
|
+
| IconText | <div> | Icon + text combination |
|
|
1294
|
+
| Button | <button> | Button with icon/text support |
|
|
1295
|
+
| Img | <img> | Image element |
|
|
1296
|
+
| Iframe | <iframe> | Embedded frame |
|
|
1297
|
+
| Video | <video> | Video element |
|
|
1298
|
+
|
|
1299
|
+
Usage examples:
|
|
1300
|
+
{ Box: { padding: 'A', background: 'surface' } }
|
|
1301
|
+
{ Flex: { flow: 'y', gap: 'B', align: 'center center' } }
|
|
1302
|
+
{ Grid: { columns: 'repeat(3, 1fr)', gap: 'A' } }
|
|
1303
|
+
{ Link: { text: 'Click here', href: '/dashboard' } }
|
|
1304
|
+
{ Button: { text: 'Submit', theme: 'primary', icon: 'check' } }
|
|
1305
|
+
{ Icon: { name: 'chevronLeft' } }
|
|
1306
|
+
{ Img: { src: 'photo.png', boxSize: 'D D' } }
|
|
1307
|
+
`,
|
|
1308
|
+
'symbols://reference/event-handlers': `# Symbols Event Handlers (v3)
|
|
1309
|
+
|
|
1310
|
+
## Lifecycle Events
|
|
1311
|
+
onInit: (el, state) => {} // Once on creation
|
|
1312
|
+
onRender: (el, state) => {} // On each render (return fn for cleanup)
|
|
1313
|
+
onUpdate: (el, state) => {} // On props/state change
|
|
1314
|
+
onStateUpdate: (changes, el, state, context) => {}
|
|
1315
|
+
|
|
1316
|
+
## DOM Events
|
|
1317
|
+
onClick: (event, el, state) => {}
|
|
1318
|
+
onInput: (event, el, state) => {}
|
|
1319
|
+
onKeydown: (event, el, state) => {}
|
|
1320
|
+
onDblclick: (event, el, state) => {}
|
|
1321
|
+
onMouseover: (event, el, state) => {}
|
|
1322
|
+
onWheel: (event, el, state) => {}
|
|
1323
|
+
onSubmit: (event, el, state) => {}
|
|
1324
|
+
onLoad: (event, el, state) => {}
|
|
1325
|
+
|
|
1326
|
+
## Calling Functions
|
|
1327
|
+
onClick: (e, el) => el.call('functionName', args) // Global function
|
|
1328
|
+
onClick: (e, el) => el.scope.localFn(el, s) // Scope function
|
|
1329
|
+
onClick: (e, el) => el.methodName() // Element method
|
|
1330
|
+
|
|
1331
|
+
## State Updates
|
|
1332
|
+
onClick: (e, el, s) => s.update({ count: s.count + 1 })
|
|
1333
|
+
onClick: (e, el, s) => s.toggle('isActive')
|
|
1334
|
+
onClick: (e, el, s) => s.root.update({ modal: '/add-item' })
|
|
1335
|
+
|
|
1336
|
+
## Navigation
|
|
1337
|
+
onClick: (e, el) => el.router('/dashboard', el.getRoot())
|
|
1338
|
+
|
|
1339
|
+
## Cleanup Pattern
|
|
1340
|
+
onRender: (el, s) => {
|
|
1341
|
+
const interval = setInterval(() => { /* ... */ }, 1000)
|
|
1342
|
+
return () => clearInterval(interval) // Called on element removal
|
|
1343
|
+
}
|
|
1344
|
+
`,
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1184
1347
|
function listResources() {
|
|
1185
|
-
|
|
1348
|
+
const skillRes = Object.entries(SKILL_RESOURCES)
|
|
1186
1349
|
.filter(([, f]) => skills[f])
|
|
1187
1350
|
.map(([uri, f]) => ({ uri, name: f.replace('.md', ''), mimeType: 'text/markdown' }));
|
|
1351
|
+
const inlineRes = Object.keys(INLINE_RESOURCES).map((uri) => ({
|
|
1352
|
+
uri,
|
|
1353
|
+
name: uri.split('/').pop(),
|
|
1354
|
+
mimeType: 'text/markdown',
|
|
1355
|
+
}));
|
|
1356
|
+
return [...skillRes, ...inlineRes];
|
|
1188
1357
|
}
|
|
1189
1358
|
|
|
1190
1359
|
function readResource(uri) {
|
|
1360
|
+
if (INLINE_RESOURCES[uri]) return INLINE_RESOURCES[uri];
|
|
1191
1361
|
const f = SKILL_RESOURCES[uri];
|
|
1192
1362
|
return f && skills[f] ? readSkill(f) : null;
|
|
1193
1363
|
}
|
|
@@ -1232,11 +1402,39 @@ const PROMPTS = [
|
|
|
1232
1402
|
},
|
|
1233
1403
|
];
|
|
1234
1404
|
|
|
1405
|
+
// ---------------------------------------------------------------------------
|
|
1406
|
+
// Prompt implementations
|
|
1407
|
+
// ---------------------------------------------------------------------------
|
|
1408
|
+
|
|
1409
|
+
function getPrompt(name, args = {}) {
|
|
1410
|
+
if (name === 'symbols_component_prompt') {
|
|
1411
|
+
const compName = args.component_name || 'MyComponent';
|
|
1412
|
+
return `Generate a Symbols.app component with these requirements:\n\nComponent Name: ${compName}\nDescription: ${args.description || ''}\n\nFollow these strict rules:\n- Use DOMQL v3 syntax ONLY (extends, childExtends, flattened props, onX events)\n- Components are plain objects with named exports: export const ${compName} = { ... }\n- **MANDATORY: ALL values MUST use design system tokens** — spacing (A, B, C, D), colors (primary, surface, white, gray.5), typography (fontSize: 'B'). ZERO px values, ZERO hex colors, ZERO rgb/hsl\n- NO imports between files — reference components by PascalCase key name\n- All folders flat — no subfolders\n- The project likely has a default library — use Button, Avatar, Icon, Field, etc. via extends\n- Include responsive breakpoints (@tabletS, @mobileL) where appropriate\n- Follow modern UI/UX: visual hierarchy, minimal cognitive load, confident typography\n\nOutput ONLY the JavaScript code.`;
|
|
1413
|
+
}
|
|
1414
|
+
if (name === 'symbols_migration_prompt') {
|
|
1415
|
+
const framework = args.source_framework || 'React';
|
|
1416
|
+
return `You are migrating ${framework} code to Symbols.app.\n\nKey conversion rules for ${framework}:\n- Components become plain objects (never functions)\n- NO imports between project files\n- All folders are flat — no subfolders\n- Use extends/childExtends (v3 plural, never v2 singular)\n- Flatten all props directly (no props: {} wrapper)\n- Events use onX prefix (no on: {} wrapper)\n- **MANDATORY: ALL values MUST use design system tokens** — ZERO px values, ZERO hex colors, ZERO rgb/hsl\n- State: state: { key: val } + s.update({ key: newVal })\n- Effects: onRender for mount, onStateUpdate for dependency changes\n- Lists: children: (el, s) => s.items, childrenAs: 'state', childExtends: 'Item'\n- The default library provides Button, Avatar, Field, Modal, etc. — use them via extends\n\nProvide the ${framework} code to convert and I will output clean DOMQL v3.`;
|
|
1417
|
+
}
|
|
1418
|
+
if (name === 'symbols_project_prompt') {
|
|
1419
|
+
return `Create a complete Symbols.app project:\n\nProject Description: ${args.description || ''}\n\nRequired structure (symbols/ folder):\n- index.js (entry: import create from 'smbls', import context, create(app, context))\n- app.js (root app with routes: (pages) => pages)\n- config.js ({ globalTheme: 'dark' })\n- context.js (re-exports: state, pages, designSystem, components, functions, snippets)\n- state.js (app state)\n- dependencies.js (external packages)\n- components/ (PascalCase files, named exports)\n- pages/ (dash-case files, camelCase exports, route mapping in index.js)\n- functions/ (camelCase, called via el.call())\n- designSystem/ (COLOR, THEME, TYPOGRAPHY, SPACING, FONT, ICONS)\n- snippets/ (reusable snippets)\n\nThe project uses the default library (default.symbo.ls) which provides:\nButton, Avatar, Icon, Field, Modal, Badge, Progress, TabSet, and 120+ more components.\nReference these by PascalCase key name — no imports needed.\n\nRules:\n- v3 syntax only — extends, childExtends, flattened props, onX events\n- Design tokens for all spacing/colors (padding: 'A', not padding: '16px')\n- Components are plain objects, never functions\n- No imports between project files\n- All folders completely flat\n\nGenerate all files with complete, production-ready code.`;
|
|
1420
|
+
}
|
|
1421
|
+
if (name === 'symbols_review_prompt') {
|
|
1422
|
+
return `Review this Symbols/DOMQL code for v3 compliance and best practices.\n\nCheck for these violations:\n1. v2 syntax: extend→extends, childExtend→childExtends, props:{}, on:{}\n2. Imports between project files (FORBIDDEN)\n3. Function-based components (must be plain objects)\n4. Subfolders (must be flat)\n5. Hardcoded pixels instead of design tokens\n6. Wrong event handler signatures (lifecycle: (el, s), DOM: (event, el, s))\n7. Default exports for components (should be named)\n8. Standard HTML attrs in attr: {} (should be at root; attr: {} only for data-*/aria-*/custom)\n9. props block CSS trying to override component-level CSS (can't)\n\nProvide:\n- Issues found with line references\n- Corrected code for each issue\n- Overall v3 compliance score (1-10)\n- Improvement suggestions\n\nPaste your code below:`;
|
|
1423
|
+
}
|
|
1424
|
+
if (name === 'symbols_convert_html_prompt') {
|
|
1425
|
+
return `Convert the provided HTML/CSS to Symbols.app DOMQL v3 components.\n\nConversion rules:\n- <div> → Box, Flex, or Grid (based on layout)\n- <span>/<p>/<h1>-<h6> → Text/P/H with tag property\n- <a> → Link (built-in SPA router, use e.preventDefault() + el.router())\n- <button> → Button\n- <input> → Input, Radio, Checkbox\n- <img> → Img\n- <form> → Form\n- <ul>/<ol> + <li> → children array with childExtends\n- CSS px → design tokens (16px→'A', 26px→'B', 42px→'C')\n- CSS colors → theme tokens\n- media queries → @tabletS, @mobileL breakpoints\n- CSS classes → flatten as component properties\n- id/class attrs → not needed\n\nOutput clean DOMQL v3 with named exports.\n\nPaste the HTML below:`;
|
|
1426
|
+
}
|
|
1427
|
+
if (name === 'symbols_design_review_prompt') {
|
|
1428
|
+
return `Review this Symbols component for design system compliance.\n\nCheck:\n1. Spacing uses tokens (A, B, C...) not pixels\n2. Colors come from theme, not hardcoded hex/rgb\n3. Typography uses design system scale (fontSize tokens)\n4. Responsive breakpoints present (@tabletS, @mobileL)\n5. Visual hierarchy is clear (heading sizes, spacing rhythm)\n6. Interactive elements have hover/focus/active states\n7. Accessibility: focus-visible, ARIA attributes where needed\n8. Consistent use of theme variants (primary, secondary, card, dialog)\n9. Layout uses Flex/Grid with proper alignment tokens\n\nProvide design improvement suggestions with corrected code.\n\nPaste your component code below:`;
|
|
1429
|
+
}
|
|
1430
|
+
return null;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1235
1433
|
// ---------------------------------------------------------------------------
|
|
1236
1434
|
// MCP JSON-RPC handler
|
|
1237
1435
|
// ---------------------------------------------------------------------------
|
|
1238
1436
|
|
|
1239
|
-
const SERVER_INFO = { name: 'Symbols MCP', version: '1.0.
|
|
1437
|
+
const SERVER_INFO = { name: 'Symbols MCP', version: '1.0.16' };
|
|
1240
1438
|
|
|
1241
1439
|
export async function handleJsonRpc(req) {
|
|
1242
1440
|
const { method, params, id } = req;
|
|
@@ -1283,9 +1481,25 @@ export async function handleJsonRpc(req) {
|
|
|
1283
1481
|
};
|
|
1284
1482
|
}
|
|
1285
1483
|
if (method === 'prompts/list') return { jsonrpc: '2.0', id, result: { prompts: PROMPTS } };
|
|
1484
|
+
if (method === 'prompts/get') {
|
|
1485
|
+
const promptName = params?.name;
|
|
1486
|
+
const promptArgs = params?.arguments || {};
|
|
1487
|
+
const text = getPrompt(promptName, promptArgs);
|
|
1488
|
+
if (text === null)
|
|
1489
|
+
return {
|
|
1490
|
+
jsonrpc: '2.0',
|
|
1491
|
+
id,
|
|
1492
|
+
error: { code: -32602, message: `Prompt not found: ${promptName}` },
|
|
1493
|
+
};
|
|
1494
|
+
return {
|
|
1495
|
+
jsonrpc: '2.0',
|
|
1496
|
+
id,
|
|
1497
|
+
result: { messages: [{ role: 'user', content: { type: 'text', text } }] },
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1286
1500
|
if (id !== undefined)
|
|
1287
1501
|
return { jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } };
|
|
1288
1502
|
return null;
|
|
1289
1503
|
}
|
|
1290
1504
|
|
|
1291
|
-
export { TOOLS, listResources, readResource, callTool, PROMPTS };
|
|
1505
|
+
export { TOOLS, listResources, readResource, callTool, PROMPTS, getPrompt };
|