trackmcp
Back to directory
mjrgr

apsystems-mcp-server

View on GitHub

A Model Context Protocol (MCP) server written in Go that wraps the APsystems OpenAPI, giving AI assistants like Claude direct access to your solar monitoring data. Includes an optional web dashboard for visual monitoring.

0 stars GoOthers Updated Mar 22, 2026

Documentation

APsystems MCP Server โ˜€๏ธ๐Ÿ›ฐ๏ธ

A production-ready Model Context Protocol (MCP) server written in Go

that wraps the APsystems OpenAPI, giving AI assistants like Claude direct access to your solar monitoring data.

Includes an optional web dashboard for visual monitoring.

Build
Go
Latest Release
Docker Pulls
Docker Image Size
Platform
License

Table of Contents

Features

  • 16 MCP tools covering all APsystems API endpoints: system details, energy summaries, ECU/inverter/meter/storage data
  • HMAC-SHA256 signature authentication โ€” implements the APsystems signature protocol
  • Built-in web dashboard โ€” dark-themed single-page app with Chart.js energy visualizations
  • Rate limiting โ€” configurable request throttling to respect API limits
  • Automatic retries โ€” exponential back-off on transient errors and rate-limit responses
  • Dual transport โ€” stdio (default) or SSE over HTTP, selectable via environment variable
  • Structured logging โ€” JSON logs via `slog` with configurable levels
  • Podman support โ€” multi-stage Containerfile for minimal production images
  • CI/CD โ€” GitHub Actions for testing, linting, and cross-platform releases

Quick Start

๐Ÿš€ Prerequisites

Before you get started, make sure you have:

๐Ÿฆซ Go (latest version recommended)

๐Ÿ”‘ APsystems OpenAPI credentials (APP_ID & APP_SECRET)

๐Ÿ†” System ID (SID) โ€” Find it in the APsystems EMA app under Settings โ†’ Account Details

How to get your API credentials

โœ‰๏ธ Email APsystems support and include:

Who you are

Why you need API access

What you plan to do with the data

๐Ÿ“ฑ Or grab them from the / APsystems EMA app:

Install & Run

bash
git clone https://github.com/mjrgr/apsystems-mcp-server.git
cd mcp-server

# Install dependencies
go mod tidy

# Set credentials
export APS_SYS_ID="your_fake_sid_1234567890"
export APS_APP_ID="your_fake_app_id_32charslong1234567890abcd"
export APS_APP_SECRET="your_fake_secret12"

# Build and run
go run ./cmd/server

With SSE Transport

By default the server uses stdio (standard input/output) for MCP communication.

Set `APS_MCP_TRANSPORT=sse` to start an HTTP server with Server-Sent Events instead:

bash
export APS_MCP_TRANSPORT=sse
export APS_MCP_SSE_ADDR=:8888     # optional, defaults to :8888
go run ./cmd/server
# SSE endpoint: http://localhost:8888/sse
# Message endpoint: http://localhost:8888/message

This is useful when you want to connect remote MCP clients over HTTP rather than running the server as a child process.

With Dashboard

bash
export APS_DASHBOARD=true
export APS_DASH_ADDR=:8080
go run ./cmd/server
# Dashboard available at http://localhost:8080

Dashboard Demo

start with Podman

bash
podman build -t apsystems-mcp -f Containerfile .
podman run --rm \
  -e APS_SYS_ID="your_fake_sid_1234567890" \
  -e APS_APP_ID="your_fake_app_id_32charslong1234567890abcd" \
  -e APS_APP_SECRET="your_fake_secret12" \
  -e APS_DASHBOARD=true \
  -p 8080:8080 \
  apsystems-mcp

To run with SSE transport instead of stdio:

bash
podman run --rm \
  -e APS_SYS_ID="your_fake_sid_1234567890" \
  -e APS_APP_ID="your_fake_app_id_32charslong1234567890abcd" \
  -e APS_APP_SECRET="your_fake_secret12" \
  -e APS_MCP_TRANSPORT=sse \
  -e APS_MCP_SSE_ADDR=:8888 \
  -e APS_DASHBOARD=true \
  -p 8888:8888 -p 8080:8080 \
  apsystems-mcp
# SSE endpoint: http://localhost:8888/sse

Table of Environment Variables

VariableRequiredExample ValueDescription
`APS_APP_ID`Yes`your_fake_app_id_32charslong1234567890abcd`32-character APsystems App ID
`APS_APP_SECRET`Yes`your_fake_secret12`12-character APsystems App Secret
`APS_SYS_ID`Yes`your_fake_sid_1234567890`System ID (SID) from EMA app, Settings โ†’ Account Details
`APS_BASE_URL`No`https://api.apsystemsema.com:9282`API base URL override
`APS_MCP_TRANSPORT`No`stdio`MCP transport: `stdio` (default) or `sse`
`APS_MCP_SSE_ADDR`No`:8888`SSE server listen address (only when `APS_MCP_TRANSPORT=sse`)
`APS_DASHBOARD`No`true`Set `true` to enable web dashboard
`APS_DASH_ADDR`No`:8080`Dashboard listen address
`APS_LOG_LEVEL`No`info`Log level: debug, info, warn, error

