Skip to main content
Glama
ToKiDoO

Advanced Obsidian MCP Server

by ToKiDoO

obsidian_open_files

Open multiple files in Obsidian vault simultaneously to view content in separate tabs for efficient reference and editing.

Instructions

Open one or more files in the vault in a new leaf.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filepathsYesList of file paths to open

Implementation Reference

  • The OpenFilesToolHandler class provides the core implementation of the 'obsidian_open_files' tool. It defines the tool schema and the run_tool method that iterates over the provided filepaths and calls the Obsidian API to open each file in a new leaf, handling errors and returning appropriate responses.
    class OpenFilesToolHandler(ToolHandler):
        def __init__(self):
            super().__init__(TOOL_OPEN_FILES)
    
        def get_tool_description(self):
            return Tool(
                name=self.name,
                description="Open one or more files in the vault in a new leaf.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "filepaths": {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "description": "Path to a file (relative to your vault root)",
                                "format": "path"
                            },
                            "description": "List of file paths to open"
                        },
                    },
                    "required": ["filepaths"]
                }
            )
        
        def run_tool(self, args: dict) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
            filepaths = args.get("filepaths")
            if not filepaths:
                raise ValueError("One or more filepaths are required")
            
            successful_opens = []
            failed_opens = []
            
            for file in filepaths:
                try:
                    api.open_file(file)
                    successful_opens.append(file)
                except Exception as e:
                    failed_opens.append((file, str(e)))
            
            if failed_opens:
                error_messages = [f"Failed to open '{file}': {error}" for file, error in failed_opens]
                if successful_opens:
                    return [
                        TextContent(
                            type="text",
                            text=f"Opened {len(successful_opens)} file(s) successfully. Errors: {'; '.join(error_messages)}"
                        )
                    ]
                else:
                    raise ValueError(f"Failed to open any files: {'; '.join(error_messages)}")
            
            return [
                TextContent(
                    type="text",
                    text="File(s) opened successfully!"
                )
            ]
  • TOOL_MAPPING dictionary registers 'obsidian_open_files' (via tools.TOOL_OPEN_FILES) to the OpenFilesToolHandler class. This mapping is used in register_tools() to instantiate and add the handler to the MCP server.
    TOOL_MAPPING = {
        tools.TOOL_LIST_FILES_IN_DIR: tools.ListFilesInDirToolHandler,
        tools.TOOL_SIMPLE_SEARCH: tools.SearchToolHandler,
        tools.TOOL_PATCH_CONTENT: tools.PatchContentToolHandler,
        tools.TOOL_PUT_CONTENT: tools.PutContentToolHandler,
        tools.TOOL_APPEND_CONTENT: tools.AppendContentToolHandler,
        tools.TOOL_DELETE_FILE: tools.DeleteFileToolHandler,
        tools.TOOL_COMPLEX_SEARCH: tools.ComplexSearchToolHandler,
        tools.TOOL_BATCH_GET_FILES: tools.BatchGetFilesToolHandler,
        tools.TOOL_PERIODIC_NOTES: tools.PeriodicNotesToolHandler,
        tools.TOOL_RECENT_PERIODIC_NOTES: tools.RecentPeriodicNotesToolHandler,
        tools.TOOL_RECENT_CHANGES: tools.RecentChangesToolHandler,
        tools.TOOL_UNDERSTAND_VAULT: tools.UnderstandVaultToolHandler,
        tools.TOOL_GET_ACTIVE_NOTE: tools.GetActiveNoteToolHandler,
        tools.TOOL_OPEN_FILES: tools.OpenFilesToolHandler,
        tools.TOOL_LIST_COMMANDS: tools.ListCommandsToolHandler,
        tools.TOOL_EXECUTE_COMMANDS: tools.ExecuteCommandsToolHandler,
    }
  • The Obsidian API client's open_file method makes a POST request to '/open/{filepath}' to open the specified file in Obsidian, which is called by the tool handler.
    def open_file(self, filepath: str) -> Any:
        """Open a file in the vault.
        
        Args:
            filepath: Path to the file to open (relative to vault root)
            
        Returns:
            None on success. Opens the file in the default editor in a new leaf.
        """
        url = f"{self.get_base_url()}/open/{filepath}"
        
        def call_fn():
            response = requests.post(url, headers=self._get_headers(), verify=self.verify_ssl, timeout=self.timeout)
            response.raise_for_status()
            return None
            
        return self._safe_call(call_fn)
  • register_tools function instantiates handlers from TOOL_MAPPING (including OpenFilesToolHandler for obsidian_open_files) and registers them with the MCP server via add_tool_handler.
    def register_tools():
        """Register the selected tools with the server."""
        tools_to_include = parse_include_tools()
        
        registered_count = 0
        for tool_name in tools_to_include:
            if tool_name in TOOL_MAPPING:
                handler_class = TOOL_MAPPING[tool_name]
                handler_instance = handler_class()
                add_tool_handler(handler_instance)
                registered_count += 1
                logger.debug(f"Registered tool: {tool_name}")
        
        logger.info(f"Successfully registered {registered_count} tools")
  • Constant defining the tool name 'obsidian_open_files' used throughout for registration and handler initialization.
    TOOL_OPEN_FILES = "obsidian_open_files"

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/ToKiDoO/mcp-obsidian-advanced'

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