Skip to main content
Glama
alohays

openai-tool2mcp

by alohays

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
NameRequiredDescriptionDefault
parametersYes

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})
  • 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
  • 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):
  • 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
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. 'Search and access file content' implies read operations, but it doesn't specify whether this tool can modify files, requires specific permissions, has rate limits, or what happens during errors. The description is too brief to provide meaningful behavioral context for safe invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise with just three words, which is efficient. However, it's arguably under-specified rather than optimally concise—it could benefit from slightly more detail without becoming verbose. The structure is simple but lacks front-loading of critical information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and a parameter with 0% schema coverage, the description is incomplete. It doesn't compensate for the lack of structured data by explaining return values, error conditions, or parameter usage. For a tool with one parameter and potential file system interactions, this leaves significant gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 1 parameter with 0% description coverage, and the tool description doesn't mention any parameters at all. The description 'Search and access file content' doesn't explain what the 'parameters' string should contain (e.g., file paths, search queries, access modes). This leaves the parameter completely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Search and access file content' states a general purpose (searching and accessing files) but lacks specificity about what resources it operates on (local files, remote files, specific file types) and doesn't clearly distinguish from sibling tools like 'browser' or 'web-search' which might also access content. It's vague about the exact scope of file operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'browser' or 'web-search'. The description doesn't mention any prerequisites, constraints, or typical use cases. It's left to the agent to infer usage from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

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/alohays/openai-tool2mcp'

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