Enhancing Easy-mcp-server With Static File Serving And Root Route Support

by StackCamp Team 74 views

In this article, we'll dive into a feature request aimed at significantly improving the easy-mcp-server framework. We'll explore the need for built-in support for static file serving and root route handling, discussing the current limitations, desired behavior, and potential implementation strategies. This enhancement will not only streamline development but also empower developers to build more comprehensive and user-friendly MCP servers.

Summary of the Feature Request

The core of this feature request is to add native support for serving static files (like HTML, CSS, JavaScript, and images) and managing the root route (/) within the easy-mcp-server framework. Currently, the framework primarily focuses on API endpoints, lacking a straightforward mechanism to handle static content and the root URL. This limitation can be a hurdle when building applications that require web-based interfaces or documentation.

Understanding the Current Behavior

Currently, easy-mcp-server operates with a specific convention for API endpoints. Let's break down the current behavior:

  • API endpoints are defined in the api/ directory, following a structure like api/{service}/{action}/{method}.js, which maps to the URL /api/{service}/{action}.
  • The framework supports standard HTTP methods such as GET, POST, PUT, and DELETE.
  • There's no built-in functionality to serve static files directly from a designated public directory. This means you can't easily serve HTML, CSS, JavaScript, or image assets.
  • Accessing the root route (/) results in a Cannot GET / error, as there's no default handler for this URL.
  • Serving static HTML files, such as settings.html or index.html, is not directly supported.

This limited functionality forces developers to find workarounds, which can complicate the development process and lead to non-standard solutions.

Desired Behavior: A Vision for Improvement

To address these limitations, the feature request proposes several key enhancements. The desired behavior includes:

1. Static File Serving

Imagine being able to easily serve static assets from a dedicated directory. This is the goal of the first enhancement. The proposed solution involves a configuration option, potentially within the server configuration or via a command-line interface (CLI) flag, that enables static file serving. This configuration would include:

// In server configuration or via CLI flag
{
 staticFiles: {
 enabled: true,
 directory: './public',
 serveIndex: true,
 defaultFile: 'index.html'
 }
}
  • enabled: A boolean flag to activate static file serving.
  • directory: Specifies the directory containing the static files (e.g., ./public).
  • serveIndex: An option to automatically serve an index file (e.g., index.html) when accessing a directory.
  • defaultFile: Sets the default file to serve if no specific file is requested (e.g., index.html).

Use case: This feature would allow developers to easily serve settings pages, documentation, web UIs, and other static assets directly from the server.

2. Root Route Handling

Handling the root route (/) is another crucial aspect. The current behavior of returning a Cannot GET / error is not ideal for applications with web interfaces. Two options are proposed for handling the root route:

  • Option 1: Automatic index.html Serving: The server automatically serves index.html from the static directory when the root route is accessed.

    GET / → serves ./public/index.html
    
  • Option 2: Custom Root Route Handler: Developers can define a custom handler for the root route, similar to API endpoints. This could involve creating a file like api/index/get.js or api/root/get.js.

    GET / → executes root route handler
    

3. Custom Route Mapping

To provide even more flexibility, the feature request suggests allowing custom route mapping. This would enable developers to map non-standard routes to specific API handlers. For example:

// Route configuration
{
 customRoutes: [
 { path: '/', handler: 'api/index/get.js' },
 { path: '/settings.html', handler: 'api/settings/ui/get.js' },
 { path: '/docs', handler: 'api/docs/get.js' }
 ]
}

This feature would allow mapping the root route to a specific handler, serving static files at custom paths (e.g., /settings.html), and even creating routes for documentation (e.g., /docs).

Motivation and Use Case: Why This Matters

The motivation behind this feature request stems from real-world development scenarios. Let's consider a real-world scenario where we're building an MCP server with integrations for over 20 services, such as GitHub, Slack, JIRA, Confluence, and AWS S3. A web-based settings UI is crucial for users to:

  1. Configure service credentials via a user-friendly web interface.
  2. Test connections before saving.
  3. Manage multi-user credentials.

Without the proposed features, developers face several current workaround problems:

  • The inability to serve the settings page at the root URL or standard paths.
  • The need to use POST endpoints to return HTML as JSON, which is not a standard practice.
  • Users cannot simply open http://localhost:8887/ in a browser to access the UI.
  • No direct way to serve CSS, JavaScript, or image assets for the web UI.
  • Developers are forced to create workarounds by embedding HTML content in JSON responses.

These challenges highlight the need for a more streamlined approach to handling static files and root routes.

The Benefits: A Clear Advantage