Security

> ๐Ÿ”’ Security Best Practices

  • Never commit real API credentials or secrets to version control. Use `.env.local` or environment variables for local development.
  • Rotate your APP_SECRET and SID if you suspect they are compromised.
  • Report vulnerabilities by opening a security issue or emailing the maintainers.
  • For production, use a secrets manager or environment injection (not plaintext files).
VariableRequiredDefaultDescription
`APS_APP_ID`Yesโ€”32-character APsystems App ID
`APS_APP_SECRET`Yesโ€”12-character APsystems App Secret
`APS_BASE_URL`No`https://api.apsystemsema.com:9282`API base URL override
`APS_SYS_ID`Noโ€”Default system identifier (`sid`) for all API calls if not provided in tool arguments
`APS_MCP_TRANSPORT`No`stdio`MCP transport: `stdio` or `sse`
`APS_MCP_SSE_ADDR`No`:8888`SSE server listen address (only when transport is `sse`)
`APS_DASHBOARD`No`false`Set `true` to enable web dashboard
`APS_DASH_ADDR`No`:8080`Dashboard listen address
`APS_LOG_LEVEL`No`info`Log level: debug, info, warn, error

MCP Tools Reference

System Tools

ToolDescription
`get_system_details`System info: capacity, timezone, ECUs, status
`get_inverters`List all ECUs and connected micro-inverters
`get_meters`List all meter IDs
`get_system_summary`Energy totals: today, month, year, lifetime (kWh)
`get_system_energy`Energy by period: hourly/daily/monthly/yearly

ECU Tools

ToolDescription
`get_ecu_summary`Energy summary for a specific ECU
`get_ecu_energy`Period energy for an ECU (supports minutely telemetry)

Inverter Tools

ToolDescription
`get_inverter_summary`Per-channel energy for a single inverter
`get_inverter_energy`Period/minutely data with DC power, current, voltage, AC telemetry
`get_inverter_batch_energy`All inverters under an ECU in one call

Meter Tools

ToolDescription
`get_meter_summary`Consumed/exported/imported/produced totals
`get_meter_period`Period energy data for a meter

Storage Tools

ToolDescription
`get_storage_latest`Live status: SOC, charge/discharge power
`get_storage_summary`Energy summary for a storage ECU
`get_storage_period`Period energy data for storage

Using with Claude Desktop

Using with Claude CLI

You can also connect this MCP server to the Claude CLI for direct, scriptable access to your solar data from the terminal.

1. Start the MCP Server

Make sure your MCP server is running and accessible (locally or remotely):

bash
go run ./cmd/server
# or with Podman/Docker as shown above

2. Configure Claude CLI

Add your MCP server to Claude CLI using the built-in command:

Podman/Docker (recommended for containerized use)

bash
claude mcp add apsystems -s local -- podman run -i --rm -p 8888:8080 -e APS_DASHBOARD=true -e APS_SYS_ID=your_fake_sid_1234567890 -e APS_APP_ID=your_fake_app_id_32charslong1234567890abcd -e APS_APP_SECRET=your_fake_secret12 docker.io/mehdijrgr/apsystems-mcp-server 2>&1

Or for Docker:

bash
claude mcp add apsystems -s local -- docker  run -i --rm -p 8888:8080 -e APS_DASHBOARD=true -e APS_SYS_ID=your_fake_sid_1234567890 -e APS_APP_ID=your_fake_app_id_32charslong1234567890abcd -e APS_APP_SECRET=your_fake_secret12 docker.io/mehdijrgr/apsystems-mcp-server 2>&1

Replace the environment variables with your actual credentials.

This will automatically update your Claude CLI configuration to include the apsystems MCP server.

3. Example Usage

Ask Claude CLI to query your solar data via the MCP server:

bash
claude ask "Show me my solar production for today"
screen_solar_today

Or use any supported MCP tool, e.g.:

bash
claude ask "List all my inverters"
screen_solar_inverters
bash
claude ask "what's the average monthly solar production?"
screen_solar_today

You can script and automate queries, integrate with other tools, or use Claude CLI in your workflows!

To use Claude Desktop with Docker or Podman, update your `claude_desktop_config.json` as follows:

json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "aps_sys_id",
      "description": "APsystems System ID"
    },
    {
      "type": "promptString",
      "id": "aps_app_id",
      "description": "APsystems App ID"
    },
    {
      "type": "promptString",
      "id": "aps_app_secret",
      "description": "APsystems App Secret",
      "password": true
    }
  ],
  "mcpServers": {
    "apsystems": {
      "command": "podman",
      "args": [
        "run", "-i", "--rm", "-p", "8888:8080",
        "-e", "APS_DASHBOARD=true",
        "-e", "APS_SYS_ID=${input:aps_sys_id}",
        "-e", "APS_APP_ID=${input:aps_app_id}",
        "-e", "APS_APP_SECRET=${input:aps_app_secret}",
        "docker.io/mehdijrgr/apsystems-mcp-server"
      ]
    }
  }
}

Or for Docker:

