Skip to main content
Glama

search_pages

Search Logseq pages by content or title, with optional filtering by tags and folder types to find specific information in your knowledge graph.

Instructions

페이지 내용/제목 검색. 태그 및 폴더 필터 지원

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes검색어
tagsNo태그 필터 (선택)
folderNo폴더 필터 (선택)

Implementation Reference

  • MCP tool handler for 'search_pages': parses arguments with schema and delegates to GraphService.searchPages method.
    case 'search_pages': {
      const { query, tags, folder } = SearchPagesSchema.parse(args);
      const results = await graph.searchPages(query, { tags, folder });
      return {
        content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
      };
    }
  • Zod schema defining input validation for search_pages tool: query (required), optional tags and folder filters.
    const SearchPagesSchema = z.object({
      query: z.string().max(MAX_QUERY_LENGTH).describe('검색어'),
      tags: z.array(z.string().max(MAX_TAG_LENGTH)).max(MAX_TAGS_COUNT).optional().describe('태그 필터 (선택)'),
      folder: z.enum(['pages', 'journals']).optional().describe('폴더 필터 (선택)'),
    });
  • src/index.ts:181-193 (registration)
    Registration of 'search_pages' tool in the TOOLS array, including name, description, and input schema for MCP server.
    {
      name: 'search_pages',
      description: '페이지 내용/제목 검색. 태그 및 폴더 필터 지원',
      inputSchema: {
        type: 'object' as const,
        properties: {
          query: { type: 'string', description: '검색어' },
          tags: { type: 'array', items: { type: 'string' }, description: '태그 필터 (선택)' },
          folder: { type: 'string', enum: ['pages', 'journals'], description: '폴더 필터 (선택)' },
        },
        required: ['query'],
      },
    },
  • Core implementation of page search in GraphService: lists pages, applies filters, scans content line-by-line for query matches, returns results with context.
    async searchPages(query: string, options?: { tags?: string[]; folder?: string }): Promise<SearchResult[]> {
      // 보안: 검색어 길이 제한 (DoS 방지)
      if (query.length > 1000) {
        throw new Error('Search query too long (max 1000 characters)');
      }
    
      const results: SearchResult[] = [];
      const pages = await this.listPages(options?.folder);
      const queryLower = query.toLowerCase();
    
      for (const page of pages) {
        // Filter by tags if specified
        if (options?.tags && options.tags.length > 0) {
          const hasTag = options.tags.some(tag => page.tags.includes(tag));
          if (!hasTag) continue;
        }
    
        // Search in content
        const filePath = join(this.graphPath, page.path);
    
        // 보안: TOCTOU 방지 - 심링크/하드링크 체크
        try {
          await this.checkRegularFile(filePath);
        } catch {
          continue; // 심링크/하드링크/특수파일은 건너뜀
        }
    
        const content = await readFile(filePath, 'utf-8');
        const lines = content.split('\n');
        const matches: SearchMatch[] = [];
    
        for (let i = 0; i < lines.length; i++) {
          if (lines[i].toLowerCase().includes(queryLower)) {
            matches.push({
              line: i + 1,
              content: lines[i],
              context: lines.slice(Math.max(0, i - 1), i + 2).join('\n'),
            });
          }
        }
    
        // Also match page name
        if (page.name.toLowerCase().includes(queryLower) || matches.length > 0) {
          results.push({ page, matches });
        }
      }
    
      return results;
    }

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/dearcloud09/logseq-mcp'

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