npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@s-tier-building-automation/stier-mcp-server

v1.8.1

Published

MCP server for STier Web API - Niagara 4 building automation

Readme

STier MCP Server

A Model Context Protocol (MCP) server that provides tools for interacting with the STier Web API on Niagara 4 building automation stations.

Features

Read Operations

  • list_histories - List all available history IDs
  • get_history - Query history trend data with time range and pagination
  • list_alarms - List all alarm source names
  • get_alarms - Query alarms with filtering
  • get_point - Get control point details (by history ID for STierAPI, by path for OBIX)
  • get_stats - Get station statistics and system info
  • list_wiresheets - List wire sheets (component containers) in the station
  • get_wiresheet - Get detailed wire sheet with components and connections
  • get_component_slots - Get available slots for a component
  • list_component_types - List available component types by category
  • get_component_tree - Browse the component hierarchy
  • search_components - Search for components by name or type
  • execute_bql - Execute BQL (Baja Query Language) queries

Write Operations

  • create_wiresheet - Create a new wire sheet with optional components and connections
  • create_component - Add a component to an existing wire sheet
  • create_connection - Create wiring connections between components
  • delete_wiresheet - Delete a wire sheet or component
  • delete_component - Delete a component
  • set_value - Set a value on a control point
  • bulk_read - Read multiple points in one call
  • bulk_write - Write multiple points in one call

Multi-Station Operations

  • list_stations - List all configured stations (multi-station mode)
  • test_connection - Test connectivity to a station
  • obix_info - Get OBIX server information
  • obix_browse - Browse OBIX object hierarchy

Authentication & Connection

  • Supports both Basic and Digest authentication (auto-detection)
  • Automatic HTTP-to-HTTPS redirect handling
  • Self-signed certificate support for development environments

Protocol Support

The server supports two protocols for connecting to Niagara stations:

  • STierAPI - Custom module with extended features (recommended when available)
  • OBIX - Standard Niagara protocol (works with any Niagara station)

Prerequisites

  • Node.js 18 or later
  • A Niagara 4 station with the STier API module installed
  • Valid credentials for the station

Required Station Connection Type: TLS WebSocket

The STier API module is served by the station's HTTPS web service (port 443 by default). The STIER_STATION_URL must point to this HTTPS port.

⚠️ Fox ports are not supported. Niagara's Fox protocol ports (1911 for Fox, 4911 for FoxS) use a binary protocol that does not expose HTTP endpoints. The STier API and OBIX endpoints are only accessible via the HTTPS web service.

In Niagara Workbench, this corresponds to the TLS WebSocket connection type. If you see your station configured with Fox or FoxS only, ensure the HTTPSWebService is also enabled on the station and use its port in STIER_STATION_URL.

Setup

Option 1: Install via npx (Recommended)

Configure in Cursor MCP (~/.cursor/mcp.json):

{
  "mcpServers": {
    "stier-api": {
      "command": "npx",
      "args": ["@s-tier-building-automation/stier-mcp-server"],
      "env": {
        "STIER_STATION_URL": "http://localhost:8080",
        "STIER_USERNAME": "your-username",
        "STIER_PASSWORD": "your-password",
        "STIER_REJECT_UNAUTHORIZED": "false"
      }
    }
  }
}

Option 2: Local Installation

If you have the source code:

cd mcp-server
npm install
npm run build

Then configure in Cursor MCP:

{
  "mcpServers": {
    "stier-api": {
      "command": "node",
      "args": ["<path-to-repo>/mcp-server/dist/index.js"],
      "env": {
        "STIER_STATION_URL": "http://localhost:8080",
        "STIER_USERNAME": "your-username",
        "STIER_PASSWORD": "your-password",
        "STIER_REJECT_UNAUTHORIZED": "false"
      }
    }
  }
}

Note:

  • The server handles HTTP-to-HTTPS redirects automatically
  • Restart Cursor or toggle the MCP server after configuration changes

Environment Variables

The server supports two modes: Legacy Mode (single station) and Multi-Station Mode.

Legacy Mode (Single Station)

