agent-ecosystem/docs/research/mastra-integration-analysis.md
iliya 71db7f153b feat(research): add comprehensive documentation on AI agent protocols and orchestration tools
- Introduced multiple new markdown files detailing the Agent Client Protocol (ACP), AI agent orchestration landscape, and various tools for managing multi-agent systems.
- Included in-depth analysis of protocol standards, governance structures, and emerging frameworks relevant to AI agent integration.
- Documented key features, architecture, and integration potential of various desktop and CLI orchestrators, enhancing understanding of the current ecosystem.
- Provided insights into best practices for integrating multi-provider agent support within the Electron framework.

This documentation aims to serve as a foundational resource for developers and stakeholders involved in AI agent orchestration and integration.
2026-03-25 14:47:52 +02:00

35 KiB

Mastra Integration Analysis

Technical feasibility study for integrating Mastra (TypeScript agent framework) with Claude Agent Teams UI. Date: 2026-03-24

Table of Contents

  1. Executive Summary
  2. Mastra Architecture Overview
  3. Our Codebase Architecture
  4. Integration Points Analysis
  5. Concrete Integration Approaches
  6. Architecture Diagram
  7. What Stays the Same
  8. What Must Change
  9. Effort Estimate
  10. Risks and Blockers
  11. Recommendations
  12. Sources

Executive Summary

Mastra is a TypeScript-first agent framework (22K+ stars, $13M seed, YC-backed) from the Gatsby team. It provides unified primitives for agents, tools, workflows, RAG, and multi-agent orchestration with 40+ LLM provider support.

Key finding: Mastra operates at a fundamentally different level than Claude CLI. Our app is a process manager and UI for Claude Code CLI sessions. Mastra is an SDK for building agents programmatically. Integration is possible but requires a significant architectural shift — specifically, replacing Claude CLI process management with in-process Mastra agent runtime.

Verdict: 6/10 feasibility, 4/10 reliability of quick integration. The integration is architecturally sound but represents 6-10 person-weeks of work with significant risk to our core differentiator (Claude Code CLI features: file editing, terminal, git, Agent tool for spawning teammates).


Mastra Architecture Overview

Core Packages

Package Purpose
@mastra/core Agent, Workflow, Tool, Server, Storage, Vector, DI
@mastra/mcp MCPClient (consume) + MCPServer (expose)
@mastra/ai-sdk AI SDK v5 compatibility layer
@mastra/client-js HTTP client for remote Mastra servers
mastra CLI for project scaffolding

Agent Definition

import { Agent } from '@mastra/core/agent';
import { MCPClient } from '@mastra/mcp';

const agent = new Agent({
  id: 'team-lead',
  name: 'Team Lead',
  instructions: 'You coordinate the team...',
  model: 'anthropic/claude-sonnet-4-20250514',  // any of 40+ providers
  tools: { taskCreate, taskUpdate, sendMessage },
});

// Usage
const result = await agent.generate('Create tasks for the frontend sprint');
const stream = await agent.stream('Review the PR');
const researcher = new Agent({
  id: 'researcher',
  description: 'Researches technical topics',
  model: 'anthropic/claude-sonnet-4-20250514',
  tools: { webSearch, readFile },
});

const developer = new Agent({
  id: 'developer',
  description: 'Implements code changes',
  model: 'anthropic/claude-sonnet-4-20250514',
  tools: { editFile, runTests, bash },
});

const supervisor = new Agent({
  id: 'supervisor',
  name: 'Team Lead',
  instructions: 'Coordinate researcher and developer...',
  model: 'anthropic/claude-sonnet-4-20250514',
  agents: { researcher, developer },  // auto-converted to tools
  memory: new Memory(),
});

const stream = await supervisor.stream('Fix the authentication bug', {
  maxSteps: 20,
});

MCP Integration

import { MCPClient } from '@mastra/mcp';

const mcp = new MCPClient({
  servers: {
    'agent-teams': {
      command: 'node',
      args: ['/path/to/mcp-server/dist/index.js'],
    },
  },
});

const agent = new Agent({
  id: 'worker',
  model: 'anthropic/claude-sonnet-4-20250514',
  instructions: '...',
});

// Dynamic tool injection
const response = await agent.stream('Update task #abc to in_progress', {
  toolsets: await mcp.listToolsets(),
});

