@optimizely-opal/opal-tools-sdk 0.1.6-dev → 0.1.9-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,83 +4,36 @@ This SDK simplifies the creation of tools services compatible with the Opal Tool
4
4
 
5
5
  ## Features
6
6
 
7
- - Modern `registerTool` API with Zod schemas for type-safe tool definitions
8
- - Legacy `@tool` decorator API for backwards compatibility
9
- - Automatic type inference with Zod (registerTool only)
10
- - Adaptive Block Document support for rich interactive UIs
11
- - Runtime validation with Zod (registerTool only)
12
- - Automatic discovery endpoint generation
7
+ - Easy definition of tool functions with decorators
8
+ - Automatic generation of discovery endpoints
9
+ - Parameter validation and type checking
13
10
  - Authentication helpers
14
11
  - Express integration
12
+ - Island components for interactive UI responses
15
13
 
16
14
  ## Installation
17
15
 
18
16
  ```bash
19
- npm install @optimizely-opal/opal-tools-sdk express zod
17
+ npm install @optimizely-opal/opal-tools-sdk
20
18
  ```
21
19
 
22
- ## Quick Start
23
-
24
- ### `registerTool`
20
+ ## Usage
25
21
 
26
22
  ```typescript
27
- import express from "express";
28
- import { z } from "zod";
29
- import { ToolsService, registerTool } from "@optimizely-opal/opal-tools-sdk";
23
+ import { ToolsService, tool, IslandResponse, IslandConfig } from '@optimizely-opal/opal-tools-sdk';
24
+ import express from 'express';
30
25
 
31
26
  const app = express();
32
27
  const toolsService = new ToolsService(app);
33
28
 
34
- // ✨ Types are automatically inferred from the inputSchema!
35
- const getWeather = registerTool(
36
- "get_weather",
37
- {
38
- description: "Gets current weather for a location",
39
- inputSchema: {
40
- location: z.string().describe("City name or location"),
41
- units: z
42
- .enum(["metric", "imperial"])
43
- .optional()
44
- .describe("Temperature units"),
45
- },
46
- },
47
- async (params) => {
48
- // params.location is typed as string
49
- // params.units is typed as 'metric' | 'imperial' | undefined
50
- return { temperature: 22, condition: "sunny" };
51
- },
52
- );
53
-
54
- app.listen(3000);
55
- ```
56
-
57
- ### Legacy `@tool` Decorator API
58
-
59
- ```typescript
60
- import { ToolsService, tool, ParameterType } from '@optimizely-opal/opal-tools-sdk';
61
-
62
29
  interface WeatherParameters {
63
30
  location: string;
64
- units?: string;
31
+ units: string;
65
32
  }
66
33
 
67
34
  @tool({
68
35
  name: 'get_weather',
69
- description: 'Gets current weather for a location',
70
- parameters: [
71
- {
72
- name: 'location',
73
- type: ParameterType.String,
74
- description: 'City name or location',
75
- required: true,
76
- },
77
- {
78
- name: 'units',
79
- type: ParameterType.String,
80
- description: 'Temperature units',
81
- required: false,
82
- },
83
- ],
36
+ description: 'Gets current weather for a location'
84
37
  })
85
38
  async function getWeather(parameters: WeatherParameters) {
86
39
  // Implementation...
@@ -92,210 +45,242 @@ async function getWeather(parameters: WeatherParameters) {
92
45
 
93
46
  ## Authentication
94
47
 
95
- Both APIs support authentication. The second parameter of your handler receives the extra context object containing auth data.
48
+ The SDK provides two ways to require authentication for your tools:
96
49
 
97
- ### With `registerTool`
50
+ ### 1. Using the `@requiresAuth` decorator
98
51
 
99
52
  ```typescript
