Skip to main content
Glama

m9k_file_history

Search past conversations and metadata to find when specific files were discussed or modified, using indexed conversation history and file path references.

Instructions

Find past conversations that touched a specific file. Searches metadata (tool_use file_path) and text content.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesFile path to search for (e.g. "src/server.ts")
limitNoMax results
sourceNoFilter by source type. Default: all sources.

Implementation Reference

  • Handler implementation for 'm9k_file_history' tool.
    async ({ filePath, limit }) => {
      const basename = path.basename(filePath);
    
      // Strategy 1: LIKE on metadata_json for the file path
      const metadataRows = ctx.db
        .prepare(
          `SELECT c.id, c.session_id, c.idx, c.user_content, c.assistant_content,
                  c.timestamp, c.metadata_json, s.project
           FROM conv_chunks c
           JOIN conv_sessions s ON c.session_id = s.id
           WHERE c.metadata_json LIKE ?
             AND c.deleted_at IS NULL
           ORDER BY c.timestamp DESC
           LIMIT ?`,
        )
        .all(`%${filePath}%`, limit * 2) as Array<{
        id: string;
        session_id: string;
        idx: number;
        user_content: string;
        assistant_content: string;
        timestamp: string;
        metadata_json: string;
        project: string;
      }>;
    
      // Strategy 2: FTS5 on the basename
      let ftsRows: typeof metadataRows = [];
      try {
        ftsRows = ctx.db
          .prepare(
            `SELECT c.id, c.session_id, c.idx, c.user_content, c.assistant_content,
                    c.timestamp, c.metadata_json, s.project
             FROM conv_chunks_fts
             JOIN conv_chunks c ON conv_chunks_fts.rowid = c.rowid
             JOIN conv_sessions s ON c.session_id = s.id
             WHERE conv_chunks_fts MATCH ?
               AND c.deleted_at IS NULL
             ORDER BY c.timestamp DESC
             LIMIT ?`,
          )
          .all(basename, limit * 2) as typeof metadataRows;
      } catch {
        // FTS5 syntax error — skip
      }
    
      // Dedup by chunkId, metadata results first (more precise)
      const seen = new Set<string>();
      const combined: Array<{
        chunkId: string;
        sessionId: string;
        project: string;
        timestamp: string;
        snippet: string;
        filePaths: string[];
      }> = [];
    
      for (const row of [...metadataRows, ...ftsRows]) {
        if (seen.has(row.id)) continue;
        seen.add(row.id);
    
        let filePaths: string[] = [];
        try {
          const meta = JSON.parse(row.metadata_json) as { filePaths?: string[] };
          filePaths = meta.filePaths ?? [];
        } catch {
          // ignore parse error
        }
    
        combined.push({
          chunkId: row.id,
          sessionId: row.session_id,
          project: row.project,
          timestamp: row.timestamp,
          snippet: (row.user_content + ' ' + row.assistant_content).slice(0, 150),
          filePaths,
        });
      }
    
      // Sort by timestamp DESC, take top limit
      combined.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
    
      return {
        content: [{ type: 'text' as const, text: JSON.stringify(combined.slice(0, limit)) }],
      };
    },
  • Input schema definition for the 'm9k_file_history' tool.
    inputSchema: {
      filePath: z.string().describe('File path to search for (e.g. "src/server.ts")'),
      limit: z.number().int().min(1).max(50).default(10).describe('Max results'),
      source: z
        .enum(['conversations', 'git', 'files'])
        .optional()
        .describe('Filter by source type. Default: all sources.'),
    },
  • Registration of the 'm9k_file_history' tool.
    export function registerSpecializedTools(server: McpServer, ctx: ToolContext): void {
      server.registerTool(
        'm9k_file_history',
        {
          description:
            'Find past conversations that touched a specific file. Searches metadata (tool_use file_path) and text content.',
          inputSchema: {
            filePath: z.string().describe('File path to search for (e.g. "src/server.ts")'),
            limit: z.number().int().min(1).max(50).default(10).describe('Max results'),
            source: z
              .enum(['conversations', 'git', 'files'])
              .optional()
              .describe('Filter by source type. Default: all sources.'),
          },
          annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: false,
          },
        },

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/louis49/melchizedek'

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