@ganintegrity/mcp 1.0.0 → 1.1.1

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 (80) hide show
  1. package/README.md +191 -84
  2. package/dist/{als.d.ts → core/als.d.ts} +11 -4
  3. package/dist/core/als.d.ts.map +1 -0
  4. package/dist/core/als.js.map +1 -0
  5. package/dist/{auth → core/auth}/auth.types.d.ts +6 -0
  6. package/dist/core/auth/auth.types.d.ts.map +1 -0
  7. package/dist/{auth → core/auth}/auth.types.js.map +1 -1
  8. package/dist/core/auth/index.d.ts +34 -0
  9. package/dist/core/auth/index.d.ts.map +1 -0
  10. package/dist/core/auth/index.js +57 -0
  11. package/dist/core/auth/index.js.map +1 -0
  12. package/dist/core/define.d.ts +80 -0
  13. package/dist/core/define.d.ts.map +1 -0
  14. package/dist/core/define.js +52 -0
  15. package/dist/core/define.js.map +1 -0
  16. package/dist/core/dispatch.d.ts +35 -0
  17. package/dist/core/dispatch.d.ts.map +1 -0
  18. package/dist/core/dispatch.js +57 -0
  19. package/dist/core/dispatch.js.map +1 -0
  20. package/dist/{errors → core/errors}/errors.types.d.ts +21 -0
  21. package/dist/core/errors/errors.types.d.ts.map +1 -0
  22. package/dist/core/errors/errors.types.js.map +1 -0
  23. package/dist/{errors → core/errors}/index.d.ts +4 -0
  24. package/dist/core/errors/index.d.ts.map +1 -0
  25. package/dist/{errors → core/errors}/index.js +4 -0
  26. package/dist/core/errors/index.js.map +1 -0
  27. package/dist/core/test-helpers.d.ts +20 -0
  28. package/dist/core/test-helpers.d.ts.map +1 -0
  29. package/dist/core/test-helpers.js +38 -0
  30. package/dist/core/test-helpers.js.map +1 -0
  31. package/dist/core/tool/index.d.ts +19 -0
  32. package/dist/core/tool/index.d.ts.map +1 -0
  33. package/dist/{tool → core/tool}/index.js +28 -25
  34. package/dist/core/tool/index.js.map +1 -0
  35. package/dist/{tool → core/tool}/tool.types.d.ts +38 -2
  36. package/dist/core/tool/tool.types.d.ts.map +1 -0
  37. package/dist/{tool → core/tool}/tool.types.js.map +1 -1
  38. package/dist/{auth/index.d.ts → express/auth.d.ts} +10 -9
  39. package/dist/express/auth.d.ts.map +1 -0
  40. package/dist/express/auth.js +49 -0
  41. package/dist/express/auth.js.map +1 -0
  42. package/dist/express/express.types.d.ts +37 -0
  43. package/dist/express/express.types.d.ts.map +1 -0
  44. package/dist/express/express.types.js +2 -0
  45. package/dist/express/express.types.js.map +1 -0
  46. package/dist/express/index.d.ts +41 -0
  47. package/dist/express/index.d.ts.map +1 -0
  48. package/dist/express/index.js +59 -0
  49. package/dist/express/index.js.map +1 -0
  50. package/dist/index.d.ts +21 -18
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +10 -4
  53. package/dist/index.js.map +1 -1
  54. package/package.json +8 -1
  55. package/dist/als.d.ts.map +0 -1
  56. package/dist/als.js.map +0 -1
  57. package/dist/auth/auth.types.d.ts.map +0 -1
  58. package/dist/auth/index.d.ts.map +0 -1
  59. package/dist/auth/index.js +0 -74
  60. package/dist/auth/index.js.map +0 -1
  61. package/dist/errors/errors.types.d.ts.map +0 -1
  62. package/dist/errors/errors.types.js.map +0 -1
  63. package/dist/errors/index.d.ts.map +0 -1
  64. package/dist/errors/index.js.map +0 -1
  65. package/dist/server/index.d.ts +0 -18
  66. package/dist/server/index.d.ts.map +0 -1
  67. package/dist/server/index.js +0 -130
  68. package/dist/server/index.js.map +0 -1
  69. package/dist/server/server.types.d.ts +0 -78
  70. package/dist/server/server.types.d.ts.map +0 -1
  71. package/dist/server/server.types.js +0 -2
  72. package/dist/server/server.types.js.map +0 -1
  73. package/dist/tool/index.d.ts +0 -26
  74. package/dist/tool/index.d.ts.map +0 -1
  75. package/dist/tool/index.js.map +0 -1
  76. package/dist/tool/tool.types.d.ts.map +0 -1
  77. /package/dist/{als.js → core/als.js} +0 -0
  78. /package/dist/{auth → core/auth}/auth.types.js +0 -0
  79. /package/dist/{errors → core/errors}/errors.types.js +0 -0
  80. /package/dist/{tool → core/tool}/tool.types.js +0 -0