Our Codebase Architecture

Process Management Layer (Claude-specific)

The core of our backend is TeamProvisioningService — an 8000+ line service that manages Claude CLI processes.

Key file: src/main/services/team/TeamProvisioningService.ts

Core flow:

  1. Resolve Claude binary via ClaudeBinaryResolver
  2. Build provisioning prompt (~100 lines of structured instructions) via buildProvisioningPrompt()
  3. Spawn CLI process with stream-json protocol:
    spawnCli(claudePath, [
      '--input-format', 'stream-json',
      '--output-format', 'stream-json',
      '--verbose',
      '--mcp-config', mcpConfigPath,
      '--disallowedTools', 'TeamDelete,TodoWrite',
      '--dangerously-skip-permissions',
    ])
    
  4. Parse stdout as NDJSON (newline-delimited JSON) — types: user, assistant, control_request, result, system
  5. Send input via stdin using stream-json protocol: {"type":"user","message":{"role":"user","content":[...]}}\n
  6. Monitor filesystem for team config, tasks, inboxes written by CLI
  7. Relay messages between lead and teammates via inbox files

Key file: src/main/utils/childProcess.tsspawnCli() and execCli() wrappers with Windows shell fallback and EINVAL handling.

Prompt/Instruction System

The prompt system is deeply intertwined with Claude Code's native capabilities:

buildProvisioningPrompt() (line ~860) constructs a multi-section prompt:

  • Team identity (name, project, lead)
  • Step 1: Call BUILT-IN TeamCreate tool (Claude Code native)
  • Step 2: Spawn teammates via Agent tool (Claude Code native) with team_name parameter
  • Step 3: Create tasks via MCP board tools
  • Persistent lead context: communication protocol, board MCP operations, agent block policy

buildMemberSpawnPrompt() (line ~444) constructs per-teammate instructions:

  • Role and workflow injection
  • member_briefing MCP bootstrap call
  • Task lifecycle protocol (comment -> start -> work -> comment -> complete)
  • Detailed notification/escalation rules

Critical Claude-specific constructs in prompts:

  • Agent tool with team_name parameter — Claude Code's native teammate spawning
  • TeamCreate built-in tool — Claude Code's team lifecycle management
  • SendMessage built-in tool — Claude Code's inter-agent messaging
  • --disallowedTools TeamDelete,TodoWrite — Claude Code CLI flags
  • --permission-mode bypassPermissions — Claude Code permission system
  • stream-json protocol for bidirectional communication
  • Post-compact context reinjection for context window management

MCP Server

Key files: mcp-server/src/ (16 TypeScript files)

Our MCP server (FastMCP-based) exposes domain tools to agents:

Tool Domain Tools File
Tasks task_create, task_get, task_list, task_start, task_complete, etc. taskTools.ts
Kanban kanban_get, kanban_set_column, kanban_clear kanbanTools.ts
Review review_request, review_approve, review_request_changes reviewTools.ts
Messages send messages between agents messageTools.ts
Process process management processTools.ts
Cross-team cross_team_send, cross_team_list_targets crossTeamTools.ts
Runtime runtime state queries runtimeTools.ts

All tools delegate to agent-teams-controller — a workspace package that manages team state (config.json, tasks/, inboxes/).

Message Parsing Pipeline

Key files:

  • src/main/types/jsonl.ts — Raw JSONL format types (Claude Code session files)
  • src/main/types/messages.ts — ParsedMessage with type guards
  • src/main/services/analysis/ChunkBuilder.ts — Builds timeline chunks from parsed messages

The JSONL parsing is tightly coupled to Claude Code's output format:

  • Entry types: user, assistant, system, summary, file-history-snapshot, queue-operation
  • Content blocks: text, thinking, tool_use, tool_result, image
  • Usage metadata: input_tokens, output_tokens, cache_read_input_tokens
  • Claude-specific fields: model, stop_reason, cwd, gitBranch, agentId, isSidechain

IPC Layer

Key file: src/main/ipc/teams.ts — 60+ IPC channels for team operations

The renderer communicates with main process via Electron IPC. The channels include team CRUD, task management, message sending, provisioning control, tool approval, and process lifecycle.


Integration Points Analysis

1. Process Spawning — Claude CLI vs Mastra Agent Runtime