100
- import { z } from "zod";
101
-
102
- const getCalendarEvents = registerTool(
103
- "get_calendar_events",
104
- {
105
- description: "Gets calendar events for a date",
106
- inputSchema: {
107
- date: z.string().describe("Date in YYYY-MM-DD format"),
108
- },
109
- authRequirements: {
110
- provider: "google",
111
- scopeBundle: "calendar",
112
- required: true,
113
- },
114
- },
115
- async (params, extra) => {
116
- // Access auth data from extra context
117
- const token = extra?.auth?.credentials?.access_token;
118
- // Check execution mode if needed
119
- const mode = extra?.mode; // 'headless' | 'interactive'
120
-
121
- // Use token to make authenticated requests
122
- return { events: ["Meeting at 10:00", "Lunch at 12:00"] };
123
- },
124
- );
53
+ import { ToolsService, tool } from '@optimizely-opal/opal-tools-sdk';
54
+ import { requiresAuth } from '@optimizely-opal/opal-tools-sdk/auth';
55
+ import express from 'express';
56
+
57
+ const app = express();
58
+ const toolsService = new ToolsService(app);
59
+
60
+ interface CalendarParameters {
61
+ date: string;
62
+ timezone?: string;
63
+ }
64
+
65
+ // Single authentication requirement
66
+ @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
67
+ @tool({
68
+ name: 'get_calendar_events',
69
+ description: 'Gets calendar events for a date'
70
+ })
71
+ async function getCalendarEvents(parameters: CalendarParameters, authData?: any) {
72
+ // The authData parameter contains authentication information
73
+ const token = authData?.credentials?.token || '';
74
+
75
+ // Use the token to make authenticated requests
76
+ // ...
77
+
78
+ return { events: ['Meeting at 10:00', 'Lunch at 12:00'] };
79
+ }
80
+
81
+ // Multiple authentication requirements (tool can work with either provider)
82
+ @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
83
+ @requiresAuth({ provider: 'microsoft', scopeBundle: 'outlook', required: true })
84
+ @tool({
85
+ name: 'get_calendar_availability',
86
+ description: 'Check calendar availability'
87
+ })
88
+ async function getCalendarAvailability(parameters: CalendarParameters, authData?: any) {
89
+ const provider = authData?.provider || '';
90
+ const token = authData?.credentials?.token || '';
91
+
92
+ if (provider === 'google') {
93
+ // Use Google Calendar API
94
+ } else if (provider === 'microsoft') {
95
+ // Use Microsoft Outlook API
96
+ }
97
+
98
+ return { available: true, provider_used: provider };
99
+ }
125
100
  ```
126
101
 
127
- ### With `@tool` Decorator
102
+ ### 2. Specifying auth requirements in the `@tool` decorator
128
103
 
129
104
  ```typescript
105
+ interface EmailParameters {
106
+ limit?: number;
107
+ folder?: string;
108
+ }
109
+
130
110
  @tool({
131
- name: 'get_calendar_events',
132
- description: 'Gets calendar events',
133
- parameters: [
134
- {
135
- name: 'date',
136
- type: ParameterType.String,
137
- description: 'Date in YYYY-MM-DD format',
138
- required: true,
139
- },
140
- ],
111
+ name: 'get_email',
112
+ description: 'Gets emails from the user\'s inbox',
141
113
  authRequirements: {
142
114
  provider: 'google',
143
- scopeBundle: 'calendar',
144
- required: true,
145
- },
115
+ scopeBundle: 'gmail',
116
+ required: true
117
+ }
146
118
  })
