@lyrra/mcp-server 1.0.1 → 1.1.0

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.
Files changed (87) hide show
  1. package/Dockerfile +16 -0
  2. package/README.md +59 -4
  3. package/dist/client.d.ts +7 -1
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +5 -5
  6. package/dist/client.js.map +1 -1
  7. package/dist/config.d.ts +1 -0
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +1 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/http-server.d.ts +8 -0
  12. package/dist/http-server.d.ts.map +1 -0
  13. package/dist/http-server.js +466 -0
  14. package/dist/http-server.js.map +1 -0
  15. package/dist/index.js +3 -69
  16. package/dist/index.js.map +1 -1
  17. package/dist/server-factory.d.ts +8 -0
  18. package/dist/server-factory.d.ts.map +1 -0
  19. package/dist/server-factory.js +82 -0
  20. package/dist/server-factory.js.map +1 -0
  21. package/dist/tools/admin.d.ts +132 -0
  22. package/dist/tools/admin.d.ts.map +1 -1
  23. package/dist/tools/admin.js +105 -101
  24. package/dist/tools/admin.js.map +1 -1
  25. package/dist/tools/ai-designer.d.ts +148 -0
  26. package/dist/tools/ai-designer.d.ts.map +1 -1
  27. package/dist/tools/ai-designer.js +80 -76
  28. package/dist/tools/ai-designer.js.map +1 -1
  29. package/dist/tools/analytics.d.ts +47 -0
  30. package/dist/tools/analytics.d.ts.map +1 -1
  31. package/dist/tools/analytics.js +38 -34
  32. package/dist/tools/analytics.js.map +1 -1
  33. package/dist/tools/auth.d.ts +30 -0
  34. package/dist/tools/auth.d.ts.map +1 -1
  35. package/dist/tools/auth.js +31 -27
  36. package/dist/tools/auth.js.map +1 -1
  37. package/dist/tools/blocks.d.ts +200 -0
  38. package/dist/tools/blocks.d.ts.map +1 -1
  39. package/dist/tools/blocks.js +154 -150
  40. package/dist/tools/blocks.js.map +1 -1
  41. package/dist/tools/connections.d.ts +86 -0
  42. package/dist/tools/connections.d.ts.map +1 -1
  43. package/dist/tools/connections.js +70 -66
  44. package/dist/tools/connections.js.map +1 -1
  45. package/dist/tools/eduflow.d.ts +223 -0
  46. package/dist/tools/eduflow.d.ts.map +1 -1
  47. package/dist/tools/eduflow.js +114 -93
  48. package/dist/tools/eduflow.js.map +1 -1
  49. package/dist/tools/participants.d.ts +110 -0
  50. package/dist/tools/participants.d.ts.map +1 -1
  51. package/dist/tools/participants.js +62 -58
  52. package/dist/tools/participants.js.map +1 -1
  53. package/dist/tools/presentation.d.ts +116 -0
  54. package/dist/tools/presentation.d.ts.map +1 -1
  55. package/dist/tools/presentation.js +51 -47
  56. package/dist/tools/presentation.js.map +1 -1
  57. package/dist/tools/projects.d.ts +65 -0
  58. package/dist/tools/projects.d.ts.map +1 -1
  59. package/dist/tools/projects.js +48 -44
  60. package/dist/tools/projects.js.map +1 -1
  61. package/dist/tools/resources.d.ts +46 -0
  62. package/dist/tools/resources.d.ts.map +1 -1
  63. package/dist/tools/resources.js +32 -28
  64. package/dist/tools/resources.js.map +1 -1
  65. package/dist/tools/store.d.ts +62 -0
  66. package/dist/tools/store.d.ts.map +1 -1
  67. package/dist/tools/store.js +59 -55
  68. package/dist/tools/store.js.map +1 -1
  69. package/mcp-config.example.json +4 -5
  70. package/package.json +7 -2
  71. package/src/client.ts +12 -5
  72. package/src/config.ts +1 -0
  73. package/src/http-server.ts +573 -0
  74. package/src/index.ts +3 -94
  75. package/src/server-factory.ts +109 -0
  76. package/src/tools/admin.ts +20 -14
  77. package/src/tools/ai-designer.ts +16 -10
  78. package/src/tools/analytics.ts +13 -7
  79. package/src/tools/auth.ts +32 -26
  80. package/src/tools/blocks.ts +18 -12
  81. package/src/tools/connections.ts +14 -8
  82. package/src/tools/eduflow.ts +36 -12
  83. package/src/tools/participants.ts +15 -9
  84. package/src/tools/presentation.ts +12 -6
  85. package/src/tools/projects.ts +14 -8
  86. package/src/tools/resources.ts +12 -6
  87. package/src/tools/store.ts +14 -8
