Integration toolkit
Build workflow and agent integration apps with @lunnoa/toolkit.
@lunnoa/toolkit is the TypeScript SDK for defining Lunnoa Automate integration apps: the actions, triggers, connections, and input forms that appear in workflows and AI agents.
Use it when you are building a publishable app package (for example @lunnoa-automate/app-http) that a Lunnoa server installs at runtime, or a private integration for your organisation.
The toolkit provides factories and types only. Your app's run handlers execute inside the Lunnoa Automate server, which supplies runtime services (database, HTTP, OAuth, logging, and more).
Requirements
- Node.js 20 or newer
- A Lunnoa Automate deployment to install and test the app against
- TypeScript recommended (the factories are typed)
Install
For a local experiment:
For publishable app packages, declare the toolkit as a peer dependency. Do not bundle it. The host server resolves @lunnoa/toolkit from its own node_modules at runtime.
Quickstart
A minimal app with one action. Export the createApp(...) result as your package default export. The platform loads installable apps with require() and registers them in the workflow app catalogue.
Recommended folder structure
Mirror the layout used by built-in apps (for example Slack and HTTP). Keep one file per action, trigger, and connection; put shared helpers in shared/; wire everything in a single app entry file.
Source layout
Naming conventions
| Path | Convention | Example |
|---|---|---|
| App entry | <app-id>.app.ts or index.ts that calls createApp | slack.app.ts |
| Action file | <kebab-name>.action.ts | send-message.action.ts |
| Trigger file | <kebab-name>.trigger.ts | new-message.trigger.ts |
| Connection file | <type>.connection.ts or <provider>.oauth2.ts | oauth2.connection.ts |
| Shared code | shared/<topic>.ts | shared/client.ts |
Practices that scale
- One export per file. Each action/trigger/connection file exports a single factory result; the app entry imports and registers them.
- No business logic in the app entry.
createAppshould only set metadata and arrays. - Put API clients in
shared/. Reuse them fromrun/mockRuninstead of duplicating fetch logic. - Keep ids aligned with folders. File
send-message.action.tspairs with idmy-service_action_send-message. - Colocate tests next to shared helpers when you need them (
shared/ssrf-guards.spec.ts), not next to every action unless the case is action-specific. - Compile to
dist/and pointpackage.jsonmainat the compiled default export. See Packaging.
A tiny app can start as a single index.ts. Split into actions/, triggers/, and connections/ as soon as you add a second action or any shared client code.
Core concepts
| Piece | Factory | Role |
|---|---|---|
| App | createApp | Top-level definition: metadata, actions, triggers, connections |
| Action | createAction | One operation in a workflow step or agent tool call |
| Trigger | createManualTrigger, poll/webhook factories, … | Starts or schedules workflow runs |
| Connection | createApiKeyConnection, OAuth helpers, … | Auth config for third-party APIs |
| Input config | createTextInputField, createSelectInputField, … | Form fields shared by actions, triggers, and connections |
ID conventions
IDs are stable registry keys. Follow these formats exactly:
| Kind | Format | Example |
|---|---|---|
| App | kebab-case slug | hello, slack, http |
| Action | <app-id>_action_<action-name> | hello_action_greet |
| Trigger | <app-id>_trigger_<trigger-name> | flow-control_trigger_manually-run |
| Connection | <app-id>_connection_<connection-name> | slack_connection_oauth2 |
Guides in this section
| Guide | What you will do |
|---|---|
| Actions | Define createAction with run, mockRun, and aiSchema |
| Input config | Build configuration forms with field factories |
| Triggers | Start workflows with manual, schedule, poll, or webhook triggers |
| Connections | Add API key, basic auth, OAuth, and other auth methods |
| Packaging | Ship a publishable npm app with the lunnoaApp manifest |
Related
- TypeScript client SDK: call the Public API from your own apps
- npm: @lunnoa/toolkit: package page and releases
- lunnoa_apps: reference and publishable app packages