Skip to content

[BUG] Workflows exposed as MCP tools receive empty RuntimeContext, preventing access to authentication #7819

@RainerAtSpirit

Description

@RainerAtSpirit

[BUG] Workflows exposed as MCP tools receive empty RuntimeContext, preventing access to authentication

Description

When workflows are exposed via MCPServer, they always receive an empty RuntimeContext regardless of the authentication context available at execution time. This prevents workflows from accessing authentication information passed through options.extra.

Steps to Reproduce

  1. Create a workflow that requires authentication:
const myWorkflow = createWorkflow({
  id: 'my-workflow',
  description: 'A workflow that needs auth',
  steps: [],
  inputSchema: z.object({ data: z.string() }),
  outputSchema: z.object({ result: z.string() })
})
  .then(createStep({
    id: 'auth-step',
    execute: async ({ inputData, runtimeContext }) => {
      // This will always be undefined when called via MCP
      const authToken = runtimeContext.get('authToken');
      if (!authToken) {
        throw new Error('Authentication required');
      }
      // ... do work
    }
  }))
  .commit();
  1. Expose it via MCPServer:
const server = new MCPServer({
  name: 'My Server',
  workflows: {
    myWorkflow
  }
});
  1. Set up authentication middleware:
// Middleware that sets req.auth
app.use((req, res, next) => {
  req.auth = { authToken: 'token123' };
  next();
});
  1. Call the workflow tool via MCP - it will fail with "Authentication required"

Expected Behavior

The workflow should receive the authentication context from options.extra.authInfo or through the runtimeContext parameter, similar to how regular tools work.

Actual Behavior

The workflow always receives an empty RuntimeContext() because:

  1. convertWorkflowsToTools creates a new empty RuntimeContext at tool creation time:
// In packages/mcp/src/server/server.ts
const options = {
  runtimeContext: new RuntimeContext(), // Always empty!
  // ...
};
const coreTool = makeCoreTool(workflowToolDefinition, options);
  1. CoreToolBuilder.createExecute uses the creation-time RuntimeContext, not the execution-time context:
// The runtimeContext used is from options (creation time), 
// not from execOptions (execution time)
runtimeContext: options.runtimeContext ?? new RuntimeContext()

Root Cause Analysis

The issue occurs because:

  • makeCoreTool is called with a static empty RuntimeContext during workflow-to-tool conversion
  • The execution-time options.extra (which contains authInfo) is never used to populate the runtimeContext
  • Unlike regular tools which can access options.extra directly, workflow steps only receive runtimeContext

Proposed Solutions

The following approaches could fix this issue:

Option 1: Pass execution-time context (Recommended)

Modify CoreToolBuilder.createExecute to check for runtime context in execOptions:

runtimeContext: execOptions.runtimeContext ?? options.runtimeContext ?? new RuntimeContext()

This maintains backward compatibility while allowing runtime context injection.

Option 2: Populate RuntimeContext from options.extra

Before calling the workflow, populate the RuntimeContext from options.extra.authInfo:

if (options.extra?.authInfo) {
  Object.entries(options.extra.authInfo).forEach(([key, value]) => {
    runtimeContext.set(key, value);
  });
}

This approach automatically maps auth info to the runtime context.

Option 3: Pass options.extra to workflow steps

Allow workflow steps to access options.extra directly, similar to regular tools.
This would require more significant API changes but provides maximum flexibility.

Impact

  • Workflows that need authentication cannot be used via MCP
  • This limits the usefulness of exposing workflows through MCP servers
  • Workaround requires using individual tools instead of workflows

Environment

  • @mastra/core: 0.16.0
  • @mastra/mcp: 0.12.0
  • Node.js: 20.x
  • TypeScript: 5.x

Related Code References

  • packages/mcp/src/server/server.ts - convertWorkflowsToTools method
  • packages/core/src/tool/builder.ts - CoreToolBuilder.createExecute method

Workaround

Currently, the only workaround is to not expose workflows via MCP and use individual tools instead, or ensure workflows only use tools internally (which get their own auth context) rather than accessing runtimeContext directly in steps.


Additional Context

This issue was discovered when trying to expose workflows that require authentication through an MCP server. Regular tools work fine because they can access options.extra.requestInfo.headers or options.extra.authInfo, but workflows don't have access to these.

The same issue likely affects agents converted to tools via convertAgentsToTools, which also creates an empty RuntimeContext.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions