skedyul 0.2.160 → 0.3.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 (2) hide show
  1. package/README.md +134 -472
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,250 +1,158 @@
1
1
  # skedyul
2
2
 
3
- Reusable helpers for building Model Context Protocol (MCP) runtimes in Node.js. This package powers the dedicated and serverless starters by exposing registry typing, environment helpers, and a shared `server.create` factory that wires JSON-RPC tooling, request counting, and runtime-specific adapters.
3
+ The official Node.js SDK for building Skedyul integration apps. This package provides everything you need to create MCP (Model Context Protocol) servers, handle webhooks, manage lifecycle events, and interact with the Skedyul platform.
4
4
 
5
- ## What's inside
5
+ ## Features
6
6
 
7
- - `ToolContext`, `ToolHandler`, and supporting typings so registries can stay strongly typed.
8
- - `server.create` accepts a config object (metadata, compute layer, rate limits, CORS) and a tool registry, then exposes a `listen()` API for HTTP servers and a Lambda-style `handler()` respectively.
9
- - Request counting, TTL, env merging (`MCP_ENV_JSON` + `MCP_ENV`), JSON-RPC transport, and health metadata so each runtime behaves consistently.
7
+ - **MCP Server**: Build tools that AI agents can invoke via the Model Context Protocol
8
+ - **Webhooks**: Receive and process external events (SMS, emails, API callbacks)
9
+ - **Lifecycle Hooks**: Handle app installation, provisioning, and cleanup
10
+ - **Core API Client**: Interact with Skedyul resources (workplaces, channels, instances)
11
+ - **CLI**: Develop and test locally with hot-reload and tunneling
10
12
 
11
- ## Billing contract
12
-
13
- Every `ToolHandler` must return both its result payload (`output`) and a `billing` object describing the credits consumed:
14
-
15
- ```ts
16
- export const helloWorld: ToolHandler<HelloWorldInput, HelloWorldOutput> = async ({
17
- input,
18
- context,
19
- }) => {
20
- // Do your work here...
21
- const credits = calculateCredits(input, context) // e.g. characters × rate
22
-
23
- return {
24
- output: {
25
- message: `Hello, ${input.name ?? 'world'}`,
26
- environmentName: context.env.SKEDYUL_ENV ?? 'local',
27
- },
28
- billing: { credits },
29
- }
30
- }
31
- ```
32
-
33
- Servers attach that `billing` data to every MCP response, so callers always know the final credit cost. Since pricing may depend on runtime data (like message length), compute credits inside the registry or another secure helper that can read your pricing tables, rather than in the shared server logic.
34
-
35
- ## Estimate endpoint
36
-
37
- Both transports expose a dedicated `POST /estimate` endpoint that reuses the same registry to calculate projected billing without executing charged work. Callers supply a tool name and inputs, and the server forwards the request to the registry with `context.mode === 'estimate'`. The response contains only the `billing` block:
38
-
39
- ```json
40
- POST /estimate
41
- {
42
- "name": "hello-world",
43
- "inputs": { "name": "demo" }
44
- }
45
-
46
- 200 OK
47
- {
48
- "billing": { "credits": 4 }
49
- }
50
- ```
51
-
52
- Treat `/estimate` as an authentication-protected route (if your runtime supports auth) because it exposes pricing metadata. Keep your pricing tables and cost calculations in a guarded part of your stack, and never return internal secrets through `estimate`.
53
-
54
- ## Core API hooks
55
-
56
- For integration-specific RPCs that belong to your platform rather than a tool, provide a `coreApi` implementation when calling `server.create`. The property accepts:
57
-
58
- - `service`: an object implementing `createCommunicationChannel`, `updateCommunicationChannel`, `deleteCommunicationChannel`, `getCommunicationChannel`, `getCommunicationChannels`, and `sendMessage`.
59
- - `webhookHandler`: an optional `(request: WebhookRequest) => Promise<WebhookResponse>` callback that will receive forwarded HTTP webhooks.
60
-
61
- The MCP server exposes `POST /core` (with `{ method, params }`) and `POST /core/webhook` for these operations. They never appear under `tools/list` unlesstaken explicit MCP tooling—they are separate transport-level handlers and do not count against tool request limits. Make sure your service returns the structured channel/message data defined in `src/core/types.ts` so the responses stay consistent, and guard `/core`/`/core/webhook` with your platform’s preferred authentication if you surface them externally.
62
-
63
- ## Core API Client
64
-
65
- The SDK includes a client for the Skedyul Core API that enables lookups across workplaces. This is especially useful in webhook handlers where you need to identify which workspace a request belongs to.
66
-
67
- ### Configuration
68
-
69
- Configure the client using environment variables or programmatically:
70
-
71
- **Environment Variables:**
13
+ ## Installation
72
14
 
