@decocms/runtime 0.28.1 → 1.0.0-alpha-candy.2

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 (97) hide show
  1. package/package.json +12 -78
  2. package/scripts/generate-json-schema.ts +24 -0
  3. package/src/asset-server/dev-server-proxy.ts +16 -0
  4. package/src/asset-server/index.ts +44 -0
  5. package/src/bindings/README.md +1 -1
  6. package/src/bindings/binder.ts +2 -5
  7. package/src/bindings/channels.ts +1 -1
  8. package/src/bindings/index.ts +0 -33
  9. package/src/bindings/language-model/utils.ts +0 -91
  10. package/src/bindings.ts +30 -108
  11. package/src/client.ts +1 -145
  12. package/src/index.ts +46 -175
  13. package/src/mcp.ts +8 -165
  14. package/src/proxy.ts +3 -62
  15. package/src/state.ts +1 -30
  16. package/src/tools.ts +336 -0
  17. package/src/wrangler.ts +5 -5
  18. package/tsconfig.json +8 -0
  19. package/dist/admin.d.ts +0 -5
  20. package/dist/admin.js +0 -21
  21. package/dist/admin.js.map +0 -1
  22. package/dist/bindings/deconfig/index.d.ts +0 -12
  23. package/dist/bindings/deconfig/index.js +0 -10
  24. package/dist/bindings/deconfig/index.js.map +0 -1
  25. package/dist/bindings/index.d.ts +0 -2315
  26. package/dist/bindings/index.js +0 -156
  27. package/dist/bindings/index.js.map +0 -1
  28. package/dist/chunk-3AWMDSOH.js +0 -96
  29. package/dist/chunk-3AWMDSOH.js.map +0 -1
  30. package/dist/chunk-4XSQKJLU.js +0 -105
  31. package/dist/chunk-4XSQKJLU.js.map +0 -1
  32. package/dist/chunk-5EYZ2LVM.js +0 -158
  33. package/dist/chunk-5EYZ2LVM.js.map +0 -1
  34. package/dist/chunk-7ITSLORK.js +0 -128
  35. package/dist/chunk-7ITSLORK.js.map +0 -1
  36. package/dist/chunk-I7BWSAN6.js +0 -49
  37. package/dist/chunk-I7BWSAN6.js.map +0 -1
  38. package/dist/chunk-L4OT2YDO.js +0 -27
  39. package/dist/chunk-L4OT2YDO.js.map +0 -1
  40. package/dist/chunk-SHQSNOFL.js +0 -769
  41. package/dist/chunk-SHQSNOFL.js.map +0 -1
  42. package/dist/chunk-UHR3BLMF.js +0 -92
  43. package/dist/chunk-UHR3BLMF.js.map +0 -1
  44. package/dist/chunk-UIJGM3NV.js +0 -518
  45. package/dist/chunk-UIJGM3NV.js.map +0 -1
  46. package/dist/chunk-ZPUT6RN6.js +0 -32
  47. package/dist/chunk-ZPUT6RN6.js.map +0 -1
  48. package/dist/client.d.ts +0 -28
  49. package/dist/client.js +0 -5
  50. package/dist/client.js.map +0 -1
  51. package/dist/d1-store.d.ts +0 -9
  52. package/dist/d1-store.js +0 -4
  53. package/dist/d1-store.js.map +0 -1
  54. package/dist/drizzle.d.ts +0 -49
  55. package/dist/drizzle.js +0 -121
  56. package/dist/drizzle.js.map +0 -1
  57. package/dist/index-LOfgE9a_.d.ts +0 -471
  58. package/dist/index-xKtm7A7B.d.ts +0 -530
  59. package/dist/index.d.ts +0 -10
  60. package/dist/index.js +0 -637
  61. package/dist/index.js.map +0 -1
  62. package/dist/mastra.d.ts +0 -10
  63. package/dist/mastra.js +0 -6
  64. package/dist/mastra.js.map +0 -1
  65. package/dist/mcp-87iLaW9V.d.ts +0 -105
  66. package/dist/mcp-client.d.ts +0 -232
  67. package/dist/mcp-client.js +0 -4
  68. package/dist/mcp-client.js.map +0 -1
  69. package/dist/proxy.d.ts +0 -11
  70. package/dist/proxy.js +0 -5
  71. package/dist/proxy.js.map +0 -1
  72. package/dist/resources.d.ts +0 -362
  73. package/dist/resources.js +0 -4
  74. package/dist/resources.js.map +0 -1
  75. package/dist/views.d.ts +0 -72
  76. package/dist/views.js +0 -4
  77. package/dist/views.js.map +0 -1
  78. package/src/admin.ts +0 -16
  79. package/src/auth.ts +0 -233
  80. package/src/bindings/deconfig/helpers.ts +0 -107
  81. package/src/bindings/deconfig/index.ts +0 -1
  82. package/src/bindings/deconfig/resources.ts +0 -659
  83. package/src/bindings/deconfig/types.ts +0 -106
  84. package/src/bindings/language-model/ai-sdk.ts +0 -87
  85. package/src/bindings/language-model/index.ts +0 -4
  86. package/src/bindings/resources/bindings.ts +0 -99
  87. package/src/bindings/resources/helpers.ts +0 -95
  88. package/src/bindings/resources/schemas.ts +0 -265
  89. package/src/bindings/views.ts +0 -14
  90. package/src/cf-imports.ts +0 -1
  91. package/src/d1-store.ts +0 -34
  92. package/src/deprecated.ts +0 -59
  93. package/src/drizzle.ts +0 -201
  94. package/src/mastra.ts +0 -898
  95. package/src/resources.ts +0 -168
  96. package/src/views.ts +0 -26
  97. package/src/workflow.ts +0 -193
