@fleetx_io/fleetx-mcp-server 1.1.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +44 -12
  2. package/README.md +56 -6
  3. package/dist/auth/fleetx/exchange.d.ts +13 -0
  4. package/dist/auth/fleetx/exchange.d.ts.map +1 -0
  5. package/dist/auth/fleetx/exchange.js +27 -0
  6. package/dist/auth/fleetx/exchange.js.map +1 -0
  7. package/dist/auth/google/callback.d.ts +3 -0
  8. package/dist/auth/google/callback.d.ts.map +1 -0
  9. package/dist/auth/google/callback.js +98 -0
  10. package/dist/auth/google/callback.js.map +1 -0
  11. package/dist/auth/google/client.d.ts +17 -0
  12. package/dist/auth/google/client.d.ts.map +1 -0
  13. package/dist/auth/google/client.js +50 -0
  14. package/dist/auth/google/client.js.map +1 -0
  15. package/dist/auth/oauth/authorize.d.ts +3 -0
  16. package/dist/auth/oauth/authorize.d.ts.map +1 -0
  17. package/dist/auth/oauth/authorize.js +74 -0
  18. package/dist/auth/oauth/authorize.js.map +1 -0
  19. package/dist/auth/oauth/cimd.d.ts +33 -0
  20. package/dist/auth/oauth/cimd.d.ts.map +1 -0
  21. package/dist/auth/oauth/cimd.js +63 -0
  22. package/dist/auth/oauth/cimd.js.map +1 -0
  23. package/dist/auth/oauth/pending-sessions.d.ts +5 -0
  24. package/dist/auth/oauth/pending-sessions.d.ts.map +1 -0
  25. package/dist/auth/oauth/pending-sessions.js +24 -0
  26. package/dist/auth/oauth/pending-sessions.js.map +1 -0
  27. package/dist/auth/oauth/pkce.d.ts +3 -0
  28. package/dist/auth/oauth/pkce.d.ts.map +1 -0
  29. package/dist/auth/oauth/pkce.js +7 -0
  30. package/dist/auth/oauth/pkce.js.map +1 -0
  31. package/dist/auth/oauth/register.d.ts +8 -0
  32. package/dist/auth/oauth/register.d.ts.map +1 -0
  33. package/dist/auth/oauth/register.js +37 -0
  34. package/dist/auth/oauth/register.js.map +1 -0
  35. package/dist/auth/oauth/token.d.ts +3 -0
  36. package/dist/auth/oauth/token.d.ts.map +1 -0
  37. package/dist/auth/oauth/token.js +111 -0
  38. package/dist/auth/oauth/token.js.map +1 -0
  39. package/dist/auth/oauth/types.d.ts +11 -0
  40. package/dist/auth/oauth/types.d.ts.map +1 -0
  41. package/dist/auth/oauth/types.js +2 -0
  42. package/dist/auth/oauth/types.js.map +1 -0
  43. package/dist/auth/oauth/userinfo.d.ts +3 -0
  44. package/dist/auth/oauth/userinfo.d.ts.map +1 -0
  45. package/dist/auth/oauth/userinfo.js +29 -0
  46. package/dist/auth/oauth/userinfo.js.map +1 -0
  47. package/dist/auth/storage/authorization-code.d.ts +19 -0
  48. package/dist/auth/storage/authorization-code.d.ts.map +1 -0
  49. package/dist/auth/storage/authorization-code.js +44 -0
  50. package/dist/auth/storage/authorization-code.js.map +1 -0
  51. package/dist/auth/storage/connected-account.d.ts +24 -0
  52. package/dist/auth/storage/connected-account.d.ts.map +1 -0
  53. package/dist/auth/storage/connected-account.js +60 -0
  54. package/dist/auth/storage/connected-account.js.map +1 -0
  55. package/dist/auth/storage/db.d.ts +3 -0
  56. package/dist/auth/storage/db.d.ts.map +1 -0
  57. package/dist/auth/storage/db.js +110 -0
  58. package/dist/auth/storage/db.js.map +1 -0
  59. package/dist/auth/storage/oauth-client.d.ts +12 -0
  60. package/dist/auth/storage/oauth-client.d.ts.map +1 -0
  61. package/dist/auth/storage/oauth-client.js +28 -0
  62. package/dist/auth/storage/oauth-client.js.map +1 -0
  63. package/dist/auth/storage/refresh-token.d.ts +17 -0
  64. package/dist/auth/storage/refresh-token.d.ts.map +1 -0
  65. package/dist/auth/storage/refresh-token.js +46 -0
  66. package/dist/auth/storage/refresh-token.js.map +1 -0
  67. package/dist/auth/tokens/encryption.d.ts +5 -0
  68. package/dist/auth/tokens/encryption.d.ts.map +1 -0
  69. package/dist/auth/tokens/encryption.js +27 -0
  70. package/dist/auth/tokens/encryption.js.map +1 -0
  71. package/dist/auth/tokens/jwt.d.ts +8 -0
  72. package/dist/auth/tokens/jwt.d.ts.map +1 -0
  73. package/dist/auth/tokens/jwt.js +34 -0
  74. package/dist/auth/tokens/jwt.js.map +1 -0
  75. package/dist/auth.d.ts +1 -1
  76. package/dist/auth.d.ts.map +1 -1
  77. package/dist/auth.js +2 -1
  78. package/dist/auth.js.map +1 -1
  79. package/dist/config/oauth.d.ts +21 -0
  80. package/dist/config/oauth.d.ts.map +1 -0
  81. package/dist/config/oauth.js +41 -0
  82. package/dist/config/oauth.js.map +1 -0
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +4 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/mcp/middleware/auth.d.ts +18 -0
  88. package/dist/mcp/middleware/auth.d.ts.map +1 -0
  89. package/dist/mcp/middleware/auth.js +35 -0
  90. package/dist/mcp/middleware/auth.js.map +1 -0
  91. package/dist/server/createMcpServer.d.ts +8 -3
  92. package/dist/server/createMcpServer.d.ts.map +1 -1
  93. package/dist/server/createMcpServer.js +28 -12
  94. package/dist/server/createMcpServer.js.map +1 -1
  95. package/dist/transports/fastify.d.ts +2 -0
  96. package/dist/transports/fastify.d.ts.map +1 -0
  97. package/dist/transports/fastify.js +223 -0
  98. package/dist/transports/fastify.js.map +1 -0
  99. package/dist/transports/sse.d.ts +1 -1
  100. package/dist/transports/sse.d.ts.map +1 -1
  101. package/dist/transports/sse.js +162 -67
  102. package/dist/transports/sse.js.map +1 -1
  103. package/dist/transports/stdio.d.ts.map +1 -1
  104. package/dist/transports/stdio.js +8 -1
  105. package/dist/transports/stdio.js.map +1 -1
  106. package/dist/utils-http.d.ts +8 -0
  107. package/dist/utils-http.d.ts.map +1 -0
  108. package/dist/utils-http.js +15 -0
  109. package/dist/utils-http.js.map +1 -0
  110. package/dist/utils.d.ts +1 -0
  111. package/dist/utils.d.ts.map +1 -1
  112. package/dist/utils.js +12 -2
  113. package/dist/utils.js.map +1 -1
  114. package/dist/well-known/discovery.d.ts +4 -0
  115. package/dist/well-known/discovery.d.ts.map +1 -0
  116. package/dist/well-known/discovery.js +25 -0
  117. package/dist/well-known/discovery.js.map +1 -0
  118. package/package.json +15 -7