73
15
  ```bash
74
- # Base URL for the Skedyul Core API
75
- SKEDYUL_API_URL=https://app.skedyul.com
76
-
77
- # Your API token (App API or Workplace API)
78
- SKEDYUL_API_TOKEN=sk_app_xxxxx
16
+ npm install skedyul
17
+ # or
18
+ pnpm add skedyul
79
19
  ```
80
20
 
81
- **Programmatic Configuration:**
21
+ ## Quick Start
82
22
 
83
- ```ts
84
- import { configure } from 'skedyul'
23
+ ### 1. Create your configuration
85
24
 
86
- configure({
87
- baseUrl: 'https://app.skedyul.com',
88
- apiToken: 'sk_app_xxxxx',
25
+ ```ts
26
+ // skedyul.config.ts
27
+ import { defineConfig } from 'skedyul'
28
+
29
+ export default defineConfig({
30
+ name: 'my-integration',
31
+ version: '1.0.0',
32
+ computeLayer: 'serverless',
33
+ tools: import('./src/tools/registry'),
34
+ webhooks: import('./src/webhooks/registry'),
89
35
  })
90
36
  ```
91
37
 
92
- ### Token Types
93
-
94
- - **App API Token (`sk_app_*`)**: Grants access to all workplaces where your app is installed. Use this for webhooks where you need to look up resources across workplaces.
95
- - **Workplace API Token (`sk_wkp_*`)**: Scoped to a single workplace. Use this when you know the target workspace (e.g., MCP tools).
96
-
97
- ### Available Methods
98
-
99
- - `workplace.list({ filter?, limit? })` - List workplaces
100
- - `workplace.get(id)` - Get a single workplace
101
- - `communicationChannel.list({ filter?, limit? })` - List communication channels
102
- - `communicationChannel.get(id)` - Get a single channel
103
-
104
- ### Example: Webhook Handler
38
+ ### 2. Define a tool
105
39
 
106
40
  ```ts
107
- import { communicationChannel, configure } from 'skedyul'
41
+ // src/tools/hello.ts
42
+ import { z } from 'skedyul'
43
+ import type { ToolHandler, ToolDefinition } from 'skedyul'
108
44
 
