Skip to main content
Glama
Lspace-io

Lspace MCP Server

Official
by Lspace-io

lspace_browse_knowledge_base

Browse and read files or directories in the Lspace knowledge base. Syncs with the remote server for updated content; use 'list_directory' to view folders or 'read_file' for file contents.

Instructions

šŸ“– BROWSE: Read existing knowledge base files/directories (read-only). Automatically syncs with remote before browsing to ensure latest content. Example: To list files in 'Lspace Official Docs' root, use repositoryId='b3fcb584-5fd9-4098-83b8-8c5d773d86eb', operation='list_directory', path='.'

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesOperation type: 'list_directory' to see files/folders, 'read_file' to read file contents. Use 'lspace_add_content' for content creation.
pathYesPath relative to repository root. Use '.' for root directory, 'folder/file.txt' for specific files.
repositoryIdYesThe ID of the Lspace repository. Use 'lspace_list_repositories' first to get repository IDs.

Implementation Reference

  • Main handler logic for 'lspace_browse_knowledge_base' tool in the callTool method. Validates parameters, syncs repository, performs list_directory or read_file operations via repository instance, and blocks write operations.
    case 'lspace_browse_knowledge_base':
      const { repositoryId: repoId2, operation, path, content: itemContent } = args;
      if (!repoId2 || !operation || !path) {
        return {
          jsonrpc: "2.0",
          id,
          error: {
            code: -32000,
            message: `Missing required parameters for lspace_browse_knowledge_base:\n` +
                    `• repositoryId: Get this from 'lspace_list_repositories'\n` +
                    `• operation: Use 'list_directory' or 'read_file'\n` +
                    `• path: Use '.' for root directory or 'folder/file.txt'\n\n` +
                    `Example: repositoryId='b3fcb584-5fd9-4098-83b8-8c5d773d86eb', operation='list_directory', path='.'`
          }
        };
      }
      
      if (!this.isInitialized || !this.repositoryManager) {
        return {
          jsonrpc: "2.0",
          id,
          error: {
            code: -32000,
            message: 'Repository manager not initialized'
          }
        };
      }
      
      // Normalize the path - if it's root ("/") or empty, use "." for repository root
      let normalizedPath = path;
      if (!normalizedPath || normalizedPath === '/' || normalizedPath === '') {
        normalizedPath = '.';
      }
      
      // Check for prohibited paths
      if (normalizedPath.includes('.lspace') || normalizedPath.includes('.git')) {
        return {
          jsonrpc: "2.0",
          id,
          error: {
            code: -32000,
            message: 'Operation on /.lspace/ or /.git/ directories is strictly prohibited'
          }
        };
      }
      
      try {
        // Get the repository configuration first
        const repoInfo = this.repositoryManager.getAllRepositoryConfigs().find(r => r.id === repoId2);
        
        if (!repoInfo) {
          return {
            jsonrpc: "2.0",
            id,
            error: {
              code: -32000,
              message: `Repository with ID ${repoId2} not found`
            }
          };
        }
        
        // Debug info before trying to access repository
        const debugInfo = {
          repositoryId: repoId2,
          configPath: repoInfo.path || 'N/A',
          repositoryType: repoInfo.type,
          originalPath: path || 'undefined',
          normalizedPath: normalizedPath,
          workingDir: process.cwd()
        };
        
        // Sync with remote before browsing (for GitHub repositories)
        try {
          await this.repositoryManager.syncWithRemote(repoId2);
        } catch (syncError) {
          console.warn(`Failed to sync repository before browsing: ${syncError.message}`);
          // Continue with browsing even if sync fails - user will see local version
        }
        
        // Get the repository instance
        const repository = this.repositoryManager.getRepository(repoId2);
        
        let result;
        switch (operation) {
          case 'list_directory':
            try {
              const items = await repository.listFiles(normalizedPath);
              result = {
                success: true,
                operation,
                path: normalizedPath,
                items: items,
                debug: debugInfo
              };
            } catch (listError) {
              // Return debug info even if listing fails
              result = {
                success: false,
                operation,
                error: listError.message,
                debug: debugInfo
              };
            }
            break;
            
          case 'read_file':
            const fileContent = await repository.readFile(path);
            result = {
              success: true,
              operation,
              path,
              content: fileContent
            };
            break;
            
          // Block all content creation/modification operations
          case 'create_file':
          case 'update_file':
          case 'delete_file':
          case 'create_directory':
          case 'delete_directory':
            return {
              jsonrpc: "2.0",
              id,
              error: {
                code: -32000,
                message: `āŒ OPERATION BLOCKED: '${operation}' is not allowed in lspace_browse_knowledge_base.\n\nšŸš€ Use 'lspace_add_content' instead to:\n  • Add new content to the knowledge base\n  • Trigger automatic LLM processing\n  • Follow proper lspace workflow\n\nThe 'lspace_browse_knowledge_base' tool is READ-ONLY for browsing existing KB structure.`
              }
            };
            
          default:
            return {
              jsonrpc: "2.0",
              id,
              error: {
                code: -32000,
                message: `Unsupported operation: ${operation}`
              }
            };
        }
        
        return {
          jsonrpc: "2.0",
          id,
          result: {
            content: [
              {
                type: "text",
                text: JSON.stringify(result, null, 2)
              }
            ]
          }
        };
        
      } catch (error) {
        return {
          jsonrpc: "2.0",
          id,
          error: {
            code: -32000,
            message: `Failed to ${operation}: ${error.message}`
          }
        };
      }
  • Tool schema definition including inputSchema for parameter validation (repositoryId, operation, path) in the getTools() method.
    {
      name: "lspace_browse_knowledge_base",
      description: "šŸ“– BROWSE: Read existing knowledge base files/directories (read-only). Automatically syncs with remote before browsing to ensure latest content. Example: To list files in 'Lspace Official Docs' root, use repositoryId='b3fcb584-5fd9-4098-83b8-8c5d773d86eb', operation='list_directory', path='.'",
      inputSchema: {
        type: "object",
        properties: {
          repositoryId: {
            type: "string",
            description: "The ID of the Lspace repository. Use 'lspace_list_repositories' first to get repository IDs."
          },
          operation: {
            type: "string", 
            description: "Operation type: 'list_directory' to see files/folders, 'read_file' to read file contents. Use 'lspace_add_content' for content creation.",
            enum: ["read_file", "list_directory"]
          },
          path: {
            type: "string",
            description: "Path relative to repository root. Use '.' for root directory, 'folder/file.txt' for specific files."
          }
        },
        required: ["repositoryId", "operation", "path"]
      }
    },
  • Registration via 'tools/list' RPC method that returns the list of tools from getTools(), which includes 'lspace_browse_knowledge_base'.
    case 'tools/list':
      return {
        jsonrpc: "2.0",
        id,
        result: {
          tools: this.getTools()
        }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: read-only operation, automatic syncing before browsing, and the tool's purpose for reading files/directories. However, it doesn't mention potential limitations like rate limits, error handling, or response format details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by key behavioral details and a concrete example. Every sentence adds value: the first states the purpose and read-only nature, the second explains automatic syncing, and the third provides a practical usage example. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 parameters, no output schema, no annotations), the description is mostly complete. It covers purpose, usage guidelines, and key behavior. However, without an output schema, it doesn't describe return values (e.g., what 'list_directory' or 'read_file' returns), leaving a minor gap in completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description adds minimal value beyond the schema, providing only an example that illustrates parameter usage without adding new semantic information. This meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Read existing knowledge base files/directories') and resource ('knowledge base'), distinguishing it from siblings like 'lspace_add_content' (creation) and 'lspace_search_knowledge_base' (searching). The emoji and 'BROWSE' reinforce the read-only browsing function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('read-only' browsing) and when not to ('Use lspace_add_content for content creation'), providing clear alternatives. It also mentions prerequisites ('Automatically syncs with remote before browsing') and references sibling tools ('lspace_list_repositories' to get repository IDs).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/Lspace-io/lspace-server'

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