@@ -0,0 +1,466 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LYRRA Studio MCP HTTP Server
4
+ * Provides Streamable HTTP transport with OAuth 2.0 for Claude.ai integration.
5
+ * All endpoints are under /mcp/ for clean nginx routing.
6
+ */
7
+ import crypto from 'crypto';
8
+ import express from 'express';
9
+ import cors from 'cors';
10
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
11
+ import { createMcpServer } from './server-factory.js';
12
+ import { LyrraClient } from './client.js';
13
+ // ─── Configuration ───────────────────────────────────────────────────────────
14
+ const PORT = parseInt(process.env.MCP_HTTP_PORT || '3002', 10);
15
+ const BASE_URL = process.env.MCP_BASE_URL || 'https://lyrrastudio.com';
16
+ const LYRRA_API_URL = process.env.LYRRA_API_URL || 'http://localhost:3001/api';
17
+ const registeredClients = new Map();
18
+ const authCodes = new Map();
19
+ const accessTokens = new Map();
20
+ const refreshTokens = new Map();
21
+ const mcpSessions = new Map();
22
+ // ─── Helper: Validate LYRRA API key ─────────────────────────────────────────
23
+ async function validateApiKey(apiKey) {
24
+ try {
25
+ const res = await fetch(`${LYRRA_API_URL}/auth/me`, {
26
+ headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
27
+ });
28
+ return res.ok;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ // ─── Helper: Verify PKCE ────────────────────────────────────────────────────
35
+ function verifyPkce(codeVerifier, codeChallenge, method) {
36
+ if (method === 'S256') {
37
+ const hash = crypto.createHash('sha256').update(codeVerifier).digest('base64url');
38
+ return hash === codeChallenge;
39
+ }
40
+ return codeVerifier === codeChallenge; // plain
41
+ }
42
+ // ─── Helper: Verify Bearer token ─────────────────────────────────────────────
43
+ function verifyBearerToken(req) {
44
+ const auth = req.headers.authorization;
45
+ if (!auth?.startsWith('Bearer '))
46
+ return null;
47
+ const token = auth.slice(7);
48
+ const data = accessTokens.get(token);
49
+ if (!data)
50
+ return null;
51
+ if (Date.now() > data.expiresAt) {
52
+ accessTokens.delete(token);
53
+ return null;
54
+ }
55
+ return data;
56
+ }
57
+ // ─── Authorize page HTML ─────────────────────────────────────────────────────
58
+ function renderAuthorizePage(pendingToken, showError = false) {
59
+ return `<!DOCTYPE html>
60
+ <html lang="fr">
61
+ <head>
62
+ <meta charset="UTF-8">
63
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
64
+ <title>LYRRA Studio - Autorisation MCP</title>
65
+ <style>
66
+ * { margin: 0; padding: 0; box-sizing: border-box; }
67
+ body {
68
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
69
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
70
+ min-height: 100vh; display: flex; align-items: center; justify-content: center;
71
+ }
72
+ .card {
73
+ background: white; border-radius: 16px; padding: 40px;
74
+ max-width: 440px; width: 100%; box-shadow: 0 20px 60px rgba(0,0,0,0.2);
75
+ }
76
+ .logo { text-align: center; margin-bottom: 24px; }
77
+ .logo h1 { font-size: 28px; color: #333; }
78
+ .logo span { color: #667eea; }
79
+ .subtitle { text-align: center; color: #666; margin-bottom: 32px; font-size: 14px; line-height: 1.5; }
80
+ label { display: block; font-size: 13px; font-weight: 600; color: #444; margin-bottom: 6px; }
81
+ input {
82
+ width: 100%; padding: 12px 16px; border: 2px solid #e2e8f0;
83
+ border-radius: 8px; font-size: 14px; transition: border-color 0.2s;
84
+ margin-bottom: 16px; outline: none;
85
+ }
86
+ input:focus { border-color: #667eea; }
87
+ button {
88
+ width: 100%; padding: 14px; background: #667eea; color: white;
89
+ border: none; border-radius: 8px; font-size: 16px; font-weight: 600;
90
+ cursor: pointer; transition: background 0.2s;
91
+ }
92
+ button:hover { background: #5a6fd6; }
93
+ button:disabled { background: #a0aec0; cursor: not-allowed; }
94
+ .error { color: #e53e3e; font-size: 13px; margin-bottom: 16px; display: ${showError ? 'block' : 'none'}; }
95
+ .info { font-size: 12px; color: #888; text-align: center; margin-top: 16px; line-height: 1.5; }
96
+ </style>
97
+ </head>
98
+ <body>
99
+ <div class="card">
100
+ <div class="logo"><h1><span>LYRRA</span> Studio</h1></div>
101
+ <p class="subtitle">
102
+ Une application souhaite accéder à votre compte LYRRA Studio via MCP.<br>
103
+ Entrez vos identifiants API pour autoriser l'accès.
104
+ </p>
105
+ <form id="authForm" method="POST" action="/mcp/approve">
106
+ <input type="hidden" name="pending_token" value="${pendingToken}">
107
+ <label for="apiKey">Clé API (Client Secret)</label>
108
+ <input type="password" id="apiKey" name="api_key" placeholder="rak_XXXXXXXX_..." required>
109
+ <div class="error" id="error">Clé API invalide. Vérifiez votre Client Secret dans le tableau de bord.</div>
110
+ <button type="submit" id="submitBtn">Autoriser l'accès</button>
111
+ </form>
112
+ <p class="info">
113
+ Votre clé API est disponible dans le tableau de bord de votre institution,<br>
114
+ section « Serveur MCP » → Client Secret (visible uniquement à la création).
115
+ </p>
116
+ </div>
117
+ <script>
118
+ document.getElementById('authForm').addEventListener('submit', function() {
119
+ document.getElementById('submitBtn').disabled = true;
120
+ document.getElementById('submitBtn').textContent = 'Vérification...';
121
+ });
122
+ </script>
123
+ </body>
124
+ </html>`;
125
+ }
126
+ // ─── Create Express app ──────────────────────────────────────────────────────
127
+ const app = express();
128
+ app.use(cors({ origin: true, credentials: true, exposedHeaders: ['mcp-session-id'] }));
129
+ app.use(express.json());
130
+ app.use(express.urlencoded({ extended: true }));
131
+ // ─── OAuth Protected Resource Metadata (RFC 9728) ────────────────────────────
132
+ // Claude.ai fetches this to discover the authorization server
133
+ app.get('/.well-known/oauth-protected-resource/mcp', (_req, res) => {
134
+ res.json({
135
+ resource: `${BASE_URL}/mcp`,
136
+ authorization_servers: [`${BASE_URL}/mcp`],
137
+ scopes_supported: ['mcp'],
138
+ resource_name: 'LYRRA Studio MCP',
139
+ resource_documentation: `${BASE_URL}/docs/mcp`,
140
+ });
141
+ });
142
+ app.get('/.well-known/oauth-protected-resource', (_req, res) => {
143
+ res.json({
144
+ resource: `${BASE_URL}/mcp`,
145
+ authorization_servers: [`${BASE_URL}/mcp`],
146
+ scopes_supported: ['mcp'],
147
+ resource_name: 'LYRRA Studio MCP',
148
+ });
149
+ });
150
+ // ─── OAuth Authorization Server Metadata (RFC 8414) ──────────────────────────
151
+ app.get('/mcp/.well-known/oauth-authorization-server', (_req, res) => {
152
+ res.json({
153
+ issuer: `${BASE_URL}/mcp`,
154
+ authorization_endpoint: `${BASE_URL}/mcp/authorize`,
155
+ token_endpoint: `${BASE_URL}/mcp/token`,
156
+ registration_endpoint: `${BASE_URL}/mcp/register`,
157
+ revocation_endpoint: `${BASE_URL}/mcp/revoke`,
158
+ response_types_supported: ['code'],
159
+ grant_types_supported: ['authorization_code', 'refresh_token'],
160
+ code_challenge_methods_supported: ['S256'],
161
+ token_endpoint_auth_methods_supported: ['client_secret_post', 'none'],
162
+ scopes_supported: ['mcp'],
163
+ service_documentation: `${BASE_URL}/docs/mcp`,
164
+ });
165
+ });
166
+ // ─── Dynamic Client Registration (RFC 7591) ──────────────────────────────────
167
+ app.post('/mcp/register', (req, res) => {
168
+ const { redirect_uris, grant_types, response_types, token_endpoint_auth_method, client_name } = req.body;
169
+ const clientId = `mcp_${crypto.randomBytes(16).toString('hex')}`;
170
+ const clientSecret = crypto.randomBytes(32).toString('hex');
171
+ const client = {
172
+ client_id: clientId,
173
+ client_secret: clientSecret,
174
+ client_id_issued_at: Math.floor(Date.now() / 1000),
175
+ redirect_uris: redirect_uris || [],
176
+ grant_types: grant_types || ['authorization_code', 'refresh_token'],
177
+ response_types: response_types || ['code'],
178
+ token_endpoint_auth_method: token_endpoint_auth_method || 'client_secret_post',
179
+ };
180
+ registeredClients.set(clientId, client);
181
+ console.log(`[MCP OAuth] Registered client: ${clientId} (${client_name || 'unnamed'})`);
182
+ res.status(201).json({
183
+ client_id: clientId,
184
+ client_secret: clientSecret,
185
+ client_id_issued_at: client.client_id_issued_at,
186
+ client_secret_expires_at: 0,
187
+ redirect_uris: client.redirect_uris,
188
+ grant_types: client.grant_types,
189
+ response_types: client.response_types,
190
+ token_endpoint_auth_method: client.token_endpoint_auth_method,
191
+ });
192
+ });
193
+ // ─── Authorization endpoint ──────────────────────────────────────────────────
194
+ app.get('/mcp/authorize', (req, res) => {
195
+ const { client_id, redirect_uri, response_type, state, code_challenge, code_challenge_method, scope } = req.query;
196
+ if (response_type !== 'code') {
197
+ res.status(400).json({ error: 'unsupported_response_type' });
198
+ return;
199
+ }
200
+ if (!client_id || !redirect_uri || !code_challenge) {
201
+ res.status(400).json({ error: 'invalid_request', error_description: 'Missing required parameters' });
202
+ return;
203
+ }
204
+ // Verify client is registered
205
+ const client = registeredClients.get(client_id);
206
+ if (!client) {
207
+ res.status(400).json({ error: 'invalid_client', error_description: 'Client not registered' });
208
+ return;
209
+ }
210
+ // Encode auth params for the form
211
+ const pendingData = {
212
+ oauthClientId: client_id,
213
+ redirectUri: redirect_uri,
214
+ codeChallenge: code_challenge,
215
+ codeChallengeMethod: code_challenge_method || 'S256',
216
+ state: state,
217
+ };
218
+ const pendingToken = Buffer.from(JSON.stringify(pendingData)).toString('base64url');
219
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
220
+ res.send(renderAuthorizePage(pendingToken));
221
+ });
222
+ // ─── Approve endpoint (form POST from authorize page) ────────────────────────
223
+ app.post('/mcp/approve', async (req, res) => {
224
+ try {
225
+ const { pending_token, api_key } = req.body;
226
+ if (!pending_token || !api_key) {
227
+ res.status(400).send('Paramètres manquants');
228
+ return;
229
+ }
230
+ let pendingData;
231
+ try {
232
+ pendingData = JSON.parse(Buffer.from(pending_token, 'base64url').toString('utf-8'));
233
+ }
234
+ catch {
235
+ res.status(400).send('Token invalide');
236
+ return;
237
+ }
238
+ // Validate the LYRRA API key
239
+ const isValid = await validateApiKey(api_key);
240
+ if (!isValid) {
241
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
242
+ res.send(renderAuthorizePage(pending_token, true));
243
+ return;
244
+ }
245
+ // Generate authorization code
246
+ const authCode = crypto.randomBytes(32).toString('hex');
247
+ authCodes.set(authCode, {
248
+ oauthClientId: pendingData.oauthClientId,
249
+ codeChallenge: pendingData.codeChallenge,
250
+ codeChallengeMethod: pendingData.codeChallengeMethod,
251
+ redirectUri: pendingData.redirectUri,
252
+ state: pendingData.state,
253
+ apiKey: api_key,
254
+ expiresAt: Date.now() + 10 * 60 * 1000,
255
+ });
256
+ // Redirect back with authorization code
257
+ const redirectUrl = new URL(pendingData.redirectUri);
258
+ redirectUrl.searchParams.set('code', authCode);
259
+ if (pendingData.state) {
260
+ redirectUrl.searchParams.set('state', pendingData.state);
261
+ }
262
+ console.log(`[MCP OAuth] Authorization granted, redirecting...`);
263
+ res.redirect(redirectUrl.toString());
264
+ }
265
+ catch (error) {
266
+ console.error('[MCP OAuth] Approve error:', error);
267
+ res.status(500).send('Erreur interne');
268
+ }
269
+ });
270
+ // ─── Token endpoint ──────────────────────────────────────────────────────────
271
+ app.post('/mcp/token', (req, res) => {
272
+ const { grant_type, code, redirect_uri, code_verifier, client_id, client_secret, refresh_token } = req.body;
273
+ if (grant_type === 'authorization_code') {
274
+ if (!code || !code_verifier) {
275
+ res.status(400).json({ error: 'invalid_request' });
276
+ return;
277
+ }
278
+ const authCode = authCodes.get(code);
279
+ if (!authCode) {
280
+ res.status(400).json({ error: 'invalid_grant', error_description: 'Invalid authorization code' });
281
+ return;
282
+ }
283
+ if (Date.now() > authCode.expiresAt) {
284
+ authCodes.delete(code);
285
+ res.status(400).json({ error: 'invalid_grant', error_description: 'Authorization code expired' });
286
+ return;
287
+ }
288
+ // Verify PKCE
289
+ if (!verifyPkce(code_verifier, authCode.codeChallenge, authCode.codeChallengeMethod)) {
290
+ res.status(400).json({ error: 'invalid_grant', error_description: 'PKCE verification failed' });
291
+ return;
292
+ }
293
+ // Verify redirect_uri matches
294
+ if (redirect_uri && redirect_uri !== authCode.redirectUri) {
295
+ res.status(400).json({ error: 'invalid_grant', error_description: 'Redirect URI mismatch' });
296
+ return;
297
+ }
298
+ // Consume the code
299
+ authCodes.delete(code);
300
+ // Issue tokens
301
+ const accessToken = `at_${crypto.randomBytes(32).toString('hex')}`;
302
+ const newRefreshToken = `rt_${crypto.randomBytes(32).toString('hex')}`;
303
+ const expiresIn = 86400; // 24h
304
+ accessTokens.set(accessToken, {
305
+ oauthClientId: authCode.oauthClientId,
306
+ apiKey: authCode.apiKey,
307
+ expiresAt: Date.now() + expiresIn * 1000,
308
+ });
309
+ refreshTokens.set(newRefreshToken, {
310
+ oauthClientId: authCode.oauthClientId,
311
+ apiKey: authCode.apiKey,
312
+ });
313
+ console.log(`[MCP OAuth] Issued tokens for client ${authCode.oauthClientId}`);
314
+ res.json({
315
+ access_token: accessToken,
316
+ token_type: 'bearer',
317
+ expires_in: expiresIn,
318
+ refresh_token: newRefreshToken,
319
+ });
320
+ }
321
+ else if (grant_type === 'refresh_token') {
322
+ if (!refresh_token) {
323
+ res.status(400).json({ error: 'invalid_request' });
324
+ return;
325
+ }
326
+ const rtData = refreshTokens.get(refresh_token);
327
+ if (!rtData) {
328
+ res.status(400).json({ error: 'invalid_grant', error_description: 'Invalid refresh token' });
329
+ return;
330
+ }
331
+ const accessToken = `at_${crypto.randomBytes(32).toString('hex')}`;
332
+ const expiresIn = 86400;
333
+ accessTokens.set(accessToken, {
334
+ oauthClientId: rtData.oauthClientId,
335
+ apiKey: rtData.apiKey,
336
+ expiresAt: Date.now() + expiresIn * 1000,
337
+ });
338
+ console.log(`[MCP OAuth] Refreshed token for client ${rtData.oauthClientId}`);
339
+ res.json({
340
+ access_token: accessToken,
341
+ token_type: 'bearer',
342
+ expires_in: expiresIn,
343
+ refresh_token: refresh_token,
344
+ });
345
+ }
346
+ else {
347
+ res.status(400).json({ error: 'unsupported_grant_type' });
348
+ }
349
+ });
350
+ // ─── Token revocation ────────────────────────────────────────────────────────
351
+ app.post('/mcp/revoke', (req, res) => {
352
+ const { token } = req.body;
353
+ if (token) {
354
+ accessTokens.delete(token);
355
+ refreshTokens.delete(token);
356
+ }
357
+ res.status(200).json({});
358
+ });
359
+ // ─── Bearer auth middleware ──────────────────────────────────────────────────
360
+ function requireAuth(req, res) {
361
+ const tokenData = verifyBearerToken(req);
362
+ if (!tokenData) {
363
+ res.status(401).json({
364
+ error: 'invalid_token',
365
+ error_description: 'Invalid or expired access token',
366
+ });
367
+ return null;
368
+ }
369
+ return tokenData;
370
+ }
371
+ // ─── MCP Protocol endpoint (Streamable HTTP) ────────────────────────────────
372
+ app.post('/mcp', async (req, res) => {
373
+ // Check if this is an OAuth/metadata request (no Authorization header = not an MCP protocol request)
374
+ const hasAuth = req.headers.authorization?.startsWith('Bearer ');
375
+ if (!hasAuth) {
376
+ res.status(401).json({ error: 'unauthorized' });
377
+ return;
378
+ }
379
+ const tokenData = requireAuth(req, res);
380
+ if (!tokenData)
381
+ return;
382
+ try {
383
+ const sessionId = req.headers['mcp-session-id'];
384
+ if (sessionId && mcpSessions.has(sessionId)) {
385
+ const session = mcpSessions.get(sessionId);
386
+ await session.transport.handleRequest(req, res, req.body);
387
+ }
388
+ else {
389
+ // New session with user's API key
390
+ const client = new LyrraClient({
391
+ clientSecret: tokenData.apiKey,
392
+ apiUrl: LYRRA_API_URL,
393
+ eduflowUrl: process.env.LYRRA_EDUFLOW_API_URL || LYRRA_API_URL.replace('/api', '/eduflow'),
394
+ });
395
+ const server = createMcpServer(client);
396
+ const transport = new StreamableHTTPServerTransport({
397
+ sessionIdGenerator: () => crypto.randomUUID(),
398
+ });
399
+ transport.onclose = () => {
400
+ const sid = transport.sessionId;
401
+ if (sid)
402
+ mcpSessions.delete(sid);
403
+ console.log(`[MCP HTTP] Session closed: ${sid}`);
404
+ };
405
+ await server.connect(transport);
406
+ if (transport.sessionId) {
407
+ mcpSessions.set(transport.sessionId, { transport, server });
408
+ console.log(`[MCP HTTP] New session: ${transport.sessionId}`);
409
+ }
410
+ await transport.handleRequest(req, res, req.body);
411
+ }
412
+ }
413
+ catch (error) {
414
+ console.error('[MCP HTTP] POST error:', error);
415
+ if (!res.headersSent) {
416
+ res.status(500).json({ error: 'Internal server error' });
417
+ }
418
+ }
419
+ });
420
+ // Handle GET (SSE stream)
421
+ app.get('/mcp', async (req, res) => {
422
+ // Check if it's a .well-known or authorize request (no auth needed)
423
+ // Those are handled by earlier routes, this is only for SSE
424
+ const tokenData = requireAuth(req, res);
425
+ if (!tokenData)
426
+ return;
427
+ const sessionId = req.headers['mcp-session-id'];
428
+ if (!sessionId || !mcpSessions.has(sessionId)) {
429
+ res.status(400).json({ error: 'Invalid or missing session ID' });
430
+ return;
431
+ }
432
+ const session = mcpSessions.get(sessionId);
433
+ await session.transport.handleRequest(req, res);
434
+ });
435
+ // Handle DELETE (close session)
436
+ app.delete('/mcp', async (req, res) => {
437
+ const tokenData = requireAuth(req, res);
438
+ if (!tokenData)
439
+ return;
440
+ const sessionId = req.headers['mcp-session-id'];
441
+ if (!sessionId || !mcpSessions.has(sessionId)) {
442
+ res.status(404).json({ error: 'Session not found' });
443
+ return;
444
+ }
445
+ const session = mcpSessions.get(sessionId);
446
+ await session.transport.handleRequest(req, res);
447
+ mcpSessions.delete(sessionId);
448
+ });
449
+ // ─── Health check ────────────────────────────────────────────────────────────
450
+ app.get('/mcp/health', (_req, res) => {
451
+ res.json({
452
+ status: 'ok',
453
+ service: 'LYRRA Studio MCP HTTP Server',
454
+ sessions: mcpSessions.size,
455
+ registeredClients: registeredClients.size,
456
+ timestamp: new Date().toISOString(),
457
+ });
458
+ });
459
+ // ─── Start server ────────────────────────────────────────────────────────────
460
+ app.listen(PORT, () => {
461
+ console.log(`🚀 LYRRA Studio MCP HTTP Server running on port ${PORT}`);
462
+ console.log(` OAuth metadata: ${BASE_URL}/mcp/.well-known/oauth-authorization-server`);
463
+ console.log(` MCP endpoint: ${BASE_URL}/mcp`);
464
+ console.log(` Health check: ${BASE_URL}/mcp/health`);
465
+ });
466
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,75 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
3
  import { config } from './config.js';
5
- // Tools
6
- import { authTools } from './tools/auth.js';
7
- import { eduflowTools } from './tools/eduflow.js';
8
- import { blocksTools } from './tools/blocks.js';
9
- import { connectionsTools } from './tools/connections.js';
10
- import { participantsTools } from './tools/participants.js';
11
- import { analyticsTools } from './tools/analytics.js';
12
- import { aiDesignerTools } from './tools/ai-designer.js';
13
- import { presentationTools } from './tools/presentation.js';
14
- import { storeTools } from './tools/store.js';
15
- import { projectsTools } from './tools/projects.js';
16
- import { resourcesTools } from './tools/resources.js';
17
- import { adminTools } from './tools/admin.js';
18
- // Resources
19
- import { BLOCK_TYPES_RESOURCE } from './resources/block-types.js';
20
- import { FLOW_SCHEMA_RESOURCE } from './resources/flow-schema.js';
21
- const server = new McpServer({
22
- name: 'lyrra-studio',
23
- version: '1.0.0',
24
- description: 'Serveur MCP pour piloter LYRRA Studio - Plateforme EdTech de création de parcours pédagogiques, conversion PDF→Audio, et store d\'audiobooks.',
25
- });
26
- // --- Register all tools ---
27
- const allTools = {
28
- ...authTools,
29
- ...eduflowTools,
30
- ...blocksTools,
31
- ...connectionsTools,
32
- ...participantsTools,
33
- ...analyticsTools,
34
- ...aiDesignerTools,
35
- ...presentationTools,
36
- ...storeTools,
37
- ...projectsTools,
38
- ...resourcesTools,
39
- ...adminTools,
40
- };
41
- for (const [name, tool] of Object.entries(allTools)) {
42
- server.tool(name, tool.description, tool.inputSchema.shape ? Object.fromEntries(Object.entries(tool.inputSchema.shape).map(([key, schema]) => [key, schema])) : {}, async (args) => {
43
- try {
44
- const result = await tool.handler(args);
45
- return {
46
- content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
47
- };
48
- }
49
- catch (error) {
50
- return {
51
- content: [{ type: 'text', text: `Erreur: ${error.message}` }],
52
- isError: true,
53
- };
54
- }
55
- });
56
- }
57
- // --- Register resources ---
58
- server.resource('block-types', BLOCK_TYPES_RESOURCE.uri, { description: BLOCK_TYPES_RESOURCE.description, mimeType: BLOCK_TYPES_RESOURCE.mimeType }, async () => ({
59
- contents: [{
60
- uri: BLOCK_TYPES_RESOURCE.uri,
61
- mimeType: BLOCK_TYPES_RESOURCE.mimeType,
62
- text: JSON.stringify(BLOCK_TYPES_RESOURCE.content, null, 2),
63
- }],
64
- }));
65
- server.resource('flow-construction-guide', FLOW_SCHEMA_RESOURCE.uri, { description: FLOW_SCHEMA_RESOURCE.description, mimeType: FLOW_SCHEMA_RESOURCE.mimeType }, async () => ({
66
- contents: [{
67
- uri: FLOW_SCHEMA_RESOURCE.uri,
68
- mimeType: FLOW_SCHEMA_RESOURCE.mimeType,
69
- text: JSON.stringify(FLOW_SCHEMA_RESOURCE.content, null, 2),
70
- }],
71
- }));
72
- // --- Start server ---
4
+ import { createMcpServer } from './server-factory.js';
5
+ // --- Start server (stdio mode) ---
73
6
  async function main() {
74
7
  if (!config.clientSecret) {
75
8
  console.error('⚠️ LYRRA_CLIENT_SECRET non défini. Définissez la variable d\'environnement LYRRA_CLIENT_SECRET.');
@@ -77,6 +10,7 @@ async function main() {
77
10
  else {
78
11
  console.error('✅ LYRRA Studio MCP connecté (authentification par API Key).');
79
12
  }
13
+ const server = createMcpServer();
80
14
  const transport = new StdioServerTransport();
81
15
  await server.connect(transport);
82
16
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,oCAAoC;AACpC,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,kGAAkG,CAAC,CAAC;IACpH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { LyrraClient } from './client.js';
3
+ /**
4
+ * Create and configure an MCP server with all tools registered.
5
+ * @param client - LyrraClient to use for API calls. If not provided, uses default (env vars).
6
+ */
7
+ export declare function createMcpServer(client?: LyrraClient): McpServer;
8
+ //# sourceMappingURL=server-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-factory.d.ts","sourceRoot":"","sources":["../src/server-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiD1C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAsD/D"}