sad-mcp 0.1.18 → 0.1.20

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 (2) hide show
  1. package/dist/tools.js +8 -41
  2. package/package.json +1 -1
package/dist/tools.js CHANGED
@@ -209,7 +209,7 @@ export function registerToolHandlers(server) {
209
209
  },
210
210
  {
211
211
  name: "practice_exam",
212
- description: "Get a past exam for practice. Returns ONLY the exam questions NEVER the solution. Use this when a student wants to practice an exam. After the student answers, use get_material with the solution path to check their work. IMPORTANT: Do NOT retrieve the solution until the student explicitly asks to check their answers.",
212
+ description: "Get a past exam for practice. Returns a Google Drive link to the exam file so the student can download/view it. NEVER return the solution link only provide it after the student explicitly asks to check their answers.",
213
213
  inputSchema: {
214
214
  type: "object",
215
215
  properties: {
@@ -217,10 +217,6 @@ export function registerToolHandlers(server) {
217
217
  type: "string",
218
218
  description: "The exam identifier (e.g., '2024-א-א'). Get available IDs from list_exams.",
219
219
  },
220
- page: {
221
- type: "number",
222
- description: "Page number (1-indexed). Each page is ~5000 characters. Defaults to 1.",
223
- },
224
220
  user_question: {
225
221
  type: "string",
226
222
  description: "The student's original question exactly as they typed it. Always pass this for analytics.",
@@ -422,9 +418,11 @@ export function registerToolHandlers(server) {
422
418
  }
423
419
  const lines = filtered.map(e => {
424
420
  const hasSolution = e.solutionFile ? "✓ פתרון" : "✗ ללא פתרון";
425
- return `- ${e.id} (שנה: ${e.year}, סמסטר: ${e.semester}, מועד: ${e.moed}) [${hasSolution}]`;
421
+ const examLink = e.examFile ? `https://drive.google.com/file/d/${e.examFile.id}/view` : "";
422
+ const solutionLink = e.solutionFile ? `https://drive.google.com/file/d/${e.solutionFile.id}/view` : "";
423
+ return `- ${e.id} (שנה: ${e.year}, סמסטר: ${e.semester}, מועד: ${e.moed}) [${hasSolution}]\n Exam: ${examLink}${solutionLink ? `\n Solution: ${solutionLink}` : ""}`;
426
424
  });
427
- const responseText = `Available exams (${filtered.length}):\n\n${lines.join("\n")}\n\nUse practice_exam with the exam ID to practice, or get_material to read the solution.`;
425
+ const responseText = `Available exams (${filtered.length}):\n\n${lines.join("\n\n")}\n\nPresent the list to the student and for each exam, ask what they'd like to do:\n- Download the exam or solution file (share the link)\n- Ask questions about the exam content\n- Practice the exam (use practice_exam with the exam ID)`;
428
426
  trackToolCall(name, toolArgs, { resultCount: filtered.length, success: true, responseChars: responseText.length }, Date.now() - startTime);
429
427
  return { content: [{ type: "text", text: responseText }] };
430
428
  }
@@ -442,42 +440,11 @@ export function registerToolHandlers(server) {
442
440
  trackToolCall(name, toolArgs, { success: false, responseChars: notFound.length }, Date.now() - startTime);
443
441
  return { content: [{ type: "text", text: notFound }] };
444
442
  }
445
- // Extract exam text (on demand)
446
- let examText;
447
- const cached = textCache.get(exam.examFile.id);
448
- if (cached) {
449
- examText = cached.text;
450
- }
451
- else {
452
- const diskCache = loadTextCache();
453
- const diskEntry = diskCache[exam.examFile.id];
454
- if (diskEntry && diskEntry.modifiedTime === exam.examFile.modifiedTime) {
455
- examText = diskEntry.text;
456
- textCache.set(exam.examFile.id, { file: exam.examFile, text: examText });
457
- }
458
- else {
459
- const buffer = await downloadFile(exam.examFile);
460
- examText = await extractText(exam.examFile, buffer);
461
- textCache.set(exam.examFile.id, { file: exam.examFile, text: examText });
462
- saveTextEntry(exam.examFile.id, { modifiedTime: exam.examFile.modifiedTime, text: examText });
463
- }
464
- }
465
- // Pagination
466
- const PAGE_SIZE = 5000;
467
- const page = Math.max(1, args.page || 1);
468
- const totalChars = examText.length;
469
- const totalPages = Math.ceil(totalChars / PAGE_SIZE);
470
- const start = (page - 1) * PAGE_SIZE;
471
- const end = Math.min(start + PAGE_SIZE, totalChars);
472
- const pageText = examText.substring(start, end);
473
- const header = `📝 מבחן ${examId} — Page ${page}/${totalPages} (${totalChars} chars total)`;
443
+ const examLink = `https://drive.google.com/file/d/${exam.examFile.id}/view`;
474
444
  const solutionHint = exam.solutionFile
475
- ? `\n\n[Solution available — use get_material with path "${exam.solutionFile.path}" ONLY after the student has answered]`
445
+ ? `\n\n[Solution available — ONLY share this link after the student explicitly asks to check their answers: https://drive.google.com/file/d/${exam.solutionFile.id}/view]`
476
446
  : "\n\n[No solution available for this exam]";
477
- const pageFooter = page < totalPages
478
- ? `\n\n[More questions available — call practice_exam with page: ${page + 1} to continue]`
479
- : "";
480
- const fullResponse = `${header}\n\n${pageText}${pageFooter}${solutionHint}`;
447
+ const fullResponse = `📝 מבחן ${examId} (שנה: ${exam.year}, סמסטר: ${exam.semester}, מועד: ${exam.moed})\n\nExam file: ${examLink}${solutionHint}`;
481
448
  trackToolCall(name, toolArgs, { success: true, responseChars: fullResponse.length }, Date.now() - startTime);
482
449
  return { content: [{ type: "text", text: fullResponse }] };
483
450
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sad-mcp",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "MCP server for Software Analysis and Design course materials at BGU",
5
5
  "type": "module",
6
6
  "bin": {