sad-mcp 0.1.7 → 0.1.8

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 +62 -11
  2. package/package.json +1 -1
package/dist/tools.js CHANGED
@@ -46,7 +46,7 @@ export function registerToolHandlers(server) {
46
46
  tools: [
47
47
  {
48
48
  name: "search_materials",
49
- description: "Search across all course materials (lecture transcripts, presentations, exams) for relevant content. Use this when a student asks about a specific topic.",
49
+ description: "Search across all course materials for a topic. Returns a SHORT summary list of matching files (name, category, match count). To read the actual content, use get_material on the most relevant file(s) from the results.",
50
50
  inputSchema: {
51
51
  type: "object",
52
52
  properties: {
@@ -58,6 +58,20 @@ export function registerToolHandlers(server) {
58
58
  required: ["query"],
59
59
  },
60
60
  },
61
+ {
62
+ name: "get_material",
63
+ description: "Get the full text content of a specific course material file. Use this AFTER search_materials to read the content of a relevant file.",
64
+ inputSchema: {
65
+ type: "object",
66
+ properties: {
67
+ name: {
68
+ type: "string",
69
+ description: "The file name (or partial name) to retrieve. Matched against file names from search_materials or list_materials results.",
70
+ },
71
+ },
72
+ required: ["name"],
73
+ },
74
+ },
61
75
  {
62
76
  name: "list_materials",
63
77
  description: "List all available course materials, optionally filtered by category.",
@@ -109,12 +123,14 @@ export function registerToolHandlers(server) {
109
123
  if (matches.length > 0) {
110
124
  results.push({
111
125
  fileName: file.name,
112
- path: file.path,
113
126
  category: categorizeFile(file),
114
- matches: matches.slice(0, 5), // Top 5 matches per file
127
+ matchCount: matches.length,
128
+ preview: matches[0].line.trim().substring(0, 120),
115
129
  });
116
130
  }
117
131
  }
132
+ // Sort by match count descending (most relevant first)
133
+ results.sort((a, b) => b.matchCount - a.matchCount);
118
134
  if (results.length === 0) {
119
135
  return {
120
136
  content: [
@@ -126,18 +142,53 @@ export function registerToolHandlers(server) {
126
142
  };
127
143
  }
128
144
  const formatted = results
129
- .map((r) => {
130
- const matchLines = r.matches
131
- .map((m) => ` Line ${m.lineNumber}: ${m.line.substring(0, 200)}`)
132
- .join("\n");
133
- return `📄 ${r.fileName} [${r.category}]\n Path: ${r.path}\n${matchLines}`;
134
- })
135
- .join("\n\n");
145
+ .map((r) => `- ${r.fileName} [${r.category}] (${r.matchCount} matches) — "${r.preview}"`)
146
+ .join("\n");
147
+ return {
148
+ content: [
149
+ {
150
+ type: "text",
151
+ text: `Found "${query}" in ${results.length} file(s). Use get_material to read the most relevant one(s):\n\n${formatted}`,
152
+ },
153
+ ],
154
+ };
155
+ }
156
+ if (name === "get_material") {
157
+ const queryName = args.name;
158
+ if (!queryName) {
159
+ return {
160
+ content: [{ type: "text", text: "Error: name parameter is required" }],
161
+ };
162
+ }
163
+ await ensureTextCache();
164
+ const queryLower = queryName.toLowerCase();
165
+ let bestMatch = null;
166
+ for (const [, entry] of textCache) {
167
+ if (entry.file.name.toLowerCase().includes(queryLower)) {
168
+ bestMatch = entry;
169
+ break;
170
+ }
171
+ }
172
+ if (!bestMatch) {
173
+ return {
174
+ content: [
175
+ {
176
+ type: "text",
177
+ text: `No file found matching "${queryName}". Use search_materials or list_materials to find available files.`,
178
+ },
179
+ ],
180
+ };
181
+ }
182
+ // Truncate very large files
183
+ const maxLen = 30000;
184
+ const text = bestMatch.text.length > maxLen
185
+ ? bestMatch.text.substring(0, maxLen) + "\n...[truncated]"
186
+ : bestMatch.text;
136
187
  return {
137
188
  content: [
138
189
  {
139
190
  type: "text",
140
- text: `Found matches in ${results.length} file(s) for "${query}":\n\n${formatted}`,
191
+ text: `📄 ${bestMatch.file.name} [${categorizeFile(bestMatch.file)}]\n\n${text}`,
141
192
  },
142
193
  ],
143
194
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sad-mcp",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "MCP server for Software Analysis and Design course materials at BGU",
5
5
  "type": "module",
6
6
  "bin": {