Skip to content

Commit 9c5a40c

Browse files
committed
feat: add prompts and resources to MCP server for better quality score
1 parent 7f1506d commit 9c5a40c

File tree

3 files changed

+242
-2
lines changed

3 files changed

+242
-2
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ Then configure your MCP client (Claude Desktop, Cursor, etc.) with the [configur
9494

9595
- 🌐 **Universal Profiles**
9696
<br>One profile for all languages
97+
98+
- 💬 **Built-in Prompts**
99+
<br>Pre-configured prompts for common tasks
100+
101+
- 📚 **Server Resources**
102+
<br>Access profiles, config, and IDE info
97103

98104
</td>
99105
</tr>
@@ -125,6 +131,23 @@ Then configure your MCP client (Claude Desktop, Cursor, etc.) with the [configur
125131

126132
## 🚀 Usage
127133

134+
### 📚 MCP Features
135+
136+
The server provides three types of MCP features:
137+
138+
#### 🔨 Tools
139+
- **get_jetbrains_code_inspections**: Runs code inspections on specified files or directories
140+
141+
#### 💬 Prompts
142+
- **analyze-project**: Analyze a project for code quality issues
143+
- **check-file**: Check a specific file for issues
144+
- **fix-issues**: Get suggestions to fix detected issues
145+
146+
#### 📚 Resources
147+
- **inspection://profiles**: List of available inspection profiles
148+
- **inspection://config**: Current MCP server configuration
149+
- **inspection://ides**: List of detected JetBrains IDEs on the system
150+
128151
### 🏃 Running the Server
129152

130153
> [!TIP]
@@ -217,8 +240,10 @@ yarn inspect:dev
217240

218241
The inspector opens a web interface where you can:
219242

220-
- View available tools
243+
- View available tools, prompts, and resources
221244
- Test get_jetbrains_code_inspections tool interactively
245+
- Use pre-configured prompts for common tasks
246+
- Access server resources (profiles, config, detected IDEs)
222247
- See requests/responses in real-time
223248

224249

src/mcp/server/MCPServer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ export class MCPServer {
2828
tools: {
2929
listChanged: true,
3030
},
31+
prompts: {
32+
listChanged: true,
33+
},
34+
resources: {
35+
subscribe: true,
36+
listChanged: true,
37+
},
3138
},
3239
},
3340
);

src/mcp/server/RequestHandlers.ts