| Variable | Required | Description | |----------|----------|-------------| | STIER_STATION_URL | Yes | URL to the Niagara station (e.g., http://localhost:8080 or https://192.168.1.100) | | STIER_USERNAME | Yes | Username for station authentication | | STIER_PASSWORD | Yes | Password for station authentication | | STIER_REJECT_UNAUTHORIZED | No | Set to true to reject self-signed certificates (default: false) |

Multi-Station Mode

Multi-station mode uses a PostgreSQL database shared with the stier-chat web app. Stations are managed through the web UI and credentials are encrypted.

| Variable | Required | Description | |----------|----------|-------------| | DATABASE_URL | Yes | PostgreSQL connection string | | ENCRYPTION_KEY | Yes | 32-character key for decrypting station credentials (must match stier-chat) | | STIER_ENABLE_WRITES | No | Set to true to enable write operations (default: false) | | STIER_RATE_LIMIT | No | Requests per second per station (default: 5) | | STIER_TIMEOUT_READ_MS | No | Read operation timeout in ms (default: 5000) | | STIER_TIMEOUT_HISTORY_MS | No | History query timeout in ms (default: 30000) | | STIER_TIMEOUT_BULK_MS | No | Bulk operation timeout in ms (default: 60000) |

Note: Multi-station mode requires running from the monorepo context where Prisma has been generated for stier-chat. See .env.example for a complete template.

Available Tools

list_histories

List all available history IDs from the station.

Parameters:

  • station (optional): Filter by station name

Example:

list_histories()
list_histories(station: "MyStation")

get_history

Query history trend data with time range and pagination.

Parameters:

  • id (required): History ID to query
  • station (optional): Station name
  • start (optional): Start time in ISO 8601 format
  • end (optional): End time in ISO 8601 format
  • page (optional): Page number (default: 1)
  • pageSize (optional): Records per page (default: 500)

Example:

get_history(id: "AHU1_SupplyTemp")
get_history(id: "AHU1_SupplyTemp", start: "2025-01-01T00:00:00Z", end: "2025-01-02T00:00:00Z")

list_alarms

List all alarm source names from the station.

Parameters:

  • station (optional): Filter by station name

get_alarms

Query alarms with filtering options.

Parameters:

  • id (optional): Filter by alarm source name
  • ackState (optional): Filter by acknowledgment state
  • alarmState (optional): Filter by alarm state
  • page (optional): Page number (default: 1)
  • pageSize (optional): Records per page (default: 500)

Example:

get_alarms()
get_alarms(ackState: "unacked")
get_alarms(id: "AHU1_HighTemp", alarmState: "offnormal")

get_point

Get control point details.

Parameters:

  • path (required): Point path or history ID (e.g., "/AHU1/SupplyTemp" or "AHU1_SupplyTemp")
  • station (optional): Station name (for multi-station mode)

Protocol-Specific Behavior:

  • STierAPI stations: The path can be a history ID from list_histories or a slot path. The API resolves the point via history configuration.
  • OBIX stations: The path is treated as a point path (e.g., /config/AHU1/SupplyTemp). The API reads the point directly.

Returns: Point information including name, path, units, precision, and range facets.

get_stats

Get station statistics and system information.

Parameters: None

Returns: Object with memory usage, OS info, Java version, timezone, and other system details.

list_wiresheets

List wire sheets (component containers with control logic) in the station.

Parameters:

  • pathPrefix (optional): Filter by path prefix (e.g., "/Drivers" to list only driver wiresheets)
  • filterByType (optional): Filter by component type (e.g., "program", "control", "folder")

Example:

list_wiresheets()
list_wiresheets(pathPrefix: "/Drivers")
list_wiresheets(filterByType: "folder")

Returns: Object with success, count, and wiresheets array containing path and type for each wire sheet.

get_wiresheet

Get detailed wire sheet information including all components, their properties, positions, and wiring connections.

Parameters:

  • path (required): Full path to the wire sheet container (e.g., "/Logic/AHU1")

Example:

get_wiresheet(path: "/Drivers/NiagaraNetwork/Controller")
get_wiresheet(path: "/Logic/TemperatureControl")

Returns: Object containing:

  • exists: Whether the wire sheet was found
  • path: The wire sheet path
  • type: Component type
  • components: Array of components with name, path, type, properties, position, and children
  • connections: Array of connections with fromComponent, fromSlot, toComponent, toSlot

create_wiresheet

Create a new wire sheet with optional components and connections.

Parameters:

  • stationPath (required): Path where the wiresheet should be created (e.g., "/Logic")
  • wiresheetName (required): Name for the new wiresheet
  • wiresheetType (optional): Type of wiresheet to create (default: "baja:Folder")
  • components (optional): Array of components to create
  • connections (optional): Array of connections to create between components

Example:

create_wiresheet(
  stationPath: "/Logic",
  wiresheetName: "AHU_Control",
  wiresheetType: "baja:Folder",
  components: [
    { name: "SetPoint", type: "control:NumericPoint", position: { x: 10, y: 10 } },
    { name: "Adder", type: "kitControl:Add", position: { x: 30, y: 10 } }
  ],
  connections: [
    { fromComponent: "SetPoint", fromSlot: "out", toComponent: "Adder", toSlot: "in" }
  ]
)

Returns: Object with success, wiresheetPath, componentsCreated, and any errors.

create_component

Add a single component to an existing wire sheet.

Parameters:

  • wiresheetPath (required): Path to the parent wiresheet
  • name (required): Name for the new component
  • type (required): Component type (e.g., "control:NumericPoint", "kitControl:Add")
  • position (optional): Visual position { x, y, width, height }
  • properties (optional): Component properties to set

Example:

create_component(
  wiresheetPath: "/Logic/AHU_Control",
  name: "TempSensor",
  type: "control:NumericPoint",
  position: { x: 20, y: 30, width: 8, height: 0 },
  properties: { out: 72.5 }
)

Returns: Object with success, componentPath, and message.

create_connection

Create a wiring connection between two components.

Parameters:

  • wiresheetPath (required): Path to the wiresheet containing both components
  • fromComponent (required): Name of the source component
  • fromSlot (optional): Output slot name (default: "out")
  • toComponent (required): Name of the target component
  • toSlot (optional): Input slot name (default: "in")

Example:

create_connection(
  wiresheetPath: "/Logic/AHU_Control",
  fromComponent: "SetPoint",
  fromSlot: "out",
  toComponent: "Controller",
  toSlot: "in1"
)

Returns: Object with success, message, linkName, and available slots if errors occur.

delete_wiresheet

Delete a wire sheet or component at the specified path.

Parameters:

  • path (required): Full path to the wiresheet/component to delete

Example:

delete_wiresheet(path: "/Logic/OldController")

Returns: Object with success and message.

set_value

Set a value on a control point.

Parameters:

  • path (required): Path to the control point
  • value (required): Value to set
  • station (optional): Station name (for multi-station mode)

Example:

set_value(path: "/Drivers/AHU1/SupplyTempSP", value: 72.5)

list_stations

List all configured stations (multi-station mode only).

Returns: Array of stations with id, name, url, protocol, and isActive status.

test_connection

Test connectivity to a station.

Parameters:

  • station (required): Station name or ID

Returns: Connection status and any error details.

obix_info

Get OBIX server information (for OBIX stations).

Parameters:

  • station (optional): Station name

Returns: OBIX server version and capabilities.

obix_browse

Browse the OBIX object hierarchy.

Parameters:

  • path (optional): Path to browse (default: root)
  • station (optional): Station name

Returns: List of child objects with their types and values.

bulk_read

Read multiple points in a single call.

Parameters:

  • paths (required): Array of point paths to read
  • station (optional): Station name

Returns: Object with values for each path.

bulk_write

Write multiple points in a single call. Requires STIER_ENABLE_WRITES=true.

Parameters:

  • values (required): Object mapping paths to values
  • station (optional): Station name

Returns: Object with success status for each write.

Development

Building

npm run build

Running in Development

npm run dev

Troubleshooting

Empty Response or JSON Parse Error

This usually indicates a connection or authentication issue:

  1. Test with Postman/curl first - Verify the API works with your credentials
  2. Check the URL - Try both HTTP and HTTPS; the server follows redirects automatically
  3. Verify credentials - Ensure username/password are correct

Connection Refused

Ensure:

  1. The station URL and port are correct — use the HTTPS web service port (typically 443), not a Fox port
    • https://192.168.1.100:1911 — Fox port (binary protocol, HTTP not supported)
    • https://192.168.1.100:4911 — FoxS port (binary protocol, HTTP not supported)
    • https://192.168.1.100:443 — HTTPS web service (TLS WebSocket in Workbench)
  2. The station is running
  3. The STier API servlet is enabled in Niagara Workbench
  4. The HTTPSWebService is enabled on the station (not just FoxService)
  5. Your firewall allows the connection

SSL Certificate Errors

For self-signed certificates (common in development):

  • Set STIER_REJECT_UNAUTHORIZED to "false" in your config

Authentication Failed (Login Page Returned)

If you receive an HTML login page instead of JSON:

  1. Username and password are incorrect
  2. The user doesn't have API access permissions
  3. The STier service is not licensed

MCP Server Not Starting

  1. Ensure you've run npm run build after any code changes
  2. Verify the path in your MCP config points to dist/index.js (not src/index.ts)
  3. Check Cursor's MCP logs for error details

License

MIT