109
- // Configure once at startup (or use env vars)
110
- configure({
111
- baseUrl: process.env.SKEDYUL_API_URL,
112
- apiToken: process.env.SKEDYUL_API_TOKEN,
45
+ const inputSchema = z.object({
46
+ name: z.string().optional(),
113
47
  })
114
48
 
115
- // In your webhook handler
116
- async function handleIncomingMessage(phoneNumber: string) {
117
- // Find the channel across all workplaces where your app is installed
118
- const channels = await communicationChannel.list({
119
- filter: { identifierValue: phoneNumber },
120
- limit: 1,
121
- })
49
+ type Input = z.infer<typeof inputSchema>
50
+ type Output = { message: string }
122
51
 
123
- if (channels.length === 0) {
124
- throw new Error('No channel found for this phone number')
52
+ const handler: ToolHandler<Input, Output> = async (input, context) => {
53
+ return {
54
+ output: { message: `Hello, ${input.name ?? 'world'}!` },
55
+ billing: { credits: 1 },
56
+ meta: { success: true, message: 'Greeting sent', toolName: 'hello' },
125
57
  }
126
-
127
- const channel = channels[0]
128
- console.log(`Found channel in workplace: ${channel.workplaceId}`)
129
-
130
- // Now you can process the message in the correct workspace context
131
- return channel
132
58
  }
133
- ```
134
59
 
135
- Use these helpers for internal wiring—like pulling the correct workplace for a webhook—without touching the MCP tooling surface directly.
136
-
137
- ## Installation
138
-
139
- ```bash
140
- npm install skedyul
60
+ export const helloTool: ToolDefinition<Input, Output> = {
61
+ name: 'hello',
62
+ description: 'Say hello to someone',
63
+ inputSchema,
64
+ handler,
65
+ }
141
66
  ```
142
67
 
143
- ## Usage
144
-
145
- ### Define your registry
146
-
147
- Each tool should follow the shared handler signature:
68
+ ### 3. Start the server
148
69
 
149
70
  ```ts
150
- import type { ToolContext, ToolHandler } from 'skedyul'
71
+ // src/server.ts
72
+ import { server } from 'skedyul'
73
+ import { toolRegistry } from './tools/registry'
151
74
 
152
- export interface HelloWorldInput {
153
- name?: string
154
- }
75
+ const mcpServer = server.create(
76
+ {
77
+ computeLayer: 'dedicated',
78
+ metadata: { name: 'my-integration', version: '1.0.0' },
79
+ },
80
+ toolRegistry,
81
+ )
155
82
 
156
- export interface HelloWorldOutput {
157
- message: string
158
- environmentName: string
159
- }
83
+ await mcpServer.listen(3000)
84
+ ```
160
85
 
161
- export const helloWorld: ToolHandler<HelloWorldInput, HelloWorldOutput> = async ({
162
- input,
163
- context,
164
- }) => {
165
- const name = input.name?.trim() || 'world'
166
- const environmentName = context.env.SKEDYUL_ENV ?? 'local'
86
+ ## Documentation
167
87
 
168
- return {
169
- message: `Hello, ${name}!`,
170
- environmentName,
171
- }
172
- }
88
+ | Guide | Description |
89
+ |-------|-------------|
90
+ | [Authentication](./docs/authentication.md) | Token types, scopes, and configuration |
91
+ | [Tools](./docs/tools.md) | Building MCP tools with handlers and schemas |
92
+ | [Webhooks](./docs/webhooks.md) | Receiving external events and callbacks |
93
+ | [Lifecycle Hooks](./docs/lifecycle-hooks.md) | Install, provision, and uninstall handlers |
94
+ | [Core API](./docs/core-api.md) | Client for Skedyul platform resources |
95
+ | [Configuration](./docs/configuration.md) | skedyul.config.ts reference |
96
+ | [Errors](./docs/errors.md) | Error types and handling patterns |
173
97
 
174
- export const registry = {
175
- 'hello-world': helloWorld,
176
- }
177
- ```
98
+ ## Server Modes
178
99
 
179
- ### Dedicated server
100
+ ### Dedicated (Docker/ECS)
180
101
 
181
- ```ts
182
- import { server } from 'skedyul'
183
- import { registry } from './registry'
102
+ Long-running HTTP server with request counting and graceful shutdown:
184
103
 
104
+ ```ts
185
105
  const mcpServer = server.create(
186
106
  {
187
107
  computeLayer: 'dedicated',
188
- metadata: {
189
- name: 'my-dedicated-server',
190
- version: '1.0.0',
191
- },
108
+ metadata: { name: 'my-app', version: '1.0.0' },
192
109
  defaultPort: 3000,
193
110
  maxRequests: 1000,
194
111
  ttlExtendSeconds: 3600,
195
112
  },
196
- registry,
113
+ toolRegistry,
114
+ webhookRegistry,
197
115
  )
198
116
 
199
117
  await mcpServer.listen()
200
118
  ```
201
119
 
202
- ### Serverless handler
120
+ ### Serverless (AWS Lambda)
203
121
 
204
- ```ts
205
- import { server } from 'skedyul'
206
- import { registry } from './registry'
122
+ Export a Lambda handler with automatic CORS:
207
123
 
124
+ ```ts
208
125
  const mcpServer = server.create(
209
126
  {
210
127
  computeLayer: 'serverless',
211
- metadata: {
212
- name: 'my-serverless-mcp',
213
- version: '1.0.0',
214
- },
215
- cors: {
216
- allowOrigin: '*',
217
- },
128
+ metadata: { name: 'my-app', version: '1.0.0' },
129
+ cors: { allowOrigin: '*' },
218
130
  },
219
- registry,
131
+ toolRegistry,
132
+ webhookRegistry,
220
133
  )
221
134
 
222
135
  export const handler = mcpServer.handler
223
136
  ```
224
137
 
225
- ## Configuration guide
226
-
227
- - **`computeLayer`**: Choose `dedicated` to expose an HTTP server (`listen`) or `serverless` to get a Lambda handler (`handler`).
228
- - **`metadata`**: Used for the MCP server versioning payload.
229
- - **`maxRequests` / `ttlExtendSeconds`**: Control request capping logic that triggers a graceful shutdown (dedicated) or throttles health stats.
230
- - **`cors`**: Serverless handlers automatically add the configured CORS headers to every response.
231
- - **Runtime env overrides**: `MCP_ENV_JSON` (build-time) and `MCP_ENV` (container runtime) merge into `process.env` before every request, while request-level `env` arguments temporarily override env vars per tool call.
232
-
233
- ## Health metadata
234
-
235
- Both adapters expose `getHealthStatus()`, returning:
138
+ ## Endpoints
236
139
 
237
- - `status`: always `running` while the process is alive.
238
- - `requests`, `maxRequests`, `requestsRemaining`.
239
- - `lastRequestTime`, `ttlExtendSeconds`.
240
- - `runtime`: string label (`dedicated` or `serverless`).
241
- - `tools`: list of registered tool names.
140
+ | Endpoint | Method | Description |
141
+ |----------|--------|-------------|
142
+ | `/mcp` | POST | MCP JSON-RPC (tools/list, tools/call) |
143
+ | `/webhooks/{name}` | * | Webhook handlers |
144
+ | `/health` | GET | Server health status |
145
+ | `/estimate` | POST | Billing estimation |
146
+ | `/install` | POST | Installation handler |
147
+ | `/provision` | POST | Provisioning handler |
148
+ | `/uninstall` | POST | Uninstall handler |
149
+ | `/oauth_callback` | POST | OAuth callback handler |
242
150
 
243
151
  ---
244
152
 
245
153
  # Skedyul CLI
246
154
 
247
- The Skedyul CLI (`skedyul`) is a powerful command-line interface for developing, testing, and debugging Skedyul integration apps locally.
155
+ The CLI provides local development tools for building and testing Skedyul apps.
248
156
 
249
157
  ## Quick Start
250
158
 
@@ -253,7 +161,7 @@ The Skedyul CLI (`skedyul`) is a powerful command-line interface for developing,
253
161
  skedyul auth login
254
162
 
255
163
  # 2. Navigate to your app directory
256
- cd packages/skedyul-integrations/integrations/my-app
164
+ cd integrations/my-app
257
165
 
258
166
  # 3. Link to a workplace
259
167
  skedyul dev link --workplace my-clinic
@@ -262,342 +170,96 @@ skedyul dev link --workplace my-clinic
262
170
  skedyul dev serve --workplace my-clinic
263
171
  ```
264
172
 
265
- That's it! The CLI will:
266
- - Prompt for any missing environment variables (API keys, credentials)
173
+ The CLI will:
174
+ - Prompt for any missing environment variables
267
175
  - Start an ngrok tunnel automatically
268
176
  - Register your local machine with Skedyul
269
- - Route tool calls from Skedyul to your local server
270
-
271
- ## Installation
272
-
273
- The CLI is included with the `skedyul` package:
274
-
275
- ```bash
276
- npm install skedyul
277
- # or
278
- pnpm add skedyul
279
- ```
280
-
281
- Run commands with `npx skedyul` or install globally:
282
-
283
- ```bash
284
- npm link # In the skedyul-node package directory
285
- skedyul --help
286
- ```
177
+ - Route tool calls to your local server
287
178
 
288
179
  ## Commands
289
180
 
290
181
  ### Authentication
291
182
 
292
183
  ```bash
293
- # Log in via browser OAuth
294
- skedyul auth login
295
-
296
- # Check authentication status
297
- skedyul auth status
298
-
299
- # Log out
300
- skedyul auth logout
184
+ skedyul auth login # Log in via browser OAuth
185
+ skedyul auth status # Check authentication status
186
+ skedyul auth logout # Log out
301
187
  ```
302
188
 
303
189
  ### Configuration
304
190
 
305
191
  ```bash
306
- # Set global configuration
307
- skedyul config set <key> <value>
308
-
309
- # Get a config value
310
- skedyul config get <key>
311
-
312
- # List all configuration
313
- skedyul config list
192
+ skedyul config set <key> <value> # Set global configuration
193
+ skedyul config get <key> # Get a config value
194
+ skedyul config list # List all configuration
314
195
  ```
315
196
 
316
- **Available config keys:**
317
-
318
197
  | Key | Description | Default |
319
198
  |-----|-------------|---------|
320
199
  | `defaultServer` | Skedyul server URL | `https://admin.skedyul.it` |
321
- | `ngrokAuthtoken` | Your ngrok authtoken for tunneling | - |
322
-
323
- ### Development Commands
200
+ | `ngrokAuthtoken` | Your ngrok authtoken | - |
324
201
 
325
- #### `skedyul dev link`
326
-
327
- Links your local app to a Skedyul workplace. This creates a personal `local-{username}` AppVersion for testing.
202
+ ### Development
328
203
 
329
204
  ```bash
330
- skedyul dev link --workplace <subdomain>
331
-
332
- # Example
333
- skedyul dev link --workplace demo-clinic
205
+ skedyul dev link --workplace <subdomain> # Link to a workplace
206
+ skedyul dev unlink --workplace <subdomain> # Remove a link
207
+ skedyul dev serve --workplace <subdomain> # Start dev server
208
+ skedyul dev invoke <tool-name> # Test a single tool
209
+ skedyul dev tools # List all tools
210
+ skedyul dev validate # Validate config
211
+ skedyul dev diff # Preview deploy changes
334
212
  ```
335
213
 
336
- **What it does:**
337
- - Creates (or finds) a `local-{username}` AppVersion in the target workplace
338
- - Creates an AppInstallation for your app in that workplace
339
- - Saves link configuration to `.skedyul/links/{subdomain}.json`
340
-
341
- #### `skedyul dev unlink`
342
-
343
- Removes a workplace link.
344
-
345
- ```bash
346
- skedyul dev unlink --workplace <subdomain>
347
- ```
348
-
349
- #### `skedyul dev serve`
350
-
351
- Starts a local MCP server for testing your tools.
352
-
353
- ```bash
354
- # Standalone mode (no Skedyul connection)
355
- skedyul dev serve
356
-
357
- # Connected to Skedyul (sidecar mode)
358
- skedyul dev serve --workplace <subdomain>
359
- ```
360
-
361
- **Options:**
214
+ ### Serve Options
362
215
 
363
216
  | Flag | Description |
364
217
  |------|-------------|
365
218
  | `--workplace, -w` | Workplace subdomain (enables sidecar mode) |
366
- | `--port, -p` | Port to listen on (default: 60000, auto-increments if busy) |
367
- | `--registry, -r` | Path to registry file (auto-detected) |
219
+ | `--port, -p` | Port to listen on (default: 60000) |
220
+ | `--registry, -r` | Path to registry file |
368
221
  | `--no-tunnel` | Don't start ngrok tunnel |
369
222
  | `--tunnel-url` | Use existing tunnel URL |
370
- | `--env, -e` | Set environment variable (e.g., `--env KEY=VALUE`) |
223
+ | `--env, -e` | Set environment variable |
371
224
  | `--env-file` | Load env vars from file |
372
225
 
373
- **Sidecar Mode:**
374
-
375
- When you specify `--workplace`, the CLI:
376
- 1. Loads your link configuration
377
- 2. Prompts for any missing required environment variables
378
- 3. Starts an ngrok tunnel (or uses `--tunnel-url`)
379
- 4. Registers the tunnel URL with Skedyul
380
- 5. Sends heartbeats to keep the connection alive
381
- 6. Routes incoming tool calls to your local server
382
-
383
- ```bash
384
- # Full example with custom port
385
- skedyul dev serve --workplace demo-clinic --port 8080
386
-
387
- # Use existing ngrok tunnel
388
- skedyul dev serve --workplace demo-clinic --tunnel-url https://abc123.ngrok.io
389
- ```
390
-
391
- #### `skedyul dev invoke`
392
-
393
- Invoke a single tool for quick testing.
394
-
395
- ```bash
396
- skedyul dev invoke <tool-name> [options]
397
-
398
- # Examples
399
- skedyul dev invoke appointment_types_list
400
- skedyul dev invoke clients_search --args '{"phone": "+1234567890"}'
401
-
402
- # With linked credentials
403
- skedyul dev invoke appointment_types_list --workplace demo-clinic
404
- ```
405
-
406
- #### `skedyul dev tools`
407
-
408
- List all tools in your registry.
409
-
410
- ```bash
411
- skedyul dev tools
412
- skedyul dev tools --registry ./dist/registry.js
413
- ```
414
-
415
- #### `skedyul dev validate`
416
-
417
- Validate your `skedyul.config.ts` file.
418
-
419
- ```bash
420
- skedyul dev validate
421
- ```
422
-
423
- #### `skedyul dev diff`
424
-
425
- Preview what would change on deploy.
426
-
427
- ```bash
428
- skedyul dev diff
429
- ```
430
-
431
226
  ## Configuration Files
432
227
 
433
- The CLI uses several configuration files:
434
-
435
228
  | File | Purpose |
436
229
  |------|---------|
437
230
  | `~/.skedyul/credentials.json` | Authentication tokens |
438
- | `~/.skedyul/config.json` | Global configuration (server URL, ngrok token) |
439
- | `.skedyul.local.json` | Local project overrides (e.g., local server URL) |
440
- | `.skedyul/links/{workplace}.json` | Per-workplace link configuration |
441
- | `.skedyul/env/{workplace}.env` | Per-workplace environment variables |
442
-
443
- ### Local Development Override
444
-
445
- To use a local Skedyul server during development, create `.skedyul.local.json` in your project root:
446
-
447
- ```json
448
- {
449
- "serverUrl": "http://localhost:3000"
450
- }
451
- ```
452
-
453
- ## Environment Variables
454
-
455
- ### Install Configuration
456
-
457
- Define required environment variables in your app's `config/install.config.ts`:
458
-
459
- ```typescript
460
- import type { InstallConfig } from 'skedyul'
461
-
462
- const config: InstallConfig = {
463
- env: {
464
- API_KEY: {
465
- label: 'API Key',
466
- required: true,
467
- visibility: 'encrypted',
468
- description: 'Your API key for authentication',
469
- },
470
- BASE_URL: {
471
- label: 'Server URL',
472
- required: true,
473
- visibility: 'visible',
474
- placeholder: 'https://api.example.com',
475
- description: 'Base URL for the API',
476
- },
477
- },
478
- }
231
+ | `~/.skedyul/config.json` | Global configuration |
232
+ | `.skedyul.local.json` | Local project overrides |
233
+ | `.skedyul/links/{workplace}.json` | Per-workplace link config |
234
+ | `.skedyul/env/{workplace}.env` | Per-workplace env vars |
479
235
 
480
- export default config
481
- ```
482
-
483
- The CLI will automatically prompt for these when you run `skedyul dev serve --workplace <name>` if they're not already configured.
484
-
485
- ### Visibility Options
486
-
487
- | Visibility | Behavior |
488
- |------------|----------|
489
- | `visible` | Shown in plain text |
490
- | `encrypted` | Hidden during input, masked in output |
491
-
492
- ## Ngrok Integration
493
-
494
- The CLI uses ngrok to create public tunnels to your local server, allowing Skedyul to route requests to your machine.
495
-
496
- ### Setup
236
+ ## Ngrok Setup
497
237
 
498
238
  1. Get a free authtoken at [ngrok.com](https://dashboard.ngrok.com/get-started/your-authtoken)
499
- 2. The CLI will prompt for it on first use, or set it manually:
500
-
501
- ```bash
502
- skedyul config set ngrokAuthtoken <your-token>
503
- ```
504
-
505
- ### Session Limits
506
-
507
- ngrok's free tier allows 1 simultaneous session. If you see an error:
508
-
509
- ```
510
- ngrok free tier only allows 1 simultaneous session.
511
- ```
512
-
513
- **Solutions:**
514
- 1. Kill other ngrok sessions: `pkill -f ngrok`
515
- 2. Use an existing tunnel: `skedyul dev serve --workplace demo --tunnel-url https://existing.ngrok.io`
516
- 3. Upgrade to a paid ngrok plan
517
-
518
- ## Workflow Example
519
-
520
- ### Setting Up a New Integration
521
-
522
- ```bash
523
- # 1. Navigate to your app
524
- cd integrations/my-app
525
-
526
- # 2. Authenticate
527
- skedyul auth login
528
-
529
- # 3. Link to your test workplace
530
- skedyul dev link --workplace staging-clinic
531
-
532
- # 4. Start development server (will prompt for env vars)
533
- skedyul dev serve --workplace staging-clinic
534
-
535
- # Server starts...
536
- # ✓ Loaded 12 tools from registry
537
- # ✓ Tunnel active: https://abc123.ngrok.io
538
- # ✓ Registered with Skedyul
539
- # Listening on http://localhost:60000
540
- ```
541
-
542
- ### Testing Individual Tools
543
-
544
- ```bash
545
- # Quick test without full server
546
- skedyul dev invoke appointment_types_list --workplace staging-clinic
547
-
548
- # With arguments
549
- skedyul dev invoke calendar_slots_availability_list \
550
- --workplace staging-clinic \
551
- --args '{"calendar_names": ["Room 1"], "dates": ["2024-01-15"]}'
552
- ```
239
+ 2. Set it: `skedyul config set ngrokAuthtoken <your-token>`
553
240
 
554
241
  ## Troubleshooting
555
242
 
556
- ### "Not linked to {workplace}"
557
-
558
- Run `skedyul dev link --workplace {workplace}` first.
559
-
560
- ### "Authentication required"
561
-
562
- Run `skedyul auth login` to authenticate.
563
-
564
- ### Port already in use
565
-
566
- The CLI auto-increments from port 60000 if busy. Or specify: `--port 8080`
567
-
568
- ### ngrok authentication failed
569
-
570
- Set your authtoken: `skedyul config set ngrokAuthtoken <token>`
571
-
572
- ### Environment variables not loading
573
-
574
- Check that your `config/install.config.ts` exports the env configuration properly. Use `--debug` flag for verbose output.
243
+ | Issue | Solution |
244
+ |-------|----------|
245
+ | "Not linked to {workplace}" | Run `skedyul dev link --workplace {workplace}` |
246
+ | "Authentication required" | Run `skedyul auth login` |
247
+ | Port already in use | Use `--port 8080` or let CLI auto-increment |
248
+ | ngrok auth failed | Run `skedyul config set ngrokAuthtoken <token>` |
575
249
 
576
250
  ---
577
251
 
578
252
  ## Development
579
253
 
580
- - `npm run build` compiles the TypeScript sources into `dist/`.
581
- - `npm test` rebuilds the package and runs `tests/server.test.js` against the compiled output.
582
- - `npm run lint` (if added later) should validate formatting/typing.
583
-
584
- ## Publishing
585
-
586
- Before publishing:
587
-
588
- 1. Run `npm run build`.
589
- 2. Verify `dist/index.js` and `.d.ts` exist.
590
- 3. Ensure `package.json` metadata (name, version, description, repository, author, license) matches the npm listing.
591
-
592
- Use `npm publish --access public` once the package is ready; the `files` array already limits the tarball to `dist/`.
254
+ ```bash
255
+ npm run build # Compile TypeScript
256
+ npm test # Run tests
257
+ ```
593
258
 
594
259
  ## Contributing
595
260
 
596
- Contributions should:
597
-
598
- 1. Follow the TypeScript style (strict types, async/await, try/catch).
599
- 2. Keep MCP transports lean and share logic in `src/server.ts`.
600
- 3. Add unit tests under `tests/` and run them via `npm test`.
601
-
602
- Open a PR with a clear summary so the release process can verify `dist/` artifacts before publishing.
261
+ 1. Follow TypeScript style (strict types, async/await)
262
+ 2. Keep MCP transports lean
263
+ 3. Add unit tests under `tests/`
603
264
 
265
+ Open a PR with a clear summary for review.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skedyul",
3
- "version": "0.2.160",
3
+ "version": "0.3.0",
4
4
  "description": "The Skedyul SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",