Skip to content

Nexlab-One/v-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

V MCP Server Template

A template repository for creating Model Context Protocol (MCP) servers in the V programming language. This template provides a clean, minimal foundation that you can extend to build your own MCP servers.

Overview

This template includes:

  • JSON-RPC 2.0 Protocol Implementation: Complete MCP protocol handling
  • Modular Architecture: Clean separation of concerns (protocol, server, tools)
  • Tool Registry System: Easy-to-extend tool handler registration
  • Configuration Management: Environment variable-based configuration
  • Build Scripts: Ready-to-use build scripts for Windows and Unix
  • Example Tools: Sample tool implementations to guide your development

Quick Start

Prerequisites

Getting Started

  1. Use this template to create your own repository:

    • Click "Use this template" on GitHub, or
    • Clone this repository and remove the .git directory
  2. Customize the module name in v.mod:

    Module {
        name: 'your_mcp_server'  // Change this
        description: 'Your MCP server description'
        version: '0.1.0'
        dependencies: []
    }
  3. Customize configuration in src/server/config.v:

    • Add your server-specific configuration fields
    • Update from_env() to read your environment variables
  4. Add your tools in src/tools/tools.v:

    • Implement your tool handler functions
    • Register them in register_all()
  5. Build and test:

    # Linux/macOS
    ./build.sh
    
    # Windows
    build.bat
  6. Run your server:

    ./mcp-server  # or mcp-server.exe on Windows

Project Structure

.
├── src/
│   ├── main.v              # Entry point and JSON-RPC message loop
│   ├── mcp/
│   │   └── mcp.v          # JSON-RPC 2.0 protocol implementation
│   ├── server/
│   │   ├── config.v        # Configuration management
│   │   └── server.v        # Server state management
│   └── tools/
│       └── tools.v         # Tool registry and handlers
├── build.sh                # Linux/macOS build script
├── build.bat               # Windows build script
├── v.mod                   # V module definition
└── README.md              # This file

Customization Guide

1. Configuration (src/server/config.v)

Add your server-specific configuration:

pub struct ServerConfig {
pub:
    data_path      string = ''
    cache_ttl_seconds int = 300
    max_results    int = 50
    log_level      string = 'INFO'
}

pub fn from_env() ServerConfig {
    data_path := os.getenv('DATA_PATH')
    // ... your configuration logic
    return ServerConfig{
        data_path: data_path
        // ...
    }
}

2. Server State (src/server/server.v)

Add your server's state and methods:

pub struct ServerState {
pub mut:
    config ServerConfig
    cache  map[string]CacheEntry
    data   map[string]string
}

pub fn new_server(config ServerConfig) ServerState {
    return ServerState{
        config: config
        cache: map[string]CacheEntry{}
        data: map[string]string{}
    }
}

3. Tools (src/tools/tools.v)

Implement your tool handlers:

fn handle_my_tool(params mcp.JsonAny, mut server_state server.ServerState) string {
    // Extract parameters
    query := mcp.extract_string_param(params, 'query') or {
        return 'Error: Query parameter is required'
    }
    
    // Implement your logic
    result := server_state.process_query(query)
    
    // Return result (markdown format recommended)
    return '# Results\n\n${result}'
}

fn (mut r ToolRegistry) register_all() {
    r.handlers['my_tool'] = handle_my_tool
    // Add more handlers...
}

4. Main Entry Point (src/main.v)

Customize startup logging and initialization:

fn main() {
    config := server.from_env()
    mut server_state := server.new_server(config)
    
    // Add your initialization logic here
    server_state.initialize() or {
        mcp.log('ERROR', 'Failed to initialize: ${err}')
        return
    }
    
    mcp.log('INFO', 'Starting My MCP Server...')
    // ... rest of the loop
}

MCP Protocol

This template implements the JSON-RPC 2.0 protocol used by MCP. The protocol module (src/mcp/mcp.v) handles:

  • Message reading/writing (stdio)
  • Request/response parsing
  • Error handling
  • Parameter extraction utilities

You don't need to modify the protocol implementation unless you need custom transport (HTTP, WebSocket, etc.).

Example Tools

The template includes two example tools:

  1. get_info: Returns server information
  2. example_tool: A template for creating new tools

Replace these with your own tool implementations.

Testing

Test your server by sending JSON-RPC requests via stdin:

echo '{"jsonrpc":"2.0","id":1,"method":"get_info","params":{}}' | ./mcp-server

Integration with MCP Clients

Cursor IDE

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "my-server": {
      "command": "/path/to/mcp-server",
      "env": {
        "LOG_LEVEL": "INFO"
      }
    }
  }
}

Other MCP Clients

The server communicates via JSON-RPC 2.0 over stdio, which is compatible with all MCP clients.

Best Practices

  1. Tool Naming: Use descriptive, action-oriented names (e.g., get_data, search_items, process_file)

  2. Error Handling: Always validate parameters and return clear error messages

  3. Response Format: Use Markdown for tool responses to enable rich formatting in clients

  4. Logging: Use mcp.log() for important events and errors

  5. Configuration: Use environment variables for configuration to keep the server flexible

  6. State Management: Keep server state in ServerState and make it thread-safe if needed

Extending the Template

Adding Caching

pub struct CacheEntry {
    data      string
    timestamp int
}

pub fn (mut s ServerState) get_cached(key string) ?string {
    entry := s.cache[key] or { return none }
    if time.now().unix - entry.timestamp > s.config.cache_ttl_seconds {
        s.cache.delete(key)
        return none
    }
    return entry.data
}

Adding File Operations

pub fn (mut s ServerState) load_data(path string) ! {
    content := os.read_file(path)!
    // Process content...
}

Adding Search Functionality

pub fn (mut s ServerState) search(query string) []SearchResult {
    // Implement search logic...
    return results
}

License

This template is provided as-is. Customize the license for your project.

Contributing

If you improve this template, consider contributing back to help others!

Resources

Example Projects

For a complete example, see:


Happy Building! 🚀

About

Vlang Based MCP Server Template

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published