Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions .github/workflows/publish-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: NPM Packages CI/CD

on:
push:
branches:
- main
- master
- development
- develop
paths:
- 'packages/**'
pull_request:
branches:
- main
- master
- development
- develop
paths:
- 'packages/**'
workflow_dispatch:

permissions:
contents: read

jobs:
detect-packages:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.filter.outputs.changes }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Detect changed package paths
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
config-gen: 'packages/config-gen/**'
create-simplens-plugin: 'packages/create-simplens-plugin/**'
mcp-server: 'packages/mcp-server/**'
onboard: 'packages/onboard/**'
sdk: 'packages/sdk/**'

build-and-test:
needs: detect-packages
if: needs.detect-packages.outputs.packages != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.detect-packages.outputs.packages) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'

- name: Install package dependencies
working-directory: packages/${{ matrix.package }}
run: npm install

- name: Build package
working-directory: packages/${{ matrix.package }}
run: npm run build --if-present

- name: Run package tests (if present)
working-directory: packages/${{ matrix.package }}
run: npm test --if-present
env:
CI: true

publish:
needs: [detect-packages, build-and-test]
if: |
needs.detect-packages.outputs.packages != '[]' &&
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.detect-packages.outputs.packages) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'

- name: Check package version on NPM
id: check
working-directory: packages/${{ matrix.package }}
run: |
PKG_NAME=$(node -p "require('./package.json').name")
PKG_VERSION=$(node -p "require('./package.json').version")
echo "pkg_name=$PKG_NAME" >> $GITHUB_OUTPUT
echo "pkg_version=$PKG_VERSION" >> $GITHUB_OUTPUT

if npm view "$PKG_NAME@$PKG_VERSION" version > /dev/null 2>&1; then
echo "published=true" >> $GITHUB_OUTPUT
echo "ℹ️ Version $PKG_VERSION of $PKG_NAME is ALREADY published on NPM. Skipping publish."
else
echo "published=false" >> $GITHUB_OUTPUT
echo "🚀 Version $PKG_VERSION of $PKG_NAME is NEW! Proceeding to publish."
fi

- name: Install package dependencies
if: steps.check.outputs.published == 'false'
working-directory: packages/${{ matrix.package }}
run: npm install

- name: Build package
if: steps.check.outputs.published == 'false'
working-directory: packages/${{ matrix.package }}
run: npm run build --if-present

- name: Publish package to NPM
if: steps.check.outputs.published == 'false'
working-directory: packages/${{ matrix.package }}
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Install dependencies with `npm install` and `npm install --prefix dashboard`.
## Coding Style & Naming Conventions
Use TypeScript with strict typing and existing `@src/*` path aliases. Match current style: 2-space indentation, camelCase for variables and functions, PascalCase for types, classes, and React components, and filenames such as `notification.controller.test.ts`.

Plan changes before writing code. Follow low-level design principles: single responsibility, clear interfaces, useful dependency inversion, and explicit error handling. Do not duplicate logic; extract shared behavior into focused utilities, services, or test helpers.
Plan changes before writing code. Follow low-level design principles: single responsibility, clear interfaces, useful dependency inversion, and explicit error handling. Do not duplicate logic; extract shared behavior into focused utilities, services, or test helpers. Always use `axios` instead of the plain `fetch` API in this project.

## Testing Guidelines
Vitest is the test runner. Integration tests also use `supertest`, `mongodb-memory-server`, and Redis mocks. Name test files with `.test.ts`, for example `tests/unit/plugins/loader.test.ts`.
Expand Down
4 changes: 2 additions & 2 deletions packages/create-simplens-plugin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions packages/create-simplens-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@simplens/create-simplens-plugin",
"version": "1.0.1",
"version": "1.0.2",
"description": "CLI tool to scaffold new SimpleNS notification plugins",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -10,11 +10,11 @@
},
"scripts": {
"build": "tsc && npm run build:copy",
"build:copy": "xcopy /E /I /Y src\\templates dist\\templates",
"build:copy": "node -e \"require('fs').cpSync('src/templates', 'dist/templates', { recursive: true })\"",
"start": "node dist/index.js",
"dev": "tsx src/index.ts",
"test": "vitest run",
"test:watch": "vitest",
"test": "vitest run --config vitest.config.ts",
"test:watch": "vitest --config vitest.config.ts",
"prepublishOnly": "npm run build",
"prepare": "husky"
},
Expand Down
1 change: 0 additions & 1 deletion packages/mcp-server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ ALLOWED_ORIGINS=*
# In HTTP mode, these are passed per-request via headers
NS_API_KEY=your-api-key-here
SIMPLENS_CORE_URL=http://localhost:3000
SIMPLENS_DASHBOARD_URL=http://localhost:3002
99 changes: 72 additions & 27 deletions packages/mcp-server/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
# SimpleNS MCP Server

A Model Context Protocol (MCP) server for the SimpleNS notification engine. Allows AI assistants like Claude Desktop and Cursor to interact with your SimpleNS instance to send notifications, check analytics, and manage alerts.
A Model Context Protocol (MCP) server for the SimpleNS notification orchestration engine (`@simplens/mcp`). Enables AI assistants like Claude Desktop, Cursor, and custom MCP clients to send notifications, manage templates, query delivery logs, resolve alerts, inspect analytics, and configure channel providers.

## Features
---

