@pikku/core 0.7.8 → 0.8.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 (151) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/dist/errors/error-handler.d.ts +2 -0
  3. package/dist/errors/errors.js +2 -0
  4. package/dist/{channel → events/channel}/channel-handler.d.ts +1 -1
  5. package/dist/{channel → events/channel}/channel-handler.js +2 -2
  6. package/dist/{channel → events/channel}/channel-runner.d.ts +1 -1
  7. package/dist/{channel → events/channel}/channel-runner.js +4 -4
  8. package/dist/{channel → events/channel}/channel-store.d.ts +1 -1
  9. package/dist/{channel → events/channel}/channel.types.d.ts +3 -3
  10. package/dist/{channel → events/channel}/local/local-channel-runner.js +6 -6
  11. package/dist/{channel → events/channel}/log-channels.d.ts +1 -1
  12. package/dist/{channel → events/channel}/log-channels.js +1 -1
  13. package/dist/{channel → events/channel}/serverless/serverless-channel-runner.js +7 -7
  14. package/dist/{http → events/http}/http-runner.d.ts +1 -1
  15. package/dist/{http → events/http}/http-runner.js +8 -8
  16. package/dist/{http → events/http}/http.types.d.ts +3 -3
  17. package/dist/{http → events/http}/index.d.ts +0 -1
  18. package/dist/{http → events/http}/index.js +0 -1
  19. package/dist/{http → events/http}/log-http-routes.d.ts +1 -1
  20. package/dist/{http → events/http}/log-http-routes.js +1 -1
  21. package/dist/{http → events/http}/pikku-fetch-http-request.js +1 -1
  22. package/dist/events/mcp/index.d.ts +2 -0
  23. package/dist/events/mcp/index.js +2 -0
  24. package/dist/events/mcp/mcp-runner.d.ts +30 -0
  25. package/dist/events/mcp/mcp-runner.js +192 -0
  26. package/dist/events/mcp/mcp.types.d.ts +117 -0
  27. package/dist/events/queue/index.d.ts +6 -0
  28. package/dist/events/queue/index.js +6 -0
  29. package/dist/events/queue/queue-runner.d.ts +24 -0
  30. package/dist/events/queue/queue-runner.js +83 -0
  31. package/dist/events/queue/queue.types.d.ts +154 -0
  32. package/dist/events/queue/register-queue-helper.d.ts +17 -0
  33. package/dist/events/queue/register-queue-helper.js +34 -0
  34. package/dist/events/queue/validate-worker-config.d.ts +41 -0
  35. package/dist/events/queue/validate-worker-config.js +50 -0
  36. package/dist/events/rpc/index.d.ts +2 -0
  37. package/dist/events/rpc/rpc-runner.d.ts +28 -0
  38. package/dist/{rpc → events/rpc}/rpc-runner.js +2 -2
  39. package/dist/events/scheduler/index.d.ts +3 -0
  40. package/dist/events/scheduler/index.js +3 -0
  41. package/dist/{scheduler → events/scheduler}/log-schedulers.d.ts +1 -1
  42. package/dist/{scheduler → events/scheduler}/log-schedulers.js +1 -1
  43. package/dist/{scheduler → events/scheduler}/scheduler-runner.d.ts +4 -3
  44. package/dist/{scheduler → events/scheduler}/scheduler-runner.js +7 -4
  45. package/dist/{scheduler → events/scheduler}/scheduler.types.d.ts +3 -4
  46. package/dist/function/function-runner.js +8 -0
  47. package/dist/function/functions.types.d.ts +3 -2
  48. package/dist/handle-error.d.ts +2 -2
  49. package/dist/handle-error.js +1 -1
  50. package/dist/index.d.ts +10 -6
  51. package/dist/index.js +10 -6
  52. package/dist/middleware-runner.d.ts +4 -4
  53. package/dist/middleware-runner.js +3 -1
  54. package/dist/pikku-state.d.ts +18 -4
  55. package/dist/pikku-state.js +12 -0
  56. package/dist/services/user-session-service.d.ts +1 -1
  57. package/dist/types/core.types.d.ts +17 -5
  58. package/dist/types/core.types.js +2 -0
  59. package/lcov.info +3191 -3123
  60. package/package.json +8 -7
  61. package/src/errors/error-handler.ts +2 -1
  62. package/src/errors/errors.ts +2 -0
  63. package/src/{channel → events/channel}/channel-handler.ts +3 -3
  64. package/src/{channel → events/channel}/channel-runner.ts +5 -5
  65. package/src/{channel → events/channel}/channel-store.ts +1 -1
  66. package/src/{channel → events/channel}/channel.types.ts +3 -3
  67. package/src/{channel → events/channel}/local/local-channel-runner.test.ts +1 -1
  68. package/src/{channel → events/channel}/local/local-channel-runner.ts +7 -7
  69. package/src/{channel → events/channel}/local/local-eventhub-service.test.ts +1 -1
  70. package/src/{channel → events/channel}/log-channels.ts +2 -2
  71. package/src/{channel → events/channel}/serverless/serverless-channel-runner.ts +8 -8
  72. package/src/{http → events/http}/http-runner.test.ts +4 -4
  73. package/src/{http → events/http}/http-runner.ts +9 -9
  74. package/src/{http → events/http}/http.types.ts +3 -3
  75. package/src/{http → events/http}/index.ts +0 -1
  76. package/src/{http → events/http}/log-http-routes.ts +2 -2
  77. package/src/{http → events/http}/pikku-fetch-http-request.ts +1 -1
  78. package/src/events/mcp/index.ts +2 -0
  79. package/src/events/mcp/mcp-runner.ts +321 -0
  80. package/src/events/mcp/mcp.types.ts +150 -0
  81. package/src/events/queue/index.ts +18 -0
  82. package/src/events/queue/queue-runner.ts +125 -0
  83. package/src/events/queue/queue.types.ts +176 -0
  84. package/src/events/queue/register-queue-helper.ts +62 -0
  85. package/src/events/queue/validate-worker-config.ts +113 -0
  86. package/src/events/rpc/index.ts +2 -0
  87. package/src/{rpc → events/rpc}/rpc-runner.ts +3 -3
  88. package/src/events/scheduler/index.ts +9 -0
  89. package/src/{scheduler → events/scheduler}/log-schedulers.ts +2 -2
  90. package/src/{scheduler → events/scheduler}/scheduler-runner.ts +11 -10
  91. package/src/{scheduler → events/scheduler}/scheduler.types.ts +2 -4
  92. package/src/function/function-runner.ts +19 -1
  93. package/src/function/functions.types.ts +3 -1
  94. package/src/handle-error.ts +2 -2
  95. package/src/index.ts +23 -6
  96. package/src/middleware-runner.ts +14 -7
  97. package/src/pikku-state.ts +40 -4
  98. package/src/services/user-session-service.ts +1 -1
  99. package/src/types/core.types.ts +24 -4
  100. package/tsconfig.json +3 -2
  101. package/tsconfig.tsbuildinfo +1 -1
  102. package/dist/rpc/index.d.ts +0 -2
  103. package/dist/rpc/rpc-runner.d.ts +0 -27
  104. package/dist/scheduler/index.d.ts +0 -3
  105. package/dist/scheduler/index.js +0 -3
  106. package/src/http/incomingmessage-to-request-convertor.ts +0 -0
  107. package/src/rpc/index.ts +0 -2
  108. package/src/scheduler/index.ts +0 -5
  109. /package/dist/{channel → events/channel}/channel-store.js +0 -0
  110. /package/dist/{channel → events/channel}/channel.types.js +0 -0
  111. /package/dist/{channel → events/channel}/eventhub-service.d.ts +0 -0
  112. /package/dist/{channel → events/channel}/eventhub-service.js +0 -0
  113. /package/dist/{channel → events/channel}/eventhub-store.d.ts +0 -0
  114. /package/dist/{channel → events/channel}/eventhub-store.js +0 -0
  115. /package/dist/{channel → events/channel}/index.d.ts +0 -0
  116. /package/dist/{channel → events/channel}/index.js +0 -0
  117. /package/dist/{channel → events/channel}/local/index.d.ts +0 -0
  118. /package/dist/{channel → events/channel}/local/index.js +0 -0
  119. /package/dist/{channel → events/channel}/local/local-channel-handler.d.ts +0 -0
  120. /package/dist/{channel → events/channel}/local/local-channel-handler.js +0 -0
  121. /package/dist/{channel → events/channel}/local/local-channel-runner.d.ts +0 -0
  122. /package/dist/{channel → events/channel}/local/local-eventhub-service.d.ts +0 -0
  123. /package/dist/{channel → events/channel}/local/local-eventhub-service.js +0 -0
  124. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.d.ts +0 -0
  125. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.js +0 -0
  126. /package/dist/{channel → events/channel}/serverless/index.d.ts +0 -0
  127. /package/dist/{channel → events/channel}/serverless/index.js +0 -0
  128. /package/dist/{channel → events/channel}/serverless/serverless-channel-runner.d.ts +0 -0
  129. /package/dist/{http → events/http}/http.types.js +0 -0
  130. /package/dist/{http → events/http}/pikku-fetch-http-request.d.ts +0 -0
  131. /package/dist/{http → events/http}/pikku-fetch-http-response.d.ts +0 -0
  132. /package/dist/{http → events/http}/pikku-fetch-http-response.js +0 -0
  133. /package/dist/{http/incomingmessage-to-request-convertor.d.ts → events/mcp/mcp.types.js} +0 -0
  134. /package/dist/{http/incomingmessage-to-request-convertor.js → events/queue/queue.types.js} +0 -0
  135. /package/dist/{rpc → events/rpc}/index.js +0 -0
  136. /package/dist/{rpc → events/rpc}/rpc-types.d.ts +0 -0
  137. /package/dist/{rpc → events/rpc}/rpc-types.js +0 -0
  138. /package/dist/{scheduler → events/scheduler}/scheduler.types.js +0 -0
  139. /package/src/{channel → events/channel}/eventhub-service.ts +0 -0
  140. /package/src/{channel → events/channel}/eventhub-store.ts +0 -0
  141. /package/src/{channel → events/channel}/index.ts +0 -0
  142. /package/src/{channel → events/channel}/local/index.ts +0 -0
  143. /package/src/{channel → events/channel}/local/local-channel-handler.ts +0 -0
  144. /package/src/{channel → events/channel}/local/local-eventhub-service.ts +0 -0
  145. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.test.ts +0 -0
  146. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.ts +0 -0
  147. /package/src/{channel → events/channel}/serverless/index.ts +0 -0
  148. /package/src/{http → events/http}/pikku-fetch-http-request.test.ts +0 -0
  149. /package/src/{http → events/http}/pikku-fetch-http-response.test.ts +0 -0
  150. /package/src/{http → events/http}/pikku-fetch-http-response.ts +0 -0
  151. /package/src/{rpc → events/rpc}/rpc-types.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,4 +1,13 @@
