@pikku/core 0.12.4 → 0.12.5
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/CHANGELOG.md +11 -1
- package/dist/dev/hot-reload.d.ts +10 -0
- package/dist/dev/hot-reload.js +158 -0
- package/dist/middleware-runner.d.ts +1 -0
- package/dist/middleware-runner.js +5 -0
- package/dist/permissions.d.ts +1 -0
- package/dist/permissions.js +5 -0
- package/dist/services/in-memory-workflow-service.js +7 -11
- package/dist/wirings/ai-agent/ai-agent-prepare.js +16 -1
- package/dist/wirings/channel/channel-middleware-runner.d.ts +1 -0
- package/dist/wirings/channel/channel-middleware-runner.js +5 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +7 -8
- package/package.json +3 -2
- package/src/crypto-utils.test.ts +214 -0
- package/src/crypto-utils.ts +213 -0
- package/src/dev/hot-reload.test.ts +484 -0
- package/src/dev/hot-reload.ts +212 -0
- package/src/errors/error-handler.ts +62 -0
- package/src/errors/error.test.ts +195 -0
- package/src/errors/errors.ts +374 -0
- package/src/errors/index.ts +2 -0
- package/src/factory-functions.test.ts +109 -0
- package/src/function/function-runner.test.ts +536 -0
- package/src/function/function-runner.ts +365 -0
- package/src/function/functions.types.ts +304 -0
- package/src/function/index.ts +5 -0
- package/src/handle-error.test.ts +424 -0
- package/src/handle-error.ts +69 -0
- package/src/index.ts +118 -0
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +363 -0
- package/src/middleware/auth-apikey.ts +47 -0
- package/src/middleware/auth-bearer.test.ts +450 -0
- package/src/middleware/auth-bearer.ts +72 -0
- package/src/middleware/auth-cookie.test.ts +528 -0
- package/src/middleware/auth-cookie.ts +80 -0
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +104 -0
- package/src/middleware/index.ts +5 -0
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware/timeout.ts +15 -0
- package/src/middleware-runner.test.ts +418 -0
- package/src/middleware-runner.ts +240 -0
- package/src/permissions.test.ts +434 -0
- package/src/permissions.ts +327 -0
- package/src/pikku-request.ts +23 -0
- package/src/pikku-response.ts +5 -0
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +216 -0
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.test.ts +249 -0
- package/src/schema.ts +151 -0
- package/src/services/ai-agent-runner-service.ts +41 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/content-service.ts +76 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gateway-service.ts +20 -0
- package/src/services/gopass-secrets.ts +98 -0
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +64 -0
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/in-memory-workflow-service.ts +502 -0
- package/src/services/index.ts +56 -0
- package/src/services/jwt-service.ts +30 -0
- package/src/services/local-content.ts +120 -0
- package/src/services/local-gateway-service.ts +62 -0
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +94 -0
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +39 -0
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +98 -0
- package/src/services/logger.ts +57 -0
- package/src/services/scheduler-service.ts +86 -0
- package/src/services/schema-service.ts +33 -0
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +38 -0
- package/src/services/trigger-service.ts +17 -0
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +86 -0
- package/src/services/variables-service.ts +11 -0
- package/src/services/workflow-service.ts +95 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/service-tests.ts +873 -0
- package/src/time-utils.test.ts +56 -0
- package/src/time-utils.ts +107 -0
- package/src/types/core.types.ts +478 -0
- package/src/types/state.types.ts +188 -0
- package/src/utils/hash.test.ts +68 -0
- package/src/utils/hash.ts +26 -0
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +129 -0
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +469 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +310 -0
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +659 -0
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
- package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +319 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +773 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +859 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +1153 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +382 -0
- package/src/wirings/ai-agent/index.ts +37 -0
- package/src/wirings/channel/channel-common.ts +90 -0
- package/src/wirings/channel/channel-handler.ts +250 -0
- package/src/wirings/channel/channel-middleware-runner.ts +126 -0
- package/src/wirings/channel/channel-runner.ts +166 -0
- package/src/wirings/channel/channel-store.ts +29 -0
- package/src/wirings/channel/channel.types.ts +172 -0
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/eventhub-service.ts +34 -0
- package/src/wirings/channel/eventhub-store.ts +13 -0
- package/src/wirings/channel/index.ts +24 -0
- package/src/wirings/channel/local/index.ts +3 -0
- package/src/wirings/channel/local/local-channel-handler.ts +81 -0
- package/src/wirings/channel/local/local-channel-runner.test.ts +215 -0
- package/src/wirings/channel/local/local-channel-runner.ts +210 -0
- package/src/wirings/channel/local/local-eventhub-service.test.ts +95 -0
- package/src/wirings/channel/local/local-eventhub-service.ts +101 -0
- package/src/wirings/channel/log-channels.ts +20 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +54 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +45 -0
- package/src/wirings/channel/serverless/index.ts +5 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +289 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +136 -0
- package/src/wirings/cli/channel/index.ts +1 -0
- package/src/wirings/cli/cli-runner.test.ts +403 -0
- package/src/wirings/cli/cli-runner.ts +529 -0
- package/src/wirings/cli/cli.types.ts +358 -0
- package/src/wirings/cli/command-parser.test.ts +445 -0
- package/src/wirings/cli/command-parser.ts +504 -0
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +19 -0
- package/src/wirings/gateway/gateway-runner.test.ts +474 -0
- package/src/wirings/gateway/gateway-runner.ts +411 -0
- package/src/wirings/gateway/gateway.types.ts +149 -0
- package/src/wirings/gateway/index.ts +13 -0
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +197 -0
- package/src/wirings/http/http-runner.test.ts +144 -0
- package/src/wirings/http/http-runner.ts +588 -0
- package/src/wirings/http/http.types.ts +369 -0
- package/src/wirings/http/index.ts +28 -0
- package/src/wirings/http/log-http-routes.ts +22 -0
- package/src/wirings/http/pikku-fetch-http-request.test.ts +237 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +170 -0
- package/src/wirings/http/pikku-fetch-http-response.test.ts +82 -0
- package/src/wirings/http/pikku-fetch-http-response.ts +147 -0
- package/src/wirings/http/routers/http-router.ts +13 -0
- package/src/wirings/http/routers/path-to-regex.test.ts +319 -0
- package/src/wirings/http/routers/path-to-regex.ts +126 -0
- package/src/wirings/http/web-request.test.ts +236 -0
- package/src/wirings/http/web-request.ts +104 -0
- package/src/wirings/mcp/index.ts +27 -0
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +389 -0
- package/src/wirings/mcp/mcp-endpoint-registry.ts +159 -0
- package/src/wirings/mcp/mcp-runner.ts +323 -0
- package/src/wirings/mcp/mcp.types.ts +216 -0
- package/src/wirings/node/index.ts +2 -0
- package/src/wirings/node/node.types.ts +23 -0
- package/src/wirings/oauth2/index.ts +3 -0
- package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
- package/src/wirings/oauth2/oauth2-client.ts +335 -0
- package/src/wirings/oauth2/oauth2.types.ts +69 -0
- package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
- package/src/wirings/queue/index.ts +31 -0
- package/src/wirings/queue/queue-runner.test.ts +710 -0
- package/src/wirings/queue/queue-runner.ts +192 -0
- package/src/wirings/queue/queue.types.ts +189 -0
- package/src/wirings/queue/register-queue-helper.ts +60 -0
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +116 -0
- package/src/wirings/rpc/index.ts +4 -0
- package/src/wirings/rpc/rpc-runner.ts +460 -0
- package/src/wirings/rpc/rpc-types.ts +56 -0
- package/src/wirings/rpc/wire-addon.ts +21 -0
- package/src/wirings/scheduler/index.ts +11 -0
- package/src/wirings/scheduler/log-schedulers.ts +20 -0
- package/src/wirings/scheduler/scheduler-runner.test.ts +660 -0
- package/src/wirings/scheduler/scheduler-runner.ts +133 -0
- package/src/wirings/scheduler/scheduler.types.ts +53 -0
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +135 -0
- package/src/wirings/trigger/trigger.types.ts +178 -0
- package/src/wirings/variable/index.ts +8 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/variable/validate-variable-definitions.ts +69 -0
- package/src/wirings/variable/variable.types.ts +22 -0
- package/src/wirings/workflow/dsl/index.ts +31 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +320 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +28 -0
- package/src/wirings/workflow/graph/graph-node.ts +222 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
- package/src/wirings/workflow/graph/graph-runner.ts +816 -0
- package/src/wirings/workflow/graph/graph-validation.test.ts +170 -0
- package/src/wirings/workflow/graph/graph-validation.ts +237 -0
- package/src/wirings/workflow/graph/index.ts +19 -0
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/graph/template.ts +42 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +104 -0
- package/src/wirings/workflow/index.ts +82 -0
- package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +1179 -0
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow.types.ts +274 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/lcov.info +0 -18891
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import type { PikkuWire } from '../../types/core.types.js'
|
|
2
|
+
import type {
|
|
3
|
+
CoreMCPResource,
|
|
4
|
+
CoreMCPPrompt,
|
|
5
|
+
JsonRpcRequest,
|
|
6
|
+
JsonRpcResponse,
|
|
7
|
+
JsonRpcErrorResponse,
|
|
8
|
+
PikkuMCP,
|
|
9
|
+
} from './mcp.types.js'
|
|
10
|
+
import type {
|
|
11
|
+
CorePikkuFunctionConfig,
|
|
12
|
+
CorePikkuFunctionSessionless,
|
|
13
|
+
} from '../../function/functions.types.js'
|
|
14
|
+
import { getErrorResponse } from '../../errors/error-handler.js'
|
|
15
|
+
import { closeWireServices } from '../../utils.js'
|
|
16
|
+
import {
|
|
17
|
+
pikkuState,
|
|
18
|
+
getSingletonServices,
|
|
19
|
+
getCreateWireServices,
|
|
20
|
+
} from '../../pikku-state.js'
|
|
21
|
+
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
22
|
+
import { resolveNamespace } from '../rpc/rpc-runner.js'
|
|
23
|
+
import {
|
|
24
|
+
BadRequestError,
|
|
25
|
+
NotFoundError,
|
|
26
|
+
PikkuMissingMetaError,
|
|
27
|
+
} from '../../errors/errors.js'
|
|
28
|
+
import {
|
|
29
|
+
PikkuSessionService,
|
|
30
|
+
createMiddlewareSessionWireProps,
|
|
31
|
+
} from '../../services/user-session-service.js'
|
|
32
|
+
|
|
33
|
+
export class MCPError extends Error {
|
|
34
|
+
constructor(public readonly error: JsonRpcErrorResponse) {
|
|
35
|
+
super(error?.message || 'MCP Error')
|
|
36
|
+
this.name = 'MCPError'
|
|
37
|
+
this.stack = new Error().stack
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type RunMCPEndpointParams<Tools extends string = any> = {
|
|
42
|
+
mcp?: PikkuMCP<Tools>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type JsonRpcError = {
|
|
46
|
+
code: number
|
|
47
|
+
message: string
|
|
48
|
+
data?: any
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const wireMCPResource = <
|
|
52
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
53
|
+
CorePikkuFunctionSessionless<any, any>
|
|
54
|
+
> = CorePikkuFunctionConfig<CorePikkuFunctionSessionless<any, any>>,
|
|
55
|
+
>(
|
|
56
|
+
mcpResource: CoreMCPResource<PikkuFunctionConfig>
|
|
57
|
+
) => {
|
|
58
|
+
const resourcesMeta = pikkuState(null, 'mcp', 'resourcesMeta')
|
|
59
|
+
const mcpResourceMeta = resourcesMeta[mcpResource.uri]
|
|
60
|
+
if (!mcpResourceMeta) {
|
|
61
|
+
throw new PikkuMissingMetaError(
|
|
62
|
+
`Missing generated metadata for MCP resource '${mcpResource.uri}'`
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
addFunction(mcpResourceMeta.pikkuFuncId, mcpResource.func as any)
|
|
66
|
+
const resources = pikkuState(null, 'mcp', 'resources')
|
|
67
|
+
if (resources.has(mcpResource.uri)) {
|
|
68
|
+
throw new Error(`MCP resource already exists: ${mcpResource.uri}`)
|
|
69
|
+
}
|
|
70
|
+
resources.set(mcpResource.uri, mcpResource)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const wireMCPPrompt = <
|
|
74
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
75
|
+
CorePikkuFunctionSessionless<any, any>
|
|
76
|
+
> = CorePikkuFunctionConfig<CorePikkuFunctionSessionless<any, any>>,
|
|
77
|
+
>(
|
|
78
|
+
mcpPrompt: CoreMCPPrompt<PikkuFunctionConfig>
|
|
79
|
+
) => {
|
|
80
|
+
const promptsMeta = pikkuState(null, 'mcp', 'promptsMeta')
|
|
81
|
+
const mcpPromptMeta = promptsMeta[mcpPrompt.name]
|
|
82
|
+
if (!mcpPromptMeta) {
|
|
83
|
+
throw new PikkuMissingMetaError(
|
|
84
|
+
`Missing generated metadata for MCP prompt '${mcpPrompt.name}'`
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
addFunction(mcpPromptMeta.pikkuFuncId, mcpPrompt.func as any)
|
|
88
|
+
const prompts = pikkuState(null, 'mcp', 'prompts')
|
|
89
|
+
if (prompts.has(mcpPrompt.name)) {
|
|
90
|
+
throw new Error(`MCP prompt already exists: ${mcpPrompt.name}`)
|
|
91
|
+
}
|
|
92
|
+
prompts.set(mcpPrompt.name, mcpPrompt)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function runMCPResource(
|
|
96
|
+
request: JsonRpcRequest,
|
|
97
|
+
params: RunMCPEndpointParams,
|
|
98
|
+
uri: string
|
|
99
|
+
) {
|
|
100
|
+
let endpoint: CoreMCPResource | undefined
|
|
101
|
+
let pikkuFuncId: string | undefined
|
|
102
|
+
let extractedParams: Record<string, string> = {}
|
|
103
|
+
|
|
104
|
+
const metas = pikkuState(null, 'mcp', 'resourcesMeta')
|
|
105
|
+
const endpoints = pikkuState(null, 'mcp', 'resources')
|
|
106
|
+
|
|
107
|
+
if (endpoints.has(uri)) {
|
|
108
|
+
endpoint = endpoints.get(uri)
|
|
109
|
+
pikkuFuncId = metas[uri]?.pikkuFuncId
|
|
110
|
+
} else {
|
|
111
|
+
for (const [uriTemplate, value] of endpoints.entries()) {
|
|
112
|
+
// Extract parameter names from the template
|
|
113
|
+
const paramNames = Array.from(
|
|
114
|
+
uriTemplate.matchAll(/\{([^}]+)\}/g),
|
|
115
|
+
(m) => m[1]
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Create regex pattern to match and capture parameter values
|
|
119
|
+
const regexPattern = uriTemplate.replace(/\{[^}]+\}/g, '([^/]+)')
|
|
120
|
+
const regex = new RegExp(`^${regexPattern}$`)
|
|
121
|
+
const match = uri.match(regex)
|
|
122
|
+
|
|
123
|
+
if (match) {
|
|
124
|
+
endpoint = value
|
|
125
|
+
pikkuFuncId = metas[uriTemplate]?.pikkuFuncId
|
|
126
|
+
|
|
127
|
+
// Extract parameter values and create params object
|
|
128
|
+
for (let i = 0; i < paramNames.length; i++) {
|
|
129
|
+
extractedParams[paramNames[i]!] = match[i + 1]! // match[0] is the full match
|
|
130
|
+
}
|
|
131
|
+
break
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return await runMCPPikkuFunc(
|
|
137
|
+
{
|
|
138
|
+
...request,
|
|
139
|
+
params: { ...request.params, ...extractedParams },
|
|
140
|
+
},
|
|
141
|
+
'resource',
|
|
142
|
+
uri,
|
|
143
|
+
endpoint,
|
|
144
|
+
pikkuFuncId,
|
|
145
|
+
{ ...params, mcp: { ...params.mcp, uri } } as RunMCPEndpointParams<
|
|
146
|
+
keyof CoreMCPResource
|
|
147
|
+
>
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function runMCPTool(
|
|
152
|
+
request: JsonRpcRequest,
|
|
153
|
+
params: RunMCPEndpointParams,
|
|
154
|
+
name: string
|
|
155
|
+
) {
|
|
156
|
+
const meta = pikkuState(null, 'mcp', 'toolsMeta')[name]
|
|
157
|
+
return await runMCPPikkuFunc(
|
|
158
|
+
request,
|
|
159
|
+
'tool',
|
|
160
|
+
name,
|
|
161
|
+
undefined,
|
|
162
|
+
meta?.pikkuFuncId,
|
|
163
|
+
params
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function runMCPPrompt(
|
|
168
|
+
request: JsonRpcRequest,
|
|
169
|
+
params: RunMCPEndpointParams,
|
|
170
|
+
name: string
|
|
171
|
+
) {
|
|
172
|
+
const endpoint = pikkuState(null, 'mcp', 'prompts').get(name)
|
|
173
|
+
const meta = pikkuState(null, 'mcp', 'promptsMeta')[name]
|
|
174
|
+
return await runMCPPikkuFunc(
|
|
175
|
+
request,
|
|
176
|
+
'prompt',
|
|
177
|
+
name,
|
|
178
|
+
endpoint,
|
|
179
|
+
meta?.pikkuFuncId,
|
|
180
|
+
params
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* JSON-RPC 2.0 compatible MCP endpoint runner
|
|
186
|
+
*/
|
|
187
|
+
async function runMCPPikkuFunc(
|
|
188
|
+
request: JsonRpcRequest,
|
|
189
|
+
type: 'resource' | 'tool' | 'prompt',
|
|
190
|
+
name: string,
|
|
191
|
+
mcp: CoreMCPResource | CoreMCPPrompt | undefined,
|
|
192
|
+
pikkuFuncId: string | undefined,
|
|
193
|
+
{ mcp: mcpWire }: RunMCPEndpointParams
|
|
194
|
+
): Promise<JsonRpcResponse> {
|
|
195
|
+
const singletonServices = getSingletonServices()
|
|
196
|
+
const createWireServices = getCreateWireServices()
|
|
197
|
+
let wireServices: any
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
if (request.jsonrpc !== '2.0') {
|
|
201
|
+
throw new BadRequestError(
|
|
202
|
+
'Invalid JSON-RPC version, only supoorted version is 2.0'
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (mcp === undefined && type !== 'tool') {
|
|
207
|
+
throw new NotFoundError(
|
|
208
|
+
`MCP '${type}' registration not found for '${name}'`
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!pikkuFuncId) {
|
|
213
|
+
throw new NotFoundError(
|
|
214
|
+
`MCP '${type}' PikkuFunction Mapping not found for '${name}'`
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
singletonServices.logger.debug(`Running MCP ${type}: ${name}`)
|
|
219
|
+
|
|
220
|
+
const mcpSessionService = new PikkuSessionService()
|
|
221
|
+
const wire: PikkuWire = {
|
|
222
|
+
mcp: mcpWire,
|
|
223
|
+
...createMiddlewareSessionWireProps(mcpSessionService),
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let meta: any
|
|
227
|
+
if (type === 'resource') {
|
|
228
|
+
meta = pikkuState(null, 'mcp', 'resourcesMeta')[name]
|
|
229
|
+
} else if (type === 'tool') {
|
|
230
|
+
meta = pikkuState(null, 'mcp', 'toolsMeta')[name]
|
|
231
|
+
} else if (type === 'prompt') {
|
|
232
|
+
meta = pikkuState(null, 'mcp', 'promptsMeta')[name]
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Resolve namespaced function IDs (e.g., 'swaggerPetstore:findPetsByStatus')
|
|
236
|
+
let resolvedFuncName = pikkuFuncId
|
|
237
|
+
let resolvedPackageName: string | null = meta?.packageName ?? null
|
|
238
|
+
if (pikkuFuncId.includes(':')) {
|
|
239
|
+
const resolved = resolveNamespace(pikkuFuncId)
|
|
240
|
+
if (resolved) {
|
|
241
|
+
resolvedFuncName = resolved.function
|
|
242
|
+
resolvedPackageName = resolved.package
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
let result = await runPikkuFunc(
|
|
247
|
+
'mcp',
|
|
248
|
+
`${type}:${name}`,
|
|
249
|
+
resolvedFuncName,
|
|
250
|
+
{
|
|
251
|
+
singletonServices,
|
|
252
|
+
createWireServices,
|
|
253
|
+
data: () => request.params,
|
|
254
|
+
inheritedMiddleware: meta?.middleware,
|
|
255
|
+
wireMiddleware: mcp?.middleware,
|
|
256
|
+
inheritedPermissions: meta?.permissions,
|
|
257
|
+
wirePermissions: mcp?.permissions,
|
|
258
|
+
tags: mcp?.tags,
|
|
259
|
+
wire,
|
|
260
|
+
sessionService: mcpSessionService,
|
|
261
|
+
packageName: resolvedPackageName,
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if (type === 'tool' && meta?.outputSchema !== 'MCPToolResponse') {
|
|
266
|
+
result = [{ type: 'text', text: JSON.stringify(result) }]
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
id: request.id,
|
|
271
|
+
result,
|
|
272
|
+
}
|
|
273
|
+
} catch (e: any) {
|
|
274
|
+
singletonServices.logger.error(
|
|
275
|
+
`Error running MCP ${type} '${name}':`,
|
|
276
|
+
e.constructor
|
|
277
|
+
)
|
|
278
|
+
const errorResponse = getErrorResponse(e)
|
|
279
|
+
if (errorResponse?.mcpCode) {
|
|
280
|
+
throw new MCPError({
|
|
281
|
+
id: request.id,
|
|
282
|
+
code: errorResponse.mcpCode,
|
|
283
|
+
message: errorResponse.message,
|
|
284
|
+
})
|
|
285
|
+
} else {
|
|
286
|
+
if (errorResponse) {
|
|
287
|
+
singletonServices.logger.warn(
|
|
288
|
+
`Got error without a mapping: ${errorResponse.message}`
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
throw new MCPError({
|
|
292
|
+
id: request.id,
|
|
293
|
+
code: -32603,
|
|
294
|
+
message: 'Internal error',
|
|
295
|
+
data: { message: e.message, stack: e.stack },
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
} finally {
|
|
299
|
+
if (wireServices) {
|
|
300
|
+
await closeWireServices(singletonServices.logger, wireServices)
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export const getMCPResources = () => {
|
|
306
|
+
return pikkuState(null, 'mcp', 'resources')
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export const getMCPResourcesMeta = () => {
|
|
310
|
+
return pikkuState(null, 'mcp', 'resourcesMeta')
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export const getMCPToolsMeta = () => {
|
|
314
|
+
return pikkuState(null, 'mcp', 'toolsMeta')
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export const getMCPPrompts = () => {
|
|
318
|
+
return pikkuState(null, 'mcp', 'prompts')
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export const getMCPPromptsMeta = () => {
|
|
322
|
+
return pikkuState(null, 'mcp', 'promptsMeta')
|
|
323
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CorePermissionGroup,
|
|
3
|
+
CorePikkuFunctionConfig,
|
|
4
|
+
CorePikkuFunctionSessionless,
|
|
5
|
+
CorePikkuPermission,
|
|
6
|
+
} from '../../function/functions.types.js'
|
|
7
|
+
import type {
|
|
8
|
+
CorePikkuMiddleware,
|
|
9
|
+
MiddlewareMetadata,
|
|
10
|
+
PermissionMetadata,
|
|
11
|
+
} from '../../types/core.types.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extract URI parameters from MCP resource URI template.
|
|
15
|
+
* E.g., "user/{userId}/post/{postId}" => "userId" | "postId"
|
|
16
|
+
*/
|
|
17
|
+
type ExtractMCPURIParams<S extends string> =
|
|
18
|
+
S extends `${string}{${infer Param}}/${infer Rest}`
|
|
19
|
+
? Param | ExtractMCPURIParams<Rest>
|
|
20
|
+
: S extends `${string}{${infer Param}}`
|
|
21
|
+
? Param
|
|
22
|
+
: never
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type-level assertion that MCP resource URI parameters are present in the input type.
|
|
26
|
+
* This ensures compile-time safety for URI parameter validation.
|
|
27
|
+
*/
|
|
28
|
+
export type AssertMCPResourceURIParams<In, URI extends string> =
|
|
29
|
+
ExtractMCPURIParams<URI> extends keyof In
|
|
30
|
+
? unknown
|
|
31
|
+
: [
|
|
32
|
+
'Error: MCP Resource URI parameters',
|
|
33
|
+
ExtractMCPURIParams<URI>,
|
|
34
|
+
'not in input type',
|
|
35
|
+
keyof In,
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
export type PikkuMCP<Tools extends string = any> = {
|
|
39
|
+
// elicitInput: <Input>(message: string) => Promise<{ action: string, content: Input }>
|
|
40
|
+
uri?: string
|
|
41
|
+
sendResourceUpdated: (uri: string) => void
|
|
42
|
+
enableResources: (resources: Record<string, boolean>) => Promise<boolean>
|
|
43
|
+
enablePrompts: (prompts: Record<string, boolean>) => Promise<boolean>
|
|
44
|
+
enableTools: (tools: Record<Tools, boolean>) => Promise<boolean>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Represents metadata for MCP resources, including name, description, and documentation.
|
|
49
|
+
*/
|
|
50
|
+
export type MCPResourceMeta = Record<
|
|
51
|
+
string,
|
|
52
|
+
Omit<CoreMCPResource, 'func' | 'middleware' | 'permissions'> & {
|
|
53
|
+
pikkuFuncId: string
|
|
54
|
+
inputSchema: string | null
|
|
55
|
+
outputSchema: string | null
|
|
56
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
57
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
58
|
+
}
|
|
59
|
+
>
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Represents metadata for MCP tools, including name, description, and documentation.
|
|
63
|
+
*/
|
|
64
|
+
export type MCPToolMeta = Record<
|
|
65
|
+
string,
|
|
66
|
+
Omit<CoreMCPTool, 'func' | 'middleware' | 'permissions'> & {
|
|
67
|
+
pikkuFuncId: string
|
|
68
|
+
inputSchema: string | null
|
|
69
|
+
outputSchema: string | null
|
|
70
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
71
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
72
|
+
}
|
|
73
|
+
>
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Represents metadata for MCP prompts, including name, description, and arguments.
|
|
77
|
+
*/
|
|
78
|
+
export type MCPPromptMeta = Record<
|
|
79
|
+
string,
|
|
80
|
+
Omit<CoreMCPPrompt, 'func' | 'middleware' | 'permissions'> & {
|
|
81
|
+
pikkuFuncId: string
|
|
82
|
+
inputSchema: string | null
|
|
83
|
+
outputSchema: string | null
|
|
84
|
+
arguments: Array<{
|
|
85
|
+
name: string
|
|
86
|
+
description: string
|
|
87
|
+
required: boolean
|
|
88
|
+
}>
|
|
89
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
90
|
+
permissions?: PermissionMetadata[] // Pre-resolved permission chain (tag + explicit)
|
|
91
|
+
}
|
|
92
|
+
>
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Represents an MCP resource with specific properties.
|
|
96
|
+
*/
|
|
97
|
+
export type CoreMCPResource<
|
|
98
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
99
|
+
CorePikkuFunctionSessionless<any, any>
|
|
100
|
+
>,
|
|
101
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
102
|
+
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
103
|
+
> = {
|
|
104
|
+
uri: string
|
|
105
|
+
title: string
|
|
106
|
+
description: string
|
|
107
|
+
summary?: string
|
|
108
|
+
errors?: string[]
|
|
109
|
+
mimeType?: string
|
|
110
|
+
size?: number
|
|
111
|
+
streaming?: boolean
|
|
112
|
+
func: PikkuFunctionConfig
|
|
113
|
+
tags?: string[]
|
|
114
|
+
middleware?: PikkuMiddleware[]
|
|
115
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Represents an MCP tool with specific properties.
|
|
120
|
+
*/
|
|
121
|
+
export type CoreMCPTool<
|
|
122
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
123
|
+
CorePikkuFunctionSessionless<any, any>
|
|
124
|
+
>,
|
|
125
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
126
|
+
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
127
|
+
> = {
|
|
128
|
+
name: string
|
|
129
|
+
title?: string
|
|
130
|
+
description: string
|
|
131
|
+
summary?: string
|
|
132
|
+
errors?: string[]
|
|
133
|
+
func: PikkuFunctionConfig
|
|
134
|
+
tags?: string[]
|
|
135
|
+
streaming?: boolean
|
|
136
|
+
middleware?: PikkuMiddleware[]
|
|
137
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Represents an MCP prompt with specific properties.
|
|
142
|
+
*/
|
|
143
|
+
export type CoreMCPPrompt<
|
|
144
|
+
PikkuFunctionConfig = CorePikkuFunctionConfig<
|
|
145
|
+
CorePikkuFunctionSessionless<any, MCPPromptResponse>
|
|
146
|
+
>,
|
|
147
|
+
PikkuPermission = CorePikkuPermission<any, any>,
|
|
148
|
+
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
149
|
+
> = {
|
|
150
|
+
name: string
|
|
151
|
+
description: string
|
|
152
|
+
summary?: string
|
|
153
|
+
errors?: string[]
|
|
154
|
+
func: PikkuFunctionConfig
|
|
155
|
+
tags?: string[]
|
|
156
|
+
middleware?: PikkuMiddleware[]
|
|
157
|
+
permissions?: CorePermissionGroup<PikkuPermission>
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type JsonRpcRequest = {
|
|
161
|
+
jsonrpc: string
|
|
162
|
+
id?: string | number | null
|
|
163
|
+
params?: any
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export type JsonRpcResponse = {
|
|
167
|
+
id?: string | number | null
|
|
168
|
+
result?: any
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type JsonRpcErrorResponse = {
|
|
172
|
+
id?: string | number | null
|
|
173
|
+
code: number
|
|
174
|
+
message: string
|
|
175
|
+
data?: any
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Represents a message in an MCP prompt response
|
|
180
|
+
*/
|
|
181
|
+
export type MCPPromptMessage = {
|
|
182
|
+
role: 'user' | 'assistant' | 'system'
|
|
183
|
+
content: {
|
|
184
|
+
type: 'text' | 'image'
|
|
185
|
+
text: string
|
|
186
|
+
data?: string // for image content
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Standard response type for MCP prompts - array of messages
|
|
192
|
+
*/
|
|
193
|
+
export type MCPPromptResponse = MCPPromptMessage[]
|
|
194
|
+
|
|
195
|
+
export type MCPResourceMessage = {
|
|
196
|
+
uri: string
|
|
197
|
+
text: string
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export type MCPResourceResponse = MCPResourceMessage[]
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Standard response type for MCP prompts - array of messages
|
|
204
|
+
*/
|
|
205
|
+
|
|
206
|
+
export type MCPToolMessage =
|
|
207
|
+
| {
|
|
208
|
+
type: 'text'
|
|
209
|
+
text: string
|
|
210
|
+
}
|
|
211
|
+
| {
|
|
212
|
+
type: 'image'
|
|
213
|
+
data: string // base64 encoded image data
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export type MCPToolResponse = MCPToolMessage[]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type NodeType = 'trigger' | 'action' | 'end'
|
|
2
|
+
|
|
3
|
+
export type CoreNodeConfig = {
|
|
4
|
+
displayName: string
|
|
5
|
+
category: string
|
|
6
|
+
type: NodeType
|
|
7
|
+
errorOutput?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type NodeMeta = {
|
|
11
|
+
name: string
|
|
12
|
+
displayName: string
|
|
13
|
+
category: string
|
|
14
|
+
type: NodeType
|
|
15
|
+
rpc: string
|
|
16
|
+
description?: string
|
|
17
|
+
errorOutput: boolean
|
|
18
|
+
inputSchemaName: string | null
|
|
19
|
+
outputSchemaName: string | null
|
|
20
|
+
tags?: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type NodesMeta = Record<string, NodeMeta>
|