- **Streamable HTTP Transport**: Local usage via npm package.
- **Stdio Transport**: Local usage via command line/npm package.
## Features

- **Tool Set**:
- `send_notification` / `send_batch_notification` (supports templates and inline content)
- `get_send_schema` — full schema docs with examples for AI agents
- `list_plugins`
- `find_failures` / `retry_failure`
- `list_alerts` / `resolve_alert`
- **Streamable HTTP Transport**: Connect remote or local MCP clients via HTTP (`/mcp`).
- **Stdio Transport**: Local execution via command line (`--stdio`).
- **Full Tool Suite (29 Tools)**: Comprehensive coverage for notifications, templates, alerts, logs, metrics, and channel configuration.

## Installation
---

No installation is required when using `npx`.
## Installation & Usage

## Usage
No pre-installation is required when using `npx`.

### Streamable HTTP (Local via npm package)

Run the server locally:

```bash
npx -y @simplens/mcp
```

The server starts default at port: `3001`
The server starts by default on port `3001`.

Then point your MCP client at the local HTTP endpoint and pass headers on every request:
Configure your MCP client:

```json
{
Expand Down Expand Up @@ -69,9 +66,9 @@ Then point your MCP client at the local HTTP endpoint and pass headers on every

### Stdio (Local via npm package)

You can run the server locally if you have SimpleNS running locally.
Run the MCP server in stdio mode alongside a running SimpleNS backend:

Add to your MCP Client config:
Add to your MCP Client configuration:

```json
{
Expand All @@ -88,15 +85,63 @@ Add to your MCP Client config:
}
```

## Tools Reference
---

## Complete Tools Reference (29 Tools)

### 1. Notification Dispatch
| Tool | Description |
| :--- | :--- |
| `send_notification` | Send a single notification via any installed channel (Email, Slack, SMS, Webhook, etc.) with inline content or template references. |
| `send_batch_notification` | Dispatch bulk notifications to multiple recipients or channels simultaneously. |

### 2. Plugin & Schema Discovery
| Tool | Description |
| :--- | :--- |
| `list_plugins` | List all active notification channel plugins installed on the SimpleNS core instance. |
| `get_send_schema` | Retrieve payload JSON schemas, required fields, and credential specifications for any channel plugin. |

### 3. Template Management
| Tool | Description |
| :--- | :--- |
| `create_template` | Create a new reusable notification template with subject and body placeholders. |
| `list_templates` | Query and list existing notification templates with pagination. |
| `get_template_by_id` | Fetch full details, metadata, and body content of a specific template. |
| `update_template` | Modify an existing notification template by ID. |
| `delete_template` | Delete a notification template from the system. |

### 4. Notification History & Logs
| Tool | Description |
| :--- | :--- |
| `list_notifications` | Query historical notification delivery logs with filtering by channel, status, recipient, or date. |
| `get_recent_notifications` | Fetch a quick snapshot of the most recent notification dispatches. |
| `get_notification_by_id` | Inspect execution details, logs, and status of a specific notification. |
| `delete_notification` | Delete a notification record from history. |

### 5. Alerts, Failures & DLQ Management
| Tool | Description |
| :--- | :--- |
| `list_alerts` | List active delivery failure alerts and dead-letter queue (DLQ) entries. |
| `delete_alert` | Dismiss or delete a specific delivery failure alert. |
| `find_failures` | Search delivery failure logs by channel, error code/message, or timeframe. |
| `retry_failure` | Manually re-queue and retry a failed notification dispatch by ID. |
| `resolve_alert_with_retry` | Resolve a failure alert and trigger an immediate notification retry. |
| `bulk_resolve_alerts` | Bulk resolve multiple delivery alerts with optional bulk retries. |

### 6. Dashboard Analytics & Metrics
| Tool | Description |
| :--- | :--- |
| `get_dashboard_stats` | Get high-level system analytics (total sent, success rate, failure rate, active channels). |
| `get_dashboard_trends` | Retrieve notification volume, error rate, and delivery latency trends over time. |

### 7. Admin Channels & Configuration
| Tool | Description |
|------|-------------|
| `send_notification` | Send a single notification via any channel (supports templates and inline content) |
| `send_batch_notification` | Send batch notifications to multiple recipients |
| `get_send_schema` | Get full request schema with examples — call before sending if unsure about format |
| `list_plugins` | List installed plugins, channels, and their schemas |
| `find_failures` | Find failed notifications with filters (channel, date, search) |
| `retry_failure` | Retry a specific failed notification by ID |
| `list_alerts` | List unresolved system alerts (ghost delivery, stuck processing) |
| `resolve_alert` | Dismiss a specific system alert |
| :--- | :--- |
| `list_admin_channel_providers` | List available channel providers (SMTP, SendGrid, Twilio, Slack Webhook, Telegram, etc.). |
| `list_admin_channels` | List all configured admin notification channels. |
| `get_admin_channel` | Retrieve configuration details and settings for a specific admin channel. |
| `create_admin_channel` | Configure and save a new admin notification channel. |
| `update_admin_channel` | Modify settings or credentials for an existing admin channel. |
| `delete_admin_channel` | Delete an admin channel configuration. |
| `test_admin_channel` | Execute a live connection and credential test for an admin channel. |
| `validate_admin_channel_config` | Validate configuration parameters against provider requirements before saving. |
Loading
Loading