Aspect Current (Claude CLI) Mastra Integration
Runtime External process (claude binary) In-process Node.js (Agent.stream())
Protocol stream-json over stdin/stdout Programmatic TypeScript API
Agent spawning Agent tool with team_name param new Agent({ agents: {...} }) supervisor pattern
Tool execution Claude Code built-in + MCP Mastra tools + @mastra/mcp MCPClient
File editing Claude Code's built-in file tools Must provide custom tools (Read, Write, Bash)
Terminal Claude Code's built-in terminal Must provide custom Bash tool
Git Claude Code's built-in git support Must provide custom git tools
Context window Claude Code manages (200K) Mastra manages via provider settings

Claude-specificity score: 9/10 — This is the most tightly coupled area.

2. Prompt/Instruction System

Aspect Current Mastra Equivalent
System prompt Injected via stream-json first message Agent.instructions property
Dynamic instructions Post-compact reinjection via stdin instructions as function returning dynamic text
Built-in tools refs TeamCreate, Agent, SendMessage in prompt Must be replaced with Mastra tool calls
MCP tool refs task_create { teamName: "..." } Same MCP tools via @mastra/mcp MCPClient

Claude-specificity score: 7/10 — Prompts reference Claude Code native tools extensively.

3. MCP Server

Aspect Current Mastra Integration
Server framework FastMCP (stdio transport) Same — OR convert to Mastra tools directly
Tool definitions server.addTool({ name, parameters, execute }) createTool({ id, inputSchema, execute })
Transport stdio (spawned by Claude CLI) Could use @mastra/mcp MCPClient or convert to native Mastra tools
Controller agent-teams-controller package Unchanged — pure JS, no Claude dependency

Claude-specificity score: 2/10 — MCP is provider-agnostic. Our agent-teams-controller is pure business logic.

4. Message Parsing / JSONL Pipeline

