Create the workflow MCP smoke tool from the portal
This tutorial creates the workflow-mcp-smoke workflow and exposes it as the
workflow_mcp_smoke MCP tool. Create both resources through the portal UI. Do
not insert rows into wf_definition_t, tool_t, or
workflow_tool_binding_t.
Light Portal uses event sourcing. The command services append domain events, and the query-side projector derives the database read models from those events:
Create Workflow Definition
-> WorkflowDefinitionCreatedEvent
-> wf_definition_t
Create Tool with Execution Placement = workflow
-> ToolCreatedEvent
-> tool_t
-> workflow_tool_binding_t
The workflow binding is part of the tool creation contract. There is no separate Create Workflow Tool Binding page.
Prerequisites
- Sign in to the portal and select the host where the smoke tool will run.
- Use an account that can administer workflow definitions and GenAI tools.
- Make sure
light-workflow, the portal command service, the portal query service, PostgreSQL, and the event projector are running. - Download the versioned workflow-mcp-smoke definition.
The host must not already contain an active workflow with this identity:
namespace: light-demo
name: workflow-mcp-smoke
version: 1.0.0
It must also not contain an active tool named workflow_mcp_smoke that was
inserted by an older SQL fixture. A projection-only record has no aggregate
history and cannot safely be replaced with the normal Create command. Start
with a clean database or have an administrator quarantine/remove the legacy
fixture before following this tutorial. Do not use the normal Update or Delete
buttons to repair projection-only data.
Workflow definition
The importable YAML is maintained with this tutorial and is included below so the rendered mdBook and downloadable asset cannot drift apart:
document:
dsl: "1.0.3"
namespace: light-demo
name: workflow-mcp-smoke
version: "1.0.0"
title: Workflow MCP Smoke Test
summary: Deterministic read-only workflow used to qualify the gateway-to-workflow MCP path.
tags:
testType: local
dependencies: none
evaluate:
language: cel
input:
schema:
format: json
document:
type: object
additionalProperties: false
required:
- message
properties:
message:
type: string
minLength: 1
maxLength: 256
output:
schema:
format: json
document:
type: object
additionalProperties: false
required:
- message
- executedBy
properties:
message:
type: string
executedBy:
type: string
do:
- finish:
set:
message: "${{ message }}"
executedBy: light-workflow
1. Create the workflow definition
-
In the portal sidebar, expand Workflow Admin and select Wf Definition.
-
Select Create New WfDefinition.
-
In Workflow Editor, select Import and open
workflow-mcp-smoke.yaml. -
Confirm the editor populated these values:
Field Value Namespace light-demoName workflow-mcp-smokeVersion 1.0.0Publish in Workflow Catalog Enabled The Host ID comes from the signed-in user’s selected host. Leave the Workflow Definition ID empty; the command service generates it.
-
Select Validate and resolve any reported errors.
-
Select Save once. A successful save displays Workflow definition saved and assigns a Workflow Definition ID.
-
Record the generated Workflow Definition ID as
<wfDefId>. You will use it when creating the tool. -
Return to Wf Definition, refresh the table, and use Update to confirm that the saved definition can be loaded. This also confirms that the event and projection have reached the same aggregate version.
Do not immediately submit the same Create form again while waiting for the projection. Refresh the list instead.
2. Create the workflow-backed tool and binding
-
In the sidebar, expand GenAI Admin and select Tool.
-
Select Create Workflow-backed Tool.
-
Enter the following tool values. Fields not listed here can remain empty.
Field Value Name workflow_mcp_smokeDescription Run a deterministic read-only workflow and return the supplied message.Routing Domain WorkflowSemantic Namespace workflow-smokeSemantic Description Qualify workflow-backed MCP execution.Lifecycle Status activeRead Only Enabled Idempotent Enabled Destructive Disabled Human Approval Required Disabled Version 1.0.0Execution Placement workflowWorkflow Definition light-demo/workflow-mcp-smoke @ 1.0.0Implementation Typeis not required for a workflow-placed tool. The workflow binding, rather than a Java class, REST endpoint, script, or MCP server, identifies its execution target. -
Portal loads the immutable workflow definition and derives the internal definition, schema, and policy digests. These implementation fields are not entered by the user. The reviewed workflow-tool runtime profile supplies the binding defaults.
-
Submit Create Tool Form once.
-
Record the generated Tool ID as
<toolId>. The command service uses this as the stable tool reference unless one was explicitly supplied. It also generates the binding ID becausebindingIdwas omitted from the JSON. -
Return to Tool, refresh the table, and open Update Tool for
workflow_mcp_smoke. Confirm that:- Execution Placement is
workflow. - Stable Tool Reference equals
<toolId>. - Workflow Binding contains the selected Workflow Definition ID and a generated
bindingId. - The tool is active.
- Execution Placement is
For a synchronous binding, the portal requires a read-only, non-destructive, headless tool: Read Only must be enabled while Destructive and Human Approval Required remain disabled. The server derives the binding integrity fields from the selected published workflow version and tool schemas.
3. Point light-gateway at the generated identities
The database identities are generated by the event-sourced Create commands,
so do not keep the fixed 22000000-... IDs from the old SQL fixture.
Open
portal-config-loc/all-in-lt/light-gateway-rust/config/mcp-router.yml and find
the workflow_mcp_smoke entry. Update only these identity fields:
workflowBinding:
stableToolRef: <toolId>
workflowDefinitionId: <wfDefId>
Keep the workflow version, schemas, digests, timeouts, result mode, and budget aligned with the values entered in the portal. Reload or restart light-gateway after changing its configuration.
The light-gateway file is runtime configuration, not a light-portal projection. Updating it does not replace the requirement to create the portal entities through commands/events.
4. Verify the smoke path
-
In Workflow Admin > Wf Definition, confirm that
workflow-mcp-smokehas exactly one active row and that Update opens it without an aggregate-version error. -
In GenAI Admin > Tool, confirm that
workflow_mcp_smokehas exactly one active row and that Update Tool shows the workflow binding. -
From a terminal on the Docker host, set a valid portal authorization value. Keep the
Bearerprefix:export LIGHT_PORTAL_AUTHORIZATION='Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkFacDAyVzZqZGNxWHpxTkk2MVlaelEifQ.eyJpc3MiOiJ1cm46Y29tOm5ldHdvcmtudDpvYXV0aDI6djEiLCJhdWQiOiJ1cm46Y29tLm5ldHdvcmtudCIsInN1YiI6IjAxOTY0YjA1LTU1MzItN2M3OS04Y2RlLTE5MWRjYmQ0MjFiOCIsImV4cCI6MTc4NjYyMjU0MywianRpIjoiRkMxM0ZmYzNUMm0zLXlMT1RHc3NHQSIsImlhdCI6MTc4NjYyMTk0MywibmJmIjoxNzg2NjIxODIzLCJ2ZXIiOiIxLjAiLCJjaWQiOiJmN2Q0MjM0OC1jNjQ3LTRlZmItYTUyZC00YzU3ODc0MjFlNzIiLCJzY3AiOlsicG9ydGFsLnIiLCJwb3J0YWwudyJdLCJjbGllbnRfaWQiOiJmN2Q0MjM0OC1jNjQ3LTRlZmItYTUyZC00YzU3ODc0MjFlNzIiLCJzY29wZSI6InBvcnRhbC5yIHBvcnRhbC53IiwiY3NyZiI6IjNFS3lmUkxpVFBtTFM2QXVIMEZNcGciLCJlaWQiOiJzaDM1IiwiZW1sIjoic3RldmUuaHVAbGlnaHRhcGkubmV0IiwiaG9zdCI6IjAxOTY0YjA1LTU1MmEtN2M0Yi05MTg0LTY4NTdlN2YzZGM1ZiIsInJvbGUiOiJhY2NvdW50LW1hbmFnZXIgYWRtaW4gZ2l0aHViLXJlYWRlciBob3N0LWFkbWluIG1jcC1yZWFkZXIgdXNlciIsInVpZCI6IjAxOTY0YjA1LTU1MzItN2M3OS04Y2RlLTE5MWRjYmQ0MjFiOCIsInV0eSI6IkUifQ.D47-XR66YEdm_KLr8sgNyKxmuXeLtqjMv0h4AIhf8w5ph0T-l4Cgyc2GIP76finZjy04OguEeAfN_qqAqQu2sLb-OOTo3-WekSmmKQAX5yJLKZJup8DbShNydhTES4GklgLVltF86Cj5npJBtj8VF3Kptd67gdrZ8TF-7o9DvLjD8Umv2kz1vjijCX0J5xyjjX8HFC7cOGsHd8gKieGTZfVykTcJlZMjbzU3zlYIIjYlkmpLrQDai56eJF7wKr-CoXV3Gg3fXjUK7wsLfo1nbBLr0I20qMdXAJLYnfoXszaN3ZYGKl27W-Hh6X5iITFrTD92XavAVU24QEltjJzk7A'Then query light-gateway directly through its published HTTPS port with MCP
tools/list:curl -skS --max-time 40 \ -H "Authorization: $LIGHT_PORTAL_AUTHORIZATION" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "MCP-Protocol-Version: 2026-07-28" \ -H "MCP-Method: tools/list" \ --data-binary '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"workflow-smoke","version":"1"},"io.modelcontextprotocol/clientCapabilities":{}}}}' \ https://localhost/mcpConfirm that the response advertises a tool whose
nameisworkflow_mcp_smoke. -
Invoke the advertised tool with a
tools/callrequest:curl -skS --max-time 40 \ -H "Authorization: $LIGHT_PORTAL_AUTHORIZATION" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "MCP-Protocol-Version: 2026-07-28" \ -H "MCP-Method: tools/call" \ -H "MCP-Name: workflow_mcp_smoke" \ --data-binary '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"workflow_mcp_smoke","arguments":{"message":"hello from workflow MCP"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"workflow-smoke","version":"1"},"io.modelcontextprotocol/clientCapabilities":{}}}}' \ https://localhost/mcp -
Confirm that the response has
isError: false, contains the supplied message, and includes:{ "executedBy": "light-workflow" }
For repeatable regression coverage against portal-config-loc or a
development light-portal-install deployment, run the corresponding
light-portal-test lane:
cd /home/steve/workspace/light-portal-test
make workflow-mcp
Troubleshooting
The workflow Create event goes to the DLQ
Check for an older projection-only row with the same host, namespace, name,
and version. Do not edit the new event payload. Remove or quarantine the
invalid legacy fixture, then use the supported event replay flow so the valid
WorkflowDefinitionCreatedEvent builds the projection.
The tool Create event goes to the DLQ
Check for an older projection-only workflow_mcp_smoke tool or binding before
retrying. Also confirm that <wfDefId> identifies an active workflow at
version 1.0.0; the projector rejects a workflow binding whose referenced
definition/version is unavailable.
The Create Tool form rejects the binding
Verify all of the following:
wfDefIdis a UUID.- All four digests start with
sha256:and contain 64 lowercase hexadecimal characters. - The binding and top-level Schema Digest values are identical.
invocationModeissyncandexecutionClassisinteractive.- The tool is read-only, non-destructive, and does not require human approval.
- Structured-data edits were applied before the form was submitted.
tools/list still shows the old IDs
Update the light-gateway mcp-router.yml entry with the IDs generated by the
portal and restart or reload light-gateway. Do not change projection-table IDs
to match the old configuration.