maas-mcp-server
Allows AI assistants to interact with MAAS (Metal as a Service) infrastructure for machine management, network configuration, storage management, and more.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@maas-mcp-serverlist all machines"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MAAS MCP Server
A Model Context Protocol (MCP) server for interacting with MAAS (Metal as a Service) through a standardized JSON-RPC 2.0 interface.
Introduction
The MAAS MCP Server implements the Model Context Protocol specification to enable AI assistants to interact with MAAS (Metal as a Service) infrastructure. It provides a standardized interface for machine management, network configuration, storage management, and more through a JSON-RPC 2.0 API.
This server can operate in two transport modes:
HTTP/HTTPS - For web-based interactions and SSE (Server-Sent Events) streaming
stdin/stdout - For direct integration with AI assistants and CLI tools
Installation
Prerequisites
Go 1.22 or later
MAAS server with API access
MAAS API key in the format "consumer:token:secret"
With script from release
curl -sSL https://raw.githubusercontent.com/lspecian/maas-mcp-server/main/scripts/install.sh | bash
From Source
Clone the repository:
git clone https://github.com/lspecian/maas-mcp-server.git cd maas-mcp-serverBuild the server:
./build.sh buildConfigure the server:
cp config/config.yaml.example config/config.yaml cp .env.example .envEdit
config/config.yamland update:MAAS API URL
MAAS API key
Server host/port
Logging configuration
Environment Variables
The server requires the following environment variables:
MAAS_API_URL- The URL of your MAAS API endpointMAAS_API_KEY- Your MAAS API key in the format "consumer:token:secret"LOG_LEVEL- (Optional) The logging level (default: "info")LOG_FORMAT- (Optional) The logging format (default: "json")AUTH_ENABLED- (Optional) Whether authentication is enabled (default: "false")
These can be set in the .env file or directly in your environment.
Roo Integration with .roo/mcp.json
For integration with Roo, you can configure the server using the .roo/mcp.json file. Here's an example configuration:
{
"mcpServers": {
"maas-server": {
"command": "./maas-mcp-server",
"args": [
"stdio"
],
"protocol": "stdio",
"jsonrpc": "2.0",
"readyMessage": "MCP server ready",
"env": {
"MAAS_API_URL": "http://your-maas-server:5240/MAAS",
"MAAS_API_KEY": "consumer:token:secret",
"LOG_LEVEL": "debug",
"LOG_FORMAT": "json",
"AUTH_ENABLED": "false"
},
"disabled": false,
"alwaysAllow": [
"maas_list_machines",
"maas_get_machine_details",
"maas_power_on_machine",
"maas_power_off_machine",
"list_machines"
]
}
}
}The environment variables in the env section are used to configure the server. The server will read these variables and use them to configure itself.
Using Docker
Build the Docker image:
./build-docker.shRun the container:
docker run -p 8081:8081 -v $(pwd)/config:/app/config maas-mcp-server
Usage
Starting the Server
HTTP Mode
./build.sh runThe server will be available at http://localhost:8081/mcp.
stdin/stdout Mode
./build.sh run-mcp-stdioOr directly:
./maas-mcp-server stdioIn this mode, the server reads JSON-RPC requests from stdin and writes responses to stdout, making it suitable for integration with AI assistants.
Version Information
To display the version information:
./maas-mcp-server --versionJSON-RPC 2.0 Message Format
The server communicates using the JSON-RPC 2.0 protocol. Here's the basic message format:
Request
{
"jsonrpc": "2.0",
"method": "method_name",
"params": {
"param1": "value1",
"param2": "value2"
},
"id": "request-id"
}Response (Success)
{
"jsonrpc": "2.0",
"result": {
"key1": "value1",
"key2": "value2"
},
"id": "request-id"
}Response (Error)
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "Error message",
"data": {}
},
"id": "request-id"
}Discovery
To discover the capabilities of the MCP server, send a discovery request:
{
"jsonrpc": "2.0",
"method": "discover",
"params": {},
"id": "1"
}The server will respond with information about available tools and resources:
{
"jsonrpc": "2.0",
"result": [
{
"name": "maas_list_machines",
"description": "List all machines managed by MAAS with filtering and pagination",
"parameters": {
"type": "object",
"properties": {
"hostname": { "type": "string" },
"zone": { "type": "string" },
"pool": { "type": "string" },
"status": { "type": "string" },
"power_state": { "type": "string" },
"system_id": { "type": "string" },
"architecture": { "type": "string" },
"tags": { "type": "array", "items": { "type": "string" } },
"limit": { "type": "integer" },
"page": { "type": "integer" } // Example parameter, actual parameters are dynamically generated
}
}
}
// ... (list of all dynamically generated tools)
],
"id": "1"
}The list of tools is dynamically generated based on the MAAS API documentation. This provides a comprehensive set of tools for interacting with various MAAS functionalities. For details on how these tools are generated and how to update them, please refer to the MAAS API Tool Generation documentation.
Example Workflows
Listing Available Machines
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"os"
"os/exec"
)
func main() {
// Start the MCP server in stdio mode
cmd := exec.Command("./build.sh", "run-mcp-stdio")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
// Wait for server to start
reader := bufio.NewReader(stdout)
for {
line, _ := reader.ReadString('\n')
if line == "MCP server ready\n" {
break
}
}
// Send list machines request
request := map[string]interface{}{
"jsonrpc": "2.0",
"method": "maas_list_machines",
"params": map[string]interface{}{},
"id": "1",
}
requestJSON, _ := json.Marshal(request)
io.WriteString(stdin, string(requestJSON)+"\n")
// Read response
responseStr, _ := reader.ReadString('\n')
var response map[string]interface{}
json.Unmarshal([]byte(responseStr), &response)
// Pretty print the response
prettyJSON, _ := json.MarshalIndent(response, "", " ")
fmt.Println(string(prettyJSON))
cmd.Process.Kill()
}Getting Machine Details and Powering On
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"os"
"os/exec"
)
func main() {
// Start the MCP server in stdio mode
cmd := exec.Command("./build.sh", "run-mcp-stdio")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
// Wait for server to start
reader := bufio.NewReader(stdout)
for {
line, _ := reader.ReadString('\n')
if line == "MCP server ready\n" {
break
}
}
// Get machine details
detailsRequest := map[string]interface{}{
"jsonrpc": "2.0",
"method": "maas_get_machine_details",
"params": map[string]string{"system_id": "abc123"},
"id": "1",
}
requestJSON, _ := json.Marshal(detailsRequest)
io.WriteString(stdin, string(requestJSON)+"\n")
// Read response
responseStr, _ := reader.ReadString('\n')
var response map[string]interface{}
json.Unmarshal([]byte(responseStr), &response)
// Check if machine is powered off
result := response["result"].(map[string]interface{})
if result["power_state"] == "off" {
// Power on the machine
powerRequest := map[string]interface{}{
"jsonrpc": "2.0",
"method": "maas_power_on_machine",
"params": map[string]string{"system_id": "abc123"},
"id": "2",
}
requestJSON, _ = json.Marshal(powerRequest)
io.WriteString(stdin, string(requestJSON)+"\n")
// Read power on response
powerResponseStr, _ := reader.ReadString('\n')
fmt.Println(powerResponseStr)
}
cmd.Process.Kill()
}Building and Testing
Building from Source
# Build the server
./build.sh build
# Build the clean architecture version
./build.sh build-mcpRunning Tests
# Run all tests
./build.sh test
# Run specific tests
go test -v ./internal/service/...Integration Tests
# Run the test client
go run test/go/test-stdio-client.goReleases
The project uses GitHub Actions to automatically build and publish binaries for multiple platforms when a new tag is pushed to the repository.
Automatic Release Process
Update the version in
internal/version/version.goUpdate the
CHANGELOG.mdwith the changes in the new versionCommit the changes
Create and push a new tag:
git tag v1.0.0 git push origin v1.0.0The GitHub Actions workflow will automatically:
Build binaries for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64)
Create a GitHub Release with the tag name
Upload the binaries as assets
Generate SHA256 checksums for all binaries
Add release notes based on the CHANGELOG.md
Manual Release Process
You can also trigger a manual release using the GitHub Actions workflow:
Go to the GitHub repository
Click on the "Actions" tab
Select the "Manual Release" workflow
Click on "Run workflow"
Enter the version number (e.g., "1.1.0")
Select whether this is a pre-release
Click "Run workflow"
The workflow will:
Build binaries for all supported platforms
Create a GitHub Release with the specified version
Upload the binaries as assets
Generate SHA256 checksums for all binaries
Add release notes from the CHANGELOG.md
Binary Naming Convention
Binaries follow a consistent naming pattern:
maas-mcp-server-{version}-{os}-{arch}[.exe]
For example:
maas-mcp-server-1.0.0-linux-amd64maas-mcp-server-1.0.0-linux-arm64maas-mcp-server-1.0.0-darwin-amd64maas-mcp-server-1.0.0-darwin-arm64maas-mcp-server-1.0.0-windows-amd64.exe
Building for Different Platforms
You can build the server for different platforms using the Go cross-compilation feature:
# Build for Linux AMD64
GOOS=linux GOARCH=amd64 go build -o maas-mcp-server-linux-amd64 pkg/mcp/cmd/main.go
# Build for Linux ARM64
GOOS=linux GOARCH=arm64 go build -o maas-mcp-server-linux-arm64 pkg/mcp/cmd/main.go
# Build for macOS AMD64
GOOS=darwin GOARCH=amd64 go build -o maas-mcp-server-darwin-amd64 pkg/mcp/cmd/main.go
# Build for macOS ARM64 (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o maas-mcp-server-darwin-arm64 pkg/mcp/cmd/main.go
# Build for Windows AMD64
GOOS=windows GOARCH=amd64 go build -o maas-mcp-server-windows-amd64.exe pkg/mcp/cmd/main.goAPI Reference
Error Codes
Code | Message | Description |
-32700 | Parse error | Invalid JSON was received |
-32600 | Invalid request | The JSON sent is not a valid Request object |
-32601 | Method not found | The method does not exist / is not available |
-32602 | Invalid params | Invalid method parameter(s) |
-32603 | Internal error | Internal JSON-RPC error |
-32000 | Authentication failed | Failed to authenticate with MAAS |
-32001 | Rate limit exceeded | Too many requests |
-32002 | Version not supported | The requested MCP version is not supported |
-32003 | Resource not found | The requested resource was not found |
-32004 | Operation failed | The requested operation failed |
Available Methods
The available methods (tools) are discovered via the discover JSON-RPC method. The server dynamically registers a comprehensive set of tools based on the parsed MAAS API. Refer to the "Discovery" section above for an example of how to retrieve the list of available tools and their schemas.
Tool Generation
The MAAS tools provided by this server are dynamically generated from the MAAS API documentation. This ensures that the server can adapt to a wide range of MAAS API functionalities. For detailed information on how these tools are parsed, generated, and how to update them if the MAAS API changes, please see the MAAS API Tool Generation documentation in cmd/gen-tools/README.md.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/lspecian/maas-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server