Skip to main content
Glama
kazuph

MCP Docs RAG Server

by kazuph

list_documents

Check all available documents in the DOCS_PATH directory to verify existing files before adding new ones, ensuring organized document retrieval and management.

Instructions

List all available documents in the DOCS_PATH directory. Always use this tool first to check if desired documents already exist before adding new ones.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Main handler for the 'list_documents' tool call within the CallToolRequestSchema handler. Calls listDocuments() and formats the response as text content.
    case "list_documents": {
      const documents = await listDocuments();
      
      // ドキュメントの情報を整形
      const documentsList = documents.map(document => {
        return `- ${document.name}: ${document.description}`;
      }).join('\n');
      
      return {
        content: [{
          type: "text",
          text: `Available documents in ${DOCS_PATH}:\n\n${documentsList}\n\nTotal documents: ${documents.length}`
        }]
      };
    }
  • Core helper function that lists all available documents in DOCS_PATH by checking for git repositories (.git dir) or text documents (index.txt file).
    export async function listDocuments(): Promise<Array<{ id: string, name: string, path: string, description: string }>> {
      const documents: Array<{ id: string, name: string, path: string, description: string }> = [];
      
      const entries = fs.readdirSync(DOCS_PATH, { withFileTypes: true });
      
      for (const entry of entries) {
        if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
        
        const entryPath = path.join(DOCS_PATH, entry.name);
        
        // Gitリポジトリかテキストファイルかを判断
        let isGitRepo = false;
        try {
          // .gitディレクトリが存在するか確認
          const gitPath = path.join(entryPath, '.git');
          isGitRepo = fs.existsSync(gitPath) && fs.statSync(gitPath).isDirectory();
        } catch (error) {
          // エラーが発生した場合はGitリポジトリではない
          isGitRepo = false;
        }
        
        // index.txtファイルがあるか確認
        const indexPath = path.join(entryPath, 'index.txt');
        const hasIndexFile = fs.existsSync(indexPath) && fs.statSync(indexPath).isFile();
        
        if (isGitRepo) {
          documents.push({
            id: entry.name,
            name: entry.name,
            path: entryPath,
            description: `Git repository: ${entry.name}`,
          });
        } else if (hasIndexFile) {
          documents.push({
            id: entry.name,
            name: entry.name,
            path: indexPath,
            description: `Text document: ${entry.name}`,
          });
        }
      }
      
      return documents;
    }
  • Schema definition for the 'list_documents' tool, including name, description, and empty input schema (no parameters required). Defined in ListToolsRequestSchema response.
    {
      name: "list_documents",
      description: "List all available documents in the DOCS_PATH directory. Always use this tool first to check if desired documents already exist before adding new ones.",
      inputSchema: {
        type: "object",
        properties: {}
      }
    },
  • src/index.ts:436-588 (registration)
    Registration of tool handlers via setRequestHandler for CallToolRequestSchema, including the switch case that handles 'list_documents'.
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
      switch (request.params.name) {
        case "list_documents": {
          const documents = await listDocuments();
          
          // ドキュメントの情報を整形
          const documentsList = documents.map(document => {
            return `- ${document.name}: ${document.description}`;
          }).join('\n');
          
          return {
            content: [{
              type: "text",
              text: `Available documents in ${DOCS_PATH}:\n\n${documentsList}\n\nTotal documents: ${documents.length}`
            }]
          };
        }
        
        case "rag_query": {
          const documentId = String(request.params.arguments?.document_id);
          const query = String(request.params.arguments?.query);
          
          if (!documentId || !query) {
            throw new Error("Document ID and query are required");
          }
          
          try {
            // ドキュメントが存在するか確認し、存在しなければ自動的に作成を試みる
            let documents = await listDocuments();
            let document = documents.find(c => c.id === documentId);
            
            if (!document) {
              return {
                content: [{
                  type: "text",
                  text: `Document '${documentId}' not found. Please add it manually using add_git_repository or add_text_file tools.`
                }]
              };
            }
            
            // Load and index document if needed
            const index = await loadDocument(documentId);
          
          // 一時的にGemini LLMを設定
          const originalLLM = Settings.llm;
          const gemini = new Gemini({
            model: GEMINI_MODEL.GEMINI_2_0_FLASH
          });
          
          // グローバル設定に設定
          Settings.llm = gemini;
          
          // クエリエンジンの作成
          const queryEngine = index.asQueryEngine();
          
          // クエリの実行
          const response = await queryEngine.query({
            query
          });
          
          return {
            content: [{
              type: "text",
              text: response.toString()
            }]
          };
          } catch (error: any) {
            console.error(`Error in rag_query:`, error.message);
            return {
              content: [{
                type: "text",
                text: `Error processing query: ${error.message}`
              }]
            };
          }
        }
        
        case "add_git_repository": {
          const repositoryUrl = String(request.params.arguments?.repository_url);
          const subdirectory = request.params.arguments?.subdirectory ? String(request.params.arguments?.subdirectory) : undefined;
          const documentName = request.params.arguments?.document_name ? String(request.params.arguments?.document_name) : undefined;
          
          if (!repositoryUrl) {
            throw new Error("Repository URL is required");
          }
          
          const result = await cloneRepository(repositoryUrl, subdirectory, documentName);
          
          // If document already exists, inform the user without updating
          if (result.exists) {
            return {
              content: [{
                type: "text",
                text: `Document '${result.name}' already exists. Please use list_documents to view existing documents.`
              }]
            };
          }
          
          // Prepare response message for new document
          let responseText = `Added git repository: ${result.name}`;
          
          if (subdirectory) {
            responseText += ` (sparse checkout of '${subdirectory}')`;  
          }
          
          if (documentName) {
            responseText += ` with custom name '${documentName}'`;  
          }
          
          return {
            content: [{
              type: "text",
              text: `${responseText}. The index will be created when you query this document for the first time.`
            }]
          };
        }
        
        case "add_text_file": {
          const fileUrl = String(request.params.arguments?.file_url);
          const documentName = String(request.params.arguments?.document_name);
          
          if (!fileUrl) {
            throw new Error("File URL is required");
          }
          
          if (!documentName) {
            throw new Error("Document name is required");
          }
          
          const result = await downloadFile(fileUrl, documentName);
          
          // If document already exists, inform the user without updating
          if (result.exists) {
            return {
              content: [{
                type: "text",
                text: `Document '${result.name}' already exists. Please use list_documents to view existing documents.`
              }]
            };
          }
          
          return {
            content: [{
              type: "text",
              text: `Added document '${result.name}' with content from ${fileUrl}. The index will be created when you query this document for the first time.`
            }]
          };
        }
        
        default:
          throw new Error("Unknown tool");
      }
    });
Install Server

Other Tools

Related Tools

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/kazuph/mcp-docs-rag'

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