Skip to content

feat(mcp-server): expose workflow tools in Forest MCP server (PRD-49) - #1792

Open
christophebrun-forest wants to merge 4 commits into
mainfrom
feature/prd-49-expose-workflow-tools-in-forest-mcp-server
Open

feat(mcp-server): expose workflow tools in Forest MCP server (PRD-49)#1792
christophebrun-forest wants to merge 4 commits into
mainfrom
feature/prd-49-expose-workflow-tools-in-forest-mcp-server

Conversation

@christophebrun-forest

@christophebrun-forest christophebrun-forest commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

Integration branch for the PRD-49 epic — expose Forest workflow triggering to MCP clients. Adds a report-only (v1) toolset so an LLM can list, trigger, and observe Forest workflows through the MCP server.

The MCP tools call into @forestadmin/forestadmin-client (WorkflowsServiceForestHttpApi), which hits the Forest orchestrator (/api/workflow-orchestrator/mcp-workflows/*) under the MCP session identity (forestServerToken, Forest-Application-Source: MCP).

Included work

Behavior (v1, report-only)

  1. listWorkflows → available MCP-enabled workflows
  2. triggerWorkflow{ runId, runState }
  3. getWorkflowRun → poll runState, currentStep, waitingForHumanInput, terminal result/error

A run parked on a human-gated step reports waitingForHumanInput: true; resuming it via MCP is out of scope here and handled in the follow-up PRD-441 (submitWorkflowInput).

Tests

New/updated unit tests across mcp-server, forestadmin-client, workflow-executor, plus cross-package mocks in agent-testing and agent.

fixes PRD-49

🤖 Generated with Claude Code

Note

Add workflow tools (listWorkflows, triggerWorkflow, getWorkflowRun) to the Forest MCP server

  • Adds three new MCP tools: listWorkflows lists MCP-enabled workflows (optionally filtered by collection), triggerWorkflow starts a workflow run on a record and logs the action via activity logs, and getWorkflowRun fetches the current status of a workflow run.
  • Introduces WorkflowsService in packages/forestadmin-client/src/workflows/index.ts that delegates to three new HTTP endpoints on ForestHttpApi: GET /api/workflow-orchestrator/mcp-workflows, POST .../mcp-workflows/{workflowId}/start, and GET .../mcp-workflows/runs/{runId}.
  • Wires WorkflowsService through ForestAdminClientWithCache, createForestAdminClient, and ForestServerClientImpl so the MCP server can use it.
  • Extracts getAuthContext into a shared auth-context.ts utility used across the new tools.
  • Adds mcp to the TriggerType and ServerWorkflowTriggerType enums in workflow-executor to represent MCP-triggered runs.
  • Risk: triggerWorkflow pre-validates the target workflow by calling listMcpWorkflows before triggering — this adds an extra HTTP round-trip per trigger call.
📊 Macroscope summarized e87448d. 18 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

christophebrun-forest and others added 4 commits July 24, 2026 14:51
Expose MCP-enabled workflows to LLM clients via a new listWorkflows tool,
calling the Forest server MS3 endpoint (GET /api/workflow-orchestrator/workflows)
over the HTTP contract with the caller's forestServerToken + renderingId.

- forestadmin-client: WorkflowsService + ForestHttpApi.listMcpEnabledWorkflows
- mcp-server: listWorkflows tool, http-client wiring, shared getAuthContext util

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(mcp-server): add triggerWorkflow tool (PRD-738)

Expose the triggerWorkflow MCP tool so an LLM can start a run on a
specific record and get a runId back. Non-blocking by design: the run
continues server-side and status is observed via getWorkflowRun (MS8).

- tool args { workflowId, recordId }; identity from the OAuth auth
  context (forestServerToken + renderingId), wrapped in withActivityLog
  so MCP-triggered runs are audited locally under the caller.
- forestadmin-client: WorkflowsService.triggerMcpWorkflow calls the
  MCP-dedicated start endpoint over HTTP
  (POST /api/workflow-orchestrator/workflows/:workflowId/start), no
  private-api internals imported.
- collectionId is derived server-side from the workflow (MS5), so the
  tool contract stays { workflowId, recordId } — consistent with the
  webhook trigger.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…32) (#1786)

MCP-triggered runs carry triggerType='mcp', but the executor only
recognized manual|webhook, so AvailableStepExecutionSchema.parse
rejected every MCP run at step 0 with a DomainValidationError before
executing. triggerType is informational only (logged in runner.ts, no
logic branches on it), so a run was aborted purely over an unrecognized
logged value.

Add 'mcp' to TriggerType and ServerWorkflowTriggerType so MCP runs map
to a valid AvailableStepExecution and execute.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(mcp-server): add getWorkflowRun tool (PRD-740)

Expose the getWorkflowRun polling tool so the LLM can observe a run's
status, closing the discover -> trigger -> poll loop. Report-only in v1:
human-gated runs report waitingForHumanInput but cannot be resumed via
MCP (tracked in PRD-441).

Threads a getMcpWorkflowRun call through forestadmin-client (types, HTTP
api, workflows service) to the MS7 read endpoint, and registers a
read-only getWorkflowRun MCP tool scoped to the caller.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jul 30, 2026

Copy link
Copy Markdown

PRD-49

@qltysh

qltysh Bot commented Jul 30, 2026

Copy link
Copy Markdown

3 new issues

Tool Category Rule Count
qlty Structure Function with many parameters (count = 14): constructor 3

* The outcome of starting a workflow run: the run continues asynchronously server-side.
*/
export interface WorkflowRunTriggerResult {
runId: number;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High src/types.ts:312

WorkflowRunTriggerResult.runId is typed as number, but GetMcpWorkflowRunParams.runId requires a string, so the result of triggerMcpWorkflow cannot be passed directly into getMcpWorkflowRun without a manual conversion. The mismatch also means MCP tool input validation (string-only) rejects the numeric ID. Use one consistent type for runId across both interfaces.

Suggested change
runId: number;
runId: string;
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/forestadmin-client/src/types.ts around line 312:

`WorkflowRunTriggerResult.runId` is typed as `number`, but `GetMcpWorkflowRunParams.runId` requires a `string`, so the result of `triggerMcpWorkflow` cannot be passed directly into `getMcpWorkflowRun` without a manual conversion. The mismatch also means MCP tool input validation (string-only) rejects the numeric ID. Use one consistent type for `runId` across both interfaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant