Skip to main content
Glama

run_agent

Delegate complex multi-step tasks to specialized autonomous agents for independent execution with dedicated context, maintaining conversation continuity across sessions.

Instructions

Delegate complex, multi-step, or specialized tasks to an autonomous agent for independent execution with dedicated context (e.g., refactoring across multiple files, fixing all test failures, systematic codebase analysis, batch operations). Returns session_id in response metadata - reuse it in subsequent calls to maintain conversation context continuity across multiple agent executions.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
agentYesAgent name exactly as listed in list_agents resource.
promptYesUser's direct request content. Agent context is separately provided via agent parameter.
cwdYesWorking directory path for agent execution context. Must be an absolute path to a valid directory.
extra_argsNoAdditional configuration parameters for agent execution (optional)
session_idNoSession ID for continuing previous conversation context (optional). If omitted, a new session will be auto-generated and returned in response metadata. Reuse the returned session_id in subsequent calls to maintain context continuity.

Implementation Reference

  • The `execute` method is the main handler that performs parameter validation, agent lookup, execution via AgentExecutor, session management, and formats the MCP-compliant response. It handles errors gracefully and provides structured logging.
    async execute(params: unknown): Promise<McpToolResponse> { const startTime = Date.now() const requestId = this.generateRequestId() this.logger.info('Run agent tool execution started', { requestId, timestamp: new Date().toISOString(), }) // Best-effort cleanup: old session files (ADR-0002) // Non-blocking execution - does not affect main processing flow if (this.sessionManager) { Promise.resolve() .then(() => this.sessionManager!.cleanupOldSessions()) .catch((error) => { this.logger.warn('Session cleanup failed (best-effort)', { requestId, error: error instanceof Error ? error.message : String(error), }) }) } try { // Validate parameters with enhanced validation const validatedParams = this.validateParams(params) // Auto-generate session_id if not provided and SessionManager is available const sessionId = validatedParams.session_id || (this.sessionManager ? randomUUID() : undefined) this.logger.debug('Parameters validated successfully', { requestId, agent: validatedParams.agent, promptLength: validatedParams.prompt.length, cwd: validatedParams.cwd, extraArgsCount: validatedParams.extra_args?.length || 0, sessionId: sessionId, sessionIdGenerated: !validatedParams.session_id && !!sessionId, }) // Check if agent exists and load agent definition once let agentDefinition: AgentDefinition | undefined if (this.agentManager) { agentDefinition = await this.agentManager.getAgent(validatedParams.agent) if (!agentDefinition) { this.logger.warn('Agent not found', { requestId, requestedAgent: validatedParams.agent, }) return this.createErrorResponse( `Agent '${validatedParams.agent}' not found`, await this.getAvailableAgentsList() ) } this.logger.debug('Agent found and validated', { requestId, agentName: agentDefinition.name, agentDescription: agentDefinition.description, }) } // Execute agent if executor is available if (this.agentExecutor) { // Report progress: Starting agent execution // Use agent definition content if available (already loaded above) const agentContext = agentDefinition?.content ?? validatedParams.agent // Load session history if session_id is provided and SessionManager is available let promptWithHistory = validatedParams.prompt if (sessionId && this.sessionManager) { try { // CRITICAL: Pass agent_type to enforce sub-agent isolation const sessionData = await this.sessionManager.loadSession( sessionId, validatedParams.agent ) if (sessionData && sessionData.history.length > 0) { // Convert session history to Markdown format for token efficiency and LLM comprehension const historyMarkdown = formatSessionHistory(sessionData) promptWithHistory = `Previous conversation history:\n\n${historyMarkdown}\n\n---\n\nCurrent request:\n${validatedParams.prompt}` this.logger.info('Session history loaded and merged', { requestId, sessionId: sessionId, historyEntries: sessionData.history.length, }) } else { this.logger.debug('No session history found', { requestId, sessionId: sessionId, }) } } catch (error) { // Log error but continue - session loading failure should not break main flow this.logger.warn('Failed to load session history', { requestId, sessionId: sessionId, error: error instanceof Error ? error.message : String(error), }) } } const executionParams: ExecutionParams = { agent: agentContext, prompt: promptWithHistory, ...(validatedParams.cwd !== undefined && { cwd: validatedParams.cwd }), ...(validatedParams.extra_args !== undefined && { extra_args: validatedParams.extra_args, }), } // Report progress: Executing agent // Execute agent (this has its own timeout: MCP -> AI) const result = await this.agentExecutor.executeAgent(executionParams) // Report progress: Execution completed // Update execution statistics this.updateExecutionStats(validatedParams.agent, result.executionTime) this.logger.info('Agent execution completed successfully', { requestId, agent: validatedParams.agent, exitCode: result.exitCode, executionTime: result.executionTime, totalTime: Date.now() - startTime, }) // Save session if session_id is available and SessionManager is available if (sessionId && this.sessionManager) { try { // Build request object with only defined properties const sessionRequest: { agent: string prompt: string cwd?: string extra_args?: string[] } = { agent: validatedParams.agent, prompt: validatedParams.prompt, } if (validatedParams.cwd !== undefined) { sessionRequest.cwd = validatedParams.cwd } if (validatedParams.extra_args !== undefined) { sessionRequest.extra_args = validatedParams.extra_args } await this.sessionManager.saveSession(sessionId, sessionRequest, { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode, executionTime: result.executionTime, }) this.logger.info('Session saved successfully', { requestId, sessionId: sessionId, }) } catch (error) { // Log error but continue - session save failure should not break main flow this.logger.warn('Failed to save session', { requestId, sessionId: sessionId, error: error instanceof Error ? error.message : String(error), }) } } // Mark MCP request as completed return this.formatExecutionResponse(result, validatedParams.agent, requestId, sessionId) } // Fallback response if executor is not available this.logger.warn('Agent executor not available', { requestId }) return { content: [ { type: 'text', text: `Agent execution request received for '${validatedParams.agent}' with prompt: "${validatedParams.prompt}"\n\nNote: Agent executor not initialized.`, }, ], } } catch (error) { const totalTime = Date.now() - startTime this.logger.error('Agent execution failed', error instanceof Error ? error : undefined, { requestId, totalTime, errorType: error instanceof Error ? error.constructor.name : 'Unknown', }) return this.createErrorResponse( `Agent execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`, null ) } }
  • Defines the input schema for the run_agent tool, specifying required parameters (agent, prompt, cwd) and optional ones (extra_args, session_id) with descriptions.
    public readonly inputSchema: RunAgentInputSchema = { type: 'object', properties: { agent: { type: 'string', description: 'Agent name exactly as listed in list_agents resource.', }, prompt: { type: 'string', description: "User's direct request content. Agent context is separately provided via agent parameter.", }, cwd: { type: 'string', description: 'Working directory path for agent execution context. Must be an absolute path to a valid directory.', }, extra_args: { type: 'array', items: { type: 'string' }, description: 'Additional configuration parameters for agent execution (optional)', }, session_id: { type: 'string', description: 'Session ID for continuing previous conversation context (optional). If omitted, a new session will be auto-generated and returned in response metadata. Reuse the returned session_id in subsequent calls to maintain context continuity.', }, }, required: ['agent', 'prompt', 'cwd'], }
  • Registers the run_agent tool in the MCP server's list_tools handler by including its name, description, and inputSchema in the returned tools list.
    tools: [ { name: this.runAgentTool.name, description: this.runAgentTool.description, inputSchema: this.runAgentTool.inputSchema, },
  • Dispatches calls to the run_agent tool in the MCP server's call_tool handler by checking the tool name and invoking the RunAgentTool's execute method.
    if (params.name === 'run_agent') { const result = await this.runAgentTool.execute(params.arguments) this.log('info', 'Tool execution completed', { tool: params.name, responseTime: Date.now() - startTime, success: true, }) return result as CallToolResult }
  • Instantiates the RunAgentTool instance in the McpServer constructor, injecting required dependencies for agent execution and management.
    this.runAgentTool = new RunAgentTool(this.agentExecutor, this.agentManager, this.sessionManager)

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shinpr/sub-agents-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server