@@ -0,0 +1,223 @@
1
+ import Fastify from "fastify";
2
+ import formbody from "@fastify/formbody";
3
+ import { randomUUID } from "node:crypto";
4
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
6
+ import { createMcpServer } from "../server/createMcpServer.js";
7
+ import { createTokenStore } from "../auth.js";
8
+ import { log } from "../utils.js";
9
+ import { isOAuthConfigured, getOAuthConfig } from "../config/oauth.js";
10
+ import { verifyMcpAccessToken } from "../auth/tokens/jwt.js";
11
+ import { findConnectedAccountByUserId, updateFleetxTokens } from "../auth/storage/connected-account.js";
12
+ import { refreshFleetxToken } from "../auth/fleetx/exchange.js";
13
+ import { handleAuthorize } from "../auth/oauth/authorize.js";
14
+ import { handleToken } from "../auth/oauth/token.js";
15
+ import { handleUserInfo } from "../auth/oauth/userinfo.js";
16
+ import { handleGoogleCallback } from "../auth/google/callback.js";
17
+ import { handleAuthorizationServerMetadata, handleProtectedResourceMetadata, } from "../well-known/discovery.js";
18
+ const transports = new Map();
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ // Credential resolution
21
+ // ─────────────────────────────────────────────────────────────────────────────
22
+ function parseBearer(header) {
23
+ if (!header?.startsWith("Bearer "))
24
+ return undefined;
25
+ return header.slice(7).trim() || undefined;
26
+ }
27
+ function parseBasic(header) {
28
+ if (!header?.startsWith("Basic "))
29
+ return undefined;
30
+ const decoded = Buffer.from(header.slice(6), "base64").toString("utf-8");
31
+ const sep = decoded.indexOf(":");
32
+ if (sep === -1)
33
+ return undefined;
34
+ const username = decoded.slice(0, sep);
35
+ const password = decoded.slice(sep + 1);
36
+ return username && password ? { type: "basic", username, password } : undefined;
37
+ }
38
+ async function resolveCredentials(authHeader) {
39
+ const bearerToken = parseBearer(authHeader);
40
+ if (bearerToken && isOAuthConfigured()) {
41
+ // Attempt to treat as MCP JWT → look up FleetX token
42
+ const payload = await verifyMcpAccessToken(bearerToken).catch(() => null);
43
+ if (payload) {
44
+ const account = findConnectedAccountByUserId(payload.sub);
45
+ if (account) {
46
+ // Refresh FleetX token if expiring soon
47
+ const BUFFER = 5 * 60 * 1000;
48
+ const expiringSoon = account.fleetxTokenExpiry !== null &&
49
+ account.fleetxTokenExpiry - Date.now() < BUFFER;
50
+ if (expiringSoon) {
51
+ const refreshed = await refreshFleetxToken(account.fleetxRefreshToken);
52
+ if (refreshed) {
53
+ updateFleetxTokens(account.userId, refreshed.accessToken, refreshed.refreshToken);
54
+ return { type: "bearer", token: refreshed.accessToken };
55
+ }
56
+ }
57
+ return { type: "bearer", token: account.fleetxAccessToken };
58
+ }
59
+ // Valid JWT but no account — deny
60
+ return undefined;
61
+ }
62
+ // Not a valid MCP JWT — fall through to raw bearer / basic / env
63
+ }
64
+ const basic = parseBasic(authHeader);
65
+ if (basic)
66
+ return basic;
67
+ if (bearerToken)
68
+ return { type: "bearer", token: bearerToken };
69
+ const envToken = process.env.BEARER_ACCESS_TOKEN?.trim();
70
+ if (envToken)
71
+ return { type: "bearer", token: envToken };
72
+ return undefined;
73
+ }
74
+ // ─────────────────────────────────────────────────────────────────────────────
75
+ // Raw-body parser (needed before passing to MCP transport)
76
+ // ─────────────────────────────────────────────────────────────────────────────
77
+ function readRawBody(req) {
78
+ return new Promise((resolve, reject) => {
79
+ const chunks = [];
80
+ req.on("data", (c) => chunks.push(c));
81
+ req.on("end", () => {
82
+ try {
83
+ resolve(JSON.parse(Buffer.concat(chunks).toString()));
84
+ }
85
+ catch (e) {
86
+ reject(e);
87
+ }
88
+ });
89
+ req.on("error", reject);
90
+ });
91
+ }
92
+ // ─────────────────────────────────────────────────────────────────────────────
93
+ // MCP session handlers (operate on Node raw req/res)
94
+ // ─────────────────────────────────────────────────────────────────────────────
95
+ async function handleMcpPost(req, res, authHeader) {
96
+ const body = await readRawBody(req);
97
+ const sessionId = req.headers["mcp-session-id"];
98
+ if (sessionId && transports.has(sessionId)) {
99
+ await transports.get(sessionId).handleRequest(req, res, body);
100
+ return;
101
+ }
102
+ if (!sessionId && isInitializeRequest(body)) {
103
+ log(`New MCP session from ${req.socket?.remoteAddress}`);
104
+ const credentials = await resolveCredentials(authHeader);
105
+ const transport = new StreamableHTTPServerTransport({
106
+ sessionIdGenerator: () => randomUUID(),
107
+ onsessioninitialized: (id) => {
108
+ transports.set(id, transport);
109
+ log(`MCP session initialized: ${id}`);
110
+ },
111
+ });
112
+ transport.onclose = () => {
113
+ const sid = transport.sessionId;
114
+ if (sid) {
115
+ transports.delete(sid);
116
+ log(`MCP session closed: ${sid}`);
117
+ }
118
+ };
119
+ const tokenStore = createTokenStore();
120
+ const server = await createMcpServer(tokenStore, credentials);
121
+ await server.connect(transport);
122
+ await transport.handleRequest(req, res, body);
123
+ return;
124
+ }
125
+ res.writeHead(400, { "Content-Type": "application/json" });
126
+ res.end(JSON.stringify({
127
+ jsonrpc: "2.0",
128
+ error: { code: -32000, message: "Bad Request: No valid session ID" },
129
+ id: null,
130
+ }));
131
+ }
132
+ async function handleMcpGetDelete(req, res) {
133
+ const sessionId = req.headers["mcp-session-id"];
134
+ if (!sessionId || !transports.has(sessionId)) {
135
+ res.writeHead(400, { "Content-Type": "application/json" });
136
+ res.end(JSON.stringify({ error: "Invalid or missing session ID" }));
137
+ return;
138
+ }
139
+ await transports.get(sessionId).handleRequest(req, res);
140
+ }
141
+ // ─────────────────────────────────────────────────────────────────────────────
142
+ // Fastify server bootstrap
143
+ // ─────────────────────────────────────────────────────────────────────────────
144
+ export async function startFastify() {
145
+ const port = parseInt(process.env.PORT ?? "3000", 10);
146
+ const oauthEnabled = isOAuthConfigured();
147
+ const fastify = Fastify({ logger: false, disableRequestLogging: true });
148
+ // Parse application/x-www-form-urlencoded (token endpoint)
149
+ await fastify.register(formbody);
150
+ // ── Health ───────────────────────────────────────────────────────────────
151
+ fastify.get("/health", async () => ({
152
+ status: "ok",
153
+ message: "FleetX MCP Server is running",
154
+ oauth: oauthEnabled,
155
+ }));
156
+ // ── OAuth + discovery (only when configured) ─────────────────────────────
157
+ if (oauthEnabled) {
158
+ const cfg = getOAuthConfig();
159
+ fastify.get("/.well-known/oauth-authorization-server", handleAuthorizationServerMetadata);
160
+ fastify.get("/.well-known/oauth-protected-resource", handleProtectedResourceMetadata);
161
+ fastify.get("/oauth/authorize", handleAuthorize);
162
+ fastify.post("/oauth/token", handleToken);
163
+ fastify.get("/userinfo", handleUserInfo);
164
+ fastify.get("/google/callback", handleGoogleCallback);
165
+ log(`OAuth endpoints enabled (issuer: ${cfg.MCP_BASE_URL})`);
166
+ }
167
+ // ── MCP endpoint ─────────────────────────────────────────────────────────
168
+ fastify.all("/mcp", async (request, reply) => {
169
+ // Hand off raw req/res to the MCP transport; Fastify must not touch the response.
170
+ reply.hijack();
171
+ const req = request.raw;
172
+ const res = reply.raw;
173
+ try {
174
+ switch (req.method) {
175
+ case "POST":
176
+ await handleMcpPost(req, res, request.headers.authorization);
177
+ break;
178
+ case "GET":
179
+ case "DELETE":
180
+ await handleMcpGetDelete(req, res);
181
+ break;
182
+ default:
183
+ res.writeHead(405, { "Content-Type": "application/json" });
184
+ res.end(JSON.stringify({ error: "Method not allowed" }));
185
+ }
186
+ }
187
+ catch (err) {
188
+ log("MCP handler error:", err);
189
+ if (!res.headersSent) {
190
+ res.writeHead(500, { "Content-Type": "application/json" });
191
+ res.end(JSON.stringify({ error: "Internal server error" }));
192
+ }
193
+ }
194
+ });
195
+ // ── 404 fallback ─────────────────────────────────────────────────────────
196
+ fastify.setNotFoundHandler(async (_, reply) => {
197
+ return reply.status(404).send({ error: "Not found" });
198
+ });
199
+ await fastify.listen({ port, host: "0.0.0.0" });
200
+ log(`FleetX MCP Server listening on http://0.0.0.0:${port}`);
201
+ log(` MCP endpoint : http://localhost:${port}/mcp`);
202
+ if (oauthEnabled) {
203
+ const cfg = getOAuthConfig();
204
+ log(` Authorize : ${cfg.MCP_BASE_URL}/oauth/authorize`);
205
+ log(` Token : ${cfg.MCP_BASE_URL}/oauth/token`);
206
+ log(` Discovery : ${cfg.MCP_BASE_URL}/.well-known/oauth-authorization-server`);
207
+ }
208
+ process.on("SIGINT", async () => {
209
+ log("Shutting down…");
210
+ for (const [id, transport] of transports) {
211
+ try {
212
+ await transport.close();
213
+ }
214
+ catch {
215
+ /* best-effort */
216
+ }
217
+ transports.delete(id);
218
+ }
219
+ await fastify.close();
220
+ process.exit(0);
221
+ });
222
+ }
223
+ //# sourceMappingURL=fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/transports/fastify.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare function startHTTP(): Promise<void>;
1
+ export declare function startSSE(): Promise<void>;
2
2
  //# sourceMappingURL=sse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AA4GA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAwD/C"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AA6MA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA+F9C"}
