@megamcp/sentinel 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -18
- package/dist/cli.js +18 -2
- package/dist/orchestrate.js +3 -15
- package/package.json +9 -15
- package/docs-run-production.md +0 -27
- package/run-check.ps1 +0 -13
package/README.md
CHANGED
|
@@ -6,24 +6,14 @@ It ships two ways:
|
|
|
6
6
|
- a **CLI** (`check` / `watch`) for cron and CI, and
|
|
7
7
|
- an **MCP server** (`list_targets`, `check_target`, `health_summary`) — i.e. an MCP server that monitors MCP servers.
|
|
8
8
|
|
|
9
|
-
## Quick start
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install
|
|
19
|
-
npm run build
|
|
20
|
-
|
|
21
|
-
# one-shot check of all targets (exits non-zero if any are DOWN)
|
|
22
|
-
npm run check
|
|
23
|
-
|
|
24
|
-
# or check one configured target / ad-hoc HTTP MCP endpoint
|
|
25
|
-
npm run check -- echo-sample
|
|
26
|
-
npm run check -- https://example.com/mcp
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install
|
|
13
|
+
npm run build
|
|
14
|
+
|
|
15
|
+
# one-shot check of all targets (exits non-zero if any are DOWN)
|
|
16
|
+
npm run check
|
|
27
17
|
|
|
28
18
|
# continuous watch
|
|
29
19
|
npm run watch # every 60s
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { checkTargets } from "./orchestrate.js";
|
|
3
3
|
import { renderResult, renderSummary } from "./format.js";
|
|
4
|
-
|
|
4
|
+
import { runCheck } from "./monitor.js";
|
|
5
|
+
const USAGE = "Usage: megamcp-sentinel <check|watch> [targetId|http-url] [--json]";
|
|
6
|
+
function isHttpUrl(value) {
|
|
7
|
+
return value !== undefined && /^https?:\/\//i.test(value);
|
|
8
|
+
}
|
|
9
|
+
function targetFromUrl(url) {
|
|
10
|
+
const parsed = new URL(url);
|
|
11
|
+
return {
|
|
12
|
+
id: `url-${parsed.hostname.replace(/[^a-z0-9-]/gi, "-").toLowerCase()}`,
|
|
13
|
+
label: parsed.hostname,
|
|
14
|
+
transport: { type: "http", url },
|
|
15
|
+
minTools: 1,
|
|
16
|
+
latencyBudgetMs: 5000,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
5
19
|
async function main() {
|
|
6
20
|
const argv = process.argv.slice(2);
|
|
7
21
|
const cmd = argv[0] ?? "check";
|
|
8
22
|
const asJson = argv.includes("--json");
|
|
9
23
|
const positional = argv.slice(1).filter((a) => !a.startsWith("--"));
|
|
10
24
|
if (cmd === "check") {
|
|
11
|
-
const results =
|
|
25
|
+
const results = isHttpUrl(positional[0])
|
|
26
|
+
? [(await runCheck(targetFromUrl(positional[0]), { fingerprint: null, tools: [] })).result]
|
|
27
|
+
: await checkTargets(positional[0]);
|
|
12
28
|
if (asJson) {
|
|
13
29
|
console.log(JSON.stringify(results, null, 2));
|
|
14
30
|
}
|
package/dist/orchestrate.js
CHANGED
|
@@ -9,10 +9,10 @@ export function configPath() {
|
|
|
9
9
|
* Returns the results in config order.
|
|
10
10
|
*/
|
|
11
11
|
export async function checkTargets(filterId) {
|
|
12
|
-
const targets =
|
|
13
|
-
const selected = filterId
|
|
12
|
+
const { targets } = loadConfig(configPath());
|
|
13
|
+
const selected = filterId ? targets.filter((t) => t.id === filterId) : targets;
|
|
14
14
|
if (filterId && selected.length === 0) {
|
|
15
|
-
throw new Error(`No target matched id
|
|
15
|
+
throw new Error(`No target matched id: ${filterId}`);
|
|
16
16
|
}
|
|
17
17
|
const results = [];
|
|
18
18
|
for (const target of selected) {
|
|
@@ -31,15 +31,3 @@ export async function checkTargets(filterId) {
|
|
|
31
31
|
}
|
|
32
32
|
return results;
|
|
33
33
|
}
|
|
34
|
-
function isHttpUrl(value) {
|
|
35
|
-
return /^https?:\/\//i.test(value);
|
|
36
|
-
}
|
|
37
|
-
function targetFromUrl(url) {
|
|
38
|
-
return {
|
|
39
|
-
id: url,
|
|
40
|
-
label: url,
|
|
41
|
-
transport: { type: "http", url },
|
|
42
|
-
minTools: 1,
|
|
43
|
-
latencyBudgetMs: 5000,
|
|
44
|
-
};
|
|
45
|
-
}
|
package/package.json
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@megamcp/sentinel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "MegaMCP Sentinel — an MCP server that monitors the health of other MCP servers.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist/",
|
|
9
|
-
"README.md",
|
|
10
|
-
"docs-run-production.md",
|
|
11
|
-
"run-check.ps1",
|
|
12
|
-
"sentinel.config.json"
|
|
13
|
-
],
|
|
14
|
-
"publishConfig": {
|
|
15
|
-
"access": "public",
|
|
16
|
-
"registry": "https://registry.npmjs.org/"
|
|
17
|
-
},
|
|
6
|
+
"type": "module",
|
|
18
7
|
"bin": {
|
|
8
|
+
"sentinel": "dist/cli.js",
|
|
19
9
|
"megamcp-sentinel": "dist/cli.js",
|
|
20
10
|
"megamcp-inspect": "dist/inspect.js",
|
|
21
11
|
"megamcp-sentinel-report": "dist/report.js"
|
|
22
12
|
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md",
|
|
16
|
+
"sentinel.config.json"
|
|
17
|
+
],
|
|
23
18
|
"scripts": {
|
|
24
|
-
"build": "tsc",
|
|
25
|
-
"prepack": "npm run build",
|
|
19
|
+
"build": "tsc",
|
|
26
20
|
"start": "node dist/server.js",
|
|
27
21
|
"check": "node dist/cli.js check",
|
|
28
22
|
"watch": "node dist/cli.js watch",
|
package/docs-run-production.md
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Running Sentinel in production (Windows)
|
|
2
|
-
|
|
3
|
-
`run-check.ps1` runs every configured check once and appends a timestamped JSON record to `logs/runs.jsonl`. Per-target rolling history is also kept in `state/`.
|
|
4
|
-
|
|
5
|
-
## Enable 24/7 monitoring (every 15 minutes, hidden)
|
|
6
|
-
|
|
7
|
-
Run this once in PowerShell (it sets up a recurring Scheduled Task — OS-level persistence, so it needs your authorization):
|
|
8
|
-
|
|
9
|
-
```powershell
|
|
10
|
-
schtasks /Create /TN "MegaMCP Sentinel" `
|
|
11
|
-
/TR "powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$env:USERPROFILE\Desktop\MegaMCP\sentinel\run-check.ps1`"" `
|
|
12
|
-
/SC MINUTE /MO 15 /F
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Check / run / disable
|
|
16
|
-
|
|
17
|
-
```powershell
|
|
18
|
-
schtasks /Query /TN "MegaMCP Sentinel" /FO LIST # status + next run
|
|
19
|
-
schtasks /Run /TN "MegaMCP Sentinel" # run now
|
|
20
|
-
schtasks /Delete /TN "MegaMCP Sentinel" /F # remove it
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Where results go
|
|
24
|
-
- `logs/runs.jsonl` — one JSON object per run: `{ at, results: [...] }`
|
|
25
|
-
- `state/<target>.json` — rolling per-target history + last-known tool schema (for drift)
|
|
26
|
-
|
|
27
|
-
When the hosted version ships, this same wrapper logic moves to a server-side cron / Vercel Cron / GitHub Action feeding the public status board.
|
package/run-check.ps1
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# MegaMCP Sentinel - production check wrapper (for Windows Task Scheduler).
|
|
2
|
-
# Runs all configured checks and appends one timestamped JSON line to logs\runs.jsonl.
|
|
3
|
-
$ErrorActionPreference = 'Continue'
|
|
4
|
-
$node = Join-Path $env:LOCALAPPDATA 'Programs\nodejs'
|
|
5
|
-
$env:Path = "$node;$env:Path"
|
|
6
|
-
$proj = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
|
7
|
-
Set-Location $proj
|
|
8
|
-
New-Item -ItemType Directory -Force (Join-Path $proj 'logs') | Out-Null
|
|
9
|
-
$stamp = (Get-Date).ToString('o')
|
|
10
|
-
$out = (& node 'dist\cli.js' check --json) -join "`n"
|
|
11
|
-
try { $parsed = $out | ConvertFrom-Json } catch { $parsed = @{ error = 'check failed'; raw = $out } }
|
|
12
|
-
$line = [pscustomobject]@{ at = $stamp; results = $parsed } | ConvertTo-Json -Depth 8 -Compress
|
|
13
|
-
Add-Content -Path (Join-Path $proj 'logs\runs.jsonl') -Value $line
|