@@ -0,0 +1,49 @@
1
+ import { resolveAuth } from "../core/auth/index.js";
2
+ /**
3
+ * Bearer-token auth middleware for the MCP HTTP endpoint.
4
+ *
5
+ * Reads `Authorization: Bearer <token>`. If absent the middleware responds
6
+ * `401` and does not call `next`.
7
+ *
8
+ * On success it sets:
9
+ * - `req.user` — the resolved `AuthUser` (re-export from `@ganintegrity/mcp`)
10
+ * - `req.headers.company` — `user.companySubdomainName` (for downstream
11
+ * middleware that keys off the company header)
12
+ * - `req.auth` — SDK-shaped `AuthInfo`, surfaced to MCP tool handlers as
13
+ * `RequestHandlerExtra.authInfo`
14
+ * - `req.mcpSessionId` — value of the `X-Session-Id` header if present, used
15
+ * for log correlation
16
+ *
17
+ * Then calls `next()`.
18
+ *
19
+ * **Never throws.** All failures (missing token, `tokenToUser` rejection)
20
+ * are turned into `401` responses; the middleware does not call `next(err)`.
21
+ *
22
+ * Mounted automatically by {@link createMcpRouter}. Exported in case you
23
+ * want to compose it differently (e.g. mount under a different router, or
24
+ * stack additional middleware).
25
+ *
26
+ * @public
27
+ */
28
+ export function mcpAuth(options) {
29
+ return async (req, res, next) => {
30
+ const result = await resolveAuth(req.headers, options);
31
+ if (!result.ok) {
32
+ res.status(result.status).json({ error: result.message });
33
+ return;
34
+ }
35
+ req.user = result.user;
36
+ req.headers.company = result.user.companySubdomainName;
37
+ req.auth = {
38
+ token: result.token,
39
+ clientId: result.user.id,
40
+ scopes: [],
41
+ extra: { user: result.user },
42
+ };
43
+ if (result.sessionId) {
44
+ req.mcpSessionId = result.sessionId;
45
+ }
46
+ next();
47
+ };
48
+ }
49
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/express/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,OAAO,KAAK,EACV,GAAY,EACZ,GAAa,EACb,IAAkB,EACH,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACA,GAAmB,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxC,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;QACvD,GAAG,CAAC,IAAI,GAAG;YACT,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;YACxB,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;SAC7B,CAAC;QACF,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;QACtC,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { Request, RequestHandler } from "express";
2
+ import type { Postgan } from "@ganintegrity/postgan";
3
+ import type { Logger } from "pino";
4
+ import type { AuthUser } from "../core/auth/auth.types.ts";
5
+ /**
6
+ * Per-service options for {@link createMcpRouter}. The
7
+ * framework-neutral bits (name, version, tools, errorMapper) live on the
8
+ * `McpDefinition` argument; this options bag holds only what's specific
9
+ * to mounting against an Express stack.
10
+ *
11
+ * @public
12
+ */
13
+ export interface CreateMcpRouterOptions {
14
+ /**
15
+ * Service logger. The library calls `logger.child({ component: "mcp" })`
16
+ * internally and further childs with `sessionId` / `userId` / `company`
17
+ * per request and with `tool` / `sessionId` per tool call.
18
+ */
19
+ logger: Logger;
20
+ /**
21
+ * Resolve a bearer token to a user. The library is neutral about how
22
+ * tokens are verified — plug in your service's existing JWT/cipher/identity
23
+ * pipeline. Reject by throwing — the router responds `401`.
24
+ */
25
+ tokenToUser: (token: string) => Promise<AuthUser>;
26
+ /**
27
+ * Express middleware that attaches a `Postgan` instance to `req.postgan`.
28
+ * Mounted between auth and the JSON-RPC dispatcher; tools open per-call
29
+ * transactions against `ctx.postgan`.
30
+ */
31
+ setupPostgan: RequestHandler;
32
+ }
33
+ export type ReqWithUserPostgan = Request & {
34
+ user?: AuthUser;
35
+ postgan?: Postgan;
36
+ };
37
+ //# sourceMappingURL=express.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.types.d.ts","sourceRoot":"","sources":["../../src/express/express.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClD;;;;OAIG;IACH,YAAY,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG;IACzC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=express.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.types.js","sourceRoot":"","sources":["../../src/express/express.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Express adapter for `@ganintegrity/mcp`. Mounts an `McpDefinition` (built
3
+ * with `defineMcpServer`) as an Express router and provides the bearer-token
4
+ * auth middleware that resolves users for incoming requests.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import { type Router } from "express";
9
+ import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
10
+ import { mcpAuth } from "./auth.ts";
11
+ import type { McpDefinition } from "../core/define.ts";
12
+ import type { CreateMcpRouterOptions } from "./express.types.ts";
13
+ declare global {
14
+ namespace Express {
15
+ interface Request {
16
+ mcpSessionId?: string;
17
+ auth?: AuthInfo;
18
+ }
19
+ }
20
+ }
21
+ export { mcpAuth };
22
+ export type { CreateMcpRouterOptions } from "./express.types.ts";
23
+ /**
24
+ * Build an Express router that serves an `McpDefinition` (from `@ganintegrity/mcp`). Mount the
25
+ * returned router on whatever path you like
26
+ * (`app.use("/mcp", createMcpRouter(mcp, opts))`).
27
+ *
28
+ * Each request runs through:
29
+ *
30
+ * `express.json()` → `mcpAuth` → caller's `setupPostgan` → tool dispatch
31
+ *
32
+ * Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
33
+ * `user` / `postgan` / `transaction` / `sessionId` / `logger` from
34
+ * `ToolContext` without Express objects leaking in.
35
+ *
36
+ * Synchronous and never throws.
37
+ *
38
+ * @public
39
+ */
40
+ export declare function createMcpRouter(mcp: McpDefinition, options: CreateMcpRouterOptions): Router;
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAgB,EAA+B,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAG/E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,sBAAsB,EAEvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,CAAC,MAAM,CAAC;IAIb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;SACjB;KACF;CACF;AAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AA+BjE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAQR"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Express adapter for `@ganintegrity/mcp`. Mounts an `McpDefinition` (built
3
+ * with `defineMcpServer`) as an Express router and provides the bearer-token
4
+ * auth middleware that resolves users for incoming requests.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import express, {} from "express";
9
+ import { mcpAuth } from "./auth.js";
10
+ import { dispatchMcpRequest } from "../core/dispatch.js";
11
+ export { mcpAuth };
12
+ /**
13
+ * Express adapter around {@link dispatchMcpRequest}: pulls `user` /
14
+ * `postgan` / `mcpSessionId` off the request (set upstream by the auth
15
+ * middleware and `setupPostgan`), then hands the SDK transport an Express
16
+ * `req`/`res` pair via the dispatcher's `invokeTransport` callback.
17
+ */
18
+ function handleMcpRequest(mcp, logger) {
19
+ return async (req, res) => {
20
+ const { user, postgan } = req;
21
+ if (!user || !postgan) {
22
+ // Defensive: mcpAuth + setupPostgan should have populated both.
23
+ res.status(401).json({ error: "Unauthenticated" });
24
+ return;
25
+ }
26
+ await dispatchMcpRequest(mcp, logger, { user, postgan, sessionId: req.mcpSessionId }, (transport) => transport.handleRequest(req, res, req.body), () => {
27
+ if (!res.headersSent) {
28
+ res.status(500).json({ error: "Internal MCP transport error" });
29
+ }
30
+ });
31
+ };
32
+ }
33
+ /**
34
+ * Build an Express router that serves an `McpDefinition` (from `@ganintegrity/mcp`). Mount the
35
+ * returned router on whatever path you like
36
+ * (`app.use("/mcp", createMcpRouter(mcp, opts))`).
37
+ *
38
+ * Each request runs through:
39
+ *
40
+ * `express.json()` → `mcpAuth` → caller's `setupPostgan` → tool dispatch
41
+ *
42
+ * Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
43
+ * `user` / `postgan` / `transaction` / `sessionId` / `logger` from
44
+ * `ToolContext` without Express objects leaking in.
45
+ *
46
+ * Synchronous and never throws.
47
+ *
48
+ * @public
49
+ */
50
+ export function createMcpRouter(mcp, options) {
51
+ const mcpLogger = options.logger.child({ component: "mcp" });
52
+ const router = express.Router();
53
+ router.use(express.json());
54
+ router.use(mcpAuth({ tokenToUser: options.tokenToUser, logger: mcpLogger }));
55
+ router.use(options.setupPostgan);
56
+ router.post("/", handleMcpRequest(mcp, mcpLogger));
57
+ return router;
58
+ }
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,OAAO,EAAE,EAA4C,MAAM,SAAS,CAAC;AAI5E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAmBzD,OAAO,EAAE,OAAO,EAAE,CAAC;AAGnB;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,GAAkB,EAAE,MAAc;IAC1D,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAiB,EAAE;QAC1D,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,GAAyB,CAAC;QACpD,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtB,gEAAgE;YAChE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,kBAAkB,CACtB,GAAG,EACH,MAAM,EACN,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,YAAY,EAAE,EAC9C,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EAC1D,GAAG,EAAE;YACH,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAkB,EAClB,OAA+B;IAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAC7E,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACjC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,20 +1,23 @@
1
- import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
2
- declare global {
3
- namespace Express {
4
- interface Request {
5
- mcpSessionId?: string;
6
- auth?: AuthInfo;
7
- }
8
- }
9
- }
10
- export { createMcpServer } from "./server/index.ts";
11
- export type { CreateMcpServerOptions, CreateMcpServerResult, } from "./server/server.types.ts";
12
- export { tool } from "./tool/index.ts";
13
- export type { ToolSpec, ToolAnnotations, ToolContext, } from "./tool/tool.types.ts";
1
+ /**
2
+ * Framework-neutral entry for `@ganintegrity/mcp`. Tool definitions, error
3
+ * envelope plumbing, and the types every adapter shares live here. Bootstrap
4
+ * files importing the adapter factory should reach for a per-framework
5
+ * subpath (`@ganintegrity/mcp/express`); tool files import from this root.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { defineMcpServer, materializeSdkServer } from "./core/define.ts";
10
+ export type { DefineMcpServerOptions, McpDefinition } from "./core/define.ts";
11
+ export type { ToolSpec, ToolAnnotations, ToolContext, ToolRegister, ToolRegistration, } from "./core/tool/tool.types.ts";
12
+ /**
13
+ * MCP SDK server class re-exported as a type for convenience so consumers
14
+ * can annotate adapter callbacks without importing the SDK directly.
15
+ *
16
+ * @public
17
+ */
14
18
  export type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