Aspect Current Mastra Integration
Session storage ~/.claude/projects/{path}/*.jsonl Mastra has its own storage/memory system
Format Claude Code JSONL (specific schema) Mastra streaming chunks (text-delta, tool-call, etc.)
Type guards isParsedRealUserMessage, etc. New type guards for Mastra output format
Chunk building ChunkBuilder from JSONL messages New adapter from Mastra stream events
Subagent detection SubagentResolver from tool_use content Mastra supervisor tracks sub-agent calls natively

Claude-specificity score: 8/10 — The entire analysis pipeline assumes Claude Code JSONL format.

5. Team Lifecycle (config, inboxes, tasks)

Aspect Current Mastra Integration
Team config ~/.claude/teams/{name}/config.json (Claude CLI creates) Must be managed by our app directly
Task storage ~/.claude/tasks/{name}/ (agent-teams-controller) Unchanged
Inbox messaging ~/.claude/teams/{name}/inboxes/{member}.json Replace with Mastra memory or direct tool calls
Cross-team comms Inbox files with relay Mastra agents can call each other directly

Claude-specificity score: 6/10 — File-based coordination is Claude CLI convention, but our controller is independent.


Concrete Integration Approaches

Approach A: Mastra as Agent Runtime (Replace Claude CLI)

Confidence: 5/10 | Reliability: 4/10

Replace spawnCli() with in-process Mastra agents. The lead becomes a supervisor Agent, teammates become sub-agents.

// src/main/services/team/MastraTeamRuntime.ts (new file)
import { Agent } from '@mastra/core/agent';
import { MCPClient } from '@mastra/mcp';
import { createTool } from '@mastra/core/tools';

// Convert our MCP tools to native Mastra tools
const taskCreateTool = createTool({
  id: 'task_create',
  description: 'Create a team task',
  inputSchema: z.object({
    teamName: z.string(),
    subject: z.string(),
    description: z.string().optional(),
    owner: z.string().optional(),
  }),
  execute: async (input) => {
    const controller = getController(input.teamName);
    return controller.tasks.createTask(input);
  },
});

// File editing tool (replaces Claude Code built-in)
const editFileTool = createTool({
  id: 'edit_file',
  description: 'Edit a file on disk',
  inputSchema: z.object({
    path: z.string(),
    oldText: z.string(),
    newText: z.string(),
  }),
  execute: async (input) => {
    // Must implement file editing logic ourselves
    const content = await fs.promises.readFile(input.path, 'utf8');
    const updated = content.replace(input.oldText, input.newText);
    await fs.promises.writeFile(input.path, updated);
    return { success: true };
  },
});

// Bash tool (replaces Claude Code built-in)
const bashTool = createTool({
  id: 'bash',
  description: 'Execute a bash command',
  inputSchema: z.object({ command: z.string() }),
  execute: async (input) => {
    const { stdout, stderr } = await execAsync(input.command);
    return { stdout, stderr };
  },
});

// Create teammate agents
function createTeammateAgent(member: TeamMember, teamTools: Record<string, Tool>) {
  return new Agent({
    id: `teammate-${member.name}`,
    name: member.name,
    description: member.role || 'Team member',
    instructions: buildMemberInstructions(member),  // adapted from buildMemberSpawnPrompt
    model: 'anthropic/claude-sonnet-4-20250514',
    tools: {
      ...teamTools,
      editFileTool,
      bashTool,
      readFileTool,
      // ... other dev tools
    },
  });
}

// Create supervisor (lead) agent
function createLeadAgent(
  request: TeamCreateRequest,
  teammates: Record<string, Agent>
) {
  return new Agent({
    id: `lead-${request.teamName}`,
    name: 'team-lead',
    instructions: buildLeadInstructions(request),  // adapted from buildPersistentLeadContext
    model: request.model || 'anthropic/claude-sonnet-4-20250514',
    agents: teammates,  // Mastra auto-converts to tools
    tools: {
      ...teamTools,  // task_create, kanban_get, etc.
      editFileTool,
      bashTool,
      readFileTool,
    },
    memory: new Memory(),
  });
}

What breaks:

  • Claude Code's file editing (diff view, permission system) — must reimplement
  • Claude Code's terminal integration
  • Claude Code's git support
  • Claude Code's extended thinking
  • Claude Code's session persistence/resume
  • The entire JSONL parsing pipeline
  • Tool approval flow (our control_request handling)
  • Post-compact context reinjection

Approach B: Mastra as Middleware / Orchestration Layer (Keep Claude CLI)

Confidence: 7/10 | Reliability: 6/10

Use Mastra as an orchestration layer that manages routing and coordination, while still spawning Claude CLI processes for actual work.

// src/main/services/team/MastraOrchestrator.ts (new file)
import { Agent } from '@mastra/core/agent';
import { createTool } from '@mastra/core/tools';

// Tool that spawns a Claude CLI process for actual work
const claudeCliTool = createTool({
  id: 'claude_cli_execute',
  description: 'Execute a task using Claude Code CLI',
  inputSchema: z.object({
    prompt: z.string(),
    cwd: z.string(),
    model: z.string().optional(),
  }),
  execute: async (input) => {
    // Spawn Claude CLI with -p (one-shot)
    const result = await execCli(claudePath, [
      '-p', input.prompt,
      '--output-format', 'text',
      ...(input.model ? ['--model', input.model] : []),
    ], { cwd: input.cwd });
    return { output: result.stdout };
  },
});

// Mastra agent for high-level orchestration
const orchestrator = new Agent({
  id: 'orchestrator',
  name: 'Task Orchestrator',
  instructions: `You coordinate a development team.
    Use claude_cli_execute for actual coding tasks.
    Use task tools for board management.`,
  model: 'anthropic/claude-sonnet-4-20250514',
  tools: {
    claudeCliTool,
    ...teamBoardTools,
  },
});

// Orchestrator decides what to do, Claude CLI does the coding
const stream = await orchestrator.stream(userMessage);

What this preserves:

  • Claude CLI's file editing, terminal, git, etc.
  • Our existing JSONL pipeline (for CLI-executed tasks)
  • MCP server tools (used by CLI processes)

What this adds:

  • Model-agnostic orchestration layer
  • Ability to use OpenAI/Gemini/etc. for routing decisions
  • Mastra's workflow engine for deterministic task flows

What breaks / gets complex:

  • Two runtime models (Mastra in-process + Claude CLI processes)
  • Doubled complexity for message flow
  • Unclear who "owns" the conversation state

Approach C: Mastra MCP Bridge (Minimal Integration)

Confidence: 8/10 | Reliability: 7/10

Use @mastra/mcp MCPServer to expose our existing tools to any Mastra-compatible client, and @mastra/mcp MCPClient to consume external MCP tools.

// mcp-server/src/mastra-bridge.ts (new file)
import { MCPServer } from '@mastra/mcp';
import { Agent } from '@mastra/core/agent';
import { registerTools } from './tools';

// Expose our existing tools as an MCP server that Mastra agents can consume
const mcpServer = new MCPServer({
  name: 'agent-teams-mcp',
  version: '1.0.0',
  tools: {
    // Convert FastMCP tools to Mastra tools, or expose via MCP protocol
    ...convertFastMcpToMastraTools(registerTools),
  },
});

// Any Mastra agent can now use our board tools
const externalAgent = new Agent({
  id: 'external-worker',
  model: 'openai/gpt-4o',
  instructions: 'You manage tasks on the team board.',
  tools: await new MCPClient({
    servers: {
      'agent-teams': {
        command: 'node',
        args: ['path/to/mcp-server/dist/index.js'],
      },
    },
  }).listTools(),
});

What this preserves:

  • Everything — this is additive, not replacement
  • Claude CLI remains the primary runtime

What this adds:

  • Mastra agents can interact with our board
  • Path to multi-provider support
  • Future extensibility

Architecture Diagram

┌──────────────────────────────────────────────────────────────────┐
│                     Electron App (Renderer)                       │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────────┐    │
│  │  Kanban   │  │ Timeline │  │  Inbox   │  │ Code Editor   │    │
│  │  Board    │  │  View    │  │  Chat    │  │ (Diff View)   │    │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └───────┬───────┘    │
│       └──────────────┴─────────────┴────────────────┘            │
│                              │ IPC                                │
└──────────────────────────────┼───────────────────────────────────┘
                               │
┌──────────────────────────────┼───────────────────────────────────┐
│                     Electron App (Main)                           │
│                              │                                    │
│  ┌───────────────────────────┴──────────────────────────────┐    │
│  │              IPC Handler Layer (teams.ts)                  │    │
│  └───────────────────────────┬──────────────────────────────┘    │
│                              │                                    │
│  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐   │
│          MASTRA MIDDLEWARE LAYER (Approach B / Future)            │
│  │  ┌─────────────────┐    │    ┌─────────────────────┐    │   │
│     │  Mastra Agent    │    │    │  Mastra Workflow    │         │
│  │  │  (Orchestrator)  │    │    │  (Task Routing)     │    │   │
│     │  model-agnostic  │    │    │  DAG execution      │         │
│  │  └────────┬─────────┘    │    └──────────┬──────────┘    │   │
│              │              │               │                    │
│  └ ─ ─ ─ ─ ─┼─ ─ ─ ─ ─ ─ ─┼─ ─ ─ ─ ─ ─ ─ ┼─ ─ ─ ─ ─ ─ ─ ┘   │
│              │              │               │                    │
│  ┌───────────┴──────────────┴───────────────┴──────────────┐    │
│  │          TeamProvisioningService (existing)              │    │
│  │  ┌─────────────┐  ┌──────────────┐  ┌───────────────┐  │    │
│  │  │ spawnCli()  │  │ stream-json  │  │ FS monitor    │  │    │
│  │  │ (Claude CLI)│  │ parser       │  │ (tasks/inbox) │  │    │
│  │  └──────┬──────┘  └──────┬───────┘  └───────┬───────┘  │    │
│  └─────────┼────────────────┼───────────────────┼──────────┘    │
│            │                │                   │                │
│  ┌─────────┴────────────────┴───────────────────┴──────────┐    │
│  │              agent-teams-controller (pure JS)            │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌────────┐  │    │
│  │  │ Tasks    │  │ Kanban   │  │ Inbox    │  │ Config │  │    │
│  │  │ CRUD     │  │ State    │  │ Messages │  │ Reader │  │    │
│  │  └──────────┘  └──────────┘  └──────────┘  └────────┘  │    │
│  └──────────────────────────────────────────────────────────┘    │
│                              │                                    │
│  ┌──────────────────────────┼───────────────────────────────┐    │
│  │           MCP Server (agent-teams-mcp)                    │    │
│  │  ┌────────┐  ┌────────┐  ┌────────┐  ┌────────────────┐ │    │
│  │  │ Tasks  │  │ Kanban │  │ Review │  │ Messages       │ │    │
│  │  │ Tools  │  │ Tools  │  │ Tools  │  │ & Cross-team   │ │    │
│  │  └────────┘  └────────┘  └────────┘  └────────────────┘ │    │
│  └──────────────────────────────────────────────────────────┘    │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘
                               │
                    ┌──────────┴──────────┐
                    │  Claude CLI Process  │ ← or Mastra agent.stream()
                    │  (stream-json)       │
                    │  ┌────────────────┐  │
                    │  │ File Edit      │  │
                    │  │ Terminal/Bash  │  │
                    │  │ Git            │  │
                    │  │ Agent (spawn)  │  │
                    │  │ SendMessage    │  │
                    │  │ MCP tools      │  │
                    │  └────────────────┘  │
                    └─────────────────────┘

What Stays the Same

These modules are not Claude-specific and would survive any integration:

Module Path Why
agent-teams-controller agent-teams-controller/ Pure JS business logic for tasks, kanban, review, inbox. Zero Claude dependency.
MCP Server tools mcp-server/src/tools/*.ts Standard MCP protocol. Works with any MCP-compatible agent.
UI components src/renderer/ React/Zustand/Tailwind. Communicates via IPC, agnostic to backend.
IPC layer interface src/preload/constants/ipcChannels.ts Channel names are just strings.
Shared types src/shared/types/team.ts TeamTask, InboxMessage, etc. — domain types.
Team data services TeamDataService, TeamConfigReader, TeamTaskReader File-based, read team state from disk.
TeamMcpConfigBuilder src/main/services/team/TeamMcpConfigBuilder.ts Builds MCP config files. Could serve Mastra MCPClient too.
Notification system NotificationManager UI notifications, not Claude-specific.

What Must Change

Tier 1: Core Runtime (Required for any Mastra integration)

File/Module Lines Change Required
TeamProvisioningService.ts ~8000 Major refactor: abstract AgentRuntime interface. spawnCli() becomes one implementation, Mastra becomes another.
childProcess.ts 220 Keep as-is for Claude CLI path. New MastraRuntime.ts for in-process agents.
ClaudeBinaryResolver.ts ~200 Keep for Claude CLI path. Not needed for Mastra path.

Tier 2: Message Parsing (Required for Approach A)

File/Module Lines Change Required
src/main/types/jsonl.ts 200+ New parallel types for Mastra streaming events.
src/main/types/messages.ts 377 Extend ParsedMessage or create MastraMessage adapter.
ChunkBuilder.ts ~600 Abstract chunk building from JSONL parsing. Mastra adapter produces same chunk types.
SubagentResolver.ts ~400 Mastra supervisor natively tracks sub-agents. Simpler resolver.
SemanticStepExtractor.ts ~300 Mastra tool calls have different structure. Adapter needed.

Tier 3: Prompt System (Required for all approaches)

File/Module Lines Change Required
buildProvisioningPrompt() ~100 Remove Claude-specific steps (TeamCreate, Agent tool). Replace with Mastra tool references.
buildMemberSpawnPrompt() ~80 Convert to Mastra Agent instructions. Remove Agent tool spawn references.
buildPersistentLeadContext() ~100 Remove Agent tool references. Keep MCP tool instructions (they still apply).
buildTeamCtlOpsInstructions() ~100 Keep — these reference MCP tools which are provider-agnostic.
actionModeInstructions.ts 50 Keep — action modes are prompt-level, not provider-specific.

Tier 4: Tool Approval (Required for Approach A)

File/Module Change Required
Tool approval flow Mastra has its own requireApproval: true on tools + approveToolCall()/declineToolCall(). Must adapt our UI's approval dialog to use Mastra's API instead of control_request stream-json messages.

Effort Estimate

Approach A: Full Mastra Runtime (Replace Claude CLI)

Phase Effort Risk
Abstract AgentRuntime interface 2 weeks Medium — large refactor of 8K line service
Implement Mastra runtime adapter 2 weeks High — need to reimplement file/terminal/git tools
Adapt message parsing pipeline 1 week Medium — new adapter for Mastra events
Adapt prompt system 1 week Low — mostly string template changes
Tool approval integration 1 week Medium — different approval API
Testing + stabilization 2 weeks High — regression risk
Total 9-10 weeks High

Approach B: Mastra Middleware (Keep Claude CLI)

Phase Effort Risk
Mastra orchestrator service 1 week Medium
Claude CLI adapter tool 1 week Low
Dual runtime state management 2 weeks High — complexity
Message flow unification 1 week Medium
Testing 1 week Medium
Total 6-7 weeks Medium-High

Approach C: MCP Bridge (Minimal)

Phase Effort Risk
@mastra/mcp MCPServer wrapper 3 days Low
Example Mastra agent consuming our tools 2 days Low
Documentation + examples 2 days Low
Total 1-2 weeks Low

Risks and Blockers

Critical Blockers

  1. Claude Code's built-in tools are not replicable via Mastra. Claude Code has deep integration with the filesystem, terminal, git, and its own Agent tool for spawning teammates. Mastra provides no equivalent — you would need to build editFile, bash, readFile, glob, grep, git tools from scratch. These tools must handle permissions, sandboxing, diff generation, and conflict resolution. This is not just wrapping fs.writeFile() — it's thousands of lines of battle-tested code.

  2. stream-json protocol is Claude Code proprietary. Our entire real-time UI (live typing, tool progress, subagent tracking) depends on the stream-json wire format. Mastra's streaming format is different (AI SDK compatible). The translation layer is non-trivial.

  3. Team/teammate lifecycle is Claude Code's native feature. TeamCreate, Agent with team_name, SendMessage — these are built into Claude Code CLI. Mastra's supervisor pattern is conceptually similar but mechanically different (in-process sub-agents vs. separate CLI processes).

  4. Context window management. Claude Code manages its own context window, compaction, and session persistence. Mastra delegates this to the model provider's API. Our post-compact reinjection system would need complete redesign.

High Risks

  1. Performance: in-process vs. out-of-process. Claude CLI runs as a separate process with its own Node.js runtime. Mastra agents run in-process within Electron's main process. Long-running agent tasks could block the Electron event loop. Would need worker threads or separate Node processes.

  2. Authentication divergence. Claude Code CLI handles its own auth (OAuth, API key). Mastra uses provider API keys directly. Different auth models for different users.

  3. Losing Claude Code ecosystem. Claude Code has CLAUDE.md, settings.json, .mcp.json, hooks, and growing features. Switching to Mastra means losing access to this ecosystem for Claude users.

Medium Risks

  1. Mastra version churn. Mastra is pre-1.0 (currently ~1.10.x) and evolving rapidly. The AgentNetwork API was deprecated in favor of supervisor agents in just months. API stability is not guaranteed.

  2. Dual dependency burden. Adding @mastra/core (~150KB+ with deps) to an Electron app increases bundle size and potential version conflicts.


Recommendations

Short Term (Now): Approach C — MCP Bridge

Confidence: 9/10 | Reliability: 8/10

  • Wrap our MCP server with @mastra/mcp MCPServer
  • Publish as a standalone MCP endpoint that any Mastra agent can consume
  • Zero risk to existing functionality
  • Opens the door for external Mastra agents to manage our board
  • 1-2 weeks effort

Medium Term (Q2-Q3 2026): Abstract AgentRuntime Interface

Confidence: 7/10 | Reliability: 6/10

  • Extract AgentRuntime interface from TeamProvisioningService
  • ClaudeCliRuntime implements it (current behavior)
  • Prepare the seam for MastraRuntime without building it yet
  • De-risk the eventual full integration
  • 2-3 weeks effort

Long Term (Q4 2026+): Approach B — Mastra Middleware

Confidence: 6/10 | Reliability: 5/10

  • Add Mastra as orchestration layer for routing and multi-provider support
  • Keep Claude CLI as the "worker" runtime for actual coding
  • Use Mastra for decision-making, task routing, and provider switching
  • Full multi-model support without losing Claude Code's tooling
  • 6-7 weeks effort

Confidence: 3/10 | Reliability: 2/10

Replacing Claude CLI entirely with Mastra-managed agents would lose our core differentiator (deep Claude Code integration: file editing, terminal, git, session persistence, extended thinking, etc.). The effort (~10 weeks) and risk are not justified unless Claude Code CLI is deprecated, which shows no signs of happening.


Sources