@@ -1,19 +1,30 @@
1
- import http from "node:http";
1
+ import Fastify from "fastify";
2
+ import formbody from "@fastify/formbody";
2
3
  import { randomUUID } from "node:crypto";
3
4
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
5
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
5
6
  import { createMcpServer } from "../server/createMcpServer.js";
6
7
  import { createTokenStore } from "../auth.js";
7
8
  import { log } from "../utils.js";
9
+ import { isOAuthConfigured, getOAuthConfig } from "../config/oauth.js";
10
+ import { verifyMcpAccessToken } from "../auth/tokens/jwt.js";
11
+ import { findConnectedAccountByUserId, expireConnectedAccountToken } from "../auth/storage/connected-account.js";
12
+ import { handleAuthorize } from "../auth/oauth/authorize.js";
13
+ import { handleToken } from "../auth/oauth/token.js";
14
+ import { handleClientRegistration } from "../auth/oauth/register.js";
15
+ import { handleUserInfo } from "../auth/oauth/userinfo.js";
16
+ import { handleGoogleCallback } from "../auth/google/callback.js";
17
+ import { handleAuthorizationServerMetadata, handleProtectedResourceMetadata, } from "../well-known/discovery.js";
8
18
  const transports = new Map();
9
- /**
10
- * Extracts username and password from an HTTP Basic Authorization header.
11
- *
12
- * Header format: Authorization: Basic <base64(username:password)>
13
- * Example: Authorization: Basic am9obkBleGFtcGxlLmNvbTpzM2NyZXQ=
14
- * → { username: "john@example.com", password: "s3cret" }
15
- */
16
- function parseBasicAuth(header) {
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ // Credential resolution
21
+ // ─────────────────────────────────────────────────────────────────────────────
22
+ function parseBearer(header) {
23
+ if (!header?.startsWith("Bearer "))
24
+ return undefined;
25
+ return header.slice(7).trim() || undefined;
26
+ }
27
+ function parseBasic(header) {
17
28
  if (!header?.startsWith("Basic "))
18
29
  return undefined;
19
30
  const decoded = Buffer.from(header.slice(6), "base64").toString("utf-8");
@@ -22,102 +33,175 @@ function parseBasicAuth(header) {
22
33
  return undefined;
23
34
  const username = decoded.slice(0, sep);
24
35
  const password = decoded.slice(sep + 1);
25
- return username && password ? { username, password } : undefined;
36
+ return username && password ? { type: "basic", username, password } : undefined;
26
37
  }
27
- function parseBody(req) {
28
- return new Promise((resolve, reject) => {
29
- const chunks = [];
30
- req.on("data", (chunk) => chunks.push(chunk));
31
- req.on("end", () => {
32
- try {
33
- resolve(JSON.parse(Buffer.concat(chunks).toString()));
34
- }
35
- catch (err) {
36
- reject(err);
37
- }
38
+ async function resolveCredentials(authHeader) {
39
+ const bearerToken = parseBearer(authHeader);
40
+ if (bearerToken && isOAuthConfigured()) {
41
+ const payload = await verifyMcpAccessToken(bearerToken).catch((err) => {
42
+ log("MCP JWT verification failed:", err);
43
+ return null;
38
44
  });
39
- req.on("error", reject);
45
+ if (payload) {
46
+ const account = findConnectedAccountByUserId(payload.sub);
47
+ if (account && account.fleetxAccessToken) {
48
+ log("resolveCredentials: OAuth JWT → FleetX bearer for", payload.sub);
49
+ return { credentials: { type: "bearer", token: account.fleetxAccessToken }, userId: payload.sub };
50
+ }
51
+ log("resolveCredentials: JWT valid but no active FleetX token for sub:", payload.sub);
52
+ return undefined;
53
+ }
54
+ // Not a valid MCP JWT — fall through to raw bearer / basic / env
55
+ }
56
+ const basic = parseBasic(authHeader);
57
+ if (basic) {
58
+ log("resolveCredentials: basic auth");
59
+ return { credentials: basic };
60
+ }
61
+ if (bearerToken) {
62
+ log("resolveCredentials: raw bearer token");
63
+ return { credentials: { type: "bearer", token: bearerToken } };
64
+ }
65
+ const envToken = process.env.BEARER_ACCESS_TOKEN?.trim();
66
+ if (envToken) {
67
+ log("resolveCredentials: BEARER_ACCESS_TOKEN env");
68
+ return { credentials: { type: "bearer", token: envToken } };
69
+ }
70
+ log("resolveCredentials: no credentials (authHeader present:", !!authHeader, ")");
71
+ return undefined;
72
+ }
73
+ // Send 401 with WWW-Authenticate so Claude triggers the OAuth flow.
74
+ function sendUnauthorized(res) {
75
+ const base = process.env.MCP_BASE_URL ?? "https://mcp.fleetx.io";
76
+ res.writeHead(401, {
77
+ "Content-Type": "application/json",
78
+ "WWW-Authenticate": `Bearer resource_metadata="${base}/.well-known/oauth-protected-resource"`,
40
79
  });
80
+ res.end(JSON.stringify({
81
+ error: "unauthorized",
82
+ error_description: "Authentication required. Please complete OAuth flow.",
83
+ }));
41
84
  }
42
- async function handlePost(req, res) {
43
- const body = await parseBody(req);
85
+ // ─────────────────────────────────────────────────────────────────────────────
86
+ // MCP session handlers (operate on Node raw req/res)
87
+ // ─────────────────────────────────────────────────────────────────────────────
88
+ async function handleMcpPost(req, res, authHeader, body) {
44
89
  const sessionId = req.headers["mcp-session-id"];
90
+ // Existing session — forward directly (already authenticated when session was created)
45
91
  if (sessionId && transports.has(sessionId)) {
92
+ log(`MCP POST session=${sessionId}`);
46
93
  await transports.get(sessionId).handleRequest(req, res, body);
47
94
  return;
48
95
  }
96
+ // New session must start with initialize
49
97
  if (!sessionId && isInitializeRequest(body)) {
50
- log(`New session from ${req.socket.remoteAddress}`);
98
+ log(`MCP initialize from ${req.socket?.remoteAddress} auth=${!!authHeader}`);
99
+ const resolved = await resolveCredentials(authHeader);
100
+ // OAuth is enabled but no valid token → tell Claude to authenticate
101
+ if (!resolved && isOAuthConfigured()) {
102
+ log("MCP initialize rejected: no credentials, sending 401");
103
+ sendUnauthorized(res);
104
+ return;
105
+ }
51
106
  const transport = new StreamableHTTPServerTransport({
52
107
  sessionIdGenerator: () => randomUUID(),
53
108
  onsessioninitialized: (id) => {
54
109
  transports.set(id, transport);
55
- log(`Session initialized: ${id}`);
110
+ log(`MCP session created: ${id}`);
56
111
  },
57
112
  });
58
113
  transport.onclose = () => {
59
114
  const sid = transport.sessionId;
60
115
  if (sid) {
61
116
  transports.delete(sid);
62
- log(`Session closed: ${sid}`);
117
+ log(`MCP session closed: ${sid}`);
63
118
  }
64
119
  };
65
- const tokenStore = createTokenStore();
66
- const credentials = parseBasicAuth(req.headers.authorization);
67
- const server = await createMcpServer(tokenStore, credentials);
120
+ // For OAuth sessions, when FleetX returns 401 the tokenStore.clearToken()
121
+ // also wipes the stored token in SQLite → next MCP connect gets 401 → Claude re-auths.
122
+ const onClear = resolved?.userId
123
+ ? () => {
124
+ log("FleetX token expired for userId:", resolved.userId);
125
+ expireConnectedAccountToken(resolved.userId);
126
+ }
127
+ : undefined;
128
+ const tokenStore = createTokenStore(onClear);
129
+ const server = await createMcpServer(tokenStore, resolved?.credentials);
68
130
  await server.connect(transport);
69
131
  await transport.handleRequest(req, res, body);
70
132
  return;
71
133
  }
134
+ // Unknown session or non-initialize without session
135
+ log(`MCP POST bad request: sessionId=${sessionId} isInit=${isInitializeRequest(body)}`);
72
136
  res.writeHead(400, { "Content-Type": "application/json" });
73
137
  res.end(JSON.stringify({
74
138
  jsonrpc: "2.0",
75
- error: { code: -32000, message: "Bad Request: No valid session ID provided" },
139
+ error: { code: -32000, message: "Bad Request: send initialize first" },
76
140
  id: null,
77
141
  }));
78
142
  }
79
- async function handleGet(req, res) {
143
+ async function handleMcpGetDelete(req, res, authHeader) {
80
144
  const sessionId = req.headers["mcp-session-id"];
81
- if (!sessionId || !transports.has(sessionId)) {
82
- res.writeHead(400, { "Content-Type": "application/json" });
83
- res.end(JSON.stringify({ error: "Invalid or missing session ID" }));
145
+ if (sessionId && transports.has(sessionId)) {
146
+ await transports.get(sessionId).handleRequest(req, res);
84
147
  return;
85
148
  }
86
- await transports.get(sessionId).handleRequest(req, res);
87
- }
88
- async function handleDelete(req, res) {
89
- const sessionId = req.headers["mcp-session-id"];
90
- if (!sessionId || !transports.has(sessionId)) {
91
- res.writeHead(400, { "Content-Type": "application/json" });
92
- res.end(JSON.stringify({ error: "Invalid or missing session ID" }));
149
+ // No valid session — return 401 if OAuth enabled so Claude triggers the auth flow,
150
+ // otherwise 400.
151
+ if (isOAuthConfigured() && !(await resolveCredentials(authHeader))) {
152
+ sendUnauthorized(res);
93
153
  return;
94
154
  }
95
- await transports.get(sessionId).handleRequest(req, res);
155
+ res.writeHead(400, { "Content-Type": "application/json" });
156
+ res.end(JSON.stringify({ error: "Invalid or missing session ID" }));
96
157
  }
97
- export async function startHTTP() {
98
- const port = parseInt(process.env.PORT || "3000", 10);
99
- const httpServer = http.createServer(async (req, res) => {
100
- const url = new URL(req.url, `http://localhost:${port}`);
101
- if (url.pathname === "/health") {
102
- res.writeHead(200, { "Content-Type": "application/json" });
103
- res.end(JSON.stringify({ status: "ok", message: "FleetX MCP Server is running" }));
104
- return;
105
- }
106
- if (url.pathname !== "/mcp") {
107
- res.writeHead(404, { "Content-Type": "application/json" });
108
- res.end(JSON.stringify({ error: "Not found" }));
109
- return;
110
- }
158
+ // ─────────────────────────────────────────────────────────────────────────────
159
+ // Fastify server bootstrap
160
+ // ─────────────────────────────────────────────────────────────────────────────
161
+ export async function startSSE() {
162
+ const port = parseInt(process.env.PORT ?? "3000", 10);
163
+ const oauthEnabled = isOAuthConfigured();
164
+ const fastify = Fastify({
165
+ logger: {
166
+ stream: process.stderr,
167
+ level: process.env.LOG_LEVEL ?? "info",
168
+ },
169
+ });
170
+ // Parse application/x-www-form-urlencoded (token endpoint)
171
+ await fastify.register(formbody);
172
+ // ── Health ───────────────────────────────────────────────────────────────
173
+ fastify.get("/health", async () => ({
174
+ status: "ok",
175
+ message: "FleetX MCP Server is running",
176
+ oauth: oauthEnabled,
177
+ }));
178
+ // ── OAuth + discovery (only when configured) ─────────────────────────────
179
+ if (oauthEnabled) {
180
+ const cfg = getOAuthConfig();
181
+ fastify.get("/.well-known/oauth-authorization-server", handleAuthorizationServerMetadata);
182
+ fastify.get("/.well-known/oauth-protected-resource", handleProtectedResourceMetadata);
183
+ fastify.get("/oauth/authorize", handleAuthorize);
184
+ fastify.post("/oauth/token", handleToken);
185
+ fastify.post("/oauth/register", handleClientRegistration);
186
+ fastify.get("/userinfo", handleUserInfo);
187
+ fastify.get("/google/callback", handleGoogleCallback);
188
+ log(`OAuth endpoints enaxbled (issuer: ${cfg.MCP_BASE_URL})`);
189
+ }
190
+ // ── MCP endpoint ─────────────────────────────────────────────────────────
191
+ fastify.all("/mcp", async (request, reply) => {
192
+ // Hand off raw req/res to the MCP transport; Fastify must not touch the response.
193
+ reply.hijack();
194
+ const req = request.raw;
195
+ const res = reply.raw;
111
196
  try {
112
197
  switch (req.method) {
113
198
  case "POST":
114
- await handlePost(req, res);
199
+ // Pass Fastify's already-parsed body — raw stream is consumed by this point.
200
+ await handleMcpPost(req, res, request.headers.authorization, request.body);
115
201
  break;
116
202
  case "GET":
117
- await handleGet(req, res);
118
- break;
119
203
  case "DELETE":
120
- await handleDelete(req, res);
204
+ await handleMcpGetDelete(req, res, request.headers.authorization);
121
205
  break;
122
206
  default:
123
207
  res.writeHead(405, { "Content-Type": "application/json" });
@@ -125,27 +209,38 @@ export async function startHTTP() {
125
209
  }
126
210
  }
127
211
  catch (err) {
128
- log("HTTP handler error:", err);
212
+ log("MCP handler error:", err);
129
213
  if (!res.headersSent) {
130
214
  res.writeHead(500, { "Content-Type": "application/json" });
131
215
  res.end(JSON.stringify({ error: "Internal server error" }));
132
216
  }
133
217
  }
134
218
  });
135
- httpServer.listen(port, () => {
136
- log(`FleetX MCP Server started in SSE mode on http://localhost:${port}/mcp`);
219
+ // ── 404 fallback ─────────────────────────────────────────────────────────
220
+ fastify.setNotFoundHandler(async (_, reply) => {
221
+ return reply.status(404).send({ error: "Not found" });
137
222
  });
223
+ await fastify.listen({ port, host: "0.0.0.0" });
224
+ log(`FleetX MCP Server listening on http://0.0.0.0:${port}`);
225
+ log(`MCP endpoint : http://localhost:${port}/mcp`);
226
+ if (oauthEnabled) {
227
+ const cfg = getOAuthConfig();
228
+ log(` Authorize : ${cfg.MCP_BASE_URL}/oauth/authorize`);
229
+ log(` Token : ${cfg.MCP_BASE_URL}/oauth/token`);
230
+ log(` Discovery : ${cfg.MCP_BASE_URL}/.well-known/oauth-authorization-server`);
231
+ }
138
232
  process.on("SIGINT", async () => {
139
- log("Shutting down...");
233
+ log("Shutting down");
140
234
  for (const [id, transport] of transports) {
141
235
  try {
142
236
  await transport.close();
143
- transports.delete(id);
144
237
  }
145
238
  catch {
146
- // best-effort cleanup
239
+ /* best-effort */
147
240
  }
241
+ transports.delete(id);
148
242
  }
243
+ await fastify.close();
149
244
  process.exit(0);
150
245
  });
151
246
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAMA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAShD"}
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAMA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAehD"}
@@ -6,7 +6,14 @@ import { log } from "../utils.js";
6
6
  export async function startStdio() {
7
7
  const tokenStore = createTokenStore();
8
8
  const { username, password } = getUsernameLoginDetails();
9
- const credentials = username && password ? { username, password } : undefined;
9
+ const envBearer = process.env.BEARER_ACCESS_TOKEN?.trim();
10
+ let credentials;
11
+ if (envBearer) {
12
+ credentials = { type: "bearer", token: envBearer };
13
+ }
14
+ else if (username && password) {
15
+ credentials = { type: "basic", username, password };
16
+ }
10
17
  const server = await createMcpServer(tokenStore, credentials);
11
18
  const transport = new StdioServerTransport();
12
19
  await server.connect(transport);