package/package.json CHANGED
@@ -1,101 +1,35 @@
1
1
  {
2
2
  "name": "@decocms/runtime",
3
- "version": "0.28.1",
3
+ "version": "1.0.0-alpha-candy.2",
4
4
  "type": "module",
5
- "scripts": {
6
- "build": "tsup",
7
- "prepublishOnly": "npm run build"
8
- },
9
5
  "dependencies": {
10
6
  "@cloudflare/workers-types": "^4.20250617.0",
11
7
  "@deco/mcp": "npm:@jsr/deco__mcp@0.5.5",
12
- "@decocms/bindings": "*",
13
- "@mastra/cloudflare-d1": "^0.13.4",
8
+ "@decocms/bindings": "1.0.1-alpha-candy.1",
14
9
  "@mastra/core": "^0.20.2",
15
10
  "@modelcontextprotocol/sdk": "^1.19.1",
16
11
  "@ai-sdk/provider": "^2.0.0",
17
12
  "bidc": "0.0.3",
18
13
  "drizzle-orm": "^0.44.5",
14
+ "hono": "^4.10.7",
19
15
  "jose": "^6.0.11",
20
16
  "mime-db": "1.52.0",
21
17
  "zod": "^3.25.76",
22
18
  "zod-from-json-schema": "^0.0.5",
23
19
  "zod-to-json-schema": "3.25.0"
24
20
  },
25
- "main": "./dist/index.js",
26
- "types": "./dist/index.d.ts",
27
- "files": [
28
- "dist/**/*",
29
- "src/**/*",
30
- "config-schema.json"
31
- ],
32
21
  "exports": {
33
- ".": {
34
- "source": "./src/index.ts",
35
- "types": "./dist/index.d.ts",
36
- "default": "./dist/index.js"
37
- },
38
- "./proxy": {
39
- "source": "./src/proxy.ts",
40
- "types": "./dist/proxy.d.ts",
41
- "default": "./dist/proxy.js"
42
- },
43
- "./admin": {
44
- "source": "./src/admin.ts",
45
- "types": "./dist/admin.d.ts",
46
- "default": "./dist/admin.js"
47
- },
48
- "./client": {
49
- "source": "./src/client.ts",
50
- "types": "./dist/client.d.ts",
51
- "default": "./dist/client.js"
52
- },
53
- "./mastra": {
54
- "source": "./src/mastra.ts",
55
- "types": "./dist/mastra.d.ts",
56
- "default": "./dist/mastra.js"
57
- },
58
- "./drizzle": {
59
- "source": "./src/drizzle.ts",
60
- "types": "./dist/drizzle.d.ts",
61
- "default": "./dist/drizzle.js"
62
- },
63
- "./d1": {
64
- "source": "./src/d1-store.ts",
65
- "types": "./dist/d1-store.d.ts",
66
- "default": "./dist/d1-store.js"
67
- },
68
- "./resources": {
69
- "source": "./src/resources.ts",
70
- "types": "./dist/resources.d.ts",
71
- "default": "./dist/resources.js"
72
- },
73
- "./views": {
74
- "source": "./src/views.ts",
75
- "types": "./dist/views.d.ts",
76
- "default": "./dist/views.js"
77
- },
78
- "./mcp-client": {
79
- "source": "./src/mcp-client.ts",
80
- "types": "./dist/mcp-client.d.ts",
81
- "default": "./dist/mcp-client.js"
82
- },
83
- "./bindings": {
84
- "source": "./src/bindings/index.ts",
85
- "types": "./dist/bindings/index.d.ts",
86
- "default": "./dist/bindings/index.js"
87
- },
88
- "./deconfig": {
89
- "source": "./src/bindings/deconfig/index.ts",
90
- "types": "./dist/bindings/deconfig/index.d.ts",
91
- "default": "./dist/bindings/deconfig/index.js"
92
- }
22
+ ".": "./src/index.ts",
23
+ "./proxy": "./src/proxy.ts",
24
+ "./client": "./src/client.ts",
25
+ "./mcp-client": "./src/mcp-client.ts",
26
+ "./bindings": "./src/bindings/index.ts",
27
+ "./asset-server": "./src/asset-server/index.ts",
28
+ "./tools": "./src/tools.ts"
93
29
  },
94
30
  "devDependencies": {
95
31
  "@types/mime-db": "^1.43.6",
96
- "ts-json-schema-generator": "^2.4.0",
97
- "tsup": "^8.5.0",
98
- "typescript": "^5.9.3"
32
+ "ts-json-schema-generator": "^2.4.0"
99
33
  },
100
34
  "engines": {
101
35
  "node": ">=24.0.0"
@@ -103,4 +37,4 @@
103
37
  "publishConfig": {
104
38
  "access": "public"
105
39
  }
106
- }
40
+ }
@@ -0,0 +1,24 @@
1
+ // heavily inspired by https://github.com/cloudflare/workers-sdk/blob/main/packages/wrangler/scripts/generate-json-schema.ts
2
+ import { writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { createGenerator } from "ts-json-schema-generator";
5
+ import type { Config, Schema } from "ts-json-schema-generator";
6
+
7
+ const config: Config = {
8
+ path: join(import.meta.dirname!, "../src/wrangler.ts"),
9
+ type: "WranglerConfig",
10
+ skipTypeCheck: true,
11
+ };
12
+
13
+ const applyFormattingRules = (schema: Schema) => {
14
+ return { ...schema, allowTrailingCommas: true };
15
+ };
16
+
17
+ const schema = applyFormattingRules(
18
+ createGenerator(config).createSchema(config.type),
19
+ );
20
+
21
+ writeFileSync(
22
+ join(import.meta.dirname!, "../config-schema.json"),
23
+ JSON.stringify(schema, null, 2),
24
+ );
@@ -0,0 +1,16 @@
1
+ import { proxy } from "hono/proxy";
2
+ import { Context } from "hono";
3
+
4
+ export const devServerProxy = (url: string | URL) => (c: Context) => {
5
+ const incomingUrl = new URL(c.req.raw.url);
6
+ const target = new URL(url);
7
+ target.pathname = incomingUrl.pathname;
8
+ target.search = incomingUrl.search;
9
+
10
+ return proxy(target, {
11
+ raw: c.req.raw,
12
+ headers: {
13
+ ...c.req.raw.headers,
14
+ },
15
+ });
16
+ };
@@ -0,0 +1,44 @@
1
+ import { serveStatic } from "hono/bun";
2
+ import { Hono } from "hono";
3
+ import { devServerProxy } from "./dev-server-proxy";
4
+ import { Handler } from "hono/types";
5
+
6
+ interface AssetServerConfig {
7
+ env: "development" | "production" | "test";
8
+ localDevProxyUrl?: string | URL;
9
+ assetsDirectory?: string;
10
+ }
11
+
12
+ const DEFAULT_LOCAL_DEV_PROXY_URL = "http://localhost:4000";
13
+ const DEFAULT_ASSETS_DIRECTORY = "./dist/client";
14
+
15
+ interface HonoApp {
16
+ use: (path: string, handler: Handler) => void;
17
+ get: (path: string, handler: Handler) => void;
18
+ }
19
+
20
+ export const applyAssetServerRoutes = (
21
+ app: HonoApp,
22
+ config: AssetServerConfig,
23
+ ) => {
24
+ const environment = config.env;
25
+ const localDevProxyUrl =
26
+ config.localDevProxyUrl ?? DEFAULT_LOCAL_DEV_PROXY_URL;
27
+ const assetsDirectory = config.assetsDirectory ?? DEFAULT_ASSETS_DIRECTORY;
28
+
29
+ if (environment === "development") {
30
+ app.use("*", devServerProxy(localDevProxyUrl));
31
+ } else if (environment === "production") {
32
+ app.use("/assets/*", serveStatic({ root: assetsDirectory }));
33
+ app.get("*", serveStatic({ path: `${assetsDirectory}/index.html` }));
34
+ }
35
+ };
36
+
37
+ export const createAssetServer = (config: AssetServerConfig) => {
38
+ const app = new Hono();
39
+ applyAssetServerRoutes(app, config);
40
+ return app;
41
+ };
42
+
43
+ export const createAssetServerFetcher = (config: AssetServerConfig) =>
44
+ createAssetServer(config).fetch;
@@ -78,7 +78,7 @@ To create a new binding:
78
78
  input/output:
79
79
 
80
80
  ```ts
81
- import { z } from "zod/v3";
81
+ import { z } from "zod";
82
82
  import type { Binder } from "../index.ts";
83
83
 
84
84
  const myInputSchema = z.object({ ... });
@@ -1,14 +1,13 @@
1
1
  /* oxlint-disable no-explicit-any */
2
- import { z } from "zod/v3";
2
+ import { z } from "zod";
3
3
  import type { MCPConnection } from "../connection.ts";
4
- import { createPrivateTool, createStreamableTool } from "../mastra.ts";
5
4
  import {
6
5
  createMCPFetchStub,
7
6
  type MCPClientFetchStub,
8
7
  type ToolBinder,
9
8
  } from "../mcp.ts";
9
+ import { createPrivateTool, createStreamableTool } from "../tools.ts";
10
10
  import { CHANNEL_BINDING } from "./channels.ts";
11
- import { VIEW_BINDING } from "./views.ts";
12
11
 
13
12
  // ToolLike is a simplified version of the Tool interface that matches what we need for bindings
14
13
  export interface ToolLike<
@@ -93,8 +92,6 @@ export type MCPBindingClient<T extends ReturnType<typeof bindingClient>> =
93
92
  ReturnType<T["forConnection"]>;
94
93
 
95
94
  export const ChannelBinding = bindingClient(CHANNEL_BINDING);
96
- export const ViewBinding = bindingClient(VIEW_BINDING);
97
-
98
95
  export type { Callbacks } from "./channels.ts";
99
96
 
100
97
  export const impl = <TBinder extends Binder>(
@@ -1,4 +1,4 @@
1
- import { z } from "zod/v3";
1
+ import { z } from "zod";
2
2
  import type { ToolBinder } from "../mcp.ts";
3
3
 
4
4
  const callbacksSchema = z.object({
@@ -1,16 +1,13 @@
1
1
  import { CHANNEL_BINDING } from "./channels.ts";
2
- import { VIEW_BINDING as VIEWS_BINDING } from "./views.ts";
3
2
 
4
3
  // Import new Resources 2.0 bindings function
5
4
  import { LANGUAGE_MODEL_BINDING } from "@decocms/bindings/llm";
6
- import { createResourceBindings } from "./resources/bindings.ts";
7
5
 
8
6
  // Export types and utilities from binder
9
7
  export {
10
8
  bindingClient,
11
9
  ChannelBinding,
12
10
  impl,
13
- ViewBinding,
14
11
  type Binder,
15
12
  type BinderImplementation,
16
13
  type MCPBindingClient,
@@ -23,40 +20,10 @@ export * from "./channels.ts";
23
20
  // Export binding utilities
24
21
  export * from "./utils.ts";
25
22
 
26
- // Export views schemas
27
- export * from "./views.ts";
28
-
29
- // Re-export Resources bindings function for convenience
30
- export { createResourceBindings };
31
-
32
- // Export resources types and schemas
33
- export * from "./resources/bindings.ts";
34
- export * from "./resources/helpers.ts";
35
- export * from "./resources/schemas.ts";
36
-
37
- // Export deconfig helpers and types
38
- export {
39
- getMetadataString as deconfigGetMetadataString,
40
- getMetadataValue as deconfigGetMetadataValue,
41
- normalizeDirectory as deconfigNormalizeDirectory,
42
- ResourcePath,
43
- ResourceUri,
44
- } from "./deconfig/helpers.ts";
45
- export { createDeconfigResource } from "./deconfig/index.ts";
46
- export type {
47
- DeconfigClient,
48
- DeconfigResourceOptions,
49
- EnhancedResourcesTools,
50
- ResourcesBinding,
51
- ResourcesTools,
52
- } from "./deconfig/index.ts";
53
- export { deconfigTools } from "./deconfig/types.ts";
54
-
55
23
  export { streamToResponse } from "./language-model/utils.ts";
56
24
 
57
25
  export const WellKnownBindings = {
58
26
  Channel: CHANNEL_BINDING,
59
- View: VIEWS_BINDING,
60
27
  LanguageModel: LANGUAGE_MODEL_BINDING,
61
28
  // Note: Resources is not included here since it's a generic function
62
29
  // Use createResourceBindings(dataSchema) directly for Resources 2.0
@@ -25,94 +25,3 @@ export function streamToResponse(
25
25
  },
26
26
  });
27
27
  }
28
-
29
- export function responseToStream(
30
- response: Response,
31
- ): ReadableStream<LanguageModelV2StreamPart> {
32
- if (!response.body) {
33
- throw new Error("Response body is null");
34
- }
35
-
36
- return response.body.pipeThrough(new TextDecoderStream()).pipeThrough(
37
- new TransformStream<string, LanguageModelV2StreamPart>({
38
- transform(chunk, controller) {
39
- // Split by newlines and parse each line
40
- const lines = chunk.split("\n");
41
-
42
- for (const line of lines) {
43
- if (line.trim()) {
44
- try {
45
- const parsed = JSON.parse(line) as LanguageModelV2StreamPart;
46
- controller.enqueue(parsed);
47
- } catch (error) {
48
- console.error("Failed to parse stream chunk:", error);
49
- }
50
- }
51
- }
52
- },
53
- }),
54
- );
55
- }
56
-
57
- /**
58
- * Lazy promise wrapper that defers execution until the promise is awaited.
59
- * The factory function is only called when .then() is invoked for the first time.
60
- */
61
- class Lazy<T> implements PromiseLike<T> {
62
- private promise: Promise<T> | null = null;
63
-
64
- constructor(private factory: () => Promise<T>) {}
65
-
66
- private getOrCreatePromise(): Promise<T> {
67
- if (!this.promise) {
68
- this.promise = this.factory();
69
- }
70
- return this.promise;
71
- }
72
-
73
- // eslint-disable-next-line no-thenable
74
- then<TResult1 = T, TResult2 = never>(
75
- onfulfilled?:
76
- | ((value: T) => TResult1 | PromiseLike<TResult1>)
77
- | null
78
- | undefined,
79
- onrejected?:
80
- | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)
81
- | null
82
- | undefined,
83
- ): PromiseLike<TResult1 | TResult2> {
84
- return this.getOrCreatePromise().then(onfulfilled, onrejected);
85
- }
86
-
87
- catch<TResult = never>(
88
- onrejected?:
89
- | ((reason: unknown) => TResult | PromiseLike<TResult>)
90
- | null
91
- | undefined,
92
- ): Promise<T | TResult> {
93
- return this.getOrCreatePromise().catch(onrejected);
94
- }
95
-
96
- finally(onfinally?: (() => void) | null | undefined): Promise<T> {
97
- return this.getOrCreatePromise().finally(onfinally);
98
- }
99
- }
100
-
101
- /**
102
- * Creates a lazy promise that only executes when awaited.
103
- *
104
- * @param factory - A function that returns a Promise<T>
105
- * @returns A Promise-like object that defers execution until .then() is called
106
- *
107
- * @example
108
- * ```ts
109
- * const lazyData = lazy(() => fetchExpensiveData());
110
- * // fetchExpensiveData() is NOT called yet
111
- *
112
- * const result = await lazyData;
113
- * // fetchExpensiveData() is called NOW
114
- * ```
115
- */
116
- export function lazy<T>(factory: () => Promise<T>): Promise<T> {
117
- return new Lazy(factory) as unknown as Promise<T>;
118
- }
package/src/bindings.ts CHANGED
@@ -4,88 +4,22 @@ import { MCPClient } from "./mcp.ts";
4
4
  import type {
5
5
  BindingBase,
6
6
  ContractBinding,
7
+ MCPAppBinding,
7
8
  MCPBinding,
8
- MCPIntegrationNameBinding,
9
9
  } from "./wrangler.ts";
10
10
 
11
- interface IntegrationContext {
12
- integrationId: string;
13
- workspace: string;
14
- branch?: string;
15
- decoCmsApiUrl?: string;
16
- }
17
-
18
- const normalizeWorkspace = (workspace: string) => {
19
- if (workspace.startsWith("/users")) {
20
- return workspace;
21
- }
22
- if (workspace.startsWith("/shared")) {
23
- return workspace;
24
- }
25
- if (workspace.includes("/")) {
26
- return workspace;
27
- }
28
- return `/shared/${workspace}`;
29
- };
30
-
31
- /**
32
- * Url: /apps/mcp?appName=$appName
33
- */
34
- const createAppsUrl = ({
35
- appName,
36
- decoChatApiUrl,
37
- }: {
38
- appName: string;
39
- decoChatApiUrl?: string;
40
- }) =>
41
- new URL(
42
- `/apps/mcp?appName=${appName}`,
43
- decoChatApiUrl ?? "https://api.decocms.com",
44
- ).href;
45
- /**
46
- * Url: /:workspace.root/:workspace.slug/:integrationId/mcp
47
- */
48
- const createIntegrationsUrl = ({
49
- integrationId,
50
- workspace,
51
- decoCmsApiUrl,
52
- branch,
53
- }: IntegrationContext) => {
54
- const base = `${normalizeWorkspace(workspace)}/${integrationId}/mcp`;
55
- const url = new URL(base, decoCmsApiUrl ?? "https://api.decocms.com");
56
- branch && url.searchParams.set("branch", branch);
57
- return url.href;
58
- };
59
-
60
- type WorkspaceClientContext = Omit<
11
+ type ClientContext = Omit<
61
12
  RequestContext,
62
13
  "ensureAuthenticated" | "state" | "fetchIntegrationMetadata"
63
14
  >;
64
- export const workspaceClient = (
65
- ctx: WorkspaceClientContext,
66
- ): ReturnType<(typeof MCPClient)["forWorkspace"]> => {
67
- return MCPClient.forWorkspace(ctx.workspace, ctx.token);
68
- };
69
-
70
- const mcpClientForAppName = (appName: string, decoChatApiUrl?: string) => {
71
- const mcpConnection: MCPConnection = {
72
- type: "HTTP",
73
- url: createAppsUrl({
74
- appName,
75
- decoChatApiUrl,
76
- }),
77
- };
78
-
79
- return MCPClient.forConnection(mcpConnection);
80
- };
81
15
 
82
16
  export const proxyConnectionForId = (
83
- integrationId: string,
84
- ctx: Omit<WorkspaceClientContext, "token"> & {
17
+ connectionId: string,
18
+ ctx: Omit<ClientContext, "token"> & {
85
19
  token?: string;
86
20
  cookie?: string;
21
+ meshUrl: string;
87
22
  },
88
- decoChatApiUrl?: string,
89
23
  appName?: string,
90
24
  ): MCPConnection => {
91
25
  let headers: Record<string, string> | undefined = appName
@@ -97,55 +31,39 @@ export const proxyConnectionForId = (
97
31
  }
98
32
  return {
99
33
  type: "HTTP",
100
- url: createIntegrationsUrl({
101
- integrationId,
102
- workspace: ctx.workspace,
103
- decoCmsApiUrl: decoChatApiUrl,
104
- branch: ctx.branch,
105
- }),
34
+ url: new URL(`/mcp/${connectionId}`, ctx.meshUrl).href,
106
35
  token: ctx.token,
107
36
  headers,
108
37
  };
109
38
  };
110
- const mcpClientForIntegrationId = (
111
- integrationId: string,
112
- ctx: WorkspaceClientContext,
113
- decoChatApiUrl?: string,
39
+ const mcpClientForConnectionId = (
40
+ connectionId: string,
41
+ ctx: ClientContext,
114
42
  appName?: string,
115
43
  ) => {
116
- const mcpConnection = proxyConnectionForId(
117
- integrationId,
118
- ctx,
119
- decoChatApiUrl,
120
- appName,
121
- );
44
+ const mcpConnection = proxyConnectionForId(connectionId, ctx, appName);
122
45
 
123
46
  // TODO(@igorbrasileiro): Switch this proxy to be a proxy that call MCP Client.toolCall from @modelcontextprotocol
124
47
  return MCPClient.forConnection(mcpConnection);
125
48
  };
126
49
 
127
50
  function mcpClientFromState(
128
- binding: BindingBase | MCPIntegrationNameBinding,
51
+ binding: BindingBase | MCPAppBinding,
129
52
  env: DefaultEnv,
130
53
  ) {
131
- const ctx = env.DECO_REQUEST_CONTEXT;
54
+ const ctx = env.MESH_REQUEST_CONTEXT;
132
55
  const bindingFromState = ctx?.state?.[binding.name];
133
- const integrationId =
56
+ const connectionId =
134
57
  bindingFromState &&
135
58
  typeof bindingFromState === "object" &&
136
59
  "value" in bindingFromState
137
60
  ? bindingFromState.value
138
61
  : undefined;
139
- if (typeof integrationId !== "string" && "integration_name" in binding) {
62
+ if (typeof connectionId !== "string" && "app_name" in binding) {
140
63
  // in case of a binding to an app name, we need to use the new apps/mcp endpoint which will proxy the request to the app but without any token
141
- return mcpClientForAppName(binding.integration_name, env.DECO_API_URL);
64
+ throw new Error("Binding to an app name is not supported");
142
65
  }
143
- return mcpClientForIntegrationId(
144
- integrationId,
145
- ctx,
146
- env.DECO_API_URL,
147
- env.DECO_APP_NAME,
148
- );
66
+ return mcpClientForConnectionId(connectionId, ctx);
149
67
  }
150
68
 
151
69
  export const createContractBinding = (
@@ -159,20 +77,24 @@ export const createIntegrationBinding = (
159
77
  binding: MCPBinding,
160
78
  env: DefaultEnv,
161
79
  ) => {
162
- const integrationId =
163
- "integration_id" in binding ? binding.integration_id : undefined;
164
- if (!integrationId) {
80
+ const connectionId =
81
+ "connection_id" in binding ? binding.connection_id : undefined;
82
+ if (!connectionId) {
165
83
  return mcpClientFromState(binding, env);
166
84
  }
85
+ if (!env.MESH_RUNTIME_TOKEN) {
86
+ throw new Error("MESH_RUNTIME_TOKEN is required");
87
+ }
88
+ if (!env.MESH_URL) {
89
+ throw new Error("MESH_URL is required");
90
+ }
167
91
  // bindings pointed to an specific integration id are binded using the app deployment workspace
168
- return mcpClientForIntegrationId(
169
- integrationId,
92
+ return mcpClientForConnectionId(
93
+ connectionId,
170
94
  {
171
- workspace: env.DECO_WORKSPACE,
172
- token: env.DECO_API_TOKEN,
173
- branch: env.DECO_REQUEST_CONTEXT?.branch,
95
+ token: env.MESH_RUNTIME_TOKEN,
96
+ meshUrl: env.MESH_URL,
174
97
  },
175
- env.DECO_API_URL,
176
- env.DECO_APP_NAME,
98
+ env.MESH_APP_NAME,
177
99
  );
178
100
  };