Build a custom activity
Through Koodisi MCP, a client can turn a vendor's API into a group of custom activities, connect them to the vendor's OAuth sign-in, test them, and use them in workflows. This page walks through that flow. The WhatsApp activities were built this way.
Before you begin
- Connect your client and sign in. See Connect to Koodisi MCP.
- Select the workspace that should own the activities. Activity groups are shared across the organization, so many teams keep them in one dedicated workspace.
- Have the vendor's API description ready: an OpenAPI spec if there is one, otherwise the endpoints, parameters and request bodies.
1. Create the activities
Ask the client to create an activity group with one activity per API operation. It uses
create_activity_group for a new group, or create_custom_activity and
bulk_create_custom_activities to add to an existing one. With an OpenAPI spec,
generate_activity_metadata_from_openapi and generate_mappable_fields_from_openapi draft
the names, descriptions and fields.
Each activity is a prefilled REST Client: the host, method and path are fixed, and its Configuration fields are sent into the request. Each field has a Mapped Source that says where its value goes:
| Mapped Source | Goes to |
|---|---|
pathParams/<name> | A {name} placeholder in the path |
queryParams/<name> | A query string parameter |
body/<name> | A field in the JSON request body |
Anything a field doesn't cover is mapped on the activity's Input tab in each workflow.
Ask the client to run validate_custom_activity before creating; it applies every check
without writing anything.
Rules that save you a debugging session
- Don't name a field
templateNameortemplateGroup. The engine uses those keys to remember which template a custom activity came from, so a field with either name sends the activity's own name in its place. Use a specific key, for examplefilterTemplateName. - Send fixed values through the configuration, not a schema default. A
defaultin the input schema only shows as a grey hint in the mapper and is never sent. For a value that's always the same (for examplemessaging_product: "whatsapp"), add a hidden field with its Mapped Source, and set its value in the activity's default configuration. - Make mapping widgets full width. The Input and Output mappers are alone on their
tabs; give them a span of
24.
2. Connect the vendor's OAuth sign-in
If the API uses OAuth, three things connect it:
- An identity provider for the vendor's OAuth app. Check
list_idpsfirst, thencreate_idpwith the app's authorization and token URLs. Studio admins can also do this under Library → ID Providers. - A resource template for that provider, with the scopes the activities need:
create_resource_template. - A resource in your app, created from the template. Sign in once, either from the
resource's Authenticate button in the Studio or with
initiate_oauth_connection, which returns a link to open in your browser.
check_oauth_credential_status then reports connected: true. On each activity's Auth
tab, drop the resource into the connection field.
3. Test
test_custom_activityruns an activity against sample input, like the editor's Test button.test_activity_with_live_credentialruns it with a resource's real OAuth connection.- To test exactly as production runs, build a small workflow (trigger, the activity, End), publish it, deploy it, and call its endpoint.
4. Make your changes reach deployments
Deployments don't read the activity definition directly. They use a compiled copy that the Studio's activity editor rebuilds when you save. After creating or changing activities through Koodisi MCP:
- Open each activity in the Studio's activity editor, check it, and Save.
- Approve the activity, so deployments use the new version.
- In each app that uses the group, Update the activity group.
- Publish the workflows again and deploy the new versions.
If a deployed workflow still behaves like the old activity, one of these steps was skipped.
5. Use it in a workflow
Ask the client to build the workflow with compile_workflow_spec, or add the activity to an
existing one with apply_workflow_patch. Then create_workflow_in_app, publish_workflow
and deploy_workflow.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| A field's value never reaches the API | Its Mapped Source is missing, or it's not a mappable field. | Give the field a Mapped Source. Only mappable, remote-select and table fields are sent. |
The request carries the activity's own name, for example name=ListMessageTemplates | A field is named templateName or templateGroup. | Rename the field, then save and approve the activity in the editor. |
| A deployed workflow ignores your latest activity change | The compiled copy wasn't rebuilt. | Follow Make your changes reach deployments. |
check_oauth_credential_status returns connected: false after signing in | The resource was signed in under a different app or workspace, or with another account. | Sign in again from the resource in the app the workflow runs in. |
| The vendor rejects calls with a permissions error | The OAuth consent didn't grant access to the account you're calling. | Sign in again and select the right business or account in the vendor's consent dialog. |
Related
- Supported tools
- WhatsApp activities: an activity group built this way.