Lines changed: 209 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2-
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
2+
import {
3+
CallToolRequestSchema,
4+
ListToolsRequestSchema,
5+
ListPromptsRequestSchema,
6+
GetPromptRequestSchema,
7+
ListResourcesRequestSchema,
8+
ReadResourceRequestSchema
9+
} from '@modelcontextprotocol/sdk/types.js';
310
import { InspectionTool, InspectionToolParams } from '../tools/InspectionTool.js';
411
import { MarkdownFormatter } from '../formatters/MarkdownFormatter.js';
512
import { JSONFormatter } from '../formatters/JSONFormatter.js';
@@ -27,6 +34,8 @@ export class RequestHandlers {
2734
setup(): void {
2835
this.setupToolListHandler();
2936
this.setupToolCallHandler();
37+
this.setupPromptHandlers();
38+
this.setupResourceHandlers();
3039
this.logger.info('Request handlers setup complete');
3140
}
3241

@@ -101,4 +110,203 @@ export class RequestHandlers {
101110
};
102111
});
103112
}
113+
114+
private setupPromptHandlers(): void {
115+
// List available prompts
116+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
117+
const prompts = [
118+
{
119+
name: 'analyze-project',
120+
description: 'Analyze a project for code quality issues',
121+
arguments: [
122+
{
123+
name: 'projectPath',
124+
description: 'Path to the project to analyze',
125+
required: true,
126+
},
127+
{
128+
name: 'profile',
129+
description: 'Inspection profile to use',
130+
required: false,
131+
},
132+
],
133+
},
134+
{
135+
name: 'check-file',
136+
description: 'Check a specific file for issues',
137+
arguments: [
138+
{
139+
name: 'filePath',
140+
description: 'Path to the file to check',
141+
required: true,
142+
},
143+
],
144+
},
145+
{
146+
name: 'fix-issues',
147+
description: 'Get suggestions to fix detected issues',
148+
arguments: [
149+
{
150+
name: 'projectPath',
151+
description: 'Path to the project',
152+
required: true,
153+
},
154+
{
155+
name: 'severity',
156+
description: 'Minimum severity level (ERROR, WARNING, INFO)',
157+
required: false,
158+
},
159+
],
160+
},
161+
];
162+
163+
this.logger.debug('Listed prompts', { count: prompts.length });
164+
return { prompts };
165+
});
166+
167+
// Get a specific prompt
168+
this.server.setRequestHandler(GetPromptRequestSchema, async (request: any) => {
169+
const { name, arguments: args } = request.params;
170+
171+
const prompts: Record<string, (args: any) => { messages: any[] }> = {
172+
'analyze-project': (args: any) => ({
173+
messages: [
174+
{
175+
role: 'user',
176+
content: {
177+
type: 'text',
178+
text: `Please analyze the project at ${args.projectPath} using JetBrains inspections${args.profile ? ` with profile "${args.profile}"` : ''}.`,
179+
},
180+
},
181+
],
182+
}),
183+
'check-file': (args: any) => ({
184+
messages: [
185+
{
186+
role: 'user',
187+
content: {
188+
type: 'text',
189+
text: `Check the file at ${args.filePath} for code quality issues using JetBrains inspections.`,
190+
},
191+
},
192+
],
193+
}),
194+
'fix-issues': (args: any) => ({
195+
messages: [
196+
{
197+
role: 'user',
198+
content: {
199+
type: 'text',
200+
text: `Analyze the project at ${args.projectPath} and provide fix suggestions for issues${args.severity ? ` with severity ${args.severity} or higher` : ''}.`,
201+
},
202+
},
203+
],
204+
}),
205+
};
206+
207+
const promptHandler = prompts[name];
208+
if (promptHandler) {
209+
return promptHandler(args);
210+
}
211+
212+
throw new Error(`Unknown prompt: ${name}`);
213+
});
214+
}
215+
216+
private setupResourceHandlers(): void {
217+
// List available resources
218+
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
219+
const resources = [
220+
{
221+
uri: 'inspection://profiles',
222+
name: 'Available Inspection Profiles',
223+
description: 'List of available inspection profiles',
224+
mimeType: 'application/json',
225+
},
226+
{
227+
uri: 'inspection://config',
228+
name: 'Current Configuration',
229+
description: 'Current MCP server configuration',
230+
mimeType: 'application/json',
231+
},
232+
{
233+
uri: 'inspection://ides',
234+
name: 'Detected IDEs',
235+
description: 'List of detected JetBrains IDEs on the system',
236+
mimeType: 'application/json',
237+
},
238+
];
239+
240+
this.logger.debug('Listed resources', { count: resources.length });
241+
return { resources };
242+
});
243+
244+
// Read a specific resource
245+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request: any) => {
246+
const { uri } = request.params;
247+
248+
if (uri === 'inspection://profiles') {
249+
return {
250+
contents: [
251+
{
252+
uri,
253+
mimeType: 'application/json',
254+
text: JSON.stringify(
255+
{
256+
profiles: [
257+
'Default',
258+
'Project Default',
259+
'Strict',
260+
'Essential',
261+
],
262+
description: 'Available inspection profiles for code analysis',
263+
},
264+
null,
265+
2,
266+
),
267+
},
268+
],
269+
};
270+
}
271+
272+
if (uri === 'inspection://config') {
273+
const config = this.container.resolve<ConfigLoader>('ConfigLoader').getConfig();
274+
return {
275+
contents: [
276+
{
277+
uri,
278+
mimeType: 'application/json',
279+
text: JSON.stringify(config, null, 2),
280+
},
281+
],
282+
};
283+
}
284+
285+
if (uri === 'inspection://ides') {
286+
const { IDEDetector } = await import('../../core/ide/IDEDetector.js');
287+
const { getIDEPaths } = await import('../../infrastructure/config/IDEPaths.js');
288+
const detector = new IDEDetector(getIDEPaths(), this.logger);
289+
const ides = await detector.findAvailableIDEs();
290+
291+
return {
292+
contents: [
293+
{
294+
uri,
295+
mimeType: 'application/json',
296+
text: JSON.stringify(
297+
{
298+
detected: ides,
299+
count: ides.length,
300+
},
301+
null,
302+
2,
303+
),
304+
},
305+
],
306+
};
307+
}
308+
309+
throw new Error(`Unknown resource: ${uri}`);
310+
});
311+
}
104312
}

0 commit comments

Comments
 (0)