@forumone/throughline-core 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +104 -28
  4. package/dist/audit/collection.d.ts +19 -0
  5. package/dist/audit/collection.d.ts.map +1 -0
  6. package/dist/audit/collection.js +107 -0
  7. package/dist/audit/collection.js.map +1 -0
  8. package/dist/audit/index.d.ts +9 -0
  9. package/dist/audit/index.d.ts.map +1 -0
  10. package/dist/audit/index.js +5 -0
  11. package/dist/audit/index.js.map +1 -0
  12. package/dist/audit/plugin.d.ts +20 -0
  13. package/dist/audit/plugin.d.ts.map +1 -0
  14. package/dist/audit/plugin.js +55 -0
  15. package/dist/audit/plugin.js.map +1 -0
  16. package/dist/audit/types.d.ts +11 -0
  17. package/dist/audit/types.d.ts.map +1 -0
  18. package/dist/audit/types.js +44 -0
  19. package/dist/audit/types.js.map +1 -0
  20. package/dist/audit/writer.d.ts +50 -0
  21. package/dist/audit/writer.d.ts.map +1 -0
  22. package/dist/audit/writer.js +101 -0
  23. package/dist/audit/writer.js.map +1 -0
  24. package/dist/auth/api-keys.d.ts +21 -0
  25. package/dist/auth/api-keys.d.ts.map +1 -0
  26. package/dist/auth/api-keys.js +115 -0
  27. package/dist/auth/api-keys.js.map +1 -0
  28. package/dist/auth/authenticator.d.ts +15 -0
  29. package/dist/auth/authenticator.d.ts.map +1 -0
  30. package/dist/auth/authenticator.js +63 -0
  31. package/dist/auth/authenticator.js.map +1 -0
  32. package/dist/auth/index.d.ts +5 -0
  33. package/dist/auth/index.d.ts.map +1 -0
  34. package/dist/auth/index.js +3 -0
  35. package/dist/auth/index.js.map +1 -0
  36. package/dist/env/index.d.ts +51 -0
  37. package/dist/env/index.d.ts.map +1 -0
  38. package/dist/env/index.js +59 -0
  39. package/dist/env/index.js.map +1 -0
  40. package/dist/events/index.d.ts +4 -0
  41. package/dist/events/index.d.ts.map +1 -0
  42. package/dist/events/index.js +2 -0
  43. package/dist/events/index.js.map +1 -0
  44. package/dist/events/inngest.d.ts +24 -0
  45. package/dist/events/inngest.d.ts.map +1 -0
  46. package/dist/events/inngest.js +24 -0
  47. package/dist/events/inngest.js.map +1 -0
  48. package/dist/events/taxonomy.d.ts +84 -0
  49. package/dist/events/taxonomy.d.ts.map +1 -0
  50. package/dist/events/taxonomy.js +10 -0
  51. package/dist/events/taxonomy.js.map +1 -0
  52. package/dist/index.d.ts +14 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +10 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/logger/index.d.ts +9 -0
  57. package/dist/logger/index.d.ts.map +1 -0
  58. package/dist/logger/index.js +41 -0
  59. package/dist/logger/index.js.map +1 -0
  60. package/dist/mcp/handler.d.ts +20 -0
  61. package/dist/mcp/handler.d.ts.map +1 -0
  62. package/dist/mcp/handler.js +109 -0
  63. package/dist/mcp/handler.js.map +1 -0
  64. package/dist/mcp/index.d.ts +5 -0
  65. package/dist/mcp/index.d.ts.map +1 -0
  66. package/dist/mcp/index.js +3 -0
  67. package/dist/mcp/index.js.map +1 -0
  68. package/dist/mcp/meta.d.ts +74 -0
  69. package/dist/mcp/meta.d.ts.map +1 -0
  70. package/dist/mcp/meta.js +27 -0
  71. package/dist/mcp/meta.js.map +1 -0
  72. package/dist/utils/diff.d.ts +13 -0
  73. package/dist/utils/diff.d.ts.map +1 -0
  74. package/dist/utils/diff.js +31 -0
  75. package/dist/utils/diff.js.map +1 -0
  76. package/dist/utils/id.d.ts +6 -0
  77. package/dist/utils/id.d.ts.map +1 -0
  78. package/dist/utils/id.js +13 -0
  79. package/dist/utils/id.js.map +1 -0
  80. package/dist/utils/index.d.ts +3 -0
  81. package/dist/utils/index.d.ts.map +1 -0
  82. package/dist/utils/index.js +3 -0
  83. package/dist/utils/index.js.map +1 -0
  84. package/package.json +82 -7
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Canonical event taxonomy for Throughline. Server packages add their own
3
+ * events via TypeScript module augmentation — see {@link FrameworkEvents}.
4
+ *
5
+ * The runtime client (created by `createInngestClient`) does not enforce
6
+ * this taxonomy at type-check time; the interface is for documentation and
7
+ * for callers who want to type-check their own `inngest.send(...)` calls.
8
+ */
9
+ export interface CoreEvents {
10
+ /** Fired by the audit writer after every audit-log entry is persisted. */
11
+ 'audit/event.recorded': {
12
+ data: {
13
+ auditEventId: string;
14
+ action: string;
15
+ actorId?: string;
16
+ targetCollection?: string;
17
+ targetId?: string;
18
+ approvalRequestId?: string;
19
+ integrationId?: string;
20
+ };
21
+ };
22
+ /** Fired by the publishing server when a page is published. */
23
+ 'content/page.published': {
24
+ data: {
25
+ collection: string;
26
+ id: string;
27
+ slug: string;
28
+ publishedBy: string;
29
+ previousPublishedAt: string | null;
30
+ isFirstPublish: boolean;
31
+ };
32
+ };
33
+ /** Fired when a page is unpublished or reverted to draft. */
34
+ 'content/page.unpublished': {
35
+ data: {
36
+ collection: string;
37
+ id: string;
38
+ slug: string;
39
+ unpublishedBy: string;
40
+ };
41
+ };
42
+ /** Fired when a publish is scheduled for a future time. */
43
+ 'content/page.scheduled': {
44
+ data: {
45
+ collection: string;
46
+ id: string;
47
+ scheduledFor: string;
48
+ };
49
+ };
50
+ /** Fired when a page is rolled back to a previous version. */
51
+ 'content/page.rolled_back': {
52
+ data: {
53
+ collection: string;
54
+ id: string;
55
+ rolledBackBy: string;
56
+ toVersionId: string;
57
+ };
58
+ };
59
+ /** Periodic system healthcheck event. */
60
+ 'system/healthcheck': {
61
+ data: {
62
+ source: string;
63
+ timestamp: string;
64
+ };
65
+ };
66
+ }
67
+ /**
68
+ * Framework-wide event taxonomy. Server packages extend this interface via
69
+ * TypeScript module augmentation:
70
+ *
71
+ * ```ts
72
+ * declare module '@forumone/throughline-core/events' {
73
+ * interface FrameworkEvents {
74
+ * 'approval/decided': { data: { approvalId: string; decision: 'granted' | 'declined' } }
75
+ * }
76
+ * }
77
+ * ```
78
+ *
79
+ * After augmentation, callers in any package can `inngest.send({ name: 'approval/decided', data: ... })`
80
+ * and TypeScript will type-check the payload against the merged set.
81
+ */
82
+ export interface FrameworkEvents extends CoreEvents {
83
+ }
84
+ //# sourceMappingURL=taxonomy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taxonomy.d.ts","sourceRoot":"","sources":["../../src/events/taxonomy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,sBAAsB,EAAE;QACtB,IAAI,EAAE;YACJ,YAAY,EAAE,MAAM,CAAA;YACpB,MAAM,EAAE,MAAM,CAAA;YACd,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;YACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;YACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;YAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;SACvB,CAAA;KACF,CAAA;IACD,+DAA+D;IAC/D,wBAAwB,EAAE;QACxB,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM,CAAA;YAClB,EAAE,EAAE,MAAM,CAAA;YACV,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,CAAA;YACnB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;YAClC,cAAc,EAAE,OAAO,CAAA;SACxB,CAAA;KACF,CAAA;IACD,6DAA6D;IAC7D,0BAA0B,EAAE;QAC1B,IAAI,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,aAAa,EAAE,MAAM,CAAA;SAAE,CAAA;KAC9E,CAAA;IACD,2DAA2D;IAC3D,wBAAwB,EAAE;QACxB,IAAI,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAA;KAC/D,CAAA;IACD,8DAA8D;IAC9D,0BAA0B,EAAE;QAC1B,IAAI,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;KACpF,CAAA;IACD,yCAAyC;IACzC,oBAAoB,EAAE;QACpB,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAC5C,CAAA;CACF;AAED;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,eAAgB,SAAQ,UAAU;CAAG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Canonical event taxonomy for Throughline. Server packages add their own
3
+ * events via TypeScript module augmentation — see {@link FrameworkEvents}.
4
+ *
5
+ * The runtime client (created by `createInngestClient`) does not enforce
6
+ * this taxonomy at type-check time; the interface is for documentation and
7
+ * for callers who want to type-check their own `inngest.send(...)` calls.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=taxonomy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taxonomy.js","sourceRoot":"","sources":["../../src/events/taxonomy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,14 @@
1
+ export { AUDIT_ACTIONS, AUDIT_MCP_SERVERS, DEFAULT_AUDIT_SLUG, auditPlugin, createAuditCollection, createAuditWriter, getAuditWriter, } from './audit/index.js';
2
+ export type { AuditAction, AuditActor, AuditCollectionOptions, AuditEventInput, AuditMcpServer, AuditPluginOptions, AuditWriter, AuditWriterOptions, } from './audit/index.js';
3
+ export { DEFAULT_API_KEYS_SLUG, createApiKeysCollection, createBearerTokenAuthenticator, generateApiKey, sha256Hex, } from './auth/index.js';
4
+ export type { ApiKeysCollectionOptions, BearerTokenAuthenticatorOptions } from './auth/index.js';
5
+ export { ENV_VARS, validateBaseEnv, requireEnv, optionalEnv } from './env/index.js';
6
+ export type { EnvVarName, BaseEnv } from './env/index.js';
7
+ export { createInngestClient } from './events/index.js';
8
+ export type { CoreEvents, FrameworkEvents, InngestClientOptions } from './events/index.js';
9
+ export { McpMetaSchema, createMcpHandler, withMeta } from './mcp/index.js';
10
+ export type { McpHandlerOptions, McpMeta } from './mcp/index.js';
11
+ export { defaultLogger, createNamedLogger } from './logger/index.js';
12
+ export { shallowDiff, generateId } from './utils/index.js';
13
+ export type { AuthenticatedUser, BaseCorePluginOptions, CorePlugin, Logger, McpAuthResult, McpAuthenticator, McpToolContext, McpToolDefinition, PluginRegistry, PluginRegistryEntry, } from '@forumone/throughline-plugin-contract';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACV,WAAW,EACX,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,cAAc,EACd,SAAS,GACV,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAA;AAEhG,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACnF,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAE1F,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC1E,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAI1D,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,MAAM,EACN,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,mBAAmB,GACpB,MAAM,uCAAuC,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // Subsystems are re-exported as they are added during C4. The aggregated
2
+ // surface here mirrors the package's `./<subpath>` exports.
3
+ export { AUDIT_ACTIONS, AUDIT_MCP_SERVERS, DEFAULT_AUDIT_SLUG, auditPlugin, createAuditCollection, createAuditWriter, getAuditWriter, } from './audit/index.js';
4
+ export { DEFAULT_API_KEYS_SLUG, createApiKeysCollection, createBearerTokenAuthenticator, generateApiKey, sha256Hex, } from './auth/index.js';
5
+ export { ENV_VARS, validateBaseEnv, requireEnv, optionalEnv } from './env/index.js';
6
+ export { createInngestClient } from './events/index.js';
7
+ export { McpMetaSchema, createMcpHandler, withMeta } from './mcp/index.js';
8
+ export { defaultLogger, createNamedLogger } from './logger/index.js';
9
+ export { shallowDiff, generateId } from './utils/index.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4DAA4D;AAE5D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAA;AAYzB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,cAAc,EACd,SAAS,GACV,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAGnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAGvD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAG1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { Logger } from '@forumone/throughline-plugin-contract';
2
+ /** Default logger that delegates to `console`. Plugins fall back to this when no logger is supplied. */
3
+ export declare const defaultLogger: Logger;
4
+ /**
5
+ * Wraps a logger so every message is prefixed with a `[name]` tag. Useful
6
+ * for request-scoped or plugin-scoped logging.
7
+ */
8
+ export declare function createNamedLogger(name: string, base?: Logger): Logger;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAA;AAEnE,wGAAwG;AACxG,eAAO,MAAM,aAAa,EAAE,MAiB3B,CAAA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,MAAM,CAQpF"}
@@ -0,0 +1,41 @@
1
+ /** Default logger that delegates to `console`. Plugins fall back to this when no logger is supplied. */
2
+ export const defaultLogger = {
3
+ debug: (message, context) => {
4
+ if (context)
5
+ console.debug(message, context);
6
+ else
7
+ console.debug(message);
8
+ },
9
+ info: (message, context) => {
10
+ if (context)
11
+ console.log(message, context);
12
+ else
13
+ console.log(message);
14
+ },
15
+ warn: (message, context) => {
16
+ if (context)
17
+ console.warn(message, context);
18
+ else
19
+ console.warn(message);
20
+ },
21
+ error: (message, context) => {
22
+ if (context)
23
+ console.error(message, context);
24
+ else
25
+ console.error(message);
26
+ },
27
+ };
28
+ /**
29
+ * Wraps a logger so every message is prefixed with a `[name]` tag. Useful
30
+ * for request-scoped or plugin-scoped logging.
31
+ */
32
+ export function createNamedLogger(name, base = defaultLogger) {
33
+ const tag = `[${name}]`;
34
+ return {
35
+ debug: (message, context) => base.debug(`${tag} ${message}`, context),
36
+ info: (message, context) => base.info(`${tag} ${message}`, context),
37
+ warn: (message, context) => base.warn(`${tag} ${message}`, context),
38
+ error: (message, context) => base.error(`${tag} ${message}`, context),
39
+ };
40
+ }
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAGA,wGAAwG;AACxG,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QAC1B,IAAI,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;YACvC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QACzB,IAAI,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;YACrC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3B,CAAC;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QACzB,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;YACtC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IACD,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QAC1B,IAAI,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;YACvC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;CACF,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAe,aAAa;IAC1E,MAAM,GAAG,GAAG,IAAI,IAAI,GAAG,CAAA;IACvB,OAAO;QACL,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,OAAO,EAAE,EAAE,OAAO,CAAC;QACrE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,OAAO,EAAE,EAAE,OAAO,CAAC;QACnE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,OAAO,EAAE,EAAE,OAAO,CAAC;QACnE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,OAAO,EAAE,EAAE,OAAO,CAAC;KACtE,CAAA;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Payload } from 'payload';
2
+ import type { Logger, McpAuthenticator, McpToolDefinition } from '@forumone/throughline-plugin-contract';
3
+ export interface McpHandlerOptions {
4
+ payload: Payload;
5
+ /** Server identifier surfaced in logs (e.g. `'publishing'`). */
6
+ serverName: string;
7
+ /** Tools the server exposes via `tools/list` and `tools/call`. */
8
+ tools: McpToolDefinition[];
9
+ /** Optional override; defaults to a bearer-token authenticator. */
10
+ authenticator?: McpAuthenticator;
11
+ /** Optional logger; defaults to the framework's console logger. */
12
+ logger?: Logger;
13
+ }
14
+ /**
15
+ * Returns an HTTP handler that implements the Model Context Protocol's
16
+ * JSON-RPC subset over a single POST endpoint. Handles authentication,
17
+ * tool listing, tool dispatch, and error formatting.
18
+ */
19
+ export declare function createMcpHandler(options: McpHandlerOptions): (request: Request) => Promise<Response>;
20
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/mcp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGtC,OAAO,KAAK,EACV,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,uCAAuC,CAAA;AAI9C,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,KAAK,EAAE,iBAAiB,EAAE,CAAA;IAC1B,mEAAmE;IACnE,aAAa,CAAC,EAAE,gBAAgB,CAAA;IAChC,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAoFpG"}
@@ -0,0 +1,109 @@
1
+ import { z } from 'zod';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
3
+ import { createBearerTokenAuthenticator } from '../auth/index.js';
4
+ import { defaultLogger } from '../logger/index.js';
5
+ /**
6
+ * Returns an HTTP handler that implements the Model Context Protocol's
7
+ * JSON-RPC subset over a single POST endpoint. Handles authentication,
8
+ * tool listing, tool dispatch, and error formatting.
9
+ */
10
+ export function createMcpHandler(options) {
11
+ const authenticator = options.authenticator ?? createBearerTokenAuthenticator({ payload: options.payload });
12
+ const toolsByName = new Map(options.tools.map((t) => [t.name, t]));
13
+ const logger = options.logger ?? defaultLogger;
14
+ const tag = `[${options.serverName}]`;
15
+ return async function handleMcp(request) {
16
+ const auth = await authenticator.authenticate(request);
17
+ if (!auth)
18
+ return jsonResponse({ error: 'Unauthorized' }, 401);
19
+ let body;
20
+ try {
21
+ body = await request.json();
22
+ }
23
+ catch {
24
+ return jsonRpcError(null, JSON_RPC_PARSE_ERROR, 'Parse error');
25
+ }
26
+ const parsed = JsonRpcRequestSchema.safeParse(body);
27
+ if (!parsed.success)
28
+ return jsonRpcError(null, JSON_RPC_INVALID_REQUEST, 'Invalid request');
29
+ const rpc = parsed.data;
30
+ const id = rpc.id ?? null;
31
+ try {
32
+ if (rpc.method === 'tools/list') {
33
+ return jsonRpcResult(id, {
34
+ tools: options.tools.map((tool) => ({
35
+ name: tool.name,
36
+ description: tool.description,
37
+ inputSchema: zodToJsonSchema(tool.inputSchema, { target: 'jsonSchema7' }),
38
+ })),
39
+ });
40
+ }
41
+ if (rpc.method === 'tools/call') {
42
+ const params = ToolCallParamsSchema.safeParse(rpc.params);
43
+ if (!params.success) {
44
+ return jsonRpcError(id, JSON_RPC_INVALID_PARAMS, 'Invalid params');
45
+ }
46
+ const tool = toolsByName.get(params.data.name);
47
+ if (!tool) {
48
+ return jsonRpcError(id, JSON_RPC_METHOD_NOT_FOUND, `Unknown tool: ${params.data.name}`);
49
+ }
50
+ const inputResult = tool.inputSchema.safeParse(params.data.arguments ?? {});
51
+ if (!inputResult.success) {
52
+ return jsonRpcError(id, JSON_RPC_INVALID_PARAMS, `Invalid arguments: ${inputResult.error.message}`);
53
+ }
54
+ const toolLogger = {
55
+ debug: (m, c) => logger.debug(`${tag} ${m}`, c),
56
+ info: (m, c) => logger.info(`${tag} ${m}`, c),
57
+ warn: (m, c) => logger.warn(`${tag} ${m}`, c),
58
+ error: (m, c) => logger.error(`${tag} ${m}`, c),
59
+ };
60
+ const result = await tool.handler(inputResult.data, {
61
+ user: auth.user,
62
+ apiKeyName: auth.apiKeyName,
63
+ logger: toolLogger,
64
+ });
65
+ return jsonRpcResult(id, {
66
+ content: [
67
+ {
68
+ type: 'text',
69
+ text: typeof result === 'string' ? result : JSON.stringify(result),
70
+ },
71
+ ],
72
+ });
73
+ }
74
+ return jsonRpcError(id, JSON_RPC_METHOD_NOT_FOUND, `Method not found: ${rpc.method}`);
75
+ }
76
+ catch (error) {
77
+ logger.error(`${tag} MCP handler error`, { error: String(error), method: rpc.method });
78
+ return jsonRpcError(id, JSON_RPC_INTERNAL_ERROR, 'Internal error');
79
+ }
80
+ };
81
+ }
82
+ const JSON_RPC_PARSE_ERROR = -32700;
83
+ const JSON_RPC_INVALID_REQUEST = -32600;
84
+ const JSON_RPC_METHOD_NOT_FOUND = -32601;
85
+ const JSON_RPC_INVALID_PARAMS = -32602;
86
+ const JSON_RPC_INTERNAL_ERROR = -32603;
87
+ const JsonRpcRequestSchema = z.object({
88
+ jsonrpc: z.literal('2.0'),
89
+ id: z.union([z.string(), z.number(), z.null()]).optional(),
90
+ method: z.string(),
91
+ params: z.unknown().optional(),
92
+ });
93
+ const ToolCallParamsSchema = z.object({
94
+ name: z.string(),
95
+ arguments: z.record(z.string(), z.unknown()).optional(),
96
+ });
97
+ function jsonResponse(body, status = 200) {
98
+ return new Response(JSON.stringify(body), {
99
+ status,
100
+ headers: { 'content-type': 'application/json' },
101
+ });
102
+ }
103
+ function jsonRpcResult(id, result) {
104
+ return jsonResponse({ jsonrpc: '2.0', id, result });
105
+ }
106
+ function jsonRpcError(id, code, message) {
107
+ return jsonResponse({ jsonrpc: '2.0', id, error: { code, message } });
108
+ }
109
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/mcp/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { createMcpHandler } from './handler.js';
2
+ export type { McpHandlerOptions } from './handler.js';
3
+ export { McpMetaSchema, withMeta } from './meta.js';
4
+ export type { McpMeta } from './meta.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAErD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACnD,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { createMcpHandler } from './handler.js';
2
+ export { McpMetaSchema, withMeta } from './meta.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Optional `_meta` payload Claude can attach to consequential tool calls.
4
+ * The audit writer reads `userPrompt`, `reasoning`, and `changesSummary`
5
+ * to give audit log entries narrative context.
6
+ */
7
+ export declare const McpMetaSchema: z.ZodOptional<z.ZodObject<{
8
+ userPrompt: z.ZodOptional<z.ZodString>;
9
+ reasoning: z.ZodOptional<z.ZodString>;
10
+ changesSummary: z.ZodOptional<z.ZodString>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ reasoning?: string | undefined;
13
+ changesSummary?: string | undefined;
14
+ userPrompt?: string | undefined;
15
+ }, {
16
+ reasoning?: string | undefined;
17
+ changesSummary?: string | undefined;
18
+ userPrompt?: string | undefined;
19
+ }>>;
20
+ export type McpMeta = z.infer<typeof McpMetaSchema>;
21
+ /**
22
+ * Wraps a Zod object shape in a schema that also accepts an optional `_meta`
23
+ * field. Plugin authors use this for any tool whose input belongs in the
24
+ * audit log:
25
+ *
26
+ * ```ts
27
+ * const inputSchema = withMeta({ pageId: z.string() })
28
+ * type Input = z.infer<typeof inputSchema> // { pageId: string; _meta?: McpMeta }
29
+ * ```
30
+ */
31
+ export declare function withMeta<Shape extends z.ZodRawShape>(shape: Shape): z.ZodObject<Shape & {
32
+ _meta: z.ZodOptional<z.ZodObject<{
33
+ userPrompt: z.ZodOptional<z.ZodString>;
34
+ reasoning: z.ZodOptional<z.ZodString>;
35
+ changesSummary: z.ZodOptional<z.ZodString>;
36
+ }, "strip", z.ZodTypeAny, {
37
+ reasoning?: string | undefined;
38
+ changesSummary?: string | undefined;
39
+ userPrompt?: string | undefined;
40
+ }, {
41
+ reasoning?: string | undefined;
42
+ changesSummary?: string | undefined;
43
+ userPrompt?: string | undefined;
44
+ }>>;
45
+ }, "strip", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape & {
46
+ _meta: z.ZodOptional<z.ZodObject<{
47
+ userPrompt: z.ZodOptional<z.ZodString>;
48
+ reasoning: z.ZodOptional<z.ZodString>;
49
+ changesSummary: z.ZodOptional<z.ZodString>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ reasoning?: string | undefined;
52
+ changesSummary?: string | undefined;
53
+ userPrompt?: string | undefined;
54
+ }, {
55
+ reasoning?: string | undefined;
56
+ changesSummary?: string | undefined;
57
+ userPrompt?: string | undefined;
58
+ }>>;
59
+ }>, any> extends infer T ? { [k in keyof T]: T[k]; } : never, z.baseObjectInputType<Shape & {
60
+ _meta: z.ZodOptional<z.ZodObject<{
61
+ userPrompt: z.ZodOptional<z.ZodString>;
62
+ reasoning: z.ZodOptional<z.ZodString>;
63
+ changesSummary: z.ZodOptional<z.ZodString>;
64
+ }, "strip", z.ZodTypeAny, {
65
+ reasoning?: string | undefined;
66
+ changesSummary?: string | undefined;
67
+ userPrompt?: string | undefined;
68
+ }, {
69
+ reasoning?: string | undefined;
70
+ changesSummary?: string | undefined;
71
+ userPrompt?: string | undefined;
72
+ }>>;
73
+ }> extends infer T_1 ? { [k_1 in keyof T_1]: T_1[k_1]; } : never>;
74
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/mcp/meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;GAMb,CAAA;AAEb,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEnD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEAEjE"}
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Optional `_meta` payload Claude can attach to consequential tool calls.
4
+ * The audit writer reads `userPrompt`, `reasoning`, and `changesSummary`
5
+ * to give audit log entries narrative context.
6
+ */
7
+ export const McpMetaSchema = z
8
+ .object({
9
+ userPrompt: z.string().optional(),
10
+ reasoning: z.string().optional(),
11
+ changesSummary: z.string().optional(),
12
+ })
13
+ .optional();
14
+ /**
15
+ * Wraps a Zod object shape in a schema that also accepts an optional `_meta`
16
+ * field. Plugin authors use this for any tool whose input belongs in the
17
+ * audit log:
18
+ *
19
+ * ```ts
20
+ * const inputSchema = withMeta({ pageId: z.string() })
21
+ * type Input = z.infer<typeof inputSchema> // { pageId: string; _meta?: McpMeta }
22
+ * ```
23
+ */
24
+ export function withMeta(shape) {
25
+ return z.object({ ...shape, _meta: McpMetaSchema });
26
+ }
27
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/mcp/meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACtC,CAAC;KACD,QAAQ,EAAE,CAAA;AAIb;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAA8B,KAAY;IAChE,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAA;AACrD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Computes a shallow diff between two records. Returns an entry per
3
+ * field whose value changed, with `before` and `after` values.
4
+ *
5
+ * Field equality is determined by JSON-string equality for objects and
6
+ * arrays, and `===` for primitives. That is sufficient for audit-log
7
+ * payloads where structures are JSON-shaped to begin with.
8
+ */
9
+ export declare function shallowDiff<T extends Record<string, unknown>>(before: T, after: T): Record<string, {
10
+ before: unknown;
11
+ after: unknown;
12
+ }>;
13
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,CAAC,GACP,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CASrD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Computes a shallow diff between two records. Returns an entry per
3
+ * field whose value changed, with `before` and `after` values.
4
+ *
5
+ * Field equality is determined by JSON-string equality for objects and
6
+ * arrays, and `===` for primitives. That is sufficient for audit-log
7
+ * payloads where structures are JSON-shaped to begin with.
8
+ */
9
+ export function shallowDiff(before, after) {
10
+ const diff = {};
11
+ const keys = new Set([...Object.keys(before), ...Object.keys(after)]);
12
+ for (const key of keys) {
13
+ if (!isEqual(before[key], after[key])) {
14
+ diff[key] = { before: before[key], after: after[key] };
15
+ }
16
+ }
17
+ return diff;
18
+ }
19
+ function isEqual(a, b) {
20
+ if (Object.is(a, b))
21
+ return true;
22
+ if (a === null || b === null || a === undefined || b === undefined)
23
+ return false;
24
+ if (typeof a !== typeof b)
25
+ return false;
26
+ if (typeof a === 'object') {
27
+ return JSON.stringify(a) === JSON.stringify(b);
28
+ }
29
+ return false;
30
+ }
31
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,MAAS,EACT,KAAQ;IAER,MAAM,IAAI,GAAwD,EAAE,CAAA;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACrE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAA;QACxD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,OAAO,CAAC,CAAU,EAAE,CAAU;IACrC,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAChF,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACvC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generates a short, URL-safe, hex-encoded random ID. Optionally prefixed
3
+ * with a token category (e.g. `evt_a1b2c3...`).
4
+ */
5
+ export declare function generateId(prefix?: string): string;
6
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAOlD"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Generates a short, URL-safe, hex-encoded random ID. Optionally prefixed
3
+ * with a token category (e.g. `evt_a1b2c3...`).
4
+ */
5
+ export function generateId(prefix) {
6
+ const bytes = new Uint8Array(12);
7
+ crypto.getRandomValues(bytes);
8
+ const id = Array.from(bytes)
9
+ .map((b) => b.toString(16).padStart(2, '0'))
10
+ .join('');
11
+ return prefix ? `${prefix}_${id}` : id;
12
+ }
13
+ //# sourceMappingURL=id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe;IACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IAChC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAC7B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAA;IACX,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { shallowDiff } from './diff.js';
2
+ export { generateId } from './id.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { shallowDiff } from './diff.js';
2
+ export { generateId } from './id.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}