Skip to content

Commit c3c07a1

Browse files
authored
Merge pull request #1 from QuantGeekDev/feature/mcp-cli
Feature/mcp cli
2 parents 16f2793 + 27cb517 commit c3c07a1

File tree

3 files changed

+106
-8
lines changed

3 files changed

+106
-8
lines changed

Diff for: package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mcp-framework",
3-
"version": "0.1.3",
3+
"version": "0.1.5",
44
"description": "Framework for building Model Context Protocol (MCP) servers in Typescript",
55
"type": "module",
66
"author": "Alex Andru <[email protected]>",
@@ -15,6 +15,9 @@
1515
"files": [
1616
"dist"
1717
],
18+
"bin": {
19+
"mcp-build": "./dist/cli/build.js"
20+
},
1821
"scripts": {
1922
"build": "tsc",
2023
"watch": "tsc --watch",

Diff for: src/cli/build.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env node
2+
import { spawnSync } from "child_process";
3+
import { readFileSync, writeFileSync } from "fs";
4+
import { join } from "path";
5+
6+
function runTsc() {
7+
const tscPath = join(process.cwd(), "node_modules", ".bin", "tsc");
8+
const tsc = spawnSync(tscPath, [], {
9+
stdio: "inherit",
10+
shell: true,
11+
});
12+
13+
if (tsc.status !== 0) {
14+
process.exit(tsc.status ?? 1);
15+
}
16+
}
17+
18+
function addShebang() {
19+
const indexPath = join(process.cwd(), "dist", "index.js");
20+
try {
21+
const content = readFileSync(indexPath, "utf8");
22+
const shebang = "#!/usr/bin/env node\n";
23+
24+
if (!content.startsWith(shebang)) {
25+
writeFileSync(indexPath, shebang + content);
26+
console.log("Added shebang to dist/index.js");
27+
}
28+
} catch (error) {
29+
console.error("Error adding shebang:", error);
30+
process.exit(1);
31+
}
32+
}
33+
34+
runTsc();
35+
36+
addShebang();
37+
38+
console.log("MCP Build complete");

Diff for: src/core/MCPServer.ts

+64-7
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,34 @@ import {
66
} from "@modelcontextprotocol/sdk/types.js";
77
import { ToolLoader } from "./toolLoader.js";
88
import { BaseTool } from "../tools/BaseTool.js";
9+
import { readFileSync } from "fs";
10+
import { join, dirname } from "path";
11+
import { logger } from "./Logger.js";
912

1013
export interface MCPServerConfig {
11-
name: string;
12-
version: string;
14+
name?: string;
15+
version?: string;
1316
}
1417

1518
export class MCPServer {
1619
private server: Server;
1720
private toolsMap: Map<string, BaseTool> = new Map();
1821
private toolLoader: ToolLoader;
22+
private serverName: string;
23+
private serverVersion: string;
24+
25+
constructor(config: MCPServerConfig = {}) {
26+
this.serverName = config.name ?? this.getDefaultName();
27+
this.serverVersion = config.version ?? this.getDefaultVersion();
28+
29+
logger.info(
30+
`Initializing MCP Server: ${this.serverName}@${this.serverVersion}`
31+
);
1932

20-
constructor(config: MCPServerConfig) {
2133
this.server = new Server(
2234
{
23-
name: config.name,
24-
version: config.version,
35+
name: this.serverName,
36+
version: this.serverVersion,
2537
},
2638
{
2739
capabilities: {
@@ -36,6 +48,46 @@ export class MCPServer {
3648
this.setupHandlers();
3749
}
3850

51+
private readPackageJson(): any {
52+
try {
53+
const mainModulePath = process.argv[1];
54+
const packagePath = join(dirname(mainModulePath), "..", "package.json");
55+
const packageContent = readFileSync(packagePath, "utf-8");
56+
const packageJson = JSON.parse(packageContent);
57+
logger.debug(`Successfully read package.json from: ${packagePath}`);
58+
return packageJson;
59+
} catch (error) {
60+
logger.warn(`Could not read package.json: ${error}`);
61+
return null;
62+
}
63+
}
64+
65+
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}`);
74+
}
75+
return "unnamed-mcp-server";
76+
}
77+
78+
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}`);
87+
}
88+
return "0.0.0";
89+
}
90+
3991
private setupHandlers() {
4092
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
4193
return {
@@ -66,9 +118,14 @@ export class MCPServer {
66118
const transport = new StdioServerTransport();
67119
await this.server.connect(transport);
68120

69-
process.stderr.write(`Server started with ${tools.length} tools\n`);
121+
logger.info(
122+
`Started ${this.serverName}@${this.serverVersion} with ${tools.length} tools`
123+
);
124+
logger.info(
125+
`Available tools: ${Array.from(this.toolsMap.keys()).join(", ")}`
126+
);
70127
} catch (error) {
71-
process.stderr.write(`Server initialization error: ${error}\n`);
128+
logger.error(`Server initialization error: ${error}`);
72129
throw error;
73130
}
74131
}

0 commit comments

Comments
 (0)