1+ #!/usr/bin/env tsx
2+
3+ import { spawn } from 'child_process' ;
4+ import * as path from 'path' ;
5+ import { fileURLToPath } from 'url' ;
6+
7+ const __filename = fileURLToPath ( import . meta. url ) ;
8+ const __dirname = path . dirname ( __filename ) ;
9+
10+ // Terminal color codes
11+ const colors = {
12+ reset : '\x1b[0m' ,
13+ bold : '\x1b[1m' ,
14+ red : '\x1b[31m' ,
15+ green : '\x1b[32m' ,
16+ yellow : '\x1b[33m' ,
17+ blue : '\x1b[34m' ,
18+ cyan : '\x1b[36m' ,
19+ magenta : '\x1b[35m' ,
20+ } ;
21+
22+ const colorize = ( text : string , ...colorCodes : string [ ] ) : string => {
23+ return colorCodes . join ( '' ) + text + colors . reset ;
24+ } ;
25+
26+ class MCPFeatureTester {
27+ private serverProcess : any = null ;
28+ private messageId = 0 ;
29+ private responses : any [ ] = [ ] ;
30+
31+ async start ( ) : Promise < void > {
32+ console . log ( colorize ( '🚀 Testing MCP Server New Features' , colors . bold , colors . cyan ) ) ;
33+ console . log ( colorize ( '=' . repeat ( 50 ) , colors . cyan ) ) ;
34+
35+ try {
36+ await this . startServer ( ) ;
37+ await this . initialize ( ) ;
38+
39+ // Test all new features
40+ await this . testPrompts ( ) ;
41+ await this . testResources ( ) ;
42+ await this . testTools ( ) ;
43+
44+ console . log ( colorize ( '\n✅ All tests completed successfully!' , colors . green , colors . bold ) ) ;
45+ } catch ( error ) {
46+ console . error ( colorize ( '❌ Test failed:' , colors . red , colors . bold ) , error ) ;
47+ process . exit ( 1 ) ;
48+ } finally {
49+ this . cleanup ( ) ;
50+ }
51+ }
52+
53+ private async startServer ( ) : Promise < void > {
54+ const serverPath = path . join ( __dirname , '../../dist/index.js' ) ;
55+ console . log ( colorize ( '📦 Starting server...' , colors . blue ) ) ;
56+
57+ this . serverProcess = spawn ( 'node' , [ serverPath ] , {
58+ stdio : [ 'pipe' , 'pipe' , 'pipe' ] ,
59+ env : {
60+ ...process . env ,
61+ DEBUG : 'false' ,
62+ } ,
63+ } ) ;
64+
65+ this . serverProcess . stdout ?. on ( 'data' , ( data : Buffer ) => {
66+ const lines = data . toString ( ) . split ( '\n' ) . filter ( line => line . trim ( ) ) ;
67+ lines . forEach ( line => {
68+ try {
69+ const response = JSON . parse ( line ) ;
70+ this . responses . push ( response ) ;
71+ } catch {
72+ // Ignore non-JSON lines
73+ }
74+ } ) ;
75+ } ) ;
76+
77+ // Wait for server to start
78+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
79+ }
80+
81+ private async initialize ( ) : Promise < void > {
82+ console . log ( colorize ( '🔄 Initializing MCP connection...' , colors . blue ) ) ;
83+
84+ await this . sendRequest ( {
85+ jsonrpc : '2.0' ,
86+ id : this . messageId ++ ,
87+ method : 'initialize' ,
88+ params : {
89+ protocolVersion : '1.0.0' ,
90+ capabilities : { } ,
91+ clientInfo : {
92+ name : 'mcp-feature-tester' ,
93+ version : '1.0.0' ,
94+ } ,
95+ } ,
96+ } ) ;
97+
98+ await this . waitForResponse ( ) ;
99+ console . log ( colorize ( '✅ Initialized' , colors . green ) ) ;
100+ }
101+
102+ private async testPrompts ( ) : Promise < void > {
103+ console . log ( colorize ( '\n📝 Testing Prompts...' , colors . bold , colors . yellow ) ) ;
104+
105+ // List prompts
106+ await this . sendRequest ( {
107+ jsonrpc : '2.0' ,
108+ id : this . messageId ++ ,
109+ method : 'prompts/list' ,
110+ params : { } ,
111+ } ) ;
112+
113+ const promptsResponse = await this . waitForResponse ( ) ;
114+ const prompts = promptsResponse ?. result ?. prompts || [ ] ;
115+
116+ console . log ( ` Found ${ prompts . length } prompts:` ) ;
117+ prompts . forEach ( ( prompt : any ) => {
118+ console . log ( ` - ${ colorize ( prompt . name , colors . cyan ) } : ${ prompt . description } ` ) ;
119+ } ) ;
120+
121+ // Test getting a specific prompt
122+ if ( prompts . length > 0 ) {
123+ await this . sendRequest ( {
124+ jsonrpc : '2.0' ,
125+ id : this . messageId ++ ,
126+ method : 'prompts/get' ,
127+ params : {
128+ name : 'analyze-project' ,
129+ arguments : {
130+ projectPath : '/test/path' ,
131+ profile : 'Default'
132+ }
133+ } ,
134+ } ) ;
135+
136+ const promptResponse = await this . waitForResponse ( ) ;
137+ if ( promptResponse ?. result ?. messages ) {
138+ console . log ( colorize ( ' ✅ Prompt "analyze-project" works correctly' , colors . green ) ) ;
139+ }
140+ }
141+ }
142+
143+ private async testResources ( ) : Promise < void > {
144+ console . log ( colorize ( '\n📚 Testing Resources...' , colors . bold , colors . yellow ) ) ;
145+
146+ // List resources
147+ await this . sendRequest ( {
148+ jsonrpc : '2.0' ,
149+ id : this . messageId ++ ,
150+ method : 'resources/list' ,
151+ params : { } ,
152+ } ) ;
153+
154+ const resourcesResponse = await this . waitForResponse ( ) ;
155+ const resources = resourcesResponse ?. result ?. resources || [ ] ;
156+
157+ console . log ( ` Found ${ resources . length } resources:` ) ;
158+ resources . forEach ( ( resource : any ) => {
159+ console . log ( ` - ${ colorize ( resource . uri , colors . cyan ) } : ${ resource . name } ` ) ;
160+ } ) ;
161+
162+ // Test reading each resource
163+ for ( const resource of resources ) {
164+ await this . sendRequest ( {
165+ jsonrpc : '2.0' ,
166+ id : this . messageId ++ ,
167+ method : 'resources/read' ,
168+ params : {
169+ uri : resource . uri ,
170+ } ,
171+ } ) ;
172+
173+ const readResponse = await this . waitForResponse ( ) ;
174+ if ( readResponse ?. result ?. contents ) {
175+ console . log ( colorize ( ` ✅ Resource "${ resource . uri } " is accessible` , colors . green ) ) ;
176+ }
177+ }
178+ }
179+
180+ private async testTools ( ) : Promise < void > {
181+ console . log ( colorize ( '\n🔧 Testing Tools...' , colors . bold , colors . yellow ) ) ;
182+
183+ // List tools
184+ await this . sendRequest ( {
185+ jsonrpc : '2.0' ,
186+ id : this . messageId ++ ,
187+ method : 'tools/list' ,
188+ params : { } ,
189+ } ) ;
190+
191+ const toolsResponse = await this . waitForResponse ( ) ;
192+ const tools = toolsResponse ?. result ?. tools || [ ] ;
193+
194+ console . log ( ` Found ${ tools . length } tools:` ) ;
195+ tools . forEach ( ( tool : any ) => {
196+ console . log ( ` - ${ colorize ( tool . name , colors . cyan ) } : ${ tool . description } ` ) ;
197+ } ) ;
198+
199+ if ( tools . length > 0 ) {
200+ console . log ( colorize ( ' ✅ Tool "get_jetbrains_code_inspections" is available' , colors . green ) ) ;
201+ }
202+ }
203+
204+ private async sendRequest ( request : any ) : Promise < void > {
205+ const requestStr = JSON . stringify ( request ) + '\n' ;
206+ if ( this . serverProcess ?. stdin ) {
207+ this . serverProcess . stdin . write ( requestStr ) ;
208+ }
209+ }
210+
211+ private async waitForResponse ( timeout = 3000 ) : Promise < any > {
212+ const startTime = Date . now ( ) ;
213+ const initialLength = this . responses . length ;
214+
215+ while ( Date . now ( ) - startTime < timeout ) {
216+ if ( this . responses . length > initialLength ) {
217+ return this . responses [ this . responses . length - 1 ] ;
218+ }
219+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
220+ }
221+
222+ throw new Error ( 'Timeout waiting for response' ) ;
223+ }
224+
225+ private cleanup ( ) : void {
226+ if ( this . serverProcess ) {
227+ this . serverProcess . kill ( ) ;
228+ }
229+ }
230+ }
231+
232+ // Main execution
233+ async function main ( ) {
234+ const tester = new MCPFeatureTester ( ) ;
235+ await tester . start ( ) ;
236+ }
237+
238+ main ( ) . catch ( error => {
239+ console . error ( colorize ( '❌ Fatal error:' , colors . red , colors . bold ) , error ) ;
240+ process . exit ( 1 ) ;
241+ } ) ;
0 commit comments