import { Box, Text } from 'ink'
import * as React from 'react'
import { z } from 'zod'
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
import { type Tool } from '../../Tool'
import { getTheme } from '../../utils/theme'
import { DESCRIPTION, PROMPT } from './prompt'
import { OutputLine } from '../BashTool/OutputLine'
// Allow any input object since MCP tools define their own schemas
const inputSchema = z.object({}).passthrough()
export const MCPTool = {
async isEnabled() {
return true
},
isReadOnly() {
return false
},
isConcurrencySafe() {
return false // MCPTool can modify state through MCP calls, not safe for concurrent execution
},
// Overridden in mcpClient.ts
name: 'mcp',
// Overridden in mcpClient.ts
async description() {
return DESCRIPTION
},
// Overridden in mcpClient.ts
async prompt() {
return PROMPT
},
inputSchema,
// Overridden in mcpClient.ts
async *call() {
yield {
type: 'result',
data: '',
resultForAssistant: '',
}
},
needsPermissions() {
return true
},
renderToolUseMessage(input) {
return Object.entries(input)
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
.join(', ')
},
// Overridden in mcpClient.ts
userFacingName: () => 'mcp',
renderToolUseRejectedMessage() {
return
},
renderToolResultMessage(output) {
const verbose = false // Set default value for verbose
if (Array.isArray(output)) {
return (
{output.map((item, i) => {
if (item.type === 'image') {
return (
⎿
[Image]
)
}
const lines = item.text.split('\n').length
return (
)
})}
)
}
if (!output) {
return (
⎿
(No content)
)
}
const lines = output.split('\n').length
return
},
renderResultForAssistant(content) {
return content
},
} satisfies Tool