@lyrra/mcp-server 1.1.3 → 1.1.7
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/README.md +80 -250
- package/dist/auth-session.js +171 -0
- package/dist/eduflow-block-docs.js +438 -0
- package/dist/http-incoming-auth.js +48 -0
- package/dist/http-main.js +104 -0
- package/dist/index.js +16 -12
- package/dist/lyrra-http.js +80 -0
- package/dist/lyrra-mcp-core.js +174 -0
- package/dist/openapi-parse.js +61 -0
- package/dist/register-eduflow-block-tools.js +31 -0
- package/package.json +41 -13
- package/Dockerfile +0 -16
- package/dist/client.d.ts +0 -23
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -92
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -8
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +0 -1
- package/dist/http-server.d.ts +0 -8
- package/dist/http-server.d.ts.map +0 -1
- package/dist/http-server.js +0 -481
- package/dist/http-server.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/resources/block-types.d.ts +0 -318
- package/dist/resources/block-types.d.ts.map +0 -1
- package/dist/resources/block-types.js +0 -297
- package/dist/resources/block-types.js.map +0 -1
- package/dist/resources/flow-schema.d.ts +0 -147
- package/dist/resources/flow-schema.d.ts.map +0 -1
- package/dist/resources/flow-schema.js +0 -143
- package/dist/resources/flow-schema.js.map +0 -1
- package/dist/server-factory.d.ts +0 -8
- package/dist/server-factory.d.ts.map +0 -1
- package/dist/server-factory.js +0 -82
- package/dist/server-factory.js.map +0 -1
- package/dist/tools/admin.d.ts +0 -265
- package/dist/tools/admin.d.ts.map +0 -1
- package/dist/tools/admin.js +0 -118
- package/dist/tools/admin.js.map +0 -1
- package/dist/tools/ai-designer.d.ts +0 -297
- package/dist/tools/ai-designer.d.ts.map +0 -1
- package/dist/tools/ai-designer.js +0 -89
- package/dist/tools/ai-designer.js.map +0 -1
- package/dist/tools/analytics.d.ts +0 -95
- package/dist/tools/analytics.d.ts.map +0 -1
- package/dist/tools/analytics.js +0 -44
- package/dist/tools/analytics.js.map +0 -1
- package/dist/tools/auth.d.ts +0 -61
- package/dist/tools/auth.d.ts.map +0 -1
- package/dist/tools/auth.js +0 -36
- package/dist/tools/auth.js.map +0 -1
- package/dist/tools/blocks.d.ts +0 -457
- package/dist/tools/blocks.d.ts.map +0 -1
- package/dist/tools/blocks.js +0 -173
- package/dist/tools/blocks.js.map +0 -1
- package/dist/tools/connections.d.ts +0 -173
- package/dist/tools/connections.d.ts.map +0 -1
- package/dist/tools/connections.js +0 -81
- package/dist/tools/connections.js.map +0 -1
- package/dist/tools/eduflow.d.ts +0 -409
- package/dist/tools/eduflow.d.ts.map +0 -1
- package/dist/tools/eduflow.js +0 -139
- package/dist/tools/eduflow.js.map +0 -1
- package/dist/tools/participants.d.ts +0 -221
- package/dist/tools/participants.d.ts.map +0 -1
- package/dist/tools/participants.js +0 -70
- package/dist/tools/participants.js.map +0 -1
- package/dist/tools/presentation.d.ts +0 -233
- package/dist/tools/presentation.d.ts.map +0 -1
- package/dist/tools/presentation.js +0 -57
- package/dist/tools/presentation.js.map +0 -1
- package/dist/tools/projects.d.ts +0 -131
- package/dist/tools/projects.d.ts.map +0 -1
- package/dist/tools/projects.js +0 -55
- package/dist/tools/projects.js.map +0 -1
- package/dist/tools/resources.d.ts +0 -93
- package/dist/tools/resources.d.ts.map +0 -1
- package/dist/tools/resources.js +0 -37
- package/dist/tools/resources.js.map +0 -1
- package/dist/tools/store.d.ts +0 -125
- package/dist/tools/store.d.ts.map +0 -1
- package/dist/tools/store.js +0 -66
- package/dist/tools/store.js.map +0 -1
- package/mcp-config.example.json +0 -14
- package/src/client.ts +0 -106
- package/src/config.ts +0 -7
- package/src/http-server.ts +0 -591
- package/src/index.ts +0 -23
- package/src/resources/block-types.ts +0 -298
- package/src/resources/flow-schema.ts +0 -148
- package/src/server-factory.ts +0 -109
- package/src/tools/admin.ts +0 -128
- package/src/tools/ai-designer.ts +0 -97
- package/src/tools/analytics.ts +0 -49
- package/src/tools/auth.ts +0 -39
- package/src/tools/blocks.ts +0 -186
- package/src/tools/connections.ts +0 -83
- package/src/tools/eduflow.ts +0 -150
- package/src/tools/participants.ts +0 -77
- package/src/tools/presentation.ts +0 -61
- package/src/tools/projects.ts +0 -61
- package/src/tools/resources.ts +0 -41
- package/src/tools/store.ts +0 -67
- package/tsconfig.json +0 -19
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { clearTokenCache, getLyrraRequestAuthHeaders, requestOrigin } from './auth-session.js';
|
|
2
|
+
function substitutePath(template, pathParams) {
|
|
3
|
+
let p = template;
|
|
4
|
+
const re = /\{([^}]+)\}/g;
|
|
5
|
+
let m;
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
while ((m = re.exec(template)) !== null) {
|
|
8
|
+
seen.add(m[1]);
|
|
9
|
+
}
|
|
10
|
+
for (const name of seen) {
|
|
11
|
+
const val = pathParams[name];
|
|
12
|
+
if (val === undefined || val === '') {
|
|
13
|
+
throw new Error(`Required URL parameter: "${name}"`);
|
|
14
|
+
}
|
|
15
|
+
p = p.replaceAll(`{${name}}`, encodeURIComponent(val));
|
|
16
|
+
}
|
|
17
|
+
return p;
|
|
18
|
+
}
|
|
19
|
+
function buildQueryString(query) {
|
|
20
|
+
if (!query || Object.keys(query).length === 0)
|
|
21
|
+
return '';
|
|
22
|
+
const sp = new URLSearchParams();
|
|
23
|
+
for (const [k, v] of Object.entries(query)) {
|
|
24
|
+
if (v === undefined || v === null)
|
|
25
|
+
continue;
|
|
26
|
+
if (typeof v === 'object' && !Array.isArray(v)) {
|
|
27
|
+
sp.set(k, JSON.stringify(v));
|
|
28
|
+
}
|
|
29
|
+
else if (Array.isArray(v)) {
|
|
30
|
+
for (const item of v) {
|
|
31
|
+
sp.append(k, String(item));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sp.set(k, String(v));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const s = sp.toString();
|
|
39
|
+
return s ? `?${s}` : '';
|
|
40
|
+
}
|
|
41
|
+
async function doFetch(method, url, authHeaders, body) {
|
|
42
|
+
const headers = {
|
|
43
|
+
Accept: 'application/json, text/plain, */*',
|
|
44
|
+
...authHeaders,
|
|
45
|
+
};
|
|
46
|
+
let bodyInit;
|
|
47
|
+
if (body !== undefined && body !== null && method !== 'GET' && method !== 'HEAD') {
|
|
48
|
+
if (typeof body === 'string') {
|
|
49
|
+
bodyInit = body;
|
|
50
|
+
if (!headers['Content-Type'])
|
|
51
|
+
headers['Content-Type'] = 'text/plain; charset=utf-8';
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
bodyInit = JSON.stringify(body);
|
|
55
|
+
headers['Content-Type'] = 'application/json; charset=utf-8';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const r = await fetch(url, { method, headers, body: bodyInit });
|
|
59
|
+
const bodyText = await r.text();
|
|
60
|
+
const outHeaders = {};
|
|
61
|
+
r.headers.forEach((v, k) => {
|
|
62
|
+
outHeaders[k] = v;
|
|
63
|
+
});
|
|
64
|
+
return { status: r.status, headers: outHeaders, bodyText };
|
|
65
|
+
}
|
|
66
|
+
export async function callLyrraOperation(method, openApiPath, input) {
|
|
67
|
+
const origin = requestOrigin();
|
|
68
|
+
const pathParams = input.pathParams ?? {};
|
|
69
|
+
const resolvedPath = substitutePath(openApiPath, pathParams);
|
|
70
|
+
const qs = buildQueryString(input.query);
|
|
71
|
+
const url = `${origin}${resolvedPath}${qs}`;
|
|
72
|
+
let authHeaders = await getLyrraRequestAuthHeaders();
|
|
73
|
+
let result = await doFetch(method.toUpperCase(), url, authHeaders, input.body);
|
|
74
|
+
if (result.status === 401) {
|
|
75
|
+
clearTokenCache();
|
|
76
|
+
authHeaders = await getLyrraRequestAuthHeaders();
|
|
77
|
+
result = await doFetch(method.toUpperCase(), url, authHeaders, input.body);
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construction du McpServer Lyrra (outils OpenAPI + EduFlow) — partagé entre stdio et HTTP.
|
|
3
|
+
*/
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { requestOrigin } from './auth-session.js';
|
|
7
|
+
import { callLyrraOperation } from './lyrra-http.js';
|
|
8
|
+
import { fetchOpenApiJson, parseOpenApiOperations } from './openapi-parse.js';
|
|
9
|
+
import { eduflowBlockDocToolCount, registerEduflowBlockDocumentationTools, } from './register-eduflow-block-tools.js';
|
|
10
|
+
const MAX_DESC_CHARS = 12_000;
|
|
11
|
+
const MAX_TOOLS_ENV = process.env.LYRRA_MCP_MAX_TOOLS;
|
|
12
|
+
function truncateDesc(s) {
|
|
13
|
+
if (s.length <= MAX_DESC_CHARS)
|
|
14
|
+
return s;
|
|
15
|
+
return `${s.slice(0, MAX_DESC_CHARS)}\n\n[… truncated description — see OpenAPI / Swagger]`;
|
|
16
|
+
}
|
|
17
|
+
function zodShapeForOperation(op) {
|
|
18
|
+
const shape = {
|
|
19
|
+
query: z
|
|
20
|
+
.record(z.string(), z.unknown())
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Query parameters (key → value). Serialize complex values as JSON in a key if needed.'),
|
|
23
|
+
body: z
|
|
24
|
+
.unknown()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('JSON body (object or array) for POST, PUT, PATCH. Ignored for GET/DELETE.'),
|
|
27
|
+
};
|
|
28
|
+
for (const p of op.pathParamNames) {
|
|
29
|
+
shape[p] = z
|
|
30
|
+
.string()
|
|
31
|
+
.describe(`Value for path segment "${p}" in ${op.path}`);
|
|
32
|
+
}
|
|
33
|
+
return shape;
|
|
34
|
+
}
|
|
35
|
+
function formatToolResult(result) {
|
|
36
|
+
const snippet = result.bodyText.length > 120_000 ? `${result.bodyText.slice(0, 120_000)}\n… [truncated]` : result.bodyText;
|
|
37
|
+
const text = [
|
|
38
|
+
`HTTP ${result.status}`,
|
|
39
|
+
result.headers['content-type'] ? `Content-Type: ${result.headers['content-type']}` : '',
|
|
40
|
+
'',
|
|
41
|
+
snippet || '(empty body)',
|
|
42
|
+
]
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
.join('\n');
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: 'text', text }],
|
|
47
|
+
isError: result.status >= 400,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export async function createLyrraMcpServer() {
|
|
51
|
+
process.stderr.write('[lyrra-mcp] Loading OpenAPI…\n');
|
|
52
|
+
const spec = await fetchOpenApiJson();
|
|
53
|
+
let ops = parseOpenApiOperations(spec);
|
|
54
|
+
const maxTools = MAX_TOOLS_ENV ? parseInt(MAX_TOOLS_ENV, 10) : NaN;
|
|
55
|
+
if (!Number.isNaN(maxTools) && maxTools > 0) {
|
|
56
|
+
ops = ops.slice(0, maxTools);
|
|
57
|
+
process.stderr.write(`[lyrra-mcp] LYRRA_MCP_MAX_TOOLS=${maxTools} — ${ops.length} tools registered.\n`);
|
|
58
|
+
}
|
|
59
|
+
process.stderr.write(`[lyrra-mcp] ${ops.length} operations → MCP tools.\n`);
|
|
60
|
+
const mcp = new McpServer({
|
|
61
|
+
name: 'lyrra-studio',
|
|
62
|
+
version: '1.0.0',
|
|
63
|
+
title: 'Lyrra Studio',
|
|
64
|
+
});
|
|
65
|
+
registerEduflowBlockDocumentationTools(mcp);
|
|
66
|
+
process.stderr.write(`[lyrra-mcp] EduFlow docs: ${eduflowBlockDocToolCount()} tools (index + per-block sheets).\n`);
|
|
67
|
+
mcp.registerTool('lyrra_meta', {
|
|
68
|
+
description: 'Configuration summary: API origin, registered tool count, useful environment variables (no secrets shown).',
|
|
69
|
+
inputSchema: z.object({}),
|
|
70
|
+
}, async () => {
|
|
71
|
+
let tokenMode = 'CLIENT_ID+SECRET';
|
|
72
|
+
if (process.env.LYRRA_ACCESS_TOKEN?.trim())
|
|
73
|
+
tokenMode = 'ACCESS_TOKEN';
|
|
74
|
+
const hn = process.env.LYRRA_MCP_HEADER_NAME?.trim() || process.env.LYRRA_HEADER_AUTH_NAME?.trim();
|
|
75
|
+
const hv = process.env.LYRRA_MCP_HEADER_SECRET?.trim() ||
|
|
76
|
+
process.env.LYRRA_MCP_HEADER_VALUE?.trim() ||
|
|
77
|
+
process.env.LYRRA_HEADER_AUTH_VALUE?.trim();
|
|
78
|
+
if (hn && hv)
|
|
79
|
+
tokenMode = 'HEADER_AUTH_ENV';
|
|
80
|
+
const text = [
|
|
81
|
+
`Request origin: ${requestOrigin()}`,
|
|
82
|
+
`OpenAPI tools registered: ${ops.length}`,
|
|
83
|
+
`EduFlow block doc tools: ${eduflowBlockDocToolCount()} (lyrra_eduflow_blocks_index + lyrra_eduflow_block_*)`,
|
|
84
|
+
`Token mode: ${tokenMode}`,
|
|
85
|
+
`HTTP MCP: forward Authorization, X-Lyrra-Api-Key, or X-Api-Key from each request (n8n Header Auth).`,
|
|
86
|
+
`LYRRA_API_URL: ${process.env.LYRRA_API_URL ? 'set' : 'missing'}`,
|
|
87
|
+
`LYRRA_OPENAPI_URL: ${process.env.LYRRA_OPENAPI_URL ? 'set' : 'default /api/openapi.json'}`,
|
|
88
|
+
].join('\n');
|
|
89
|
+
return { content: [{ type: 'text', text }] };
|
|
90
|
+
});
|
|
91
|
+
mcp.registerTool('lyrra_search_operations', {
|
|
92
|
+
description: 'Search operations (operationId, method, path, start of description). Useful when the tool list is long.',
|
|
93
|
+
inputSchema: z.object({
|
|
94
|
+
q: z.string().min(1).describe('Search text (case-insensitive)'),
|
|
95
|
+
limit: z.number().int().min(1).max(80).optional().describe('Max results (default 30)'),
|
|
96
|
+
}),
|
|
97
|
+
}, async ({ q, limit }) => {
|
|
98
|
+
const lim = limit ?? 30;
|
|
99
|
+
const qq = q.toLowerCase();
|
|
100
|
+
const hits = ops
|
|
101
|
+
.filter((o) => o.operationId.toLowerCase().includes(qq) ||
|
|
102
|
+
o.path.toLowerCase().includes(qq) ||
|
|
103
|
+
o.method.toLowerCase().includes(qq) ||
|
|
104
|
+
o.description.toLowerCase().includes(qq))
|
|
105
|
+
.slice(0, lim);
|
|
106
|
+
const text = hits.length === 0
|
|
107
|
+
? 'No operations found.'
|
|
108
|
+
: hits.map((o) => `${o.method} ${o.path}\n operationId: ${o.operationId}`).join('\n\n');
|
|
109
|
+
return { content: [{ type: 'text', text }] };
|
|
110
|
+
});
|
|
111
|
+
const staticGuide = `# Lyrra Studio — MCP integration
|
|
112
|
+
|
|
113
|
+
- Each tool named after an OpenAPI **operationId** calls **exactly** the documented endpoint.
|
|
114
|
+
- **EduFlow blocks**: tools \`lyrra_eduflow_blocks_index\` then \`lyrra_eduflow_block_<type>\` (e.g. \`lyrra_eduflow_block_quiz_mcq\`) — full sheet: role, \`data\`, \`settings\`, graph.
|
|
115
|
+
- API args: path segments \`{id}\` → required properties of the same name; \`query\`; \`body\` (JSON).
|
|
116
|
+
- Auth (stdio / env): \`LYRRA_CLIENT_ID\` + \`LYRRA_CLIENT_SECRET\`, \`LYRRA_ACCESS_TOKEN\`, or \`LYRRA_MCP_HEADER_NAME\` + value.
|
|
117
|
+
- Auth (HTTP MCP / n8n): send **Header Auth** on every MCP request (e.g. \`X-Lyrra-Api-Key: rak_…\` matching your institution key).
|
|
118
|
+
`;
|
|
119
|
+
mcp.registerResource('lyrra-mcp-guide', 'lyrra://flow-construction-guide', {
|
|
120
|
+
description: 'How to use the Lyrra MCP server',
|
|
121
|
+
mimeType: 'text/markdown',
|
|
122
|
+
}, async () => ({
|
|
123
|
+
contents: [{ uri: 'lyrra://flow-construction-guide', mimeType: 'text/markdown', text: staticGuide }],
|
|
124
|
+
}));
|
|
125
|
+
mcp.registerResource('lyrra-block-types', 'lyrra://block-types', {
|
|
126
|
+
description: 'Points to MCP tools lyrra_eduflow_block_* (per-type sheet) + persistence via eduflows API',
|
|
127
|
+
mimeType: 'text/markdown',
|
|
128
|
+
}, async () => ({
|
|
129
|
+
contents: [
|
|
130
|
+
{
|
|
131
|
+
uri: 'lyrra://block-types',
|
|
132
|
+
mimeType: 'text/markdown',
|
|
133
|
+
text: [
|
|
134
|
+
'# EduFlow block types (MCP)',
|
|
135
|
+
'',
|
|
136
|
+
`1. Call **lyrra_eduflow_blocks_index** for documented types (${eduflowBlockDocToolCount() - 1} blocks).`,
|
|
137
|
+
'2. Call **lyrra_eduflow_block_<type>** (e.g. `lyrra_eduflow_block_video`) for the full sheet: pedagogical role, `BlockData`, `settings`, connections.',
|
|
138
|
+
'3. HTTP persistence: OpenAPI routes under `/api/eduflows/{id}/blocks` and flow save.',
|
|
139
|
+
'',
|
|
140
|
+
'Code reference: `apps/frontend/src/types/eduflow.ts`, palette `eduflow-designer-palette-blueprint.ts`.',
|
|
141
|
+
].join('\n'),
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
}));
|
|
145
|
+
for (const op of ops) {
|
|
146
|
+
const inputSchema = z.object(zodShapeForOperation(op));
|
|
147
|
+
const desc = truncateDesc(`${op.description}\n\n— HTTP ${op.method} \`${op.path}\``);
|
|
148
|
+
mcp.registerTool(op.operationId, {
|
|
149
|
+
description: desc,
|
|
150
|
+
inputSchema,
|
|
151
|
+
}, async (rawArgs) => {
|
|
152
|
+
const args = rawArgs;
|
|
153
|
+
const pathParams = {};
|
|
154
|
+
for (const name of op.pathParamNames) {
|
|
155
|
+
const v = args[name];
|
|
156
|
+
pathParams[name] = typeof v === 'string' ? v : String(v ?? '');
|
|
157
|
+
}
|
|
158
|
+
const query = args.query;
|
|
159
|
+
const body = args.body;
|
|
160
|
+
try {
|
|
161
|
+
const result = await callLyrraOperation(op.method, op.path, { pathParams, query, body });
|
|
162
|
+
return formatToolResult(result);
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
166
|
+
return {
|
|
167
|
+
content: [{ type: 'text', text: `Error: ${msg}` }],
|
|
168
|
+
isError: true,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return { mcp, operationsCount: ops.length };
|
|
174
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { requestOrigin } from './auth-session.js';
|
|
2
|
+
const HTTP_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete']);
|
|
3
|
+
function pathParamsFromOpenApiPath(path) {
|
|
4
|
+
const names = [];
|
|
5
|
+
const re = /\{([^}]+)\}/g;
|
|
6
|
+
let m;
|
|
7
|
+
while ((m = re.exec(path)) !== null) {
|
|
8
|
+
names.push(m[1]);
|
|
9
|
+
}
|
|
10
|
+
return names;
|
|
11
|
+
}
|
|
12
|
+
export function parseOpenApiOperations(spec) {
|
|
13
|
+
if (!spec || typeof spec !== 'object')
|
|
14
|
+
return [];
|
|
15
|
+
const paths = spec.paths;
|
|
16
|
+
if (!paths || typeof paths !== 'object')
|
|
17
|
+
return [];
|
|
18
|
+
const out = [];
|
|
19
|
+
const usedIds = new Map();
|
|
20
|
+
for (const [path, item] of Object.entries(paths)) {
|
|
21
|
+
if (!item || typeof item !== 'object')
|
|
22
|
+
continue;
|
|
23
|
+
for (const [method, op] of Object.entries(item)) {
|
|
24
|
+
const m = method.toLowerCase();
|
|
25
|
+
if (!HTTP_METHODS.has(m))
|
|
26
|
+
continue;
|
|
27
|
+
if (!op || typeof op !== 'object')
|
|
28
|
+
continue;
|
|
29
|
+
const o = op;
|
|
30
|
+
let operationId = typeof o.operationId === 'string' && o.operationId.length > 0
|
|
31
|
+
? o.operationId
|
|
32
|
+
: `${m}_${path.replace(/[^a-zA-Z0-9]+/g, '_')}`;
|
|
33
|
+
const n = (usedIds.get(operationId) ?? 0) + 1;
|
|
34
|
+
usedIds.set(operationId, n);
|
|
35
|
+
if (n > 1) {
|
|
36
|
+
operationId = `${operationId}__${n}`;
|
|
37
|
+
}
|
|
38
|
+
const summary = typeof o.summary === 'string' ? o.summary : `${m.toUpperCase()} ${path}`;
|
|
39
|
+
const description = typeof o.description === 'string' && o.description.length > 0 ? o.description : summary;
|
|
40
|
+
out.push({
|
|
41
|
+
operationId,
|
|
42
|
+
method: m.toUpperCase(),
|
|
43
|
+
path,
|
|
44
|
+
description,
|
|
45
|
+
pathParamNames: pathParamsFromOpenApiPath(path),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
out.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
export async function fetchOpenApiJson() {
|
|
53
|
+
const override = process.env.LYRRA_OPENAPI_URL?.trim();
|
|
54
|
+
const origin = requestOrigin();
|
|
55
|
+
const url = override || `${origin}/api/openapi.json`;
|
|
56
|
+
const r = await fetch(url, { headers: { Accept: 'application/json' } });
|
|
57
|
+
if (!r.ok) {
|
|
58
|
+
throw new Error(`OpenAPI introuvable (${r.status}) : ${url}`);
|
|
59
|
+
}
|
|
60
|
+
return r.json();
|
|
61
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { EDUFLOW_BLOCK_DOCS, eduflowBlockToolName, renderEduflowBlockMarkdown, } from './eduflow-block-docs.js';
|
|
3
|
+
/** MCP tools: one per block type + index (detailed JSON/settings sheets). */
|
|
4
|
+
export function registerEduflowBlockDocumentationTools(mcp) {
|
|
5
|
+
mcp.registerTool('lyrra_eduflow_blocks_index', {
|
|
6
|
+
description: 'Lists MCP tools `lyrra_eduflow_block_*` (one per EduFlow block type) with a short summary; call them for full docs (data, settings, graph).',
|
|
7
|
+
inputSchema: z.object({}),
|
|
8
|
+
}, async () => {
|
|
9
|
+
const lines = EDUFLOW_BLOCK_DOCS.map((e) => `- \`${eduflowBlockToolName(e.id)}\` — **${e.label}** (\`${e.id}\`, ${e.category}): ${e.summary}`);
|
|
10
|
+
const text = [
|
|
11
|
+
'# Index — EduFlow block types',
|
|
12
|
+
'',
|
|
13
|
+
'Each line is a distinct **MCP tool**. Invoke it with no arguments for full documentation (JSON model, configuration).',
|
|
14
|
+
'',
|
|
15
|
+
...lines,
|
|
16
|
+
].join('\n');
|
|
17
|
+
return { content: [{ type: 'text', text }] };
|
|
18
|
+
});
|
|
19
|
+
for (const e of EDUFLOW_BLOCK_DOCS) {
|
|
20
|
+
const toolName = eduflowBlockToolName(e.id);
|
|
21
|
+
mcp.registerTool(toolName, {
|
|
22
|
+
description: `EduFlow block “${e.label}” (type \`${e.id}\`) — ${e.summary}`,
|
|
23
|
+
inputSchema: z.object({}),
|
|
24
|
+
}, async () => ({
|
|
25
|
+
content: [{ type: 'text', text: renderEduflowBlockMarkdown(e.id) }],
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function eduflowBlockDocToolCount() {
|
|
30
|
+
return EDUFLOW_BLOCK_DOCS.length + 1;
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,28 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lyrra/mcp-server",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "Lyrra Studio stdio MCP server — OpenAPI-aligned tools for Claude Desktop, Cursor, and compatible MCP clients",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"lyrra-mcp": "dist/index.js"
|
|
8
|
+
"lyrra-mcp": "./dist/index.js",
|
|
9
|
+
"lyrra-mcp-http": "./dist/http-main.js"
|
|
9
10
|
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
10
15
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
12
18
|
"start": "node dist/index.js",
|
|
13
|
-
"start:http": "node dist/http-
|
|
19
|
+
"start:http": "node dist/http-main.js",
|
|
14
20
|
"dev": "tsx src/index.ts",
|
|
15
|
-
"dev:http": "tsx src/http-
|
|
21
|
+
"dev:http": "tsx src/http-main.ts",
|
|
22
|
+
"test:mcp": "npm run build && node scripts/mcp-smoke-test.mjs"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20.0.0"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"mcp",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"lyrra",
|
|
31
|
+
"lyrra-studio",
|
|
32
|
+
"openapi",
|
|
33
|
+
"claude",
|
|
34
|
+
"stdio"
|
|
35
|
+
],
|
|
36
|
+
"author": "Lyrra",
|
|
37
|
+
"license": "UNLICENSED",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/LyrraStudio/LyrraStudio.git",
|
|
41
|
+
"directory": "lyrra-studio-app/apps/mcp-server"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
16
45
|
},
|
|
17
46
|
"dependencies": {
|
|
18
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"cors": "^2.8.6",
|
|
22
|
-
"zod": "^3.24.0"
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
48
|
+
"express": "^5.2.1",
|
|
49
|
+
"zod": "^3.23.8"
|
|
23
50
|
},
|
|
24
51
|
"devDependencies": {
|
|
25
|
-
"@types/
|
|
52
|
+
"@types/express": "^5.0.0",
|
|
53
|
+
"@types/node": "^20.10.8",
|
|
26
54
|
"tsx": "^4.7.0",
|
|
27
55
|
"typescript": "^5.2.2"
|
|
28
56
|
}
|
package/Dockerfile
DELETED
package/dist/client.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface LyrraClientOptions {
|
|
2
|
-
apiUrl?: string;
|
|
3
|
-
eduflowUrl?: string;
|
|
4
|
-
clientId?: string;
|
|
5
|
-
clientSecret?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class LyrraClient {
|
|
8
|
-
private apiUrl;
|
|
9
|
-
private eduflowUrl;
|
|
10
|
-
private clientId;
|
|
11
|
-
private clientSecret;
|
|
12
|
-
private jwtToken;
|
|
13
|
-
constructor(options?: LyrraClientOptions);
|
|
14
|
-
private get headers();
|
|
15
|
-
setToken(token: string): void;
|
|
16
|
-
get(path: string, base?: 'api' | 'eduflow'): Promise<any>;
|
|
17
|
-
post(path: string, data?: any, base?: 'api' | 'eduflow'): Promise<any>;
|
|
18
|
-
put(path: string, data?: any, base?: 'api' | 'eduflow'): Promise<any>;
|
|
19
|
-
patch(path: string, data?: any, base?: 'api' | 'eduflow'): Promise<any>;
|
|
20
|
-
delete(path: string, base?: 'api' | 'eduflow'): Promise<any>;
|
|
21
|
-
}
|
|
22
|
-
export declare const client: LyrraClient;
|
|
23
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,OAAO,CAAC,EAAE,kBAAkB;IAOxC,OAAO,KAAK,OAAO,GAMlB;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM;IAIhB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,KAAK,GAAG,SAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAUhE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,GAAE,KAAK,GAAG,SAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAe7E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,GAAE,KAAK,GAAG,SAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAe5E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,GAAE,KAAK,GAAG,SAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAe9E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,KAAK,GAAG,SAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;CAa1E;AAED,eAAO,MAAM,MAAM,aAAoB,CAAC"}
|
package/dist/client.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { config } from './config.js';
|
|
2
|
-
export class LyrraClient {
|
|
3
|
-
apiUrl;
|
|
4
|
-
eduflowUrl;
|
|
5
|
-
clientId;
|
|
6
|
-
clientSecret;
|
|
7
|
-
jwtToken = null;
|
|
8
|
-
constructor(options) {
|
|
9
|
-
this.apiUrl = options?.apiUrl || config.apiUrl;
|
|
10
|
-
this.eduflowUrl = options?.eduflowUrl || config.eduflowApiUrl;
|
|
11
|
-
this.clientId = options?.clientId || config.clientId;
|
|
12
|
-
this.clientSecret = options?.clientSecret || config.clientSecret;
|
|
13
|
-
}
|
|
14
|
-
get headers() {
|
|
15
|
-
const h = { 'Content-Type': 'application/json' };
|
|
16
|
-
// Client Secret is the API key used for X-API-Key header authentication
|
|
17
|
-
if (this.clientSecret)
|
|
18
|
-
h['X-API-Key'] = this.clientSecret;
|
|
19
|
-
if (this.jwtToken)
|
|
20
|
-
h['Authorization'] = `Bearer ${this.jwtToken}`;
|
|
21
|
-
return h;
|
|
22
|
-
}
|
|
23
|
-
setToken(token) {
|
|
24
|
-
this.jwtToken = token;
|
|
25
|
-
}
|
|
26
|
-
async get(path, base = 'api') {
|
|
27
|
-
const url = `${base === 'eduflow' ? this.eduflowUrl : this.apiUrl}${path}`;
|
|
28
|
-
const res = await fetch(url, { headers: this.headers });
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
const body = await res.text();
|
|
31
|
-
throw new Error(`GET ${path} failed (${res.status}): ${body}`);
|
|
32
|
-
}
|
|
33
|
-
return res.json();
|
|
34
|
-
}
|
|
35
|
-
async post(path, data, base = 'api') {
|
|
36
|
-
const url = `${base === 'eduflow' ? this.eduflowUrl : this.apiUrl}${path}`;
|
|
37
|
-
const res = await fetch(url, {
|
|
38
|
-
method: 'POST',
|
|
39
|
-
headers: this.headers,
|
|
40
|
-
body: data ? JSON.stringify(data) : undefined,
|
|
41
|
-
});
|
|
42
|
-
if (!res.ok) {
|
|
43
|
-
const body = await res.text();
|
|
44
|
-
throw new Error(`POST ${path} failed (${res.status}): ${body}`);
|
|
45
|
-
}
|
|
46
|
-
const text = await res.text();
|
|
47
|
-
return text ? JSON.parse(text) : {};
|
|
48
|
-
}
|
|
49
|
-
async put(path, data, base = 'api') {
|
|
50
|
-
const url = `${base === 'eduflow' ? this.eduflowUrl : this.apiUrl}${path}`;
|
|
51
|
-
const res = await fetch(url, {
|
|
52
|
-
method: 'PUT',
|
|
53
|
-
headers: this.headers,
|
|
54
|
-
body: data ? JSON.stringify(data) : undefined,
|
|
55
|
-
});
|
|
56
|
-
if (!res.ok) {
|
|
57
|
-
const body = await res.text();
|
|
58
|
-
throw new Error(`PUT ${path} failed (${res.status}): ${body}`);
|
|
59
|
-
}
|
|
60
|
-
const text = await res.text();
|
|
61
|
-
return text ? JSON.parse(text) : {};
|
|
62
|
-
}
|
|
63
|
-
async patch(path, data, base = 'api') {
|
|
64
|
-
const url = `${base === 'eduflow' ? this.eduflowUrl : this.apiUrl}${path}`;
|
|
65
|
-
const res = await fetch(url, {
|
|
66
|
-
method: 'PATCH',
|
|
67
|
-
headers: this.headers,
|
|
68
|
-
body: data ? JSON.stringify(data) : undefined,
|
|
69
|
-
});
|
|
70
|
-
if (!res.ok) {
|
|
71
|
-
const body = await res.text();
|
|
72
|
-
throw new Error(`PATCH ${path} failed (${res.status}): ${body}`);
|
|
73
|
-
}
|
|
74
|
-
const text = await res.text();
|
|
75
|
-
return text ? JSON.parse(text) : {};
|
|
76
|
-
}
|
|
77
|
-
async delete(path, base = 'api') {
|
|
78
|
-
const url = `${base === 'eduflow' ? this.eduflowUrl : this.apiUrl}${path}`;
|
|
79
|
-
const res = await fetch(url, {
|
|
80
|
-
method: 'DELETE',
|
|
81
|
-
headers: this.headers,
|
|
82
|
-
});
|
|
83
|
-
if (!res.ok) {
|
|
84
|
-
const body = await res.text();
|
|
85
|
-
throw new Error(`DELETE ${path} failed (${res.status}): ${body}`);
|
|
86
|
-
}
|
|
87
|
-
const text = await res.text();
|
|
88
|
-
return text ? JSON.parse(text) : {};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
export const client = new LyrraClient();
|
|
92
|
-
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
DELETED
package/dist/config.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;;;CAMlB,CAAC"}
|
package/dist/config.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const config = {
|
|
2
|
-
apiUrl: process.env.LYRRA_API_URL || 'http://localhost:3001/api',
|
|
3
|
-
clientId: process.env.LYRRA_CLIENT_ID || '',
|
|
4
|
-
clientSecret: process.env.LYRRA_CLIENT_SECRET || '',
|
|
5
|
-
eduflowApiUrl: process.env.LYRRA_EDUFLOW_API_URL || 'http://localhost:3001/eduflow',
|
|
6
|
-
frontendUrl: process.env.LYRRA_FRONTEND_URL || (process.env.LYRRA_API_URL ? process.env.LYRRA_API_URL.replace(/\/api$/, '') : 'http://localhost:5173'),
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,2BAA2B;IAChE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE;IAC3C,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE;IACnD,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,+BAA+B;IACnF,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC;CACvJ,CAAC"}
|
package/dist/http-server.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|