15
- export { mcpAuth } from "./auth/index.ts";
16
- export type { McpAuthOptions, AuthUser } from "./auth/auth.types.ts";
17
- export { INTERNAL_ERROR, toCallToolError } from "./errors/index.ts";
18
- export type { McpErrorMapper, McpToolError, McpToolErrorSeverity, ToolErrorMeta, } from "./errors/errors.types.ts";
19
- export type { RequestStore } from "./als.ts";
19
+ export type { AuthUser, McpAuthOptions } from "./core/auth/auth.types.ts";
20
+ export { INTERNAL_ERROR, toCallToolError } from "./core/errors/index.ts";
21
+ export type { McpErrorMapper, McpToolError, McpToolErrorSeverity, ToolErrorMeta, } from "./core/errors/errors.types.ts";
22
+ export type { RequestStore } from "./core/als.ts";
20
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAE/E,OAAO,CAAC,MAAM,CAAC;IAIb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;SACjB;KACF;CACF;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EACV,QAAQ,EACR,eAAe,EACf,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EACV,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACzE,YAAY,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE9E,YAAY,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,EACZ,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC;;;;;GAKG;AACH,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EACV,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,aAAa,GACd,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,11 @@
1
- export { createMcpServer } from "./server/index.js";
2
- export { tool } from "./tool/index.js";
3
- export { mcpAuth } from "./auth/index.js";
4
- export { INTERNAL_ERROR, toCallToolError } from "./errors/index.js";
1
+ /**
2
+ * Framework-neutral entry for `@ganintegrity/mcp`. Tool definitions, error
3
+ * envelope plumbing, and the types every adapter shares live here. Bootstrap
4
+ * files importing the adapter factory should reach for a per-framework
5
+ * subpath (`@ganintegrity/mcp/express`); tool files import from this root.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { defineMcpServer, materializeSdkServer } from "./core/define.js";
10
+ export { INTERNAL_ERROR, toCallToolError } from "./core/errors/index.js";
5
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMpD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AASvC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAqBzE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganintegrity/mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Provides tooling to scaffold an MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "default": "./dist/index.js"
12
+ },
13
+ "./express": {
14
+ "types": "./dist/express/index.d.ts",
15
+ "default": "./dist/express/index.js"
12
16
  }
13
17
  },
14
18
  "files": [
@@ -22,6 +26,8 @@
22
26
  "test:coverage": "vitest run --coverage",
23
27
  "lint": "eslint 'src/**/*.ts'",
