@ganintegrity/mcp 1.0.0 → 1.1.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.
- package/README.md +186 -60
- package/dist/core/als.d.ts.map +1 -0
- package/dist/core/als.js.map +1 -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 +33 -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 +64 -0
- package/dist/core/define.d.ts.map +1 -0
- package/dist/core/define.js +48 -0
- package/dist/core/define.js.map +1 -0
- package/dist/core/dispatch.d.ts +34 -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/core/errors/errors.types.d.ts.map +1 -0
- package/dist/core/errors/errors.types.js.map +1 -0
- package/dist/core/errors/index.d.ts.map +1 -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 +21 -0
- 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} +4 -5
- package/dist/express/auth.d.ts.map +1 -0
- package/dist/express/auth.js +47 -0
- package/dist/express/auth.js.map +1 -0
- package/dist/express/express.types.d.ts +35 -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 +32 -0
- package/dist/express/index.d.ts.map +1 -0
- package/dist/express/index.js +50 -0
- package/dist/express/index.js.map +1 -0
- package/dist/index.d.ts +13 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -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.d.ts → core/als.d.ts} +0 -0
- /package/dist/{als.js → core/als.js} +0 -0
- /package/dist/{auth → core/auth}/auth.types.d.ts +0 -0
- /package/dist/{auth → core/auth}/auth.types.js +0 -0
- /package/dist/{errors → core/errors}/errors.types.d.ts +0 -0
- /package/dist/{errors → core/errors}/errors.types.js +0 -0
- /package/dist/{errors → core/errors}/index.d.ts +0 -0
- /package/dist/{errors → core/errors}/index.js +0 -0
- /package/dist/{tool → core/tool}/tool.types.js +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
|
+
import { requestStore } from "./als.js";
|
|
3
|
+
import { materializeSdkServer } from "./define.js";
|
|
4
|
+
/**
|
|
5
|
+
* Framework-neutral per-request dispatcher.
|
|
6
|
+
*
|
|
7
|
+
* Builds the {@link RequestStore} from `scope` + `mcp.errorMapper`,
|
|
8
|
+
* materialises a fresh SDK `McpServer` (with all tools replayed onto it),
|
|
9
|
+
* connects a fresh transport, runs `invokeTransport` inside
|
|
10
|
+
* `requestStore.run(...)` so tool handlers can pull request context from
|
|
11
|
+
* ALS, and tears server + transport down in `finally`. A failing close is
|
|
12
|
+
* logged at warn but never re-thrown.
|
|
13
|
+
*
|
|
14
|
+
* If `invokeTransport` throws, the error is logged at error level and
|
|
15
|
+
* `onTransportError` is called so the framework adapter can write a 500
|
|
16
|
+
* onto its native response object (with whatever headers-sent guard it
|
|
17
|
+
* uses). The error is otherwise swallowed — this is the request boundary.
|
|
18
|
+
*
|
|
19
|
+
* Never throws.
|
|
20
|
+
*/
|
|
21
|
+
export async function dispatchMcpRequest(mcp, logger, scope, invokeTransport, onTransportError) {
|
|
22
|
+
const { user, postgan, sessionId } = scope;
|
|
23
|
+
const store = {
|
|
24
|
+
user,
|
|
25
|
+
postgan,
|
|
26
|
+
sessionId,
|
|
27
|
+
logger: logger.child({
|
|
28
|
+
sessionId,
|
|
29
|
+
userId: user.id,
|
|
30
|
+
company: user.companySubdomainName,
|
|
31
|
+
}),
|
|
32
|
+
errorMapper: mcp.errorMapper,
|
|
33
|
+
};
|
|
34
|
+
const requestServer = materializeSdkServer(mcp);
|
|
35
|
+
const transport = new StreamableHTTPServerTransport({
|
|
36
|
+
sessionIdGenerator: undefined,
|
|
37
|
+
});
|
|
38
|
+
await requestServer.connect(transport);
|
|
39
|
+
await requestStore.run(store, async () => {
|
|
40
|
+
try {
|
|
41
|
+
await invokeTransport(transport);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
logger.error({ err, sessionId }, "mcp: transport.handleRequest threw");
|
|
45
|
+
onTransportError();
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await transport.close().catch((closeErr) => {
|
|
49
|
+
logger.warn({ err: closeErr }, "mcp: transport close failed");
|
|
50
|
+
});
|
|
51
|
+
await requestServer.close().catch((closeErr) => {
|
|
52
|
+
logger.warn({ err: closeErr }, "mcp: server close failed");
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/core/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAInG,OAAO,EAAE,YAAY,EAAqB,MAAM,UAAU,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAsB,MAAM,aAAa,CAAC;AAavE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAkB,EAClB,MAAc,EACd,KAAoB,EACpB,eAA4E,EAC5E,gBAA4B;IAE5B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC3C,MAAM,KAAK,GAAiB;QAC1B,IAAI;QACJ,OAAO;QACP,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;YACnB,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,oBAAoB;SACnC,CAAC;QACF,WAAW,EAAE,GAAG,CAAC,WAAW;KAC7B,CAAC;IAEF,MAAM,aAAa,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;QAClD,kBAAkB,EAAE,SAAS;KAC9B,CAAC,CAAC;IACH,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,MAAM,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,oCAAoC,CAAC,CAAC;YACvE,gBAAgB,EAAE,CAAC;QACrB,CAAC;gBAAS,CAAC;YACT,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,QAAiB,EAAE,EAAE;gBAClD,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,6BAA6B,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,QAAiB,EAAE,EAAE;gBACtD,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,0BAA0B,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.types.d.ts","sourceRoot":"","sources":["../../../src/core/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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.types.js","sourceRoot":"","sources":["../../../src/core/errors/errors.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
import type { Logger } from "pino";
|
|
3
|
+
/**
|
|
4
|
+
* A pino-shaped mock logger. `child()` returns the same logger so assertions
|
|
5
|
+
* on `logger.error` capture calls from child loggers too — required for
|
|
6
|
+
* tests that exercise code paths which child the logger before logging.
|
|
7
|
+
*/
|
|
8
|
+
export declare function makeLogger(): Logger;
|
|
9
|
+
export interface MockTransaction {
|
|
10
|
+
active: boolean;
|
|
11
|
+
begin: ReturnType<typeof vi.fn>;
|
|
12
|
+
commit: ReturnType<typeof vi.fn>;
|
|
13
|
+
rollback: ReturnType<typeof vi.fn>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Mock postgan transaction with `commit` / `rollback` flipping `active` to
|
|
17
|
+
* false to mirror real postgan behaviour.
|
|
18
|
+
*/
|
|
19
|
+
export declare function makeTransaction(): MockTransaction;
|
|
20
|
+
//# sourceMappingURL=test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../src/core/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAanC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACjC,QAAQ,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAYjD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
/**
|
|
3
|
+
* A pino-shaped mock logger. `child()` returns the same logger so assertions
|
|
4
|
+
* on `logger.error` capture calls from child loggers too — required for
|
|
5
|
+
* tests that exercise code paths which child the logger before logging.
|
|
6
|
+
*/
|
|
7
|
+
export function makeLogger() {
|
|
8
|
+
const logger = {
|
|
9
|
+
info: vi.fn(),
|
|
10
|
+
warn: vi.fn(),
|
|
11
|
+
error: vi.fn(),
|
|
12
|
+
debug: vi.fn(),
|
|
13
|
+
fatal: vi.fn(),
|
|
14
|
+
trace: vi.fn(),
|
|
15
|
+
};
|
|
16
|
+
// Cast through `Logger["child"]` because pino's child is generic over a
|
|
17
|
+
// custom-levels type parameter that vi.fn() can't satisfy directly.
|
|
18
|
+
logger.child = vi.fn(() => logger);
|
|
19
|
+
return logger;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Mock postgan transaction with `commit` / `rollback` flipping `active` to
|
|
23
|
+
* false to mirror real postgan behaviour.
|
|
24
|
+
*/
|
|
25
|
+
export function makeTransaction() {
|
|
26
|
+
const tx = {
|
|
27
|
+
active: true,
|
|
28
|
+
begin: vi.fn().mockResolvedValue(undefined),
|
|
29
|
+
commit: vi.fn().mockImplementation(async () => {
|
|
30
|
+
tx.active = false;
|
|
31
|
+
}),
|
|
32
|
+
rollback: vi.fn().mockImplementation(async () => {
|
|
33
|
+
tx.active = false;
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
return tx;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/core/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG5B;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAoB;QAC9B,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACf,CAAC;IACF,wEAAwE;IACxE,oEAAoE;IACpE,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAgB,CAA+B,CAAC;IAC3E,OAAO,MAAgB,CAAC;AAC1B,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,GAAoB;QAC1B,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC3C,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE;YAC5C,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,CAAC,CAAC;QACF,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE;YAC9C,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,CAAC,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { ToolRegistration, ToolSpec } from "./tool.types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Wrap a {@link ToolSpec} into an SDK-shaped {@link ToolRegistration}. The
|
|
5
|
+
* wrapped handler:
|
|
6
|
+
*
|
|
7
|
+
* 1. Reads the active request scope from `requestStore` (ALS).
|
|
8
|
+
* 2. Opens a fresh `Postgan.Transaction`.
|
|
9
|
+
* 3. Builds a {@link ToolContext} and invokes the consumer's handler.
|
|
10
|
+
* 4. Commits on resolve and returns a `CallToolResult` carrying the result
|
|
11
|
+
* as both a JSON `text` block and `structuredContent`.
|
|
12
|
+
* 5. On throw: rolls back the transaction and routes the error through the
|
|
13
|
+
* request store's `errorMapper` to build an error envelope.
|
|
14
|
+
*
|
|
15
|
+
* Internal — `defineMcpServer`'s `register.tool(spec)` calls this and
|
|
16
|
+
* pushes the result onto the definition's registration array.
|
|
17
|
+
*/
|
|
18
|
+
export declare function wrapToolHandler<Schema extends z.ZodObject, Output extends Record<string, unknown>>(spec: ToolSpec<Schema, Output>): ToolRegistration;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tool/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,KAAK,EAAe,gBAAgB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AA6B/E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,MAAM,SAAS,CAAC,CAAC,SAAS,EAC1B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,CA0DlD"}
|
|
@@ -24,35 +24,25 @@ async function withTransaction(postgan, logger, body) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* Wrap a {@link ToolSpec} into an SDK-shaped {@link ToolRegistration}. The
|
|
28
|
+
* wrapped handler:
|
|
29
29
|
*
|
|
30
|
-
* 1.
|
|
31
|
-
* 2. Opens a fresh `Postgan.Transaction
|
|
32
|
-
* 3.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* the consumer's `McpErrorMapper` (passed to `createMcpServer`) to
|
|
38
|
-
* build an MCP error envelope.
|
|
30
|
+
* 1. Reads the active request scope from `requestStore` (ALS).
|
|
31
|
+
* 2. Opens a fresh `Postgan.Transaction`.
|
|
32
|
+
* 3. Builds a {@link ToolContext} and invokes the consumer's handler.
|
|
33
|
+
* 4. Commits on resolve and returns a `CallToolResult` carrying the result
|
|
34
|
+
* as both a JSON `text` block and `structuredContent`.
|
|
35
|
+
* 5. On throw: rolls back the transaction and routes the error through the
|
|
36
|
+
* request store's `errorMapper` to build an error envelope.
|
|
39
37
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* active request scope, which indicates a programming bug (the handler was
|
|
43
|
-
* dispatched without going through `mount()`'s ALS wrapper). Such throws
|
|
44
|
-
* propagate to the SDK transport and surface as an HTTP 500. Errors raised
|
|
45
|
-
* by your own handler logic are caught and never propagate.
|
|
38
|
+
* Internal — `defineMcpServer`'s `register.tool(spec)` calls this and
|
|
39
|
+
* pushes the result onto the definition's registration array.
|
|
46
40
|
*/
|
|
47
|
-
export function
|
|
48
|
-
|
|
49
|
-
description: spec.description,
|
|
50
|
-
inputSchema: spec.inputSchema.shape,
|
|
51
|
-
...(spec.annotations ? { annotations: spec.annotations } : {}),
|
|
52
|
-
}, async (args, extra) => {
|
|
41
|
+
export function wrapToolHandler(spec) {
|
|
42
|
+
const handler = async (args, extra) => {
|
|
53
43
|
const store = requestStore.getStore();
|
|
54
44
|
if (!store) {
|
|
55
|
-
// Unreachable:
|
|
45
|
+
// Unreachable in practice: adapters always wrap dispatch in
|
|
56
46
|
// requestStore.run(). Throw to surface the bug rather than silently
|
|
57
47
|
// returning an error envelope without a logger.
|
|
58
48
|
throw new Error("mcp tool invoked outside request scope");
|
|
@@ -83,6 +73,19 @@ export function tool(server, spec) {
|
|
|
83
73
|
logger,
|
|
84
74
|
});
|
|
85
75
|
}
|
|
86
|
-
}
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
name: spec.name,
|
|
79
|
+
config: {
|
|
80
|
+
description: spec.description,
|
|
81
|
+
inputSchema: spec.inputSchema.shape,
|
|
82
|
+
...(spec.annotations ? { annotations: spec.annotations } : {}),
|
|
83
|
+
},
|
|
84
|
+
// Cast: ToolRegistration intentionally uses loose types because the
|
|
85
|
+
// SDK's `registerTool` is generically overloaded; the cast at this
|
|
86
|
+
// boundary lets the wrapped handler's specific signature flow through
|
|
87
|
+
// unchanged at the SDK call site in `materializeSdkServer`.
|
|
88
|
+
handler: handler,
|
|
89
|
+
};
|
|
87
90
|
}
|
|
88
91
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tool/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -69,4 +69,25 @@ export interface ToolSpec<Schema extends z.ZodObject, Output> {
|
|
|
69
69
|
*/
|
|
70
70
|
handler: (args: z.infer<Schema>, ctx: ToolContext) => Promise<Output>;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Internal data shape produced by `wrapToolHandler` and held on
|
|
74
|
+
* `McpDefinition.registrations`. Loose types here — the SDK's
|
|
75
|
+
* `registerTool` is generically overloaded so `Parameters<>` resolves
|
|
76
|
+
* unhelpfully; `materializeSdkServer` casts at the boundary.
|
|
77
|
+
*
|
|
78
|
+
* Consumers never construct or inspect `ToolRegistration` directly.
|
|
79
|
+
*/
|
|
80
|
+
export interface ToolRegistration {
|
|
81
|
+
name: string;
|
|
82
|
+
config: object;
|
|
83
|
+
handler: (...args: unknown[]) => Promise<unknown>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* What `defineMcpServer({ tools })` hands to its callback. The single
|
|
87
|
+
* `tool(spec)` method captures each registration into the underlying
|
|
88
|
+
* {@link McpDefinition}.
|
|
89
|
+
*/
|
|
90
|
+
export interface ToolRegister {
|
|
91
|
+
tool<Schema extends z.ZodObject, Output extends Record<string, unknown>>(spec: ToolSpec<Schema, Output>): void;
|
|
92
|
+
}
|
|
72
93
|
//# sourceMappingURL=tool.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.types.d.ts","sourceRoot":"","sources":["../../../src/core/tool/tool.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,IAAI,EAAE,QAAQ,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,WAAW,EAAE,kBAAkB,CAAC;IAChC,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oFAAoF;IACpF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM;IAC1D,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;;;OAKG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACnD;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAAC;CACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.types.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"tool.types.js","sourceRoot":"","sources":["../../../src/core/tool/tool.types.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { RequestHandler } from "express";
|
|
2
|
-
import type { McpAuthOptions } from "
|
|
2
|
+
import type { McpAuthOptions } from "../core/auth/auth.types.ts";
|
|
3
3
|
/**
|
|
4
4
|
* Bearer-token auth middleware for the MCP HTTP endpoint.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
* does not call `next`.
|
|
6
|
+
* Reads `Authorization: Bearer <token>`. If absent the middleware responds
|
|
7
|
+
* `401` and does not call `next`.
|
|
9
8
|
*
|
|
10
9
|
* On success it sets:
|
|
11
10
|
* - `req.user` — the resolved {@link AuthUser}
|
|
@@ -26,4 +25,4 @@ import type { McpAuthOptions } from "./auth.types.ts";
|
|
|
26
25
|
* or stack additional middleware).
|
|
27
26
|
*/
|
|
28
27
|
export declare function mcpAuth(options: McpAuthOptions): RequestHandler;
|
|
29
|
-
//# sourceMappingURL=
|
|
28
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/express/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAG/E,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAwB/D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
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 {@link AuthUser}
|
|
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 `createMcpServer`'s `mount()`. Exported in case
|
|
23
|
+
* you want to compose it differently (e.g. mount under a different router,
|
|
24
|
+
* or stack additional middleware).
|
|
25
|
+
*/
|
|
26
|
+
export function mcpAuth(options) {
|
|
27
|
+
return async (req, res, next) => {
|
|
28
|
+
const result = await resolveAuth(req.headers, options);
|
|
29
|
+
if (!result.ok) {
|
|
30
|
+
res.status(result.status).json({ error: result.message });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
req.user = result.user;
|
|
34
|
+
req.headers.company = result.user.companySubdomainName;
|
|
35
|
+
req.auth = {
|
|
36
|
+
token: result.token,
|
|
37
|
+
clientId: result.user.id,
|
|
38
|
+
scopes: [],
|
|
39
|
+
extra: { user: result.user },
|
|
40
|
+
};
|
|
41
|
+
if (result.sessionId) {
|
|
42
|
+
req.mcpSessionId = result.sessionId;
|
|
43
|
+
}
|
|
44
|
+
next();
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# 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;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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,35 @@
|
|
|
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
|
+
export interface CreateMcpRouterOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Service logger. The library calls `logger.child({ component: "mcp" })`
|
|
14
|
+
* internally and further childs with `sessionId` / `userId` / `company`
|
|
15
|
+
* per request and with `tool` / `sessionId` per tool call.
|
|
16
|
+
*/
|
|
17
|
+
logger: Logger;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a bearer token to a user. The library is neutral about how
|
|
20
|
+
* tokens are verified — plug in your service's existing JWT/cipher/identity
|
|
21
|
+
* pipeline. Reject by throwing — the router responds `401`.
|
|
22
|
+
*/
|
|
23
|
+
tokenToUser: (token: string) => Promise<AuthUser>;
|
|
24
|
+
/**
|
|
25
|
+
* Express middleware that attaches a `Postgan` instance to `req.postgan`.
|
|
26
|
+
* Mounted between auth and the JSON-RPC dispatcher; tools open per-call
|
|
27
|
+
* transactions against `ctx.postgan`.
|
|
28
|
+
*/
|
|
29
|
+
setupPostgan: RequestHandler;
|
|
30
|
+
}
|
|
31
|
+
export type ReqWithUserPostgan = Request & {
|
|
32
|
+
user?: AuthUser;
|
|
33
|
+
postgan?: Postgan;
|
|
34
|
+
};
|
|
35
|
+
//# 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;;;;;GAKG;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,32 @@
|
|
|
1
|
+
import { type Router } from "express";
|
|
2
|
+
import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
|
|
3
|
+
import { mcpAuth } from "./auth.ts";
|
|
4
|
+
import type { McpDefinition } from "../core/define.ts";
|
|
5
|
+
import type { CreateMcpRouterOptions } from "./express.types.ts";
|
|
6
|
+
declare global {
|
|
7
|
+
namespace Express {
|
|
8
|
+
interface Request {
|
|
9
|
+
mcpSessionId?: string;
|
|
10
|
+
auth?: AuthInfo;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export { mcpAuth };
|
|
15
|
+
export type { CreateMcpRouterOptions } from "./express.types.ts";
|
|
16
|
+
/**
|
|
17
|
+
* Build an Express router that serves an {@link McpDefinition}. Mount the
|
|
18
|
+
* returned router on whatever path you like
|
|
19
|
+
* (`app.use("/mcp", createMcpRouter(mcp, opts))`).
|
|
20
|
+
*
|
|
21
|
+
* Each request runs through:
|
|
22
|
+
*
|
|
23
|
+
* `express.json()` → `mcpAuth` → caller's `setupPostgan` → tool dispatch
|
|
24
|
+
*
|
|
25
|
+
* Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
|
|
26
|
+
* `user` / `postgan` / `transaction` / `sessionId` / `logger` from
|
|
27
|
+
* `ToolContext` without Express objects leaking in.
|
|
28
|
+
*
|
|
29
|
+
* Synchronous and never throws.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createMcpRouter(mcp: McpDefinition, options: CreateMcpRouterOptions): Router;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA,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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAQR"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import express, {} from "express";
|
|
2
|
+
import { mcpAuth } from "./auth.js";
|
|
3
|
+
import { dispatchMcpRequest } from "../core/dispatch.js";
|
|
4
|
+
export { mcpAuth };
|
|
5
|
+
/**
|
|
6
|
+
* Express adapter around {@link dispatchMcpRequest}: pulls `user` /
|
|
7
|
+
* `postgan` / `mcpSessionId` off the request (set upstream by the auth
|
|
8
|
+
* middleware and `setupPostgan`), then hands the SDK transport an Express
|
|
9
|
+
* `req`/`res` pair via the dispatcher's `invokeTransport` callback.
|
|
10
|
+
*/
|
|
11
|
+
function handleMcpRequest(mcp, logger) {
|
|
12
|
+
return async (req, res) => {
|
|
13
|
+
const { user, postgan } = req;
|
|
14
|
+
if (!user || !postgan) {
|
|
15
|
+
// Defensive: mcpAuth + setupPostgan should have populated both.
|
|
16
|
+
res.status(401).json({ error: "Unauthenticated" });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
await dispatchMcpRequest(mcp, logger, { user, postgan, sessionId: req.mcpSessionId }, (transport) => transport.handleRequest(req, res, req.body), () => {
|
|
20
|
+
if (!res.headersSent) {
|
|
21
|
+
res.status(500).json({ error: "Internal MCP transport error" });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build an Express router that serves an {@link McpDefinition}. Mount the
|
|
28
|
+
* returned router on whatever path you like
|
|
29
|
+
* (`app.use("/mcp", createMcpRouter(mcp, opts))`).
|
|
30
|
+
*
|
|
31
|
+
* Each request runs through:
|
|
32
|
+
*
|
|
33
|
+
* `express.json()` → `mcpAuth` → caller's `setupPostgan` → tool dispatch
|
|
34
|
+
*
|
|
35
|
+
* Tool handlers run inside an `AsyncLocalStorage` scope, so they pull
|
|
36
|
+
* `user` / `postgan` / `transaction` / `sessionId` / `logger` from
|
|
37
|
+
* `ToolContext` without Express objects leaking in.
|
|
38
|
+
*
|
|
39
|
+
* Synchronous and never throws.
|
|
40
|
+
*/
|
|
41
|
+
export function createMcpRouter(mcp, options) {
|
|
42
|
+
const mcpLogger = options.logger.child({ component: "mcp" });
|
|
43
|
+
const router = express.Router();
|
|
44
|
+
router.use(express.json());
|
|
45
|
+
router.use(mcpAuth({ tokenToUser: options.tokenToUser, logger: mcpLogger }));
|
|
46
|
+
router.use(options.setupPostgan);
|
|
47
|
+
router.post("/", handleMcpRequest(mcp, mcpLogger));
|
|
48
|
+
return router;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA,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;;;;;;;;;;;;;;GAcG;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,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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. Tool definitions, error envelope plumbing, and
|
|
3
|
+
* the types every adapter shares live here. Bootstrap files importing the
|
|
4
|
+
* adapter factory should reach for a per-framework subpath
|
|
5
|
+
* (`@ganintegrity/mcp/express`); tool files import from this root.
|
|
6
|
+
*/
|
|
7
|
+
export { defineMcpServer, materializeSdkServer } from "./core/define.ts";
|
|
8
|
+
export type { DefineMcpServerOptions, McpDefinition } from "./core/define.ts";
|
|
9
|
+
export type { ToolSpec, ToolAnnotations, ToolContext, ToolRegister, } from "./core/tool/tool.types.ts";
|
|
14
10
|
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";
|
|
11
|
+
export type { AuthUser, McpAuthOptions } from "./core/auth/auth.types.ts";
|
|
12
|
+
export { INTERNAL_ERROR, toCallToolError } from "./core/errors/index.ts";
|
|
13
|
+
export type { McpErrorMapper, McpToolError, McpToolErrorSeverity, ToolErrorMeta, } from "./core/errors/errors.types.ts";
|
|
14
|
+
export type { RequestStore } from "./core/als.ts";
|
|
20
15
|
//# 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;;;;;GAKG;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,GACb,MAAM,2BAA2B,CAAC;AAEnC,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,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Framework-neutral entry. Tool definitions, error envelope plumbing, and
|
|
3
|
+
* the types every adapter shares live here. Bootstrap files importing the
|
|
4
|
+
* adapter factory should reach for a per-framework subpath
|
|
5
|
+
* (`@ganintegrity/mcp/express`); tool files import from this root.
|
|
6
|
+
*/
|
|
7
|
+
export { defineMcpServer, materializeSdkServer } from "./core/define.js";
|
|
8
|
+
export { INTERNAL_ERROR, toCallToolError } from "./core/errors/index.js";
|
|
5
9
|
//# 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;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAczE,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.0",
|
|
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": [
|
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"}
|