json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "aps_sys_id",
      "description": "APsystems System ID"
    },
    {
      "type": "promptString",
      "id": "aps_app_id",
      "description": "APsystems App ID"
    },
    {
      "type": "promptString",
      "id": "aps_app_secret",
      "description": "APsystems App Secret",
      "password": true
    }
  ],
  "mcpServers": {
    "apsystems": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm", "-p", "8888:8080",
        "-e", "APS_DASHBOARD=true",
        "-e", "APS_SYS_ID=${input:aps_sys_id}",
        "-e", "APS_APP_ID=${input:aps_app_id}",
        "-e", "APS_APP_SECRET=${input:aps_app_secret}",
        "docker.io/mehdijrgr/apsystems-mcp-server"
      ]
    }
  }
}

For SSE transport (remote/network mode), use the `url` field instead of `command`:

json
{
  "mcpServers": {
    "apsystems": {
      "url": "http://localhost:8888/sse"
    }
  }
}

You can also mount a config file or credentials as needed:

json
{
  "mcpServers": {
    "apsystems": {
      "command": "podman run -i --rm --env-file /path/to/env.local mehdijrgr/apsystems-mcp-server 2>&1",
      "env": {}
    }
  }
}

Then ask Claude things like:

  • "Show me my solar production for today"
  • "How much energy did my system produce this month?"
  • "What's the status of my inverters?"
  • "Compare my daily production this week"

Project Structure

shell
โ”œโ”€โ”€ cmd/server/          # CLI entry point
โ”œโ”€โ”€ internal/
โ”‚   โ”œโ”€โ”€ api/             # HTTP client with auth, retries, rate limiting
โ”‚   โ”œโ”€โ”€ auth/            # HMAC-SHA256 signature implementation
โ”‚   โ”œโ”€โ”€ dashboard/       # Optional web UI (embedded HTML)
โ”‚   โ”œโ”€โ”€ mcp/             # MCP tool definitions and handlers
โ”‚   โ””โ”€โ”€ models/          # Go structs for API responses
โ”œโ”€โ”€ .devcontainer/       # VS Code dev container config
โ”œโ”€โ”€ .github/workflows/   # CI/CD pipelines
โ”œโ”€โ”€ .vscode/             # Editor settings and launch configs
โ”œโ”€โ”€ Containerfile        # Multi-stage Podman/OCI build
โ”œโ”€โ”€ Makefile             # Build, test, lint targets
โ””โ”€โ”€ go.mod

Authentication Details

The APsystems API uses HMAC signature authentication. Every request includes five custom headers:

1. X-CA-AppId โ€” your application identifier

2. X-CA-Timestamp โ€” Unix timestamp in milliseconds

3. X-CA-Nonce โ€” unique 32-character hex string (UUID without dashes)

4. X-CA-Signature-Method โ€” `HmacSHA256`

5. X-CA-Signature โ€” `Base64(HMAC-SHA256(stringToSign, appSecret))`

The string to sign is composed as:

console
timestamp/nonce/appId/requestPath/HTTPMethod/HmacSHA256

where `requestPath` is the last segment of the URL path.

Development

bash
# Run tests
make test

# Lint
make lint

# Build for all platforms
make build

API Error Codes

CodeDescription
0Success
1000Data exception
1001No data
2001Invalid application account
2002Not authorized
2005Access limit exceeded
4001Invalid request parameter
5000Internal server error
7002Too many requests (auto-retried)
7003System busy (auto-retried)

Troubleshooting

> โ„น๏ธ Note: If you encounter API errors, check that your credentials (APP_ID, APP_SECRET, SID) are correct and that your account has API access enabled. If you see rate limit errors, try again later or adjust your request frequency.

  • Q: I get 'Not authorized' or 'Invalid application account' errors.
    • A: Double-check your APP_ID, APP_SECRET, and SID. Make sure your account is approved for API access by APsystems.
  • Q: Claude CLI can't connect to the MCP server.
    • A: Ensure the server is running and the address/port matches your CLI config. Check firewall or container port mappings.
  • Q: The dashboard doesn't load.
    • A: Make sure APS_DASHBOARD is set to true and the server is running. Visit the correct port in your browser.

Community & Support

  • GitHub Issues โ€” for bug reports and feature requests
  • Discussions โ€” for Q&A, ideas, and community help
  • Email: support@apsystems.com (for API credential requests)

Contributing

Contributions are welcome! To get started:

1. Fork the repository

2. Create a new branch for your feature or fix

3. Make your changes and add tests if needed

4. Open a pull request with a clear description

Please see CONTRIBUTING.md if available, or open an issue to discuss major changes first.

Frequently asked questions

What is apsystems-mcp-server?

apsystems-mcp-server is A Model Context Protocol (MCP) server written in Go that wraps the APsystems OpenAPI, giving AI assistants like Claude direct access to your solar monitoring data. Includes an optional web dashboard for visual monitoring.

How do I install apsystems-mcp-server?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is apsystems-mcp-server open source?

Yes โ€” it is hosted on GitHub at https://github.com/mjrgr/apsystems-mcp-server.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP