Skip to main content
Glama
quinny1187

Obsidian MCP Server

by quinny1187

search_vault

Search for text across all notes in an Obsidian vault using queries with case-sensitive and regex options.

Instructions

Search for text across all notes in vault

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
vault_pathYesPath to the Obsidian vault
queryYesSearch query
optionsNo

Implementation Reference

  • Main handler function for the 'search_vault' tool. Searches all markdown files in the vault for the given query, supports regex and case sensitivity options, returns matches with line numbers and context.
    export async function handleSearchVault(
      vaultManager: VaultManager,
      vaultPath: string,
      query: string,
      options?: {
        case_sensitive?: boolean;
        regex?: boolean;
      }
    ) {
      await vaultManager.validateVault(vaultPath);
      
      const files = await vaultManager.listMarkdownFiles(vaultPath);
      const results: SearchResult[] = [];
      
      // Prepare search pattern
      let searchPattern: RegExp;
      if (options?.regex) {
        searchPattern = new RegExp(query, options.case_sensitive ? 'g' : 'gi');
      } else {
        // Escape special regex characters if not in regex mode
        const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        searchPattern = new RegExp(escaped, options?.case_sensitive ? 'g' : 'gi');
      }
      
      for (const file of files) {
        try {
          const filePath = path.join(vaultPath, file);
          const content = await fs.readFile(filePath, 'utf-8');
          const lines = content.split('\n');
          
          const matches: SearchResult['matches'] = [];
          
          lines.forEach((line, index) => {
            if (searchPattern.test(line)) {
              // Get context (previous and next line)
              const prevLine = index > 0 ? lines[index - 1] : '';
              const nextLine = index < lines.length - 1 ? lines[index + 1] : '';
              
              matches.push({
                line: index + 1,
                content: line.trim(),
                context: [prevLine.trim(), line.trim(), nextLine.trim()]
                  .filter(l => l)
                  .join(' ... '),
              });
            }
            // Reset lastIndex for global regex
            searchPattern.lastIndex = 0;
          });
          
          if (matches.length > 0) {
            results.push({
              path: file,
              matches,
              matchCount: matches.length,
            });
          }
        } catch (error) {
          logger.warn(`Could not search file ${file}:`, error);
        }
      }
      
      return {
        query,
        options,
        resultCount: results.length,
        totalMatches: results.reduce((sum, r) => sum + r.matchCount, 0),
        results,
      };
    }
  • Input schema for the search_vault tool, defining parameters: vault_path (required), query (required), and optional options for case_sensitive and regex.
    inputSchema: {
      type: 'object',
      properties: {
        vault_path: {
          type: 'string',
          description: 'Path to the Obsidian vault',
        },
        query: {
          type: 'string',
          description: 'Search query',
        },
        options: {
          type: 'object',
          properties: {
            case_sensitive: {
              type: 'boolean',
              default: false,
            },
            regex: {
              type: 'boolean',
              default: false,
            },
          },
        },
      },
      required: ['vault_path', 'query'],
    },
  • src/index.ts:122-152 (registration)
    Registration of the search_vault tool in the TOOLS array used for listing available tools.
    {
      name: 'search_vault',
      description: 'Search for text across all notes in vault',
      inputSchema: {
        type: 'object',
        properties: {
          vault_path: {
            type: 'string',
            description: 'Path to the Obsidian vault',
          },
          query: {
            type: 'string',
            description: 'Search query',
          },
          options: {
            type: 'object',
            properties: {
              case_sensitive: {
                type: 'boolean',
                default: false,
              },
              regex: {
                type: 'boolean',
                default: false,
              },
            },
          },
        },
        required: ['vault_path', 'query'],
      },
    },
  • src/index.ts:210-220 (registration)
    Dispatch logic in the tool call handler switch statement that invokes handleSearchVault for search_vault calls.
    case 'search_vault':
      if (!args || typeof args !== 'object' || !('vault_path' in args) || !('query' in args)) {
        throw new McpError(ErrorCode.InvalidParams, 'Missing required parameters');
      }
      result = await handleSearchVault(
        vaultManager,
        args.vault_path as string,
        args.query as string,
        args.options as any
      );
      break;
  • Type definition for search results used internally by the handler.
    interface SearchResult {
      path: string;
      matches: Array<{
        line: number;
        content: string;
        context: string;
      }>;
      matchCount: number;
    }

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

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