Skip to content

Commit 70a9f96

Browse files
committed
init server
1 parent 1f8d44d commit 70a9f96

File tree

5 files changed

+925
-4
lines changed

5 files changed

+925
-4
lines changed

server/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66
"scripts": {
77
"build": "tsc",
88
"start": "node build/index.js",
9-
"dev": "tsx watch --clear-screen=false src/index.ts",
10-
"update:mcp": "git subtree pull --prefix=packages/mcp-typescript https://github.com/modelcontextprotocol/typescript-sdk.git main --squash"
9+
"dev": "tsx watch --clear-screen=false src/index.ts"
1110
},
1211
"devDependencies": {
1312
"@types/eventsource": "^1.1.15",
1413
"@types/express": "^4.17.21",
14+
"@types/ws": "^8.5.12",
1515
"eventsource": "^2.0.2",
1616
"tsx": "^4.19.0",
1717
"typescript": "^5.6.2"
1818
},
1919
"dependencies": {
20-
"express": "^4.20.0",
21-
"mcp-typescript": "file:packages/mcp-typescript"
20+
"express": "^4.21.0",
21+
"mcp-typescript": "file:../packages/mcp-typescript",
22+
"ws": "^8.18.0"
2223
}
2324
}

server/src/client.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Client } from "mcp-typescript/client/index.js";
2+
import { SSEClientTransport } from "mcp-typescript/client/sse.js";
3+
import { StdioClientTransport } from "mcp-typescript/client/stdio.js";
4+
import {
5+
ListResourcesResult,
6+
ReadResourceResult,
7+
ListResourcesResultSchema,
8+
ReadResourceResultSchema,
9+
} from "mcp-typescript/types.js";
10+
11+
export class McpClient {
12+
private client: Client;
13+
private transport?: SSEClientTransport | StdioClientTransport;
14+
15+
constructor(name: string, version: string) {
16+
this.client = new Client({
17+
name,
18+
version,
19+
});
20+
}
21+
22+
async connect(url: string | URL) {
23+
const urlObj = typeof url === "string" ? new URL(url) : url;
24+
25+
if (urlObj.protocol === "http:" || urlObj.protocol === "https:") {
26+
this.transport = new SSEClientTransport();
27+
} else {
28+
throw new Error(`Unsupported protocol: ${urlObj.protocol}`);
29+
}
30+
31+
await this.transport.connect(urlObj);
32+
await this.client.connect(this.transport);
33+
}
34+
35+
async connectStdio(command: string, args: string[] = []) {
36+
this.transport = new StdioClientTransport();
37+
await this.transport.spawn({ command, args });
38+
await this.client.connect(this.transport);
39+
}
40+
41+
async close() {
42+
await this.client.close();
43+
}
44+
45+
// Resource Operations
46+
async listResources(): Promise<ListResourcesResult> {
47+
return await this.client.request(
48+
{
49+
method: "resources/list",
50+
},
51+
ListResourcesResultSchema,
52+
);
53+
}
54+
55+
async readResource(uri: string): Promise<ReadResourceResult> {
56+
return await this.client.request(
57+
{
58+
method: "resources/read",
59+
params: { uri },
60+
},
61+
ReadResourceResultSchema,
62+
);
63+
}
64+
65+
getServerCapabilities() {
66+
return this.client.getServerCapabilities();
67+
}
68+
69+
getServerVersion() {
70+
return this.client.getServerVersion();
71+
}
72+
}
73+
74+
export default McpClient;

server/src/index.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import McpClient from "./client.js";
2+
import express from "express";
3+
import http from "http";
4+
import { WebSocket, WebSocketServer } from "ws";
5+
6+
const app = express();
7+
const server = http.createServer(app);
8+
const wss = new WebSocketServer({ server });
9+
10+
// Create and connect the MCP client
11+
const mcpClient = new McpClient("MyApp", "1.0.0");
12+
await mcpClient.connectStdio(
13+
"/Users/ashwin/.nvm/versions/node/v18.20.4/bin/node",
14+
["/Users/ashwin/code/example-servers/build/everything/index.js"],
15+
);
16+
17+
wss.on("connection", (ws: WebSocket) => {
18+
ws.on("message", async (message: string) => {
19+
try {
20+
const command = JSON.parse(message);
21+
22+
if (command.type === "listResources") {
23+
const resources = await mcpClient.listResources();
24+
ws.send(JSON.stringify({ type: "resources", data: resources }));
25+
} else if (command.type === "readResource" && command.uri) {
26+
const resource = await mcpClient.readResource(command.uri);
27+
ws.send(JSON.stringify({ type: "resource", data: resource }));
28+
}
29+
} catch (error) {
30+
console.error("Error:", error);
31+
ws.send(JSON.stringify({ type: "error", message: String(error) }));
32+
}
33+
});
34+
});
35+
36+
const PORT = process.env.PORT || 3000;
37+
server.listen(PORT, () => {
38+
console.log(`Server is running on port ${PORT}`);
39+
});
40+
41+
// Close the client when the server is shutting down
42+
process.on("SIGINT", async () => {
43+
await mcpClient.close();
44+
process.exit();
45+
});

server/tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "Node16",
5+
"moduleResolution": "Node16",
6+
"outDir": "./build",
7+
"rootDir": "./src",
8+
"strict": true,
9+
"esModuleInterop": true,
10+
"skipLibCheck": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"resolveJsonModule": true
13+
},
14+
"include": ["src/**/*"],
15+
"exclude": ["node_modules", "packages", "**/*.spec.ts"]
16+
}

0 commit comments

Comments
 (0)