147
- async function getCalendarEvents(params: any, environment?: any) {
148
- const token = environment?.auth?.credentials?.access_token;
149
- return { events: [] };
119
+ async function getEmail(parameters: EmailParameters, authData?: any) {
120
+ // Implementation...
121
+ return { emails: ['Email 1', 'Email 2'] };
150
122
  }
151
123
  ```
152
124
 
153
- ## Adaptive Block Documents
154
-
155
- Adaptive Block Documents enable rich, interactive UI responses with forms, buttons, and dynamic content.
125
+ ## Authentication
156
126
 
157
- ### Creating Adaptive Block Responses
127
+ The SDK provides authentication support for tools that require user credentials:
158
128
 
159
129
  ```typescript
160
- import { z } from "zod";
161
- import { registerTool, Block } from "@optimizely-opal/opal-tools-sdk";
162
-
163
- const createTask = registerTool(
164
- "create_task",
165
- {
166
- description: "Create a new task",
167
- type: "block", // Specify this is an Adaptive Block tool
168
- inputSchema: {
169
- title: z.string().describe("Task title"),
170
- description: z.string().optional().describe("Task description"),
171
- },
172
- },
173
- async (params) => {
174
- // Return a BlockResponse (plain object with content/data/artifact/etc)
175
- return {
176
- content: Block.Document({
177
- children: [
178
- Block.Heading({ children: "Task Created!", level: "1" }),
179
- Block.Text({ children: `Created: ${params.title}` }),
180
- Block.Input({
181
- name: "notes",
182
- placeholder: "Add notes...",
183
- value: params.description || "",
184
- }),
185
- ],
186
- actions: [
187
- Block.Action({ name: "save", children: "Save Changes" }),
188
- Block.Action({
189
- name: "delete",
190
- children: "Delete",
191
- variant: "danger",
192
- }),
193
- ],
194
- }),
195
- data: { task_id: "123", created_at: new Date().toISOString() },
196
- artifact: {
197
- type: "task",
198
- id: "task-123",
199
- data: { title: params.title },
200
- },
201
- };
202
- },
203
- );
204
- ```
130
+ import { ToolsService, tool, requiresAuth, AuthData } from '@optimizely-opal/opal-tools-sdk';
131
+ import express from 'express';
205
132
 
206
- ### Adaptive Block Components
207
-
208
- The SDK provides a type-safe `Block` namespace with factory functions for all components:
133
+ interface CalendarParameters {
134
+ date: string;
135
+ timezone?: string;
136
+ }
209
137
 
210
- - `Block.Document()` - Root container with children and actions
211
- - `Block.Heading()` - Headings with levels 1-6
212
- - `Block.Text()` - Text content
213
- - `Block.Input()` - Text input fields
214
- - `Block.Textarea()` - Multi-line text areas
215
- - `Block.Checkbox()` - Checkbox inputs
216
- - `Block.Select()` - Dropdown selects
217
- - `Block.Button()` - Action buttons
218
- - `Block.Action()` - Document-level actions
219
- - `Block.List()` - Ordered/unordered lists
220
- - `Block.Table()` - Data tables
221
- - And more...
138
+ const app = express();
139
+ const toolsService = new ToolsService(app);
222
140
 
223
- See the generated [src/block.ts](./src/block.ts) for the complete list and TypeScript types.
141
+ @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
142
+ @tool({
143
+ name: 'get_calendar_events',
144
+ description: 'Gets calendar events for a date'
145
+ })
146
+ async function getCalendarEvents(parameters: CalendarParameters, authData?: AuthData) {
147
+ // The authData parameter contains authentication information
148
+ if (authData) {
149
+ const token = authData.credentials.access_token;
150
+ // Use the token to make authenticated requests
151
+ }
152
+
153
+ return { events: ['Meeting at 10:00', 'Lunch at 12:00'] };
154
+ }
155
+ ```
224
156
 
225
- ### Regenerating Adaptive Block Types
157
+ ## Island Components
226
158
 
227
- The Adaptive Block types are auto-generated from the JSON schema. To regenerate:
159
+ The SDK includes Island components for creating interactive UI responses:
228
160
 
229
- ```bash
230
- npm run generate:block
231
- ```
161
+ ```typescript
162
+ import {
163
+ ToolsService,
164
+ tool,
165
+ IslandResponse,
166
+ IslandConfig
167
+ } from '@optimizely-opal/opal-tools-sdk';
168
+ import express from 'express';
232
169
 
233
- This reads `block-document-spec.json` and generates TypeScript interfaces and factory functions in [src/block.ts](./src/block.ts).
170
+ interface WeatherParameters {
171
+ location: string;
172
+ units?: string;
173
+ }
234
174
 
235
- **Note:** Don't edit `src/block.ts` manually - it will be overwritten on regeneration.
175
+ const app = express();
176
+ const toolsService = new ToolsService(app);
236
177
 
237
- ## Type Definitions
178
+ @tool({
179
+ name: 'get_weather',
180
+ description: 'Gets current weather for a location'
181
+ })
182
+ async function getWeather(parameters: WeatherParameters) {
183
+ // Get weather data (implementation details omitted)
184
+ const weatherData = { temperature: 22, condition: 'sunny', humidity: 65 };
185
+
186
+ // Create an interactive island for weather settings
187
+ const island = new IslandConfig(
188
+ [
189
+ new IslandConfig.Field(
190
+ 'location',
191
+ 'Location',
192
+ 'string',
193
+ parameters.location
194
+ ),
195
+ new IslandConfig.Field(
196
+ 'units',
197
+ 'Temperature Units',
198
+ 'string',
199
+ parameters.units || 'metric',
200
+ false,
201
+ ['metric', 'imperial', 'kelvin']
202
+ ),
203
+ new IslandConfig.Field(
204
+ 'current_temp',
205
+ 'Current Temperature',
206
+ 'string',
207
+ `${weatherData.temperature}°${parameters.units === 'metric' ? 'C' : 'F'}`
208
+ )
209
+ ],
210
+ [
211
+ new IslandConfig.Action(
212
+ 'refresh_weather',
213
+ 'Refresh Weather',
214
+ 'button',
215
+ '/tools/get_weather',
216
+ 'update'
217
+ )
218
+ ],
219
+ 'button', // Optional island type
220
+ 'plus' // Optional island icon
221
+ );
222
+
223
+ return IslandResponse.create([island]);
224
+ }
225
+ ```
238
226
 
239
- The SDK provides comprehensive TypeScript type definitions:
227
+ ### Island Components
240
228
 
241
- ### Authentication Types
229
+ #### IslandConfig.Field
242
230
 
243
- - `AuthData` - Provider and credentials information
244
- - `Credentials` - Access tokens and org details
245
- - `Environment` - Execution context with auth data
231
+ Fields represent data inputs in the UI:
246
232
 
247
- ### Parameter Types
233
+ - `name`: Programmatic field identifier
234
+ - `label`: Human-readable label
235
+ - `type`: Field type (`'string'`, `'boolean'`, `'json'`)
236
+ - `value`: Current field value (optional)
237
+ - `hidden`: Whether to hide from user (optional, default: false)
238
+ - `options`: Available options for selection (optional)
248
239
 
249
- - `ParameterType` - Enum for parameter types (String, Number, Boolean, List, Dictionary)
250
- - `Parameter` - Tool parameter definitions
251
- - `Function` - Complete tool function definitions
240
+ #### IslandConfig.Action
252
241
 
253
- ### Block Types
242
+ Actions represent buttons or operations:
254
243
 
255
- All Block Document components have full TypeScript interfaces with type checking and IDE autocomplete.
244
+ - `name`: Programmatic action identifier
245
+ - `label`: Human-readable button label
246
+ - `type`: UI element type (typically `'button'`)
247
+ - `endpoint`: API endpoint to call
248
+ - `operation`: Operation type (default: `'create'`)
256
249
 
257
- ## API Reference
250
+ #### IslandConfig
258
251
 
259
- ### `registerTool<TSchema, TReturn>(name, options, handler)`
252
+ Contains the complete island configuration:
260
253
 
261
- Modern API for defining tools with Zod schemas.
254
+ - `fields`: Array of IslandConfig.Field objects
255
+ - `actions`: Array of IslandConfig.Action objects
256
+ - `type`: Optional island type for custom rendering (optional)
257
+ - `icon`: Optional icon identifier for the island (optional)
262
258
 
263
- **Parameters:**
259
+ #### IslandResponse
264
260
 
265
- - `name: string` - Tool name (required)
266
- - `options: ToolOptions` - Configuration object
267
- - `description: string` - Tool description (required)
268
- - `inputSchema: Record<string, z.ZodTypeAny>` - Zod schema for parameters (required)
269
- - `type?: 'json' | 'block'` - Response type (default: 'json')
270
- - `authRequirements?` - Authentication requirements
271
- - `handler: (params, extra?) => Result` - Tool implementation
272
- - `params` - Validated input parameters (typed from schema)
273
- - `extra?` - Optional extra context
274
- - `mode: 'headless' | 'interactive'` - Execution mode
275
- - `auth?: { provider, credentials }` - Auth data if provided
261
+ The response wrapper for islands:
276
262
 
277
- **Returns:** The handler function with full type inference
263
+ - Use `IslandResponse.create([islands])` to create responses
264
+ - Supports multiple islands per response
278
265
 
279
- ### `@tool(options)`
266
+ ## Type Definitions
280
267
 
281
- Legacy decorator for defining tools.
268
+ The SDK provides comprehensive TypeScript type definitions:
282
269
 
283
- **Options:**
270
+ ### Authentication Types
284
271
 
285
- - `name: string` - Tool name
286
- - `description: string` - Tool description
287
- - `parameters: ParameterDefinition[]` - Parameter definitions
288
- - `authRequirements?` - Authentication requirements
272
+ - `AuthData`: Interface containing provider and credentials information
273
+ - `Credentials`: Interface with access_token, org_sso_id, customer_id, instance_id, and product_sku
274
+ - `Environment`: Interface specifying execution mode (`'headless'` or `'interactive'`)
289
275
 
290
- ### `ToolsService`
276
+ ### Parameter Types
291
277
 
292
- Express service that manages tool registration and creates discovery endpoints.
278
+ - `ParameterType`: Enum for supported parameter types
279
+ - `Parameter`: Class for tool parameter definitions
280
+ - `Function`: Class for complete tool function definitions
293
281
 
294
- ```typescript
295
- const toolsService = new ToolsService(app);
296
- // Automatically creates /discovery endpoint
297
- ```
282
+ These types provide full IDE support and compile-time type checking for better development experience.
298
283
 
299
- ## License
284
+ ## Documentation
300
285
 
301
- MIT
286
+ See full documentation for more examples and configuration options.
@@ -15,6 +15,7 @@ interface ToolOptions {
15
15
  description: string;
16
16
  name: string;
17
17
  parameters?: ParameterDefinition[];
18
+ uiResource?: string;
18
19
  }
19
20
  /**
20
21
  * Decorator to register a function as an Opal tool
@@ -24,6 +25,7 @@ interface ToolOptions {
24
25
  * - authRequirements: (Optional) Authentication requirements
25
26
  * Format: { provider: "oauth_provider", scopeBundle: "permissions_scope", required: true }
26
27
  * Example: { provider: "google", scopeBundle: "calendar", required: true }
28
+ * - uiResource: (Optional) URI of associated UI resource for dynamic rendering (e.g., "ui://my-app/create-form")
27
29
  *
28
30
  * Note: If your tool requires authentication, define your handler function with two parameters:
29
31
  * ```
@@ -13,6 +13,7 @@ const registry_1 = require("./registry");
13
13
  * - authRequirements: (Optional) Authentication requirements
14
14
  * Format: { provider: "oauth_provider", scopeBundle: "permissions_scope", required: true }
15
15
  * Example: { provider: "google", scopeBundle: "calendar", required: true }
16
+ * - uiResource: (Optional) URI of associated UI resource for dynamic rendering (e.g., "ui://my-app/create-form")
16
17
  *
17
18
  * Note: If your tool requires authentication, define your handler function with two parameters:
18
19
  * ```
@@ -44,7 +45,7 @@ function tool(options) {
44
45
  }
45
46
  // Register the tool with all services
46
47
  for (const service of registry_1.registry.services) {
47
- service.registerTool(options.name, options.description, handler, parameters, endpoint, authRequirements);
48
+ service.registerTool(options.name, options.description, handler, parameters, endpoint, authRequirements, false, options.uiResource);
48
49
  }
49
50
  return isMethod ? descriptor : target;
50
51
  };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import "reflect-metadata";
2
2
  export { requiresAuth } from "./auth";
3
- export { Block, isBlockResponse } from "./block";
4
- export type * from "./block";
5
3
  export { tool } from "./decorators";
6
4
  export * from "./models";
5
+ export { UI } from "./proteus";
6
+ export type * from "./proteus";
7
+ export { registerResource } from "./registerResource";
7
8
  export { registerTool } from "./registerTool";
8
9
  export type { RequestHandlerExtra } from "./registerTool";
9
10
  export { ToolsService } from "./service";
package/dist/index.js CHANGED
@@ -14,16 +14,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ToolsService = exports.registerTool = exports.tool = exports.isBlockResponse = exports.Block = exports.requiresAuth = void 0;
17
+ exports.ToolsService = exports.registerTool = exports.registerResource = exports.UI = exports.tool = exports.requiresAuth = void 0;
18
18
  require("reflect-metadata");
19
19
  var auth_1 = require("./auth");
20
20
  Object.defineProperty(exports, "requiresAuth", { enumerable: true, get: function () { return auth_1.requiresAuth; } });
21
- var block_1 = require("./block");
22
- Object.defineProperty(exports, "Block", { enumerable: true, get: function () { return block_1.Block; } });
23
- Object.defineProperty(exports, "isBlockResponse", { enumerable: true, get: function () { return block_1.isBlockResponse; } });
24
21
  var decorators_1 = require("./decorators");
25
22
  Object.defineProperty(exports, "tool", { enumerable: true, get: function () { return decorators_1.tool; } });
26
23
  __exportStar(require("./models"), exports);
24
+ var proteus_1 = require("./proteus");
25
+ Object.defineProperty(exports, "UI", { enumerable: true, get: function () { return proteus_1.UI; } });
26
+ var registerResource_1 = require("./registerResource");
27
+ Object.defineProperty(exports, "registerResource", { enumerable: true, get: function () { return registerResource_1.registerResource; } });
27
28
  var registerTool_1 = require("./registerTool");
28
29
  Object.defineProperty(exports, "registerTool", { enumerable: true, get: function () { return registerTool_1.registerTool; } });
29
30
  var service_1 = require("./service");
package/dist/models.d.ts CHANGED
@@ -64,6 +64,7 @@ export declare class Function {
64
64
  parameters: Parameter[];
65
65
  endpoint: string;
66
66
  authRequirements?: AuthRequirement[] | undefined;
67
+ uiResource?: string | undefined;
67
68
  /**
68
69
  * HTTP method for the endpoint (default: POST)
69
70
  */
@@ -75,8 +76,9 @@ export declare class Function {
75
76
  * @param parameters Function parameters
76
77
  * @param endpoint API endpoint
77
78
  * @param authRequirements Authentication requirements (optional)
79
+ * @param uiResource URI of associated UI resource for dynamic rendering (optional)
78
80
  */
79
- constructor(name: string, description: string, parameters: Parameter[], endpoint: string, authRequirements?: AuthRequirement[] | undefined);
81
+ constructor(name: string, description: string, parameters: Parameter[], endpoint: string, authRequirements?: AuthRequirement[] | undefined, uiResource?: string | undefined);
80
82
  /**
81
83
  * Convert to JSON for the discovery endpoint
82
84
  */
@@ -287,3 +289,22 @@ export declare class Parameter {
287
289
  type: ParameterType;
288
290
  };
289
291
  }
292
+ /**
293
+ * Resource definition for MCP resources
294
+ */
295
+ export declare class Resource {
296
+ uri: string;
297
+ name: string;
298
+ description?: string | undefined;
299
+ mimeType?: string | undefined;
300
+ title?: string | undefined;
301
+ /**
302
+ * Create a new resource definition
303
+ * @param uri The unique URI for this resource (e.g., "ui://my-app/create-form")
304
+ * @param name Name of the resource
305
+ * @param description Description of the resource (optional)
306
+ * @param mimeType MIME type of the resource content (optional)
307
+ * @param title Human-readable title for the resource (optional)
308
+ */
309
+ constructor(uri: string, name: string, description?: string | undefined, mimeType?: string | undefined, title?: string | undefined);
310
+ }
package/dist/models.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Parameter = exports.IslandResponse = exports.IslandResponseConfig = exports.IslandConfig = exports.IslandField = exports.IslandAction = exports.Function = exports.AuthRequirement = exports.ParameterType = void 0;
3
+ exports.Resource = exports.Parameter = exports.IslandResponse = exports.IslandResponseConfig = exports.IslandConfig = exports.IslandField = exports.IslandAction = exports.Function = exports.AuthRequirement = exports.ParameterType = void 0;
4
4
  /**
5
5
  * Types of parameters supported by Opal tools
6
6
  */
@@ -51,13 +51,15 @@ class Function {
51
51
  * @param parameters Function parameters
52
52
  * @param endpoint API endpoint
53
53
  * @param authRequirements Authentication requirements (optional)
54
+ * @param uiResource URI of associated UI resource for dynamic rendering (optional)
54
55
  */
55
- constructor(name, description, parameters, endpoint, authRequirements) {
56
+ constructor(name, description, parameters, endpoint, authRequirements, uiResource) {
56
57
  this.name = name;
57
58
  this.description = description;
58
59
  this.parameters = parameters;
59
60
  this.endpoint = endpoint;
60
61
  this.authRequirements = authRequirements;
62
+ this.uiResource = uiResource;
61
63
  /**
62
64
  * HTTP method for the endpoint (default: POST)
63
65
  */
@@ -78,6 +80,9 @@ class Function {
78
80
  if (this.authRequirements && this.authRequirements.length > 0) {
79
81
  result.auth_requirements = this.authRequirements.map((auth) => auth.toJSON());
80
82
  }
83
+ if (this.uiResource !== undefined) {
84
+ result.ui_resource = this.uiResource;
85
+ }
81
86
  return result;
82
87
  }
83
88
  }
@@ -266,3 +271,24 @@ class Parameter {
266
271
  }
267
272
  }
268
273
  exports.Parameter = Parameter;
274
+ /**
275
+ * Resource definition for MCP resources
276
+ */
277
+ class Resource {
278
+ /**
279
+ * Create a new resource definition
280
+ * @param uri The unique URI for this resource (e.g., "ui://my-app/create-form")
281
+ * @param name Name of the resource
282
+ * @param description Description of the resource (optional)
283
+ * @param mimeType MIME type of the resource content (optional)
284
+ * @param title Human-readable title for the resource (optional)
285
+ */
286
+ constructor(uri, name, description, mimeType, title) {
287
+ this.uri = uri;
288
+ this.name = name;
289
+ this.description = description;
290
+ this.mimeType = mimeType;
291
+ this.title = title;
292
+ }
293
+ }
294
+ exports.Resource = Resource;