Skip to main content
Glama

Obsidian MCP

by takuya0206
advanced-search.ts7.35 kB
import { z } from "zod"; import { ObsidianAPI } from "../api/obsidian-api.js"; import { formatErrorResponse, formatSuccessResponse, } from "../utils/response-utils.js"; import { ToolDefinition, ToolHandler, ToolResponse } from "../types.js"; // Schema for DataView DQL search tool parameters export const AdvancedSearchDQLSchema = { query: z.string().min(1, "Query is required") .describe(`DataView DQL (Dataview Query Language) query string. DQL is an SQL-like language for searching data in Obsidian notes. Basic Syntax: All DQL queries follow this structure: <QUERY-TYPE> <fields> FROM <source> <DATA-COMMAND> <expression> Query Types (Required): - TABLE: Displays results in a table format with rows and columns. Example: 'TABLE file.name, file.tags, rating' - LIST: Displays results as a bullet list. Example: 'LIST file.mtime' - TASK: Displays results as a task list. Example: 'TASK' - CALENDAR: Displays results in a calendar view. Example: 'CALENDAR file.day' Data Sources (Optional): Use the FROM clause to narrow down the search target: - Tags: 'FROM #tag' or 'FROM #status/open OR #status/wip' - Folders: 'FROM "folder name"' - Links: 'FROM outgoing([[page name]])' - Complex conditions: 'FROM (#tag AND "folder name")' Data Commands (Optional): - WHERE: Filter results based on fields. Example: 'WHERE rating > 4' - SORT: Sort results. Example: 'SORT file.mtime DESC' - GROUP BY: Group results. Example: 'GROUP BY status' - LIMIT: Limit number of results. Example: 'LIMIT 10' - FLATTEN: Expand multi-value fields. Example: 'FLATTEN tags' Usage Examples: 1. Display all incomplete tasks: 'TASK WHERE !completed' 2. Display notes with #project tag sorted by due date: 'TABLE file.link, due, status FROM #project SORT due ASC' 3. Display only high-rated notes in a specific folder: 'LIST FROM "Books" WHERE rating >= 4 SORT rating DESC' 4. Extract related tasks from weekly review notes: 'TASK FROM "Weekly Reviews" WHERE !completed LIMIT 20' 5. Complex query combining multiple conditions: 'TABLE file.link AS "Project", status, due, team FROM #active/project WHERE due AND due <= date(today) + dur(1 week) SORT due ASC GROUP BY status' Notes: - Field names can use those defined in the frontmatter of notes - The date() function can be used for date comparisons (date(today), date(2023-01-01), etc.) - String comparisons are case-sensitive - File-related information can be accessed with file.X (file.name, file.tags, file.mtime, etc.)`), }; // Schema for JsonLogic search tool parameters export const AdvancedSearchJsonLogicSchema = { query: z.record(z.any()) .describe(`JsonLogic query object. Express logical conditions in JSON format for advanced note searching. Basic Concept: JsonLogic is a specification for expressing logical conditions in JSON format. Each condition is expressed in the form {"operator": [arg1, arg2, ...]}. In Obsidian search, you can specify conditions for note metadata fields. Main Operators: 1. Common comparison operators: - "==", "===": Equality (e.g., {"==": [{"var": "rating"}, 5]}) - "!=", "!==": Inequality - ">", ">=", "<", "<=": Magnitude comparison 2. Logical operators: - "and": All conditions are true (e.g., {"and": [condition1, condition2]}) - "or": At least one condition is true - "!": Negation of a condition 3. Obsidian-specific operators: - "glob": Glob pattern matching (e.g., {"glob": [{"var": "file.path"}, "*.md"]}) - "regexp": Regular expression matching (e.g., {"regexp": ["^task.*", {"var": "file.name"}]}) 4. Data access: - "var": Get the value of a field (e.g., {"var": "frontmatter.tags"}) Basic Structure: { "operator": [ {"var": "field name"}, comparison value ] } Or compound conditions: { "and/or": [ {condition1}, {condition2}, ... ] } Usage Examples: 1. Search for notes with a specific tag: { "in": ["project", {"var": "tags"}] } 2. Search for notes where a specific frontmatter field equals a specific value: { "==": [{"var": "frontmatter.status"}, "in progress"] } 3. Search for notes with a specific URL pattern: { "glob": [{"var": "frontmatter.url"}, "https://example.com/*"] } 4. Combination of multiple conditions - notes with a specific tag and due date before today: { "and": [ {"in": ["task", {"var": "tags"}]}, {"<=": [{"var": "frontmatter.due"}, "2023-12-31"]} ] } 5. Complex example - notes in a specific folder and having a specific status or matching a specific URL pattern: { "and": [ {"glob": [{"var": "file.path"}, "projects/*"]}, {"or": [ {"==": [{"var": "frontmatter.status"}, "important"]}, {"glob": [{"var": "frontmatter.url"}, "https://github.com/*"]} ]} ] } Notes: - Field names specified with "var" must match the actual metadata structure of notes - If a field doesn't exist, the condition is not ignored but evaluated as false - Date comparisons are treated as strings, so using ISO format (YYYY-MM-DD) is safest - File properties include file.path, file.name, file.size, file.ctime, file.mtime, etc. - Frontmatter fields can be accessed with frontmatter.fieldname - The "in" operator is useful for array-type fields (such as tags)`), }; /** * Tool definition for searching with DataView DQL */ export const advancedSearchDQLDefinition: ToolDefinition = { name: "searchWithDQL", description: `Search Obsidian notes using DataView DQL (Dataview Query Language). With SQL-like syntax, you can query note metadata and content in a structured way. Results can be obtained in various formats such as TABLE and LIST.`, schema: AdvancedSearchDQLSchema, }; /** * Tool definition for searching with JsonLogic */ export const advancedSearchJsonLogicDefinition: ToolDefinition = { name: "searchWithJsonLogic", description: `Search Obsidian notes using JsonLogic format queries. Using logical conditions expressed in JSON, you can flexibly filter note metadata and content. Suitable for programmatically generated searches, allowing complex conditions to be expressed in a structured way.`, schema: AdvancedSearchJsonLogicSchema, }; /** * Creates a tool handler for searching with DataView DQL * @param api ObsidianAPI instance * @returns Tool handler function */ export function createAdvancedSearchDQLTool(api: ObsidianAPI): ToolHandler { return async (params: { query: string }): Promise<ToolResponse> => { try { const { query } = params; const results = await api.searchWithDQL(query); return formatSuccessResponse({ results }); } catch (error) { return formatErrorResponse( `Error searching with DQL: ${(error as Error).message}` ); } }; } /** * Creates a tool handler for searching with JsonLogic * @param api ObsidianAPI instance * @returns Tool handler function */ export function createAdvancedSearchJsonLogicTool( api: ObsidianAPI ): ToolHandler { return async (params: { query: object }): Promise<ToolResponse> => { try { const { query } = params; const results = await api.searchWithJsonLogic(query); return formatSuccessResponse({ results }); } catch (error) { return formatErrorResponse( `Error searching with JsonLogic: ${(error as Error).message}` ); } }; }

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

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