24
28
  "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json",
29
+ "api:check": "api-extractor run --config etc/api-extractor.root.json && api-extractor run --config etc/api-extractor.express.json",
30
+ "api:update": "api-extractor run --local --config etc/api-extractor.root.json && api-extractor run --local --config etc/api-extractor.express.json",
25
31
  "format": "pnpx prettier . -w",
26
32
  "format:check": "pnpx prettier . -c",
27
33
  "typecheck:watch": "tsc --noEmit --watch"
@@ -47,6 +53,7 @@
47
53
  "@commitlint/cli": "^20.5.3",
48
54
  "@commitlint/config-conventional": "^20.5.3",
49
55
  "@eslint/js": "^10.0.1",
56
+ "@microsoft/api-extractor": "^7.58.7",
50
57
  "@semantic-release/changelog": "^6.0.3",
51
58
  "@semantic-release/gitlab": "^13.3.2",
52
59
  "@types/express": "^5.0.6",
package/dist/als.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"als.d.ts","sourceRoot":"","sources":["../src/als.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,eAAO,MAAM,YAAY,iCAAwC,CAAC"}
package/dist/als.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"als.js","sourceRoot":"","sources":["../src/als.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAyBrD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,iBAAiB,EAAgB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../src/auth/auth.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClD,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAmChE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAwB/D"}
@@ -1,74 +0,0 @@
1
- const BEARER_PREFIX = /^Bearer\s+/i;
2
- function extractBearer(req) {
3
- const auth = req.headers["authorization"];
4
- if (typeof auth === "string" && BEARER_PREFIX.test(auth)) {
5
- return auth.replace(BEARER_PREFIX, "").trim();
6
- }
7
- // Parity fallback: REST accepts X-Access-Token. Same middleware shape.
8
- const xat = req.headers["x-access-token"];
9
- if (typeof xat === "string" && xat && xat !== "null" && xat !== "undefined") {
10
- return xat;
11
- }
12
- return undefined;
13
- }
14
- function applyAuthToRequest(req, user, token) {
15
- req.user = user;
16
- req.headers.company = user.companySubdomainName;
17
- req.auth = {
18
- token,
19
- clientId: user.id,
20
- scopes: [],
21
- extra: { user },
22
- };
23
- const sessionId = req.headers["x-session-id"];
24
- if (typeof sessionId === "string" && sessionId.length > 0) {
25
- req.mcpSessionId = sessionId;
26
- }
27
- }
28
- /**
29
- * Bearer-token auth middleware for the MCP HTTP endpoint.
30
- *
31
- * Token sources, in order: `Authorization: Bearer <token>`, then
32
- * `X-Access-Token`. If neither is present the middleware responds `401` and
33
- * does not call `next`.
34
- *
35
- * On success it sets:
36
- * - `req.user` — the resolved {@link AuthUser}
37
- * - `req.headers.company` — `user.companySubdomainName` (for downstream
38
- * middleware that keys off the company header)
39
- * - `req.auth` — SDK-shaped `AuthInfo`, surfaced to MCP tool handlers as
40
- * `RequestHandlerExtra.authInfo`
41
- * - `req.mcpSessionId` — value of the `X-Session-Id` header if present, used
42
- * for log correlation
43
- *
44
- * Then calls `next()`.
45
- *
46
- * **Never throws.** All failures (missing token, `tokenToUser` rejection)
47
- * are turned into `401` responses; the middleware does not call `next(err)`.
48
- *
49
- * Mounted automatically by `createMcpServer`'s `mount()`. Exported in case
50
- * you want to compose it differently (e.g. mount under a different router,
51
- * or stack additional middleware).
52
- */
53
- export function mcpAuth(options) {
54
- return async (req, res, next) => {
55
- const token = extractBearer(req);
56
- if (!token) {
57
- res
58
- .status(401)
59
- .json({ error: "Missing or invalid Authorization header" });
60
- return;
61
- }
62
- try {
63
- const user = await options.tokenToUser(token);
64
- applyAuthToRequest(req, user, token);
65
- next();
66
- }
67
- catch (err) {
68
- const reason = err instanceof Error ? err.message : "invalid token";
69
- options.logger.warn({ err }, "mcp auth: token rejected");
70
- res.status(401).json({ error: `Authentication failed: ${reason}` });
71
- }
72
- };
73
- }
74
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAGA,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;IACD,uEAAuE;IACvE,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QAC5E,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAID,SAAS,kBAAkB,CAAC,GAAY,EAAE,IAAc,EAAE,KAAa;IACpE,GAAmB,CAAC,IAAI,GAAG,IAAI,CAAC;IACjC,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC;IAChD,GAAG,CAAC,IAAI,GAAG;QACT,KAAK;QACL,QAAQ,EAAE,IAAI,CAAC,EAAE;QACjB,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,EAAE,IAAI,EAAE;KAChB,CAAC;IAEF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,OAAO,KAAK,EACV,GAAY,EACZ,GAAa,EACb,IAAkB,EACH,EAAE;QACjB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG;iBACA,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC9C,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACrC,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACpE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,0BAA0B,CAAC,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,MAAM,EAAE,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.types.d.ts","sourceRoot":"","sources":["../../src/errors/errors.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,YAAY,GAAG,IAAI,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.types.js","sourceRoot":"","sources":["../../src/errors/errors.types.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAC;AA+D/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,WAAW,EAAE,OAAO,EACpB,IAAI,EAAE,aAAa,GAClB,cAAc,CAMhB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,SAAS,cAAc,CAAC,MAAoB,EAAE,IAAmB;IAC/D,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf;YACE,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,EACD,iBAAiB,CAClB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,CACd;YACE,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,EACD,mBAAmB,CACpB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB;IAC1C,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QACjD,iBAAiB,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,GAAY,EACZ,IAAmB;IAEnB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,KAAK,CACf;QACE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;QAC3C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,EACD,0BAA0B,CAC3B,CAAC;IACF,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iDAAiD,EAAE;SAC1E;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,cAAc;YACpB,OAAO;SACR;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,WAAoB,EACpB,IAAmB;IAEnB,IAAI,MAAM,EAAE,CAAC;QACX,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,oBAAoB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC"}
@@ -1,18 +0,0 @@
1
- import type { CreateMcpServerOptions, CreateMcpServerResult } from "./server.types.ts";
2
- /**
3
- * Build an MCP server bound to the Streamable HTTP transport.
4
- *
5
- * Returns a `{ server, mount }` pair. Register tools against `server` using
6
- * `tool()` at boot time, then call `mount(router)` to wire the JSON-RPC
7
- * endpoint onto an Express router. Each incoming HTTP request runs through:
8
- *
9
- * `express.json()` → auth middleware → caller's `setupPostgan` → tool dispatch
10
- *
11
- * Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
12
- * `user` / `postgan` / `transaction` / `sessionId` / `logger` from
13
- * `ToolContext` without Express objects leaking in.
14
- *
15
- * Synchronous and never throws.
16
- */
17
- export declare function createMcpServer(options: CreateMcpServerOptions): CreateMcpServerResult;
18
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EAKtB,MAAM,mBAAmB,CAAC;AA2G3B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAuBvB"}
@@ -1,130 +0,0 @@
1
- import express, {} from "express";
2
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
- import { mcpAuth } from "../auth/index.js";
5
- import { requestStore } from "../als.js";
6
- /**
7
- * Build the recording shim handed to consumers as `server`.
8
- *
9
- * Why a shim and not a real `McpServer`: the SDK's
10
- * `StreamableHTTPServerTransport` (stateless mode) is single-use — once it
11
- * has handled one request it cannot be reused. The transport must be paired
12
- * with an `McpServer`, so we need a fresh server per HTTP request. But
13
- * consumers register tools once at boot, not per request — so registration
14
- * is split in two:
15
- *
16
- * - boot: `tool(server, spec)` lands here and pushes onto `registrations`.
17
- * - request: {@link handleMcpRequest} constructs a real `McpServer` and
18
- * replays every recorded registration onto it before connecting
19
- * the transport.
20
- *
21
- * The recorder is typed as `McpServer` so `tool(server, spec)` type-checks,
22
- * but `registerTool` is the only method actually implemented. Nothing in
23
- * the library calls anything else on it, and the consumer is documented to
24
- * only pass it to `tool()` — calls to other methods are undefined behaviour.
25
- */
26
- function createToolRecorder() {
27
- const registrations = [];
28
- const recorder = {
29
- registerTool: (name, config, handler) => {
30
- registrations.push({ name, config, handler });
31
- // Real `registerTool` returns a registration handle for later
32
- // update/remove. We don't expose that surface — empty object satisfies
33
- // the return type and is never read.
34
- return {};
35
- },
36
- };
37
- return { server: recorder, registrations };
38
- }
39
- /**
40
- * Per-request handler. Builds the ALS store from `req.user` / `req.postgan`
41
- * (set upstream by the auth + setupPostgan middleware), spins up a fresh
42
- * `McpServer` + transport pair, replays the recorded tool registrations,
43
- * dispatches the JSON-RPC call inside `requestStore.run(...)`, and tears
44
- * down server + transport in `finally`.
45
- */
46
- function handleMcpRequest(deps) {
47
- return async (req, res) => {
48
- const { user, postgan } = req;
49
- if (!user || !postgan) {
50
- // Defensive: mcpAuth + setupPostgan should have populated both.
51
- res.status(401).json({ error: "Unauthenticated" });
52
- return;
53
- }
54
- const sessionId = req.mcpSessionId;
55
- const store = {
56
- user,
57
- postgan,
58
- sessionId,
59
- logger: deps.logger.child({
60
- sessionId,
61
- userId: user.id,
62
- company: user.companySubdomainName,
63
- }),
64
- errorMapper: deps.errorMapper,
65
- };
66
- const requestServer = new McpServer({
67
- name: deps.name,
68
- version: deps.version,
69
- });
70
- for (const reg of deps.registrations) {
71
- requestServer.registerTool(reg.name, reg.config, reg.handler);
72
- }
73
- const transport = new StreamableHTTPServerTransport({
74
- sessionIdGenerator: undefined,
75
- });
76
- await requestServer.connect(transport);
77
- await requestStore.run(store, async () => {
78
- try {
79
- await transport.handleRequest(req, res, req.body);
80
- }
81
- catch (err) {
82
- deps.logger.error({ err, sessionId }, "mcp: transport.handleRequest threw");
83
- if (!res.headersSent) {
84
- res.status(500).json({ error: "Internal MCP transport error" });
85
- }
86
- }
87
- finally {
88
- await transport.close().catch((closeErr) => {
89
- deps.logger.warn({ err: closeErr }, "mcp: transport close failed");
90
- });
91
- await requestServer.close().catch((closeErr) => {
92
- deps.logger.warn({ err: closeErr }, "mcp: server close failed");
93
- });
94
- }
95
- });
96
- };
97
- }
98
- /**
99
- * Build an MCP server bound to the Streamable HTTP transport.
100
- *
101
- * Returns a `{ server, mount }` pair. Register tools against `server` using
102
- * `tool()` at boot time, then call `mount(router)` to wire the JSON-RPC
103
- * endpoint onto an Express router. Each incoming HTTP request runs through:
104
- *
105
- * `express.json()` → auth middleware → caller's `setupPostgan` → tool dispatch
106
- *
107
- * Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
108
- * `user` / `postgan` / `transaction` / `sessionId` / `logger` from
109
- * `ToolContext` without Express objects leaking in.
110
- *
111
- * Synchronous and never throws.
112
- */
113
- export function createMcpServer(options) {
114
- const mcpLogger = options.logger.child({ component: "mcp" });
115
- const { server, registrations } = createToolRecorder();
116
- const mount = async (target) => {
117
- target.use(express.json());
118
- target.use(mcpAuth({ tokenToUser: options.tokenToUser, logger: mcpLogger }));
119
- target.use(options.setupPostgan);
120
- target.post("/", handleMcpRequest({
121
- name: options.name,
122
- version: options.version,
123
- registrations,
124
- logger: mcpLogger,
125
- errorMapper: options.errorMapper,
126
- }));
127
- };
128
- return { server, mount };
129
- }
130
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}