Skip to content

vMCP workflow templates cannot access JSON fields from tool results #2669

@jhrozek

Description

@jhrozek

When a workflow step calls an MCP tool that returns JSON, subsequent steps cannot access individual fields via template expansion. The JSON is stored as a raw string under a "text" key instead of being parsed.

Problem

In pkg/vmcp/client/client.go, the CallTool function stores text content without parsing:

resultMap[key] = textContent.Text  // line ~460

So when a tool returns {"count": 42, "type": "user_records"}, the step output becomes:

{"text": `{"count":42,"type":"user_records"}`}

Templates like {{.steps.fetch_data.output.count}} fail because there's no count key - only text.

Reproduction

Create a 2-step workflow where step 2 references step 1's output:

steps:
  - id: fetch_data
    tool: data_fetch_data
    
  - id: transform_data
    tool: transform_data
    arguments:
      count: "{{.steps.fetch_data.output.count}}"
    depends_on: [fetch_data]

The count argument receives <no value> instead of the actual value.

Proposed fix

Parse JSON text content and add fields to the result map:

resultMap["_raw"] = textContent.Text

var parsed map[string]any
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err == nil {
    for k, v := range parsed {
        resultMap[k] = v
    }
}

Using _raw instead of text avoids collision if the tool returns a field named "text".

The existing unit tests don't catch this because they create structured output directly via RecordStepSuccess(), bypassing the MCP client entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiItems related to the APIbugSomething isn't workinggoPull requests that update go code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions