@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.
- package/README.md +191 -84
- package/dist/{als.d.ts → core/als.d.ts} +11 -4
- package/dist/core/als.d.ts.map +1 -0
- package/dist/core/als.js.map +1 -0
- package/dist/{auth → core/auth}/auth.types.d.ts +6 -0
- package/dist/core/auth/auth.types.d.ts.map +1 -0
- package/dist/{auth → core/auth}/auth.types.js.map +1 -1
- package/dist/core/auth/index.d.ts +34 -0
- package/dist/core/auth/index.d.ts.map +1 -0
- package/dist/core/auth/index.js +57 -0
- package/dist/core/auth/index.js.map +1 -0
- package/dist/core/define.d.ts +80 -0
- package/dist/core/define.d.ts.map +1 -0
- package/dist/core/define.js +52 -0
- package/dist/core/define.js.map +1 -0
- package/dist/core/dispatch.d.ts +35 -0
- package/dist/core/dispatch.d.ts.map +1 -0
- package/dist/core/dispatch.js +57 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/{errors → core/errors}/errors.types.d.ts +21 -0
- package/dist/core/errors/errors.types.d.ts.map +1 -0
- package/dist/core/errors/errors.types.js.map +1 -0
- package/dist/{errors → core/errors}/index.d.ts +4 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/{errors → core/errors}/index.js +4 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/test-helpers.d.ts +20 -0
- package/dist/core/test-helpers.d.ts.map +1 -0
- package/dist/core/test-helpers.js +38 -0
- package/dist/core/test-helpers.js.map +1 -0
- package/dist/core/tool/index.d.ts +19 -0
- package/dist/core/tool/index.d.ts.map +1 -0
- package/dist/{tool → core/tool}/index.js +28 -25
- package/dist/core/tool/index.js.map +1 -0
- package/dist/{tool → core/tool}/tool.types.d.ts +38 -2
- package/dist/core/tool/tool.types.d.ts.map +1 -0
- package/dist/{tool → core/tool}/tool.types.js.map +1 -1
- package/dist/{auth/index.d.ts → express/auth.d.ts} +10 -9
- package/dist/express/auth.d.ts.map +1 -0
- package/dist/express/auth.js +49 -0
- package/dist/express/auth.js.map +1 -0
- package/dist/express/express.types.d.ts +37 -0
- package/dist/express/express.types.d.ts.map +1 -0
- package/dist/express/express.types.js +2 -0
- package/dist/express/express.types.js.map +1 -0
- package/dist/express/index.d.ts +41 -0
- package/dist/express/index.d.ts.map +1 -0
- package/dist/express/index.js +59 -0
- package/dist/express/index.js.map +1 -0
- package/dist/index.d.ts +21 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/package.json +8 -1
- package/dist/als.d.ts.map +0 -1
- package/dist/als.js.map +0 -1
- package/dist/auth/auth.types.d.ts.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -74
- package/dist/auth/index.js.map +0 -1
- package/dist/errors/errors.types.d.ts.map +0 -1
- package/dist/errors/errors.types.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/server/index.d.ts +0 -18
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -130
- package/dist/server/index.js.map +0 -1
- package/dist/server/server.types.d.ts +0 -78
- package/dist/server/server.types.d.ts.map +0 -1
- package/dist/server/server.types.js +0 -2
- package/dist/server/server.types.js.map +0 -1
- package/dist/tool/index.d.ts +0 -26
- package/dist/tool/index.d.ts.map +0 -1
- package/dist/tool/index.js.map +0 -1
- package/dist/tool/tool.types.d.ts.map +0 -1
- /package/dist/{als.js → core/als.js} +0 -0
- /package/dist/{auth → core/auth}/auth.types.js +0 -0
- /package/dist/{errors → core/errors}/errors.types.js +0 -0
- /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 @@
|
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
export {
|
|
11
|
-
export type {
|
|
12
|
-
|
|
13
|
-
|
|
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 {
|
|
16
|
-
export
|
|
17
|
-
export {
|
|
18
|
-
export type {
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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":"
|
|
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.
|
|
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"}
|
package/dist/auth/index.d.ts.map
DELETED
|
@@ -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"}
|
package/dist/auth/index.js
DELETED
|
@@ -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
|
package/dist/auth/index.js.map
DELETED
|
@@ -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"}
|
package/dist/errors/index.js.map
DELETED
|
@@ -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"}
|
package/dist/server/index.d.ts
DELETED
|
@@ -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"}
|
package/dist/server/index.js
DELETED
|
@@ -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
|
package/dist/server/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|