file-io
Search and access file content to retrieve information from stored documents and data files.
Instructions
Search and access file content
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| parameters | Yes |
Implementation Reference
- FileManagerAdapter implements the core logic for the 'file-io' tool, defining its ID, translating MCP requests to OpenAI parameters (operation, path, content), and formatting responses based on file operations (read, write, delete, list).class FileManagerAdapter(ToolAdapter): """Adapter for OpenAI's file management tool""" @property def tool_id(self) -> str: """Get the MCP tool ID""" return "file-io" @property def openai_tool_type(self) -> str: """Get the OpenAI tool type""" return "file_search" @property def description(self) -> str: """Get the tool description""" return "Search and access file content" async def translate_request(self, request: MCPRequest) -> dict: """ Translate MCP request to OpenAI parameters Args: request: The MCP request to translate Returns: Dictionary of OpenAI parameters """ # Extract file operation parameters operation = request.parameters.get("operation", "read") path = request.parameters.get("path", "") content = request.parameters.get("content", "") logger.debug(f"Translating file request for operation: {operation}, path: {path}") # Return OpenAI parameters return {"operation": operation, "path": path, "content": content} async def translate_response(self, response: dict) -> MCPResponse: """ Translate OpenAI response to MCP response Args: response: The OpenAI response to translate Returns: MCP response object """ # Extract result path = response.get("path", "") operation = response.get("operation", "read") content = response.get("content", "") logger.debug(f"Translating file response for operation: {operation}, path: {path}") # Format content based on operation if operation == "read": formatted_content = f"# File: {path}\n\n```\n{content}\n```" elif operation == "write": formatted_content = f"File written to {path}" elif operation == "delete": formatted_content = f"File deleted: {path}" elif operation == "list": formatted_content = f"# Directory: {path}\n\n" for item in content.split("\n"): if item.strip(): formatted_content += f"- {item.strip()}\n" else: formatted_content = f"Operation '{operation}' completed on {path}" # Check for errors error = response.get("error") # Return MCP response return MCPResponse(content=formatted_content, error=error, context={"path": path, "operation": operation})
- openai_tool2mcp/server.py:48-60 (registration)Instantiates FileManagerAdapter and adds it to the tools_map based on tool_id 'file-io', enabling its use in MCP tool registration.def _build_tools_map(self): """Build a map of tool adapters""" tools_map = {} # Register default tool adapters adapters = [WebSearchAdapter(), CodeInterpreterAdapter(), BrowserAdapter(), FileManagerAdapter()] for adapter in adapters: # Only register if the tool is enabled if adapter.openai_tool_type in self.config.tools: tools_map[adapter.tool_id] = adapter return tools_map
- openai_tool2mcp/server.py:62-115 (registration)Registers the 'file-io' tool with FastMCP using @mcp.tool(name=tool_id), creating a dynamic handler that uses the FileManagerAdapter for translation and invokes OpenAI's file_search tool.def _register_mcp_tools(self): """Register tools with the MCP SDK""" for tool_id, adapter in self.tools_map.items(): # Define a tool handler for each adapter # Create a closure to properly capture the values def create_tool_handler(tool_id=tool_id, adapter=adapter): @self.mcp.tool(name=tool_id, description=adapter.description) async def tool_handler(**parameters): """ MCP tool handler for OpenAI tools. """ # Create an MCP request from the parameters mcp_request = MCPRequest(parameters=parameters) # Translate the request parameters using the adapter translated_params = await adapter.translate_request(mcp_request) # Create an OpenAI tool request openai_request = mcp_to_openai.translate_request(mcp_request, tool_id) # Override the parameters with the adapter-specific ones openai_request.parameters = translated_params try: # Call OpenAI API to execute the tool openai_response = await self.openai_client.invoke_tool(openai_request) # Translate the OpenAI response to MCP format using the adapter if openai_response.tool_outputs: # Use the adapter to translate the tool-specific response mcp_response = await adapter.translate_response(openai_response.tool_outputs[0].output) # Add thread_id to context for state management if mcp_response.context is None: mcp_response.context = {} mcp_response.context["thread_id"] = openai_response.thread_id # Return the response content which will be used by MCP SDK return mcp_response.content else: # Fallback to generic translation mcp_response = openai_to_mcp.translate_response(openai_response) return mcp_response.content except Exception as e: logger.error(f"Error invoking tool {tool_id}: {e!s}") # Using custom exception class to fix TRY003 raise ToolInvocationError() from e return tool_handler # Create and register the tool handler create_tool_handler() def start(self, host="127.0.0.1", port=8000, transport=None):
- openai_tool2mcp/tools/registry.py:53-57 (registration)Registers 'file-io' in ToolRegistry, mapping it to OpenAI's 'file_search' tool and enabling it based on configuration."file-io": { "openai_tool": OpenAIBuiltInTools.FILE_SEARCH.value, "enabled": OpenAIBuiltInTools.FILE_SEARCH.value in self.enabled_tools, "description": "Search and access file content", },
- Maps the MCP tool ID 'file-io' to OpenAI tool type 'file_search' for request translation.def map_tool_id_to_openai_type(tool_id: str) -> str: """ Map MCP tool IDs to OpenAI tool types. Args: tool_id: MCP tool ID Returns: OpenAI tool type """ mapping = { "web-search": "retrieval", "code-execution": "code_interpreter", "browser": "web_browser", "file-io": "file_search", } openai_type = mapping.get(tool_id, tool_id) logger.debug(f"Mapped MCP tool ID {tool_id} to OpenAI tool type {openai_type}") return openai_type