theiafiberio/alm-mcp-server
If you are the rightful owner of alm-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The ALM MCP Server provides programmatic access to Automated Link Monitoring devices for optical fiber testing and monitoring operations.
ALM MCP Server
A Model Context Protocol (MCP) server that provides programmatic access to ALM (Automated Link Monitoring) devices for optical fiber testing and monitoring operations.
Features
- Port Management (12 tools): List, read, configure ports with admin state control, remarks, priority, and monitoring settings
- Measurement Operations (10 tools):
- Start fingerprint measurements with/without reflector termination (baseline optical signatures)
- Start OTDR measurements (optical time domain reflectometry)
- Save OTDR measurements to database for history tracking
- Fault analysis (compare against baseline)
- Monitor command progress with wait/cancel capabilities
- Download measurement traces (CSV/SOR format)
- Alarm Monitoring (6 tools): Track active alarms by port, severity, get summaries and counts
- Logbook Events (5 tools): Access system events, alarm history, configuration changes, and user actions
- Configuration Management (5 tools): Read device settings, update thresholds, optical defaults, and budgets
- Link budget threshold configuration
- Loss budget (loss guidance) settings
- Optical defaults for different fiber types
- Deviation sensitivity thresholds
- Enhanced Operations (5 tools):
- Batch port updates
- Trace file downloads to local filesystem
- Measurement history with filtering
- Bulk monitoring control
- Advanced Monitoring (5 tools):
- Quick alarm summaries
- Configuration audit trails
- Advanced logbook search
- System event filtering
- Port activity tracking
- Data Retrieval (2 tools): Download trace data in multiple formats (memory or direct to file)
- Dual Transport: Supports both stdio (Claude Code) and HTTP/SSE
- MCP Protocol: Full implementation of MCP 2024-11-05 specification
- Session Management: Automatic connection handling with the ALM device
- Dual API Support: Dojo REST API for commands + Official /trace/ API for downloads
Total Coverage
49 tools providing complete coverage of ALM device capabilities
Architecture
┌─────────────┐ HTTP/SSE ┌──────────────┐
│ Claude │ ◄──────────────────────► │ MCP Server │
│ Code │ JSON-RPC 2.0 │ │
└─────────────┘ └──────┬───────┘
│
REST API
│
┌──────▼───────┐
│ ALM Device │
│ (theia-core) │
└──────────────┘
Installation
Build from Source
cd alm-mcp-server
go build -o alm-mcp-server ./cmd/server
Run with Go
go run ./cmd/server/main.go \
-alm-url "https://your-alm-device" \
-alm-username "admin" \
-alm-password "password" \
-listen "localhost:8080"
Using Environment Variables
export ALM_BASE_URL="https://your-alm-device"
export ALM_USERNAME="admin"
export ALM_PASSWORD="password"
./alm-mcp-server -listen "localhost:8080"
Configuration
Command Line Flags
-listen: HTTP server address (default:localhost:8080)-alm-url: ALM device base URL (required)-alm-username: ALM device username (required)-alm-password: ALM device password (required)-log-level: Logging level: debug, info, warn, error (default:info)
Environment Variables
ALM_BASE_URL: ALM device URLALM_USERNAME: ALM usernameALM_PASSWORD: ALM password
Available Tools
Complete list of 49 tools available in
Port Operations
alm_list_ports
List all ports on the ALM device with their configuration and status.
Arguments: None
Example Response:
{
"ports": [
{
"idports": 1,
"seq": 1,
"name": "Port-1",
"adm": 2,
"os": "1",
"mon": "t",
"alarmed": "f",
"active": true
}
],
"count": 1
}
alm_get_port
Get detailed information about a specific port.
Arguments:
port_number(integer): Port number (1-based)
alm_update_port_name
Update the name of a port.
Arguments:
port_id(integer): Port IDname(string): New port name
alm_update_port_state
Update the administrative state of a port.
Arguments:
port_id(integer): Port IDstate(integer): Admin state (2=In-Service, 4=Management, 6=Out-of-Service)
Measurement Operations
alm_start_fingerprint
Start a fingerprint measurement WITH reflector termination to capture baseline optical signature.
Use when: Fiber has reflective end connector (APC/UPC)
Arguments:
port_id(integer, required): Port IDwavelength(integer, required): Wavelength in nm (1310, 1550, or 1625)pulse_width(integer, required): Pulse width in ns (10, 20, 50, 100, 200, 500, 1000, 2000)range(integer, required): Measurement range in meters (1000-300000)refractive_index(number, optional): Refractive index (default: 1.4682 for SMF-28)link_length(integer, optional): Expected link length in meters
Example:
{
"port_id": 1,
"wavelength": 1550,
"pulse_width": 100,
"range": 50000,
"refractive_index": 1.4682
}
alm_start_fingerprint_no_reflector
Start a bidirectional fingerprint measurement WITHOUT reflector termination.
Use when: Fiber link has no reflective end (open fiber, spliced connections, PON networks)
Arguments: Same as alm_start_fingerprint
alm_start_otdr
Start an OTDR measurement to analyze fiber characteristics.
Arguments:
port_id(integer, required): Port IDwavelength(integer, required): Wavelength in nmpulse_width(integer, required): Pulse width in nsrange(integer, required): Measurement range in metersmeas_time(integer, optional): Measurement time in seconds (default: 60)refractive_index(number, optional): Refractive index (default: 1.4682)
alm_save_otdr_measurement
Save an OTDR measurement to make it available in measurement history and for download. This persists the measurement to the database after completion.
Arguments:
port_id(integer, required): Port ID where the measurement was performedmeasurement_id(integer, required): Measurement ID from command status
Example Workflow:
# 1. Start OTDR measurement
alm_start_otdr {"port_id": 2, "wavelength": 1550, "pulse_width": 100, "range": 80000}
# 2. Wait for completion
alm_wait_for_completion {"port_id": 2}
# Returns: {"measurementId": 112, "status": "Complete"}
# 3. Save the measurement
alm_save_otdr_measurement {"port_id": 2, "measurement_id": 112}
# 4. Now it's available in history and for download
alm_get_measurement_history {"port_id": 2}
alm_download_trace {"port_number": 2, "measurement_id": 112}
alm_get_command_status
Get the current status of a running command.
Arguments:
port_id(integer): Port ID
Response:
{
"commandId": "cmd-1",
"portId": 1,
"commandCode": 11,
"status": 2,
"statusText": "Running",
"progress": 45,
"measurementId": 123,
"timestamp": "2024-01-15T10:30:00Z"
}
Status Codes:
- 0 = Idle
- 1 = Queued
- 2 = Running
- 10 = Complete
- 20 = Failed
- 30 = Cancelled
alm_wait_for_completion
Wait for a command to complete, polling at intervals.
Arguments:
port_id(integer, required): Port IDtimeout_seconds(integer, optional): Maximum wait time (default: 300)poll_interval_seconds(integer, optional): Poll interval (default: 5)
alm_download_trace
Download measurement trace data into memory.
Arguments:
port_number(integer, required): Port numbermeasurement_id(integer, required): Measurement IDformat(string, optional): File format - "csv" or "sor" (default: "csv")
Returns: Trace data as text in the response
alm_download_trace_to_file
Download measurement trace data and save directly to a local file.
Arguments:
port_number(integer, required): Port numbermeasurement_id(integer, required): Measurement IDfile_path(string, required): Local file path to save trace dataformat(string, optional): File format - "f" (filtered CSV), "r" (raw CSV), "sf1" (SOR filtered), "sr1" (SOR raw) (default: "f")
Supported Formats:
f- Filtered CSV (default, cleaned trace data)r- Raw CSV (unprocessed trace data)d- Debug CSV (with additional diagnostics)sf1- SOR format, filtered, smaller pulse widthsf2- SOR format, filtered, larger pulse widthsr1- SOR format, raw, smaller pulse widthsr2- SOR format, raw, larger pulse width
Example:
{
"port_number": 2,
"measurement_id": 112,
"file_path": "/tmp/trace.csv",
"format": "f"
}
alm_get_measurement_history
Get history of measurements performed on a port with filtering options.
Arguments:
port_id(integer, optional): Filter by specific portmeasurement_type(string, optional): Filter by type (e.g., "fingerprint", "otdr", "fault_analysis")limit(integer, optional): Maximum results to return (default: 50, max: 500)
Returns:
{
"measurements": [
{
"id": 112,
"port": 2,
"type": "OTDR Measurement",
"timestamp": "2025-10-29 03:25:08",
"pulsewidth": {"1": 100},
"fiberlength": 80000
}
],
"count": 1
}
Alarm Monitoring Operations
alm_list_alarms
List all active alarms on the ALM device.
Arguments: None
Response:
{
"alarms": [
{
"port": 1,
"severity": "critical",
"timestamp": "2025-10-29T10:30:00Z",
"description": "Loss of Signal"
}
],
"count": 1
}
alm_list_alarms_by_severity
Filter alarms by severity level.
Arguments:
severity(string): Severity level - "critical", "major", "minor", or "information"
alm_get_alarms_summary
Get alarm counts grouped by severity.
Response:
{
"summary": {
"critical": 2,
"major": 5,
"minor": 8,
"information": 3
},
"total_count": 18
}
Logbook Event Operations
alm_list_logbook_events
List recent logbook events including system events, alarms, and configuration changes.
Arguments:
limit(integer, optional): Maximum number of events to return (default: 100)
Response:
{
"events": [
{
"timestamp": "2025-10-29T10:30:00",
"port": "1",
"text": "Alarm: Loss of Signal",
"severity": "critical",
"status": "SET"
}
],
"count": 1
}
alm_list_logbook_events_since
List events that occurred after a specific timestamp.
Arguments:
since(string, required): ISO 8601 timestamp (e.g., "2025-10-29T00:00:00Z")
alm_list_alarm_logbook_events
List all alarm-related events (alarm set/clear history).
Arguments: None
MCP Protocol Endpoints
HTTP Transport
Endpoint: POST /mcp
Send MCP requests as JSON-RPC 2.0 messages:
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "alm_list_ports",
"arguments": {}
}
}'
SSE Transport
Endpoint: GET /sse
Connect to the SSE endpoint for streaming communication:
const eventSource = new EventSource('http://localhost:8080/sse');
eventSource.addEventListener('message', (event) => {
const response = JSON.parse(event.data);
console.log('Response:', response);
});
eventSource.addEventListener('connected', (event) => {
console.log('Connected:', event.data);
});
Health Check
Endpoint: GET /health
curl http://localhost:8080/health
Response:
{
"status": "ok",
"name": "alm-mcp-server",
"version": "0.1.0"
}
Using with Claude Code
Add to your Claude desktop configuration at ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"alm": {
"command": "/path/to/alm-mcp-server/build/alm-mcp-server",
"args": [
"-alm-url", "https://your-alm-device",
"-alm-username", "admin",
"-alm-password", "password"
]
}
}
}
The server runs in stdio mode by default (no -listen flag) for seamless Claude Code integration.
For HTTP/SSE server mode (e.g., for testing with GoLand):
./alm-mcp-server \
-alm-url "https://your-alm-device" \
-alm-username "admin" \
-alm-password "password" \
-listen "localhost:8080"
Example Workflows
Basic Fiber Monitoring
# 1. List all ports
tools/call alm_list_ports
# 2. Update port name
tools/call alm_update_port_name {"port_id": 1, "name": "Fiber-Link-A"}
# 3. Start fingerprint measurement
tools/call alm_start_fingerprint {
"port_id": 1,
"wavelength": 1550,
"pulse_width": 100,
"range": 50000
}
# 4. Wait for completion
tools/call alm_wait_for_completion {
"port_id": 1,
"timeout_seconds": 300
}
# 5. Download trace
tools/call alm_download_trace {
"port_number": 1,
"measurement_id": 123,
"format": "csv"
}
Alarm Investigation
# 1. Get alarm overview
tools/call alm_get_alarms_summary
# 2. List critical alarms
tools/call alm_list_alarms_by_severity {"severity": "critical"}
# 3. Check specific port
tools/call alm_get_port {"port_number": 1}
# 4. Analyze the issue
tools/call alm_start_fault_analysis {"port_id": 1}
# 5. Review event history
tools/call alm_list_logbook_events_by_port {"port_number": 1}
Event History Analysis
# 1. List recent events
tools/call alm_list_logbook_events {"limit": 50}
# 2. Get alarm history
tools/call alm_list_alarm_logbook_events
# 3. Check events since specific time
tools/call alm_list_logbook_events_since {
"since": "2025-10-29T00:00:00Z"
}
# 4. Get event summary
tools/call alm_get_logbook_events_summary
Development
Project Structure
alm-mcp-server/
├── cmd/
│ └── server/
│ └── main.go # Main server application
├── internal/
│ ├── mcp/
│ │ ├── types.go # MCP protocol types
│ │ ├── server.go # MCP server implementation
│ │ └── stdio.go # Stdio transport for Claude Code
│ └── alm/
│ ├── tools.go # Core MCP tool definitions
│ ├── tools_config.go # Configuration tool definitions
│ ├── tools_extended.go # Extended tool definitions
│ ├── tools_monitoring.go # Alarm & logbook tool definitions
│ ├── handlers_config.go # Configuration handlers
│ ├── handlers_extended.go # Extended tool handlers
│ ├── handlers_monitoring.go # Alarm & logbook handlers
│ └── rest/
│ ├── client.go # HTTP client with session management
│ ├── auth.go # Authentication and login
│ ├── ports.go # Port CRUD operations
│ ├── measurements.go # Fingerprint, OTDR, fault analysis
│ ├── measurement_save.go # Save OTDR measurements
│ ├── measurements_history.go # Measurement history retrieval
│ ├── trace_download.go # Trace data download (official /trace/ API)
│ ├── alarms.go # Alarm retrieval and filtering
│ ├── logbook.go # Logbook event retrieval
│ ├── config.go # Device configuration management
│ ├── types.go # Data structures
│ ├── errors.go # Error types
│ └── constants.go # API endpoints and constants
├── build/
│ └── alm-mcp-server # Compiled binary
├── go.mod
├── README.md
└── TOOLS.md # Complete tool reference
Testing
Run the server in development mode with debug logging:
go run ./cmd/server/main.go \
-log-level debug \
-alm-url "https://your-alm-device" \
-alm-username "admin" \
-alm-password "password"
Extending
To add new tools:
- Define the tool schema in
internal/alm/tools.go - Register the tool in
RegisterTools() - Implement the handler function
- Add to the switch statement in
handleToolCall()
License
See LICENSE file for details.
Contributing
Contributions are welcome! Please open an issue or pull request.