1
- ## 0.7.0
1
+ ## 0.8.0
2
+
3
+ ### Major Features
4
+
5
+ - **Model Context Protocol (MCP) Support**: Added MCP implementation with resources, tools, and prompts
6
+ - **Queue System**: Added queue support with runners and workers
7
+ - **RPC (Remote Procedure Calls)**: Added typed RPC calls inside functions with local and remote support
8
+ - **Middleware Runner**: Added middleware runner to functions for enhanced request processing
9
+ - **Multiple Bootstrap Files**: Added support for different transport bootstrap files
10
+ - **Middleware Runner**: Run middleware on any function
2
11
 
3
12
  ## 0.7.8
4
13
 
@@ -15,6 +15,7 @@ export declare class PikkuError extends Error {
15
15
  export interface ErrorDetails {
16
16
  status: number;
17
17
  message: string;
18
+ mcpCode?: number;
18
19
  }
19
20
  /**
20
21
  * Adds an error to the API errors map.
@@ -35,4 +36,5 @@ export declare const addErrors: (errors: Array<[error: any, details: ErrorDetail
35
36
  export declare const getErrorResponse: (error: Error) => {
36
37
  status: number;
37
38
  message: string;
39
+ mcpCode?: number;
38
40
  } | undefined;
@@ -10,6 +10,7 @@ export class BadRequestError extends PikkuError {
10
10
  }
11
11
  addError(BadRequestError, {
12
12
  status: 400,
13
+ mcpCode: -32600,
13
14
  message: 'The server cannot or will not process the request due to client error (e.g., malformed request syntax).',
14
15
  });
15
16
  /**
@@ -81,6 +82,7 @@ export class NotFoundError extends PikkuError {
81
82
  */
82
83
  addError(NotFoundError, {
83
84
  status: 404,
85
+ mcpCode: -32601,
84
86
  message: 'The server cannot find the requested resource.',
85
87
  });
86
88
  /**
@@ -1,3 +1,3 @@
1
- import { CoreServices, CoreUserSession } from '../types/core.types.js';
1
+ import { CoreServices, CoreUserSession } from '../../types/core.types.js';
2
2
  import { CoreAPIChannel, PikkuChannelHandler } from './channel.types.js';
3
3
  export declare const processMessageHandlers: (services: CoreServices, session: CoreUserSession | undefined, channelConfig: CoreAPIChannel<any, any>, channelHandler: PikkuChannelHandler) => (rawData: any) => Promise<unknown>;
@@ -1,5 +1,5 @@
1
- import { pikkuState } from '../pikku-state.js';
2
- import { runPikkuFunc } from '../function/function-runner.js';
1
+ import { pikkuState } from '../../pikku-state.js';
2
+ import { runPikkuFunc } from '../../function/function-runner.js';
3
3
  const getRouteMeta = (channelName, routingProperty, routerValue) => {
4
4
  const channelMeta = pikkuState('channel', 'meta')[channelName];
5
5
  if (!channelMeta) {
@@ -1,4 +1,4 @@
1
- import { UserSessionService } from '../services/user-session-service.js';
1
+ import { UserSessionService } from '../../services/user-session-service.js';
2
2
  import { ChannelMeta, CoreAPIChannel, RunChannelOptions, RunChannelParams } from './channel.types.js';
3
3
  /**
4
4
  * Adds a channel and registers all functions referenced in it using the
@@ -1,7 +1,7 @@
1
- import { NotFoundError } from '../errors/errors.js';
2
- import { addFunction } from '../function/function-runner.js';
3
- import { pikkuState } from '../pikku-state.js';
4
- import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js';
1
+ import { NotFoundError } from '../../errors/errors.js';
2
+ import { addFunction } from '../../function/function-runner.js';
3
+ import { pikkuState } from '../../pikku-state.js';
4
+ import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js';
5
5
  import { match } from 'path-to-regexp';
6
6
  /**
7
7
  * Adds a channel and registers all functions referenced in it using the
@@ -1,4 +1,4 @@
1
- import { CoreUserSession } from '../types/core.types.js';
1
+ import { CoreUserSession } from '../../types/core.types.js';
2
2
  export type Channel<ChannelType = unknown, OpeningData = unknown> = {
3
3
  channelId: string;
4
4
  channelName: string;
@@ -1,7 +1,7 @@
1
- import { PikkuError } from '../errors/error-handler.js';
1
+ import { PikkuError } from '../../errors/error-handler.js';
2
2
  import { HTTPFunctionMetaInputTypes, PikkuHTTPRequest, PikkuHTTPResponse } from '../http/http.types.js';
3
- import { APIDocs, CoreSingletonServices, CreateSessionServices, PikkuMiddleware } from '../types/core.types.js';
4
- import { CoreAPIFunction, CoreAPIFunctionSessionless, CoreAPIPermission } from '../function/functions.types.js';
3
+ import { APIDocs, CoreSingletonServices, CreateSessionServices, PikkuMiddleware } from '../../types/core.types.js';
4
+ import { CoreAPIFunction, CoreAPIFunctionSessionless, CoreAPIPermission } from '../../function/functions.types.js';
5
5
  export type RunChannelOptions = Partial<{
6
6
  skipUserSession: boolean;
7
7
  respondWith404: boolean;
@@ -1,12 +1,12 @@
1
1
  import { openChannel } from '../channel-runner.js';
2
2
  import { createHTTPInteraction } from '../../http/http-runner.js';
3
- import { closeSessionServices } from '../../utils.js';
3
+ import { closeSessionServices } from '../../../utils.js';
4
4
  import { processMessageHandlers } from '../channel-handler.js';
5
5
  import { PikkuLocalChannelHandler } from './local-channel-handler.js';
6
- import { handleError } from '../../handle-error.js';
7
- import { runMiddleware } from '../../middleware-runner.js';
8
- import { PikkuUserSessionService } from '../../services/user-session-service.js';
9
- import { runPikkuFuncDirectly } from '../../function/function-runner.js';
6
+ import { handleHTTPError } from '../../../handle-error.js';
7
+ import { runMiddleware } from '../../../middleware-runner.js';
8
+ import { PikkuUserSessionService } from '../../../services/user-session-service.js';
9
+ import { runPikkuFuncDirectly } from '../../../function/function-runner.js';
10
10
  import { rpcService } from '../../rpc/rpc-runner.js';
11
11
  export const runLocalChannel = async ({ singletonServices, channelId, request, response, route, createSessionServices, skipUserSession = false, respondWith404 = true, coerceDataFromSchema = true, logWarningsForStatusCodes = [], bubbleErrors = false, }) => {
12
12
  let sessionServices;
@@ -58,7 +58,7 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
58
58
  channelHandler.registerOnMessage(processMessageHandlers(allServices, session, channelConfig, channelHandler));
59
59
  }
60
60
  catch (e) {
61
- handleError(e, http, channelId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
61
+ handleHTTPError(e, http, channelId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
62
62
  }
63
63
  finally {
64
64
  if (sessionServices) {
@@ -1,4 +1,4 @@
1
- import { Logger } from '../services/index.js';
1
+ import { Logger } from '../../services/index.js';
2
2
  /**
3
3
  * Logs all the loaded channels.
4
4
  * @param logger - A logger for logging information.
@@ -1,4 +1,4 @@
1
- import { pikkuState } from '../pikku-state.js';
1
+ import { pikkuState } from '../../pikku-state.js';
2
2
  /**
3
3
  * Logs all the loaded channels.
4
4
  * @param logger - A logger for logging information.
@@ -1,13 +1,13 @@
1
- import { closeSessionServices } from '../../utils.js';
1
+ import { closeSessionServices } from '../../../utils.js';
2
2
  import { processMessageHandlers } from '../channel-handler.js';
3
3
  import { openChannel } from '../channel-runner.js';
4
4
  import { createHTTPInteraction } from '../../http/http-runner.js';
5
- import { handleError } from '../../handle-error.js';
6
- import { PikkuUserSessionService } from '../../services/user-session-service.js';
7
- import { runMiddleware } from '../../middleware-runner.js';
8
- import { pikkuState } from '../../pikku-state.js';
5
+ import { handleHTTPError } from '../../../handle-error.js';
6
+ import { PikkuUserSessionService } from '../../../services/user-session-service.js';
7
+ import { runMiddleware } from '../../../middleware-runner.js';
8
+ import { pikkuState } from '../../../pikku-state.js';
9
9
  import { PikkuFetchHTTPRequest } from '../../http/pikku-fetch-http-request.js';
10
- import { runPikkuFuncDirectly } from '../../function/function-runner.js';
10
+ import { runPikkuFuncDirectly } from '../../../function/function-runner.js';
11
11
  const getVariablesForChannel = ({ channelId, channelName, channelHandlerFactory, openingData, }) => {
12
12
  const channels = pikkuState('channel', 'channels');
13
13
  const channelConfig = channels[channelName];
@@ -65,7 +65,7 @@ export const runChannelConnect = async ({ singletonServices, channelId, channelO
65
65
  http?.response?.status(101);
66
66
  }
67
67
  catch (e) {
68
- handleError(e, http, channelId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
68
+ handleHTTPError(e, http, channelId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
69
69
  }
70
70
  finally {
71
71
  if (sessionServices) {
@@ -1,5 +1,5 @@
1
1
  import { CoreHTTPFunctionRoute, RunRouteOptions, RunRouteParams, PikkuHTTP, PikkuHTTPRequest, PikkuHTTPResponse } from './http.types.js';
2
- import { PikkuMiddleware } from '../types/core.types.js';
2
+ import { PikkuMiddleware } from '../../types/core.types.js';
3
3
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
4
4
  /**
5
5
  * Registers middleware either globally or for a specific route.
@@ -1,13 +1,13 @@
1
1
  import { match } from 'path-to-regexp';
2
- import { MissingSessionError, NotFoundError } from '../errors/errors.js';
3
- import { closeSessionServices, createWeakUID, isSerializable, } from '../utils.js';
4
- import { PikkuUserSessionService, } from '../services/user-session-service.js';
5
- import { runMiddleware } from '../middleware-runner.js';
6
- import { handleError } from '../handle-error.js';
7
- import { pikkuState } from '../pikku-state.js';
2
+ import { MissingSessionError, NotFoundError } from '../../errors/errors.js';
3
+ import { closeSessionServices, createWeakUID, isSerializable, } from '../../utils.js';
4
+ import { PikkuUserSessionService, } from '../../services/user-session-service.js';
5
+ import { runMiddleware } from '../../middleware-runner.js';
6
+ import { handleHTTPError } from '../../handle-error.js';
7
+ import { pikkuState } from '../../pikku-state.js';
8
8
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
9
9
  import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js';
10
- import { addFunction, runPikkuFunc } from '../function/function-runner.js';
10
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
11
11
  import { rpcService } from '../rpc/rpc-runner.js';
12
12
  /**
13
13
  * Registers middleware either globally or for a specific route.
@@ -342,7 +342,7 @@ export const fetchData = async (request, response, { singletonServices, createSe
342
342
  }
343
343
  catch (e) {
344
344
  // Handle errors and, depending on configuration, bubble them up or respond with an error
345
- handleError(e, http, requestId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
345
+ handleHTTPError(e, http, requestId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
346
346
  }
347
347
  finally {
348
348
  // Clean up any session-specific services created during processing
@@ -1,7 +1,7 @@
1
1
  import type { SerializeOptions } from 'cookie';
2
- import type { PikkuError } from '../errors/error-handler.js';
3
- import type { APIDocs, CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices, PikkuMiddleware } from '../types/core.types.js';
4
- import type { CoreAPIFunction, CoreAPIFunctionSessionless, CoreAPIPermission, CorePermissionGroup } from '../function/functions.types.js';
2
+ import type { PikkuError } from '../../errors/error-handler.js';
3
+ import type { APIDocs, CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices, PikkuMiddleware } from '../../types/core.types.js';
4
+ import type { CoreAPIFunction, CoreAPIFunctionSessionless, CoreAPIPermission, CorePermissionGroup } from '../../function/functions.types.js';
5
5
  type ExtractRouteParams<S extends string> = S extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractRouteParams<`/${Rest}`> : S extends `${string}:${infer Param}` ? Param : never;
6
6
  export type AssertRouteParams<In, Route extends string> = ExtractRouteParams<Route> extends keyof In ? unknown : ['Error: Route parameters', ExtractRouteParams<Route>, 'not in', keyof In];
7
7
  export type RunRouteOptions = Partial<{
@@ -1,6 +1,5 @@
1
1
  export * from './pikku-fetch-http-request.js';
2
2
  export * from './pikku-fetch-http-response.js';
3
- export * from './incomingmessage-to-request-convertor.js';
4
3
  export * from './log-http-routes.js';
5
4
  export { fetch, fetchData, addHTTPRoute } from './http-runner.js';
6
5
  export type * from './http.types.js';
@@ -1,5 +1,4 @@
1
1
  export * from './pikku-fetch-http-request.js';
2
2
  export * from './pikku-fetch-http-response.js';
3
- export * from './incomingmessage-to-request-convertor.js';
4
3
  export * from './log-http-routes.js';
5
4
  export { fetch, fetchData, addHTTPRoute } from './http-runner.js';
@@ -1,4 +1,4 @@
1
- import { Logger } from '../services/index.js';
1
+ import { Logger } from '../../services/index.js';
2
2
  /**
3
3
  * Logs all the loaded routes.
4
4
  * @param logger - A logger for logging information.
@@ -1,4 +1,4 @@
1
- import { pikkuState } from '../pikku-state.js';
1
+ import { pikkuState } from '../../pikku-state.js';
2
2
  /**
3
3
  * Logs all the loaded routes.
4
4
  * @param logger - A logger for logging information.
@@ -1,6 +1,6 @@
1
1
  import { parse as parseQuery } from 'picoquery';
2
2
  import { parse as parseCookie } from 'cookie';
3
- import { UnprocessableContentError } from '../errors/errors.js';
3
+ import { UnprocessableContentError } from '../../errors/errors.js';
4
4
  /**
5
5
  * Abstract class representing a pikku request.
6
6
  * @template In - The type of the request body.
@@ -0,0 +1,2 @@
1
+ export * from './mcp.types.js';
2
+ export * from './mcp-runner.js';
@@ -0,0 +1,2 @@
1
+ export * from './mcp.types.js';
2
+ export * from './mcp-runner.js';
@@ -0,0 +1,30 @@
1
+ import type { CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices } from '../../types/core.types.js';
2
+ import type { CoreMCPResource, CoreMCPTool, CoreMCPPrompt, JsonRpcRequest, JsonRpcResponse, JsonRpcErrorResponse, PikkuMCP } from './mcp.types.js';
3
+ import type { CoreAPIFunctionSessionless } from '../../function/functions.types.js';
4
+ export declare class MCPError extends Error {
5
+ readonly error: JsonRpcErrorResponse;
6
+ constructor(error: JsonRpcErrorResponse);
7
+ }
8
+ export type RunMCPEndpointParams<Tools extends string = any> = {
9
+ session?: CoreUserSession;
10
+ singletonServices: CoreSingletonServices;
11
+ mcp?: PikkuMCP<Tools>;
12
+ createSessionServices?: CreateSessionServices<CoreSingletonServices, CoreServices<CoreSingletonServices>, CoreUserSession>;
13
+ };
14
+ export type JsonRpcError = {
15
+ code: number;
16
+ message: string;
17
+ data?: any;
18
+ };
19
+ export declare const addMCPResource: <APIFunction extends CoreAPIFunctionSessionless<any, any>>(mcpResource: CoreMCPResource<APIFunction>) => void;
20
+ export declare const addMCPTool: <APIFunction extends CoreAPIFunctionSessionless<any, any>>(mcpTool: CoreMCPTool<APIFunction>) => void;
21
+ export declare const addMCPPrompt: <APIFunction extends CoreAPIFunctionSessionless<any, any>>(mcpPrompt: CoreMCPPrompt<APIFunction>) => void;
22
+ export declare function runMCPResource(request: JsonRpcRequest, params: RunMCPEndpointParams, uri: string): Promise<JsonRpcResponse>;
23
+ export declare function runMCPTool(request: JsonRpcRequest, params: RunMCPEndpointParams, name: string): Promise<JsonRpcResponse>;
24
+ export declare function runMCPPrompt(request: JsonRpcRequest, params: RunMCPEndpointParams, name: string): Promise<JsonRpcResponse>;
25
+ export declare const getMCPTools: () => Map<string, CoreMCPTool>;
26
+ export declare const getMCPResources: () => Map<string, CoreMCPResource>;
27
+ export declare const getMCPResourcesMeta: () => import("./mcp.types.js").MCPResourceMeta;
28
+ export declare const getMCPToolsMeta: () => import("./mcp.types.js").MCPToolMeta;
29
+ export declare const getMCPPrompts: () => Map<string, CoreMCPPrompt>;
30
+ export declare const getMCPPromptsMeta: () => import("./mcp.types.js").MCPPromptMeta;
@@ -0,0 +1,192 @@
1
+ import { getErrorResponse } from '../../errors/error-handler.js';
2
+ import { closeSessionServices } from '../../utils.js';
3
+ import { pikkuState } from '../../pikku-state.js';
4
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
5
+ import { rpcService } from '../rpc/rpc-runner.js';
6
+ import { BadRequestError, NotFoundError } from '../../errors/errors.js';
7
+ export class MCPError extends Error {
8
+ error;
9
+ constructor(error) {
10
+ super(error?.message || 'MCP Error');
11
+ this.error = error;
12
+ this.name = 'MCPError';
13
+ this.stack = new Error().stack;
14
+ }
15
+ }
16
+ export const addMCPResource = (mcpResource) => {
17
+ const resourcesMeta = pikkuState('mcp', 'resourcesMeta');
18
+ const mcpResourceMeta = resourcesMeta[mcpResource.uri];
19
+ if (!mcpResourceMeta) {
20
+ throw new Error(`MCP resource metadata not found for '${mcpResource.uri}'`);
21
+ }
22
+ addFunction(mcpResourceMeta.pikkuFuncName, {
23
+ func: mcpResource.func,
24
+ });
25
+ const resources = pikkuState('mcp', 'resources');
26
+ if (resources.has(mcpResource.uri)) {
27
+ throw new Error(`MCP resource already exists: ${mcpResource.uri}`);
28
+ }
29
+ resources.set(mcpResource.uri, mcpResource);
30
+ };
31
+ export const addMCPTool = (mcpTool) => {
32
+ const toolsMeta = pikkuState('mcp', 'toolsMeta');
33
+ const mcpToolMeta = toolsMeta[mcpTool.name];
34
+ if (!mcpToolMeta) {
35
+ throw new Error(`MCP tool metadata not found for '${mcpTool.name}'`);
36
+ }
37
+ addFunction(mcpToolMeta.pikkuFuncName, {
38
+ func: mcpTool.func,
39
+ });
40
+ const tools = pikkuState('mcp', 'tools');
41
+ if (tools.has(mcpTool.name)) {
42
+ throw new Error(`MCP tool already exists: ${mcpTool.name}`);
43
+ }
44
+ tools.set(mcpTool.name, mcpTool);
45
+ };
46
+ export const addMCPPrompt = (mcpPrompt) => {
47
+ const promptsMeta = pikkuState('mcp', 'promptsMeta');
48
+ const mcpPromptMeta = promptsMeta[mcpPrompt.name];
49
+ if (!mcpPromptMeta) {
50
+ throw new Error(`MCP prompt metadata not found for '${mcpPrompt.name}'`);
51
+ }
52
+ addFunction(mcpPromptMeta.pikkuFuncName, {
53
+ func: mcpPrompt.func,
54
+ });
55
+ const prompts = pikkuState('mcp', 'prompts');
56
+ if (prompts.has(mcpPrompt.name)) {
57
+ throw new Error(`MCP prompt already exists: ${mcpPrompt.name}`);
58
+ }
59
+ prompts.set(mcpPrompt.name, mcpPrompt);
60
+ };
61
+ export async function runMCPResource(request, params, uri) {
62
+ let endpoint;
63
+ let pikkuFuncName;
64
+ let extractedParams = {};
65
+ const metas = pikkuState('mcp', 'resourcesMeta');
66
+ const endpoints = pikkuState('mcp', 'resources');
67
+ if (endpoints.has(uri)) {
68
+ endpoint = endpoints.get(uri);
69
+ pikkuFuncName = metas[uri]?.pikkuFuncName;
70
+ }
71
+ else {
72
+ for (const [uriTemplate, value] of endpoints.entries()) {
73
+ // Extract parameter names from the template
74
+ const paramNames = Array.from(uriTemplate.matchAll(/\{([^}]+)\}/g), (m) => m[1]);
75
+ // Create regex pattern to match and capture parameter values
76
+ const regexPattern = uriTemplate.replace(/\{[^}]+\}/g, '([^/]+)');
77
+ const regex = new RegExp(`^${regexPattern}$`);
78
+ const match = uri.match(regex);
79
+ if (match) {
80
+ endpoint = value;
81
+ pikkuFuncName = metas[uriTemplate]?.pikkuFuncName;
82
+ // Extract parameter values and create params object
83
+ for (let i = 0; i < paramNames.length; i++) {
84
+ extractedParams[paramNames[i]] = match[i + 1]; // match[0] is the full match
85
+ }
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ return await runMCPPikkuFunc({
91
+ ...request,
92
+ params: { ...request.params, ...extractedParams },
93
+ }, 'resource', uri, endpoint, pikkuFuncName, { ...params, mcp: { uri } });
94
+ }
95
+ export async function runMCPTool(request, params, name) {
96
+ const endpoint = pikkuState('mcp', 'tools').get(name);
97
+ const meta = pikkuState('mcp', 'toolsMeta')[name];
98
+ return await runMCPPikkuFunc(request, 'tool', name, endpoint, meta?.pikkuFuncName, params);
99
+ }
100
+ export async function runMCPPrompt(request, params, name) {
101
+ const endpoint = pikkuState('mcp', 'prompts').get(name);
102
+ const meta = pikkuState('mcp', 'promptsMeta')[name];
103
+ return await runMCPPikkuFunc(request, 'prompt', name, endpoint, meta?.pikkuFuncName, params);
104
+ }
105
+ /**
106
+ * JSON-RPC 2.0 compatible MCP endpoint runner
107
+ */
108
+ async function runMCPPikkuFunc(request, type, name, mcp, pikkuFuncName, { session, singletonServices, createSessionServices, mcp: interaction, }) {
109
+ let sessionServices;
110
+ try {
111
+ // Validate JSON-RPC request structure
112
+ if (request.jsonrpc !== '2.0') {
113
+ throw new BadRequestError('Invalid JSON-RPC version, only supoorted version is 2.0');
114
+ }
115
+ if (!mcp) {
116
+ throw new NotFoundError(`MCP '${type}' registration not found for '${name}'`);
117
+ }
118
+ if (!pikkuFuncName) {
119
+ throw new NotFoundError(`MCP '${type}' PikkuFunction Mapping not found for '${name}'`);
120
+ }
121
+ singletonServices.logger.debug(`Running MCP ${type}: ${name}`);
122
+ const getAllServices = async () => {
123
+ if (createSessionServices) {
124
+ const services = await createSessionServices(singletonServices, { mcp: interaction }, session);
125
+ sessionServices = services;
126
+ return rpcService.injectRPCService({
127
+ ...singletonServices,
128
+ ...services,
129
+ mcp: interaction,
130
+ });
131
+ }
132
+ return rpcService.injectRPCService({
133
+ ...singletonServices,
134
+ mcp: interaction,
135
+ });
136
+ };
137
+ const result = await runPikkuFunc(pikkuFuncName, {
138
+ getAllServices,
139
+ session,
140
+ data: request.params,
141
+ });
142
+ return {
143
+ id: request.id,
144
+ result,
145
+ };
146
+ }
147
+ catch (e) {
148
+ singletonServices.logger.error(`Error running MCP ${type} '${name}':`, e.constructor);
149
+ const errorResponse = getErrorResponse(e);
150
+ if (errorResponse?.mcpCode) {
151
+ throw new MCPError({
152
+ id: request.id,
153
+ code: errorResponse.mcpCode,
154
+ message: errorResponse.message,
155
+ });
156
+ }
157
+ else {
158
+ if (errorResponse) {
159
+ singletonServices.logger.warn(`Got error without a mapping: ${errorResponse.message}`);
160
+ }
161
+ throw new MCPError({
162
+ id: request.id,
163
+ code: -32603,
164
+ message: 'Internal error',
165
+ data: { message: e.message, stack: e.stack },
166
+ });
167
+ }
168
+ }
169
+ finally {
170
+ if (sessionServices) {
171
+ await closeSessionServices(singletonServices.logger, sessionServices);
172
+ }
173
+ }
174
+ }
175
+ export const getMCPTools = () => {
176
+ return pikkuState('mcp', 'tools');
177
+ };
178
+ export const getMCPResources = () => {
179
+ return pikkuState('mcp', 'resources');
180
+ };
181
+ export const getMCPResourcesMeta = () => {
182
+ return pikkuState('mcp', 'resourcesMeta');
183
+ };
184
+ export const getMCPToolsMeta = () => {
185
+ return pikkuState('mcp', 'toolsMeta');
186
+ };
187
+ export const getMCPPrompts = () => {
188
+ return pikkuState('mcp', 'prompts');
189
+ };
190
+ export const getMCPPromptsMeta = () => {
191
+ return pikkuState('mcp', 'promptsMeta');
192
+ };
@@ -0,0 +1,117 @@
1
+ import { CoreAPIFunctionSessionless } from '../../function/functions.types.js';
2
+ export type PikkuMCP<Tools extends string = any> = {
3
+ uri?: string;
4
+ sendResourceUpdated: (uri: string) => void;
5
+ enableResources: (resources: Record<string, boolean>) => Promise<boolean>;
6
+ enablePrompts: (prompts: Record<string, boolean>) => Promise<boolean>;
7
+ enableTools: (tools: Record<Tools, boolean>) => Promise<boolean>;
8
+ };
9
+ /**
10
+ * Represents metadata for MCP resources, including name, description, and documentation.
11
+ */
12
+ export type MCPResourceMeta = Record<string, Omit<CoreMCPResource, 'func'> & {
13
+ pikkuFuncName: string;
14
+ inputSchema: string | null;
15
+ outputSchema: string | null;
16
+ }>;
17
+ /**
18
+ * Represents metadata for MCP tools, including name, description, and documentation.
19
+ */
20
+ export type MCPToolMeta = Record<string, Omit<CoreMCPTool, 'func'> & {
21
+ pikkuFuncName: string;
22
+ inputSchema: string | null;
23
+ outputSchema: string | null;
24
+ }>;
25
+ /**
26
+ * Represents metadata for MCP prompts, including name, description, and arguments.
27
+ */
28
+ export type MCPPromptMeta = Record<string, Omit<CoreMCPPrompt, 'func'> & {
29
+ pikkuFuncName: string;
30
+ inputSchema: string | null;
31
+ outputSchema: string | null;
32
+ arguments: Array<{
33
+ name: string;
34
+ description: string;
35
+ required: boolean;
36
+ }>;
37
+ }>;
38
+ /**
39
+ * Represents an MCP resource with specific properties.
40
+ */
41
+ export type CoreMCPResource<APIFunction = CoreAPIFunctionSessionless<any, any>> = {
42
+ uri: string;
43
+ title: string;
44
+ description?: string;
45
+ mimeType?: string;
46
+ size?: number;
47
+ streaming?: boolean;
48
+ func: APIFunction;
49
+ tags?: string[];
50
+ };
51
+ /**
52
+ * Represents an MCP tool with specific properties.
53
+ */
54
+ export type CoreMCPTool<APIFunction = CoreAPIFunctionSessionless<any, any>> = {
55
+ name: string;
56
+ title?: string;
57
+ description: string;
58
+ annotations?: Record<string, any>;
59
+ func: APIFunction;
60
+ tags?: string[];
61
+ streaming?: boolean;
62
+ };
63
+ /**
64
+ * Represents an MCP prompt with specific properties.
65
+ */
66
+ export type CoreMCPPrompt<APIFunction = CoreAPIFunctionSessionless<any, MCPPromptResponse>> = {
67
+ name: string;
68
+ description?: string;
69
+ func: APIFunction;
70
+ tags?: string[];
71
+ };
72
+ export type JsonRpcRequest = {
73
+ jsonrpc: string;
74
+ id?: string | number | null;
75
+ params?: any;
76
+ };
77
+ export type JsonRpcResponse = {
78
+ id?: string | number | null;
79
+ result?: any;
80
+ };
81
+ export type JsonRpcErrorResponse = {
82
+ id?: string | number | null;
83
+ code: number;
84
+ message: string;
85
+ data?: any;
86
+ };
87
+ /**
88
+ * Represents a message in an MCP prompt response
89
+ */
90
+ export type MCPPromptMessage = {
91
+ role: 'user' | 'assistant' | 'system';
92
+ content: {
93
+ type: 'text' | 'image';
94
+ text: string;
95
+ data?: string;
96
+ };
97
+ };
98
+ /**
99
+ * Standard response type for MCP prompts - array of messages
100
+ */
101
+ export type MCPPromptResponse = MCPPromptMessage[];
102
+ export type MCPResourceMessage = {
103
+ uri: string;
104
+ text: string;
105
+ };
106
+ export type MCPResourceResponse = MCPResourceMessage[];
107
+ /**
108
+ * Standard response type for MCP prompts - array of messages
109
+ */
110
+ export type MCPToolMessage = {
111
+ type: 'text';
112
+ text: string;
113
+ } | {
114
+ type: 'image';
115
+ data: string;
116
+ };
117
+ export type MCPToolResponse = MCPToolMessage[];
@@ -0,0 +1,6 @@
1
+ export type * from './queue.types.js';
2
+ export { addQueueWorker, runQueueJob, getQueueWorkers, removeQueueWorker, } from './queue-runner.js';
3
+ export { validateWorkerConfig } from './validate-worker-config.js';
4
+ export type { QueueConfigMapping } from './validate-worker-config.js';
5
+ export { registerqueueWorkers } from './register-queue-helper.js';
6
+ export type { QueueRegistrationCallback } from './register-queue-helper.js';
@@ -0,0 +1,6 @@
1
+ // Queue processor management
2
+ export { addQueueWorker, runQueueJob, getQueueWorkers, removeQueueWorker, } from './queue-runner.js';
3
+ // Configuration validation
4
+ export { validateWorkerConfig } from './validate-worker-config.js';
5
+ // Queue registration helper
6
+ export { registerqueueWorkers } from './register-queue-helper.js';