In Part 1, we deployed the MCP remote server using the old SSE protocol. In this Part 2, we will continue implementing a newer protocol: MCP.
The implementation is very straightforward, similar to SSE, but requires the implementation of three endpoints.
First, declare a variable transports to store the state of incoming connections based on sessionID.
const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
Implement the POST protocol for /mcp. This is the main endpoint for interaction between the server and the client.
app.post('/mcp', async (req, res) => {
// Check for existing session ID
const sessionId = req.headers['mcp-session-id'] as string | undefined;
let transport: StreamableHTTPServerTransport;
if (sessionId && transports[sessionId]) {
// Reuse existing transport
transport = transports[sessionId];
} else if (!sessionId && isInitializeRequest(req.body)) {
// New initialization request
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
onsessioninitialized: (sessionId) => {
// Store the transport by session ID
transports[sessionId] = transport;
},
});
// Clean up transport when closed
transport.onclose = () => {
if (transport.sessionId) {
delete transports[transport.sessionId];
}
};
await server.connect(transport);
} else {
res.status(400).json({
jsonrpc: '2.0',
error: {
code: -32000,
message: 'Bad Request: No valid session ID provided',
},
id: null,
});
return;
}
await transport.handleRequest(req, res, req.body);
});
Implement two additional protocols, GET and DELETE, for /mcp so that the client can receive data from the server or close the session.
const handleSessionRequest = async (req: express.Request, res: express.Response) => {
const sessionId = req.headers['mcp-session-id'] as string | undefined;
if (!sessionId || !transports[sessionId]) {
res.status(400).send('Invalid or missing session ID');
return;
}
const transport = transports[sessionId];
await transport.handleRequest(req, res);
};
// Handle GET requests for server-to-client notifications via SSE
app.get('/mcp', handleSessionRequest);
// Handle DELETE requests for session termination
app.delete('/mcp', handleSessionRequest);
Put it all together, edit the mcp.json file in LM Studio, and try issuing a command to it.

Congratulations on completing this! Refer to the source code in the example at Github. In the next article, we will implement authentication for the MCP remote server together!