Skip to content

Commit 0141b3b

Browse files
committed
feat(sse): re-introduce sse backwards compatibility
1 parent 9f14bde commit 0141b3b

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
# Outline MCP Server
22

33
A Model Context Protocol (MCP) server that provides tools for interacting with [Outline](https://www.getoutline.com/)'s API, enabling AI agents to manage documents, collections, and other entities programmatically through the Outline knowledge base platform.
4-
## 🚨 __**Upgrade Notice:**__ v5 has introduced several breaking changes: 🚨
5-
- support has been dropped for both `stdio` and `sse` transport interfaces. This server now solely exposes a [Streamable HTTP endpoint](https://modelcontextprotocol.io/specification/draft/basic/transports#streamable-http) at the `/mcp` route. If you require sse/stdio, downgrade to v4
6-
- the `--port` CLI flag has been migrated to an environment variable, `OUTLINE_MCP_PORT`
7-
- Minimum node version has been bumped to 20
4+
5+
## 🚨 \***\*Upgrade Notice:\*\*** v5 has introduced several breaking changes: 🚨
6+
7+
- support has been dropped for the `stdio` transport interfaces.
8+
- This server now exposes:
9+
- a [Streamable-HTTP endpoint](https://modelcontextprotocol.io/specification/draft/basic/transports#streamable-http) at the `/mcp` route.
10+
- an SSE endpoint at `/sse`
11+
- If you require stdio, downgrade to v4
12+
- the `--port` CLI flag has been migrated to an environment variable, `OUTLINE_MCP_PORT`
13+
- Minimum node version has been bumped to 20
814

915
## Features
1016

src/index.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#!/usr/bin/env bun
22
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
3+
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
34
import fastify from 'fastify';
45
import { getMcpServer } from './utils/getMcpServer.js';
56

6-
const server = fastify();
7+
const app = fastify();
8+
const mcpServer = await getMcpServer();
79

810
// Stateless mode (default, recommended for most deployments)
9-
server.post('/mcp', async (request, reply) => {
11+
app.post('/mcp', async (request, reply) => {
1012
try {
11-
const mcpServer = await getMcpServer();
1213
const httpTransport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
1314
sessionIdGenerator: undefined,
1415
});
@@ -32,7 +33,7 @@ server.post('/mcp', async (request, reply) => {
3233
}
3334
});
3435

35-
server.get('/mcp', async (request, reply) => {
36+
app.get('/mcp', async (request, reply) => {
3637
reply.code(405).send({
3738
jsonrpc: '2.0',
3839
error: {
@@ -43,7 +44,7 @@ server.get('/mcp', async (request, reply) => {
4344
});
4445
});
4546

46-
server.delete('/mcp', async (request, reply) => {
47+
app.delete('/mcp', async (request, reply) => {
4748
reply.code(405).send({
4849
jsonrpc: '2.0',
4950
error: {
@@ -54,8 +55,41 @@ server.delete('/mcp', async (request, reply) => {
5455
});
5556
});
5657

58+
// Legacy SSE endpoint for older clients
59+
let sseTransport: SSEServerTransport | null = null;
60+
app.get('/sse', async (request, reply) => {
61+
try {
62+
// Create SSE transport for legacy clients
63+
if (!sseTransport) {
64+
sseTransport = new SSEServerTransport('/messages', reply.raw);
65+
await mcpServer.connect(sseTransport);
66+
}
67+
} catch (error) {
68+
console.error(error);
69+
if (!reply.sent) {
70+
reply.code(500).send({
71+
jsonrpc: '2.0',
72+
error: {
73+
code: -32603,
74+
message: 'Internal server error',
75+
},
76+
id: null,
77+
});
78+
}
79+
}
80+
});
81+
82+
// Legacy message endpoint for older clients
83+
app.post('/messages', async (req, res) => {
84+
if (!sseTransport) {
85+
res.status(400).send('No transport found');
86+
return;
87+
}
88+
await sseTransport.handlePostMessage(req.raw, res.raw, req.body);
89+
});
90+
5791
const PORT = process.env.OUTLINE_MCP_PORT ? parseInt(process.env.OUTLINE_MCP_PORT, 10) : 6060;
58-
server.listen({ port: PORT }, (err, address) => {
92+
app.listen({ port: PORT }, (err, address) => {
5993
if (err) {
6094
console.error(err);
6195
process.exit(1);

0 commit comments

Comments
 (0)