The proposed features offer several significant benefits:

  1. Better Developer Experience: Natural file-based routing for static assets simplifies the development process.
  2. Standard Web Patterns: Support for conventional URLs like /, /settings, and /docs aligns with web development best practices.
  3. Multi-Purpose Servers: The framework can be used to build MCP servers that also serve web UIs, reducing the need for separate servers.
  4. Reduced Complexity: No need for external web servers or complex workarounds, streamlining the application architecture.
  5. Better Integration: MCP servers can include admin panels, dashboards, and documentation, providing a more cohesive user experience.

Proposed Implementation: How to Bring This to Life

To implement these features, several approaches are possible. Let's explore three potential implementation options:

Option 1: Configuration File Approach

This approach involves defining the configuration in a dedicated file, such as easy-mcp-server.config.js. For example:

// easy-mcp-server.config.js
module.exports = {
 apiDirectory: './api',
 mcpDirectory: './mcp',
 staticFiles: {
 enabled: true,
 directory: './public',
 routes: {
 '/': 'index.html',
 '/settings': 'settings.html'
 }
 }
};

This configuration clearly specifies the directories for API handlers and MCP definitions, as well as the settings for static file serving, including the directory and custom routes.

Option 2: CLI Flag Approach

Alternatively, the configuration can be provided via command-line flags. For instance:

npx easy-mcp-server \
 --api-directory ./api \
 --mcp-directory ./mcp \
 --static-directory ./public \
 --serve-index

This approach offers flexibility in configuring the server at runtime, allowing for different configurations in different environments.

Option 3: Convention-Based Approach

A third option is to adopt a convention-based approach. This would involve:

  • Automatically serving static files if a ./public directory exists.
  • Serving ./public/index.html at the root route (/) if it exists.
  • Allowing api/index/get.js to override the root route if needed, providing a way to define a custom handler.

This approach minimizes configuration and leverages common directory structures, making it easier to get started.

Additional Context: Understanding the Environment

To provide a clearer picture, let's consider the current project structure:

wallee-mcps/
├── api/ # API handlers (working ✓)
│ ├── confluence/
│ ├── github/
│ ├── settings/
│ │ ├── get/post.js
│ │ ├── post.js
│ │ └── ui/post.js # Returns HTML as JSON (workaround)
│ └── ...
├── public/ # Static files (not served ✗)
│ ├── index.html
│ └── settings.html
└── mcp/ # MCP definitions (working ✓)

This structure highlights the separation between API handlers, static files, and MCP definitions. The public/ directory contains the static files that are currently not being served.

The framework version in question is easy-mcp-server v1.0.96+, running on Node.js 18+ with Express 4.18.2 (if applicable).

Related Patterns: Learning from Others

Similar functionality exists in other popular frameworks, providing valuable insights and best practices. Some related patterns include:

  • Next.js: Uses a public/ directory for static assets.
  • Express: Employs the express.static() middleware for static file serving.
  • Fastify: Offers the @fastify/static plugin for serving static files.
  • Nest.js: Provides the ServeStaticModule for handling static assets.

These frameworks demonstrate the importance and commonality of static file serving in modern web development.

Alternatives Considered: Why This Approach is Best

Several alternatives were considered before proposing this feature request. Let's examine the alternatives and why this approach is the most suitable:

  1. Running a separate web server (nginx/Apache): This adds complexity to the deployment and management process.
  2. Using a custom src/index.js wrapper: This bypasses the benefits of easy-mcp-server, making it a less desirable option.
  3. Returning HTML in JSON responses: This is a non-standard approach that leads to poor user experience.
  4. Adding static file support to the framework: This is the preferred long-term solution, as it directly addresses the limitations and integrates seamlessly with the framework.

Breaking Changes: Ensuring Compatibility

A crucial consideration is whether the proposed changes would introduce any breaking changes. The good news is that this feature would be an opt-in addition, ensuring backward compatibility. Existing applications would not be affected unless they explicitly enable the new static file serving and root route handling features.

Questions for Maintainers: Seeking Guidance

To ensure the best implementation, several questions for maintainers are raised:

  1. Which implementation approach is preferred (config file, CLI flags, or convention)?
  2. Should this be a core feature or a separate plugin/middleware?
  3. Are there security considerations for serving static files?
  4. Should route priority be: custom routes → static files → API handlers?

These questions aim to guide the implementation process and ensure that the features are integrated in a way that aligns with the framework's design principles and security best practices.

Conclusion: A Step Forward for easy-mcp-server

In conclusion, the feature request for static file serving and root route support represents a significant step forward for easy-mcp-server. By addressing the current limitations and providing a more flexible and user-friendly development experience, this enhancement will empower developers to build more comprehensive MCP servers with web interfaces. Thank you for considering this feature request, and we look forward to seeing it enhance the usability of easy-mcp-server.