ls-mcp is a command-line tool for detecting and listing MCP (Model Context Protocol) servers in a local development environment. It helps developers quickly see which MCP servers are configured on their system and whether they are currently running.
The tool works by scanning for known MCP configuration files associated with various code editors and tools. Here's a high-level overview of the process:
- File Discovery: The tool starts by looking for MCP configuration files in predefined locations. These locations are specific to different applications (like VS Code, Claude, Cursor, etc.) and operating systems (Windows, macOS, and Linux). The tool gracefully handles unsupported operating systems by providing meaningful error messages.
Directory Bubbling Feature: For local (project-scoped) MCP configuration files, the tool now includes an intelligent directory bubbling feature. If a local config file isn't found in the current directory, it automatically searches up the directory tree until it finds the file or reaches the user's home directory or root directory. This provides better Developer Experience (DX) by allowing users to run ls-mcp from anywhere within their project structure and still detect project-scoped MCP config files.
-
Configuration Parsing: Once a configuration file is found, it is parsed to extract the list of configured MCP servers. The tool can handle standard JSON and JSON with comments (JSONC). It's designed to be flexible and can find server configurations under different keys like
servers,mcp.servers,mcpServers, andcontext_serversto support a variety of applications. -
Process Detection: For each configured MCP server, the tool checks if it is currently running. It does this by executing system commands (
pson macOS andpowershellon Windows) to get a list of all active processes. It then compares the command from the MCP configuration with the running processes to determine the server's status. The tool includes specific logic to handle common ways of running MCP servers, such as usinguvxornpx. -
Output Rendering: Finally, all the gathered information is displayed in a formatted table in the console. The table shows the server's status (running or stopped), name, source (the command used to start it or hostname for URL-based servers), and transport protocol.
The project is a TypeScript-based Node.js application with a clear, modular, service-oriented architecture:
src/main.ts: Contains theMCPFilesclass that orchestrates the entire discovery process, coordinating between different services and providing a clean API.src/bin/cli.ts: The entry point for the command-line interface. It handles argument parsing and delegates all business logic to the main application layer.
The project has been refactored into a modular service architecture. The core logic for file discovery and parsing has been extracted into a separate agent-files package.
-
agent-filespackage: This package is responsible for path resolution, configuration parsing, and directory bubbling.MCPPathRegistry: Handles OS-specific path resolution for MCP configuration files.MCPConfigParser: Handles parsing and validation of MCP configuration files.DirectoryBubbleService: Handles intelligent directory traversal to find local MCP config files.MCPConfigLinterService: A legacy service that delegates to the newMCPConfigParser.
-
ls-mcpservices:src/services/mcp-config-service.ts: Central orchestrator for MCP configuration operations, consuming theagent-filespackage.src/services/mcp-server-manager-service.ts: Manages MCP server process detection and status reporting.src/services/render-service.ts: Handles output formatting and display of MCP configuration information.
src/types/mcp-config-service.types.ts: Comprehensive type definitions for all MCP configuration services.agent-files/src/types/mcp-config-service.types.ts: Type definitions for theagent-filespackage.
The project maintains a clean separation between external MCP configuration files and internal application data:
- External Config Format: MCP config files use
typefield for transport specification (e.g.,"type": "stdio","type": "http","type": "streamable-http") - Internal Data Model: Our application maps
typetotransportfield for consistent UI display and internal logic - Clean Mapping: The
MCPConfigServicehandles the one-way mapping fromtype→transportat the data layer - Special Handling:
streamable-httpis treated as synonym forhttpand mapped accordingly - UI Consistency: All transport information in the UI (TRANSPORT column, summary counts) comes from the internal
transportfield - Transport Inference: When no explicit
typefield is present, the system automatically infers transport types using intelligent pattern matching:- URL Detection: Presence of
urlfield →httptransport - Args Analysis: Keywords in
argsarray → corresponding transport (stdio,http,sse) - Default Fallback:
commandpresent →stdiotransport (most common case)
- URL Detection: Presence of
This architecture ensures maintainability and clear separation of concerns between external data formats and internal application logic, while providing intelligent defaults for better user experience.
__tests__/: Comprehensive test suite with proper isolation and mocking to prevent real filesystem access during testing.__tests__/__fixtures__/: Test fixture files for isolated testing of configuration parsing.
- Service Architecture: Successfully separated MCP configuration logic into dedicated, focused services
- Data Model Architecture: Implemented clean separation between external MCP config format (
type) and internal app data (transport) - Transport Handling: Fixed transport counting by properly mapping
typefield totransportfield at the data layer - Extended Transport Support: Added support for
streamable-httptype, treating it as synonym forhttp - Transport Inference: Implemented intelligent automatic detection of transport types when not explicitly specified
- URL Hostname Extraction: Implemented feature #80 to display only hostnames for URL-based MCP servers in the SOURCE column, improving readability
- Directory Bubbling: Implemented intelligent directory traversal for local MCP config files, providing better DX when running from nested project subdirectories
- Test Isolation: Fixed critical issue where tests were accessing real files outside the project directory
- Type Safety: Created comprehensive TypeScript types for all services
- Error Handling: Improved error handling and graceful degradation for unsupported operating systems
- CI Compatibility: Tests now pass in all environments, including Linux CI
- Linux Support: Added comprehensive Linux support with appropriate file paths for all supported applications
- MCPPathRegistry: 100% coverage
- MCPConfigParser: 97% coverage
- MCPConfigService: 90.84% coverage
- MCPServerManagerService: 54.3% coverage (needs improvement)
- RenderService: 98.65% coverage
- DirectoryBubbleService: 95.89% coverage
- Package Extraction: Services are designed to be easily extracted to separate npm packages
- Enhanced Features: Architecture supports future enhancements and additional AI application definitions
- Plugin System: Extensible design for custom AI application definitions
The URL hostname extraction feature improves the readability of MCP server configurations by displaying only the hostname for URL-based servers instead of the full URL in the SOURCE column.
- URL Detection: When an MCP server configuration contains a
urlfield, the system automatically extracts the hostname portion - Hostname Extraction: Uses Node.js built-in
URLconstructor to parse URLs and extract the hostname - Fallback Handling: If URL parsing fails, the original string is displayed as a fallback
- Protocol Handling: Automatically adds
http://protocol if none is specified for proper parsing
SOURCE | STATUS | NAME | TRANSPORT
http://localhost:3000/mcp | ❌ | local-server | http
https://api.example.com | ❌ | api-server | http
SOURCE | STATUS | NAME | TRANSPORT
localhost | ❌ | local-server | http
api.example.com | ❌ | api-server | http
- Cleaner Output: SOURCE column is more readable and concise
- Better UX: Users can quickly identify the server location without URL clutter
- Consistent Display: All URL-based servers show consistent hostname format
- Robust Parsing: Handles various URL formats including those without protocols
- Utility Function:
extractHostname()insrc/utils/url-utils.ts - Service Integration: Integrated into both
MCPConfigServiceandMCPServerManagerService - Error Handling: Graceful fallback to original string if parsing fails
- Protocol Support: Handles HTTP, HTTPS, and custom protocols
The directory bubbling feature enhances the Developer Experience (DX) by automatically detecting MCP configuration files in parent directories when running ls-mcp from nested project subdirectories.
- Local Path Detection: When processing local (project-scoped) MCP configuration files, the tool first checks if the file exists in the current directory
- Intelligent Traversal: If not found, it automatically "bubbles up" the directory tree, checking each parent directory for the configuration file
- Boundary Safety: The traversal stops at the user's home directory (
~) or root directory (/) to prevent infinite loops - First Match Wins: The tool stops at the first encounter of a matching configuration file (closest to the current directory)
cd ~/projects/my-project
ls-mcp # ✅ Detects .vscode/mcp.json in current directorycd ~/projects/my-project/backend/services/api
ls-mcp # ✅ Automatically detects .vscode/mcp.json from project rootcd ~/projects/my-project/backend/services
# If both ~/projects/my-project/.vscode/mcp.json and ~/projects/my-project/backend/.mcp.json exist
ls-mcp # ✅ Detects the closer .mcp.json file in backend directory- Enabled by Default: Directory bubbling is automatically enabled for the CLI
- Optional Feature: Can be disabled by modifying the MCPConfigService constructor options
- Local Paths Only: Only applies to paths marked as
'local'type, never to global paths
- Better DX: Run
ls-mcpfrom anywhere in your project structure - No More Navigation: No need to navigate to project root to check MCP configurations
- Intelligent Discovery: Automatically finds the most relevant configuration file
- Backward Compatible: Existing behavior unchanged for users running from project root
To add support for a new application that uses MCP, you will need to:
- Add the configuration file path: In the
agent-filespackage, specifically insrc/services/mcp-path-registry.ts, add the path to the application's MCP configuration file to the appropriate OS-specific paths object. - Update the server key (if necessary): If the new application uses a different key in its configuration file to list the MCP servers, the
MCPConfigParserin theagent-filespackage already supports multiple keys and can be extended if needed.
You can extend the tool's functionality in several ways:
- Provide more server details: You could enhance the tool to display more information about the MCP servers, such as their version, the number of tools and resources they provide, or their uptime.
- Add server management capabilities: You could add features to allow users to start, stop, or restart MCP servers directly from the command line.
- Add a watch mode: You could add a watch mode that continuously monitors the status of the MCP servers and updates the display in real-time.
- Add Linux support: The architecture is ready for Linux support to be added by extending the
MCPPathRegistry.
If you encounter a bug, here's how you can approach fixing it:
- Write a failing test: The first step is to write a test case that reproduces the bug. The existing tests in the
__tests__directory can serve as a good starting point. A failing test will help you confirm that you have identified the root cause of the bug and that your fix is effective. - Identify the source of the bug: Bugs are most likely to occur in the file discovery, configuration parsing, or process detection logic. Use the debugger and add logging statements to trace the execution flow and pinpoint the exact location of the bug.
- Implement the fix: Once you have identified the source of the bug, implement a fix.
- Run the tests: After implementing the fix, run all the tests to ensure that your changes have not introduced any regressions.
The codebase has been significantly refactored to improve maintainability and testability. Here are some potential areas for future improvement:
- Improve MCPServerManagerService test coverage: Currently at 54.3%, this service needs more comprehensive testing, especially for process detection edge cases and different transport type handling.
- Performance optimization: For systems with many MCP servers, consider adding caching and parallel processing optimizations.
- Enhanced error reporting: Improve user-facing error messages and add debugging information for developers.
- High-level tests (app tests, edge case tests) must use proper mocking to prevent real filesystem access
- Service tests can test real functionality but only access fixture files within the project directory
- CI compatibility must be maintained across different operating systems
- All public methods must have test coverage
- Error scenarios must be tested
- Edge cases must be covered
- OS-specific functionality must be tested
- Use Node.js test runner's
mock.method()for method mocking - Mock filesystem operations to prevent real file access
- Use fixture files for testing configuration parsing
- Test both success and failure scenarios