@@ -13,45 +13,68 @@ import { logger } from "./Logger.js";
13
13
export interface MCPServerConfig {
14
14
name ?: string ;
15
15
version ?: string ;
16
+ basePath ?: string ;
16
17
}
17
18
19
+ export type ServerCapabilities = {
20
+ tools ?: {
21
+ enabled : true ;
22
+ } ;
23
+ schemas ?: {
24
+ enabled : true ;
25
+ } ;
26
+ prompts ?: {
27
+ enabled : true ;
28
+ } ;
29
+ } ;
30
+
18
31
export class MCPServer {
19
32
private server : Server ;
20
33
private toolsMap : Map < string , ToolProtocol > = new Map ( ) ;
21
34
private toolLoader : ToolLoader ;
22
35
private serverName : string ;
23
36
private serverVersion : string ;
37
+ private basePath : string ;
24
38
25
39
constructor ( config : MCPServerConfig = { } ) {
40
+ this . basePath = this . resolveBasePath ( config . basePath ) ;
26
41
this . serverName = config . name ?? this . getDefaultName ( ) ;
27
42
this . serverVersion = config . version ?? this . getDefaultVersion ( ) ;
28
43
29
44
logger . info (
30
45
`Initializing MCP Server: ${ this . serverName } @${ this . serverVersion } `
31
46
) ;
32
47
48
+ this . toolLoader = new ToolLoader ( this . basePath ) ;
49
+
33
50
this . server = new Server (
34
51
{
35
52
name : this . serverName ,
36
53
version : this . serverVersion ,
37
54
} ,
38
55
{
39
56
capabilities : {
40
- tools : {
41
- enabled : true ,
42
- } ,
57
+ tools : { enabled : true } ,
43
58
} ,
44
59
}
45
60
) ;
46
61
47
- this . toolLoader = new ToolLoader ( ) ;
48
62
this . setupHandlers ( ) ;
49
63
}
50
64
65
+ private resolveBasePath ( configPath ?: string ) : string {
66
+ if ( configPath ) {
67
+ return configPath ;
68
+ }
69
+ if ( process . argv [ 1 ] ) {
70
+ return process . argv [ 1 ] ;
71
+ }
72
+ return process . cwd ( ) ;
73
+ }
74
+
51
75
private readPackageJson ( ) : any {
52
76
try {
53
- const mainModulePath = process . argv [ 1 ] ;
54
- const packagePath = join ( dirname ( mainModulePath ) , ".." , "package.json" ) ;
77
+ const packagePath = join ( dirname ( this . basePath ) , "package.json" ) ;
55
78
const packageContent = readFileSync ( packagePath , "utf-8" ) ;
56
79
const packageJson = JSON . parse ( packageContent ) ;
57
80
logger . debug ( `Successfully read package.json from: ${ packagePath } ` ) ;
@@ -63,27 +86,19 @@ export class MCPServer {
63
86
}
64
87
65
88
private getDefaultName ( ) : string {
66
- try {
67
- const packageJson = this . readPackageJson ( ) ;
68
- if ( packageJson ?. name ) {
69
- logger . info ( `Using name from package.json: ${ packageJson . name } ` ) ;
70
- return packageJson . name ;
71
- }
72
- } catch ( error ) {
73
- logger . warn ( `Error getting name from package.json: ${ error } ` ) ;
89
+ const packageJson = this . readPackageJson ( ) ;
90
+ if ( packageJson ?. name ) {
91
+ logger . info ( `Using name from package.json: ${ packageJson . name } ` ) ;
92
+ return packageJson . name ;
74
93
}
75
94
return "unnamed-mcp-server" ;
76
95
}
77
96
78
97
private getDefaultVersion ( ) : string {
79
- try {
80
- const packageJson = this . readPackageJson ( ) ;
81
- if ( packageJson ?. version ) {
82
- logger . info ( `Using version from package.json: ${ packageJson . version } ` ) ;
83
- return packageJson . version ;
84
- }
85
- } catch ( error ) {
86
- logger . warn ( `Error getting version from package.json: ${ error } ` ) ;
98
+ const packageJson = this . readPackageJson ( ) ;
99
+ if ( packageJson ?. version ) {
100
+ logger . info ( `Using version from package.json: ${ packageJson . version } ` ) ;
101
+ return packageJson . version ;
87
102
}
88
103
return "0.0.0" ;
89
104
}
@@ -116,6 +131,21 @@ export class MCPServer {
116
131
} ) ;
117
132
}
118
133
134
+ private async detectCapabilities ( ) : Promise < ServerCapabilities > {
135
+ const capabilities : ServerCapabilities = { } ;
136
+
137
+ //IK this is unecessary but it'll guide future schema and prompt capability autodiscovery
138
+
139
+ if ( await this . toolLoader . hasTools ( ) ) {
140
+ capabilities . tools = { enabled : true } ;
141
+ logger . debug ( "Tools capability enabled" ) ;
142
+ } else {
143
+ logger . debug ( "No tools found, tools capability disabled" ) ;
144
+ }
145
+
146
+ return capabilities ;
147
+ }
148
+
119
149
async start ( ) {
120
150
try {
121
151
const tools = await this . toolLoader . loadTools ( ) ;
@@ -126,12 +156,18 @@ export class MCPServer {
126
156
const transport = new StdioServerTransport ( ) ;
127
157
await this . server . connect ( transport ) ;
128
158
129
- logger . info (
130
- `Started ${ this . serverName } @${ this . serverVersion } with ${ tools . length } tools`
131
- ) ;
132
- logger . info (
133
- `Available tools: ${ Array . from ( this . toolsMap . keys ( ) ) . join ( ", " ) } `
134
- ) ;
159
+ if ( tools . length > 0 ) {
160
+ logger . info (
161
+ `Started ${ this . serverName } @${ this . serverVersion } with ${ tools . length } tools`
162
+ ) ;
163
+ logger . info (
164
+ `Available tools: ${ Array . from ( this . toolsMap . keys ( ) ) . join ( ", " ) } `
165
+ ) ;
166
+ } else {
167
+ logger . info (
168
+ `Started ${ this . serverName } @${ this . serverVersion } with no tools`
169
+ ) ;
170
+ }
135
171
} catch ( error ) {
136
172
logger . error ( `Server initialization error: ${ error } ` ) ;
137
173
throw error ;
0 commit comments