chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,87 @@
import type { ToolConfig } from '@/tools/types'
import {
ALERT_CONTACT_OUTPUT_PROPERTIES,
mapAlertContact,
UPTIMEROBOT_API_BASE,
type UptimeRobotAlertContactResponse,
type UptimeRobotCreateAlertContactParams,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotCreateAlertContactTool: ToolConfig<
UptimeRobotCreateAlertContactParams,
UptimeRobotAlertContactResponse
> = {
id: 'uptimerobot_create_alert_contact',
name: 'UptimeRobot Create Alert Contact',
description:
'Create an email alert contact in UptimeRobot. The contact must be confirmed via email before it can receive alerts.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
value: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email address for the alert contact',
},
friendlyName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Display name for the alert contact',
},
enableNotificationsFor: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Which monitor events to notify for: 0, 1, 2, or 3',
},
},
request: {
url: () => `${UPTIMEROBOT_API_BASE}/alert-contacts`,
method: 'POST',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
type: 'Email',
value: params.value,
}
if (params.friendlyName) body.friendlyName = params.friendlyName
if (params.enableNotificationsFor != null) {
body.enableNotificationsFor = params.enableNotificationsFor
}
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { alertContact: mapAlertContact(data) },
}
},
outputs: {
alertContact: {
type: 'object',
description: 'The created alert contact',
properties: ALERT_CONTACT_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,108 @@
import type { ToolConfig } from '@/tools/types'
import {
buildMaintenanceWindowBody,
MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
mapMaintenanceWindow,
UPTIMEROBOT_API_BASE,
type UptimeRobotCreateMaintenanceWindowParams,
type UptimeRobotMaintenanceWindowResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotCreateMaintenanceWindowTool: ToolConfig<
UptimeRobotCreateMaintenanceWindowParams,
UptimeRobotMaintenanceWindowResponse
> = {
id: 'uptimerobot_create_maintenance_window',
name: 'UptimeRobot Create Maintenance Window',
description: 'Create a new maintenance window to suppress alerts during planned downtime',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the maintenance window',
},
interval: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Recurrence interval: once, daily, weekly, or monthly',
},
date: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Start date in YYYY-MM-DD format',
},
time: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Start time in HH:mm:ss format',
},
duration: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Duration in minutes (minimum 1)',
},
autoAddMonitors: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to automatically add all monitors to this window',
},
days: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated days for weekly (1-7) or monthly (day-of-month, -1 for last day) windows',
},
monitorIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated monitor IDs to assign to the window',
},
},
request: {
url: () => `${UPTIMEROBOT_API_BASE}/maintenance-windows`,
method: 'POST',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
body: (params) => buildMaintenanceWindowBody(params),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { maintenanceWindow: mapMaintenanceWindow(data) },
}
},
outputs: {
maintenanceWindow: {
type: 'object',
description: 'The created maintenance window',
properties: MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,205 @@
import type { ToolConfig } from '@/tools/types'
import {
buildMonitorBody,
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotCreateMonitorParams,
type UptimeRobotMonitorResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotCreateMonitorTool: ToolConfig<
UptimeRobotCreateMonitorParams,
UptimeRobotMonitorResponse
> = {
id: 'uptimerobot_create_monitor',
name: 'UptimeRobot Create Monitor',
description: 'Create a new monitor in UptimeRobot',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
friendlyName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Friendly name of the monitor',
},
type: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Monitor type: HTTP, KEYWORD, PING, PORT, HEARTBEAT, DNS, API, or UDP',
},
url: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'URL or host to monitor (not required for Heartbeat monitors)',
},
interval: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Check interval in seconds (minimum 30)',
},
checkTimeout: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Check timeout in seconds, 0-60 (HTTP, Keyword and Port monitors only)',
},
port: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Port to check, 1-65535 (required for Port and UDP monitors)',
},
keywordType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Keyword match type for Keyword monitors: ALERT_EXISTS or ALERT_NOT_EXISTS',
},
keywordValue: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Keyword to look for (Keyword monitors only)',
},
keywordCaseType: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Keyword case sensitivity: 0 (case-sensitive) or 1 (case-insensitive)',
},
httpMethodType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'HTTP method: HEAD, GET, POST, PUT, PATCH, DELETE, or OPTIONS (defaults to HEAD)',
},
authType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTTP authentication: NONE, HTTP_BASIC, DIGEST, or BEARER',
},
httpUsername: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username for HTTP authentication',
},
httpPassword: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Password for HTTP authentication',
},
gracePeriod: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Grace period in seconds, 0-86400 (Heartbeat monitors only)',
},
successHttpResponseCodes: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated success HTTP response codes (e.g. "2xx,3xx")',
},
checkSSLErrors: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to check for SSL and domain expiration errors',
},
followRedirections: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to follow redirects',
},
sslExpirationReminder: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to send SSL certificate expiration reminders',
},
domainExpirationReminder: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to send domain expiration reminders',
},
responseTimeThreshold: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Response time threshold in milliseconds, 0-60000',
},
tagNames: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated tag names to assign to the monitor',
},
assignedAlertContacts: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'JSON array of alert-contact assignments, e.g. [{"alertContactId":123,"threshold":0,"recurrence":0}]',
},
customHttpHeaders: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'JSON object of custom HTTP headers to send with the request',
},
groupId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Monitor group ID to assign the monitor to (0 for no group)',
},
},
request: {
url: () => `${UPTIMEROBOT_API_BASE}/monitors`,
method: 'POST',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
body: (params) => buildMonitorBody(params),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { monitor: mapMonitor(data) },
}
},
outputs: {
monitor: {
type: 'object',
description: 'The created monitor',
properties: MONITOR_OUTPUT_PROPERTIES,
},
},
}
+116
View File
@@ -0,0 +1,116 @@
import type { ToolConfig } from '@/tools/types'
import {
PSP_OUTPUT_PROPERTIES,
type UptimeRobotCreatePspParams,
type UptimeRobotPspResponse,
} from '@/tools/uptimerobot/types'
export const uptimeRobotCreatePspTool: ToolConfig<
UptimeRobotCreatePspParams,
UptimeRobotPspResponse
> = {
id: 'uptimerobot_create_psp',
name: 'UptimeRobot Create Status Page',
description: 'Create a public status page in UptimeRobot, optionally with a logo and icon image',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
friendlyName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the public status page',
},
monitorIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated monitor IDs to display on the page',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Status of the page: ENABLED (published) or PAUSED (unpublished)',
},
password: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Optional password protection for the page',
},
customDomain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom domain for the page (e.g. status.your-domain.com)',
},
hideUrlLinks: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to hide the "Powered by UptimeRobot" footer link',
},
noIndex: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to prevent search engines from indexing the page',
},
logo: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'Logo image (JPG/JPEG/PNG, max 150 KB)',
},
icon: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'Icon image (JPG/JPEG/PNG, max 150 KB)',
},
},
request: {
url: '/api/tools/uptimerobot/create-psp',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
apiKey: params.apiKey,
friendlyName: params.friendlyName,
monitorIds: params.monitorIds,
status: params.status,
password: params.password,
customDomain: params.customDomain,
hideUrlLinks: params.hideUrlLinks,
noIndex: params.noIndex,
logo: params.logo,
icon: params.icon,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!data.success) {
throw new Error(data.error || 'Failed to create status page')
}
return {
success: true,
output: data.output,
}
},
outputs: {
psp: {
type: 'object',
description: 'The created status page',
properties: PSP_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,54 @@
import type { ToolConfig } from '@/tools/types'
import {
UPTIMEROBOT_API_BASE,
type UptimeRobotDeleteAlertContactParams,
type UptimeRobotDeleteResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotDeleteAlertContactTool: ToolConfig<
UptimeRobotDeleteAlertContactParams,
UptimeRobotDeleteResponse
> = {
id: 'uptimerobot_delete_alert_contact',
name: 'UptimeRobot Delete Alert Contact',
description: 'Permanently delete an UptimeRobot alert contact by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
alertContactId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the alert contact to delete',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/alert-contacts/${params.alertContactId}`,
method: 'DELETE',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response, params?: UptimeRobotDeleteAlertContactParams) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
return {
success: true,
output: { deleted: true, id: params?.alertContactId ?? null },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the alert contact was deleted' },
id: { type: 'number', description: 'ID of the deleted alert contact', optional: true },
},
}
@@ -0,0 +1,57 @@
import type { ToolConfig } from '@/tools/types'
import {
UPTIMEROBOT_API_BASE,
type UptimeRobotDeleteMaintenanceWindowParams,
type UptimeRobotDeleteResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotDeleteMaintenanceWindowTool: ToolConfig<
UptimeRobotDeleteMaintenanceWindowParams,
UptimeRobotDeleteResponse
> = {
id: 'uptimerobot_delete_maintenance_window',
name: 'UptimeRobot Delete Maintenance Window',
description: 'Permanently delete an UptimeRobot maintenance window by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
maintenanceWindowId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the maintenance window to delete',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/maintenance-windows/${params.maintenanceWindowId}`,
method: 'DELETE',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (
response: Response,
params?: UptimeRobotDeleteMaintenanceWindowParams
) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
return {
success: true,
output: { deleted: true, id: params?.maintenanceWindowId ?? null },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the maintenance window was deleted' },
id: { type: 'number', description: 'ID of the deleted maintenance window', optional: true },
},
}
@@ -0,0 +1,54 @@
import type { ToolConfig } from '@/tools/types'
import {
UPTIMEROBOT_API_BASE,
type UptimeRobotDeleteMonitorParams,
type UptimeRobotDeleteResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotDeleteMonitorTool: ToolConfig<
UptimeRobotDeleteMonitorParams,
UptimeRobotDeleteResponse
> = {
id: 'uptimerobot_delete_monitor',
name: 'UptimeRobot Delete Monitor',
description: 'Permanently delete an UptimeRobot monitor by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the monitor to delete',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/monitors/${params.monitorId}`,
method: 'DELETE',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response, params?: UptimeRobotDeleteMonitorParams) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
return {
success: true,
output: { deleted: true, id: params?.monitorId ?? null },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the monitor was deleted' },
id: { type: 'number', description: 'ID of the deleted monitor', optional: true },
},
}
+54
View File
@@ -0,0 +1,54 @@
import type { ToolConfig } from '@/tools/types'
import {
UPTIMEROBOT_API_BASE,
type UptimeRobotDeletePspParams,
type UptimeRobotDeleteResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotDeletePspTool: ToolConfig<
UptimeRobotDeletePspParams,
UptimeRobotDeleteResponse
> = {
id: 'uptimerobot_delete_psp',
name: 'UptimeRobot Delete Status Page',
description: 'Permanently delete an UptimeRobot public status page by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
pspId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the status page to delete',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/psps/${params.pspId}`,
method: 'DELETE',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response, params?: UptimeRobotDeletePspParams) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
return {
success: true,
output: { deleted: true, id: params?.pspId ?? null },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the status page was deleted' },
id: { type: 'number', description: 'ID of the deleted status page', optional: true },
},
}
+54
View File
@@ -0,0 +1,54 @@
import type { ToolConfig } from '@/tools/types'
import {
ACCOUNT_OUTPUT_PROPERTIES,
mapAccount,
UPTIMEROBOT_API_BASE,
type UptimeRobotAccountResponse,
type UptimeRobotGetAccountParams,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetAccountTool: ToolConfig<
UptimeRobotGetAccountParams,
UptimeRobotAccountResponse
> = {
id: 'uptimerobot_get_account',
name: 'UptimeRobot Get Account',
description: 'Get details about the authenticated UptimeRobot account, including plan and limits',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
},
request: {
url: () => `${UPTIMEROBOT_API_BASE}/user/me`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { account: mapAccount(data) },
}
},
outputs: {
account: {
type: 'object',
description: 'The account details',
properties: ACCOUNT_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,60 @@
import type { ToolConfig } from '@/tools/types'
import {
ALERT_CONTACT_OUTPUT_PROPERTIES,
mapAlertContact,
UPTIMEROBOT_API_BASE,
type UptimeRobotAlertContactResponse,
type UptimeRobotGetAlertContactParams,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetAlertContactTool: ToolConfig<
UptimeRobotGetAlertContactParams,
UptimeRobotAlertContactResponse
> = {
id: 'uptimerobot_get_alert_contact',
name: 'UptimeRobot Get Alert Contact',
description: 'Get the details of a single UptimeRobot alert contact by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
alertContactId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the alert contact to retrieve',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/alert-contacts/${params.alertContactId}`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { alertContact: mapAlertContact(data) },
}
},
outputs: {
alertContact: {
type: 'object',
description: 'The alert contact details',
properties: ALERT_CONTACT_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,61 @@
import type { ToolConfig } from '@/tools/types'
import {
INCIDENT_DETAIL_OUTPUT_PROPERTIES,
mapIncidentDetail,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetIncidentParams,
type UptimeRobotIncidentResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetIncidentTool: ToolConfig<
UptimeRobotGetIncidentParams,
UptimeRobotIncidentResponse
> = {
id: 'uptimerobot_get_incident',
name: 'UptimeRobot Get Incident',
description: 'Get the details of a single UptimeRobot incident by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
incidentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the incident to retrieve',
},
},
request: {
url: (params) =>
`${UPTIMEROBOT_API_BASE}/incidents/${encodeURIComponent(params.incidentId.trim())}`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { incident: mapIncidentDetail(data) },
}
},
outputs: {
incident: {
type: 'object',
description: 'The incident details',
properties: INCIDENT_DETAIL_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,60 @@
import type { ToolConfig } from '@/tools/types'
import {
MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
mapMaintenanceWindow,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetMaintenanceWindowParams,
type UptimeRobotMaintenanceWindowResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetMaintenanceWindowTool: ToolConfig<
UptimeRobotGetMaintenanceWindowParams,
UptimeRobotMaintenanceWindowResponse
> = {
id: 'uptimerobot_get_maintenance_window',
name: 'UptimeRobot Get Maintenance Window',
description: 'Get the details of a single UptimeRobot maintenance window by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
maintenanceWindowId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the maintenance window to retrieve',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/maintenance-windows/${params.maintenanceWindowId}`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { maintenanceWindow: mapMaintenanceWindow(data) },
}
},
outputs: {
maintenanceWindow: {
type: 'object',
description: 'The maintenance window details',
properties: MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
},
},
}
+60
View File
@@ -0,0 +1,60 @@
import type { ToolConfig } from '@/tools/types'
import {
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetMonitorParams,
type UptimeRobotMonitorResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetMonitorTool: ToolConfig<
UptimeRobotGetMonitorParams,
UptimeRobotMonitorResponse
> = {
id: 'uptimerobot_get_monitor',
name: 'UptimeRobot Get Monitor',
description: 'Get the details of a single UptimeRobot monitor by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the monitor to retrieve',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/monitors/${params.monitorId}`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { monitor: mapMonitor(data) },
}
},
outputs: {
monitor: {
type: 'object',
description: 'The monitor details',
properties: MONITOR_OUTPUT_PROPERTIES,
},
},
}
+57
View File
@@ -0,0 +1,57 @@
import type { ToolConfig } from '@/tools/types'
import {
mapPsp,
PSP_OUTPUT_PROPERTIES,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetPspParams,
type UptimeRobotPspResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotGetPspTool: ToolConfig<UptimeRobotGetPspParams, UptimeRobotPspResponse> = {
id: 'uptimerobot_get_psp',
name: 'UptimeRobot Get Status Page',
description: 'Get the details of a single UptimeRobot public status page by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
pspId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the status page to retrieve',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/psps/${params.pspId}`,
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { psp: mapPsp(data) },
}
},
outputs: {
psp: {
type: 'object',
description: 'The status page details',
properties: PSP_OUTPUT_PROPERTIES,
},
},
}
+25
View File
@@ -0,0 +1,25 @@
export { uptimeRobotCreateAlertContactTool } from '@/tools/uptimerobot/create_alert_contact'
export { uptimeRobotCreateMaintenanceWindowTool } from '@/tools/uptimerobot/create_maintenance_window'
export { uptimeRobotCreateMonitorTool } from '@/tools/uptimerobot/create_monitor'
export { uptimeRobotCreatePspTool } from '@/tools/uptimerobot/create_psp'
export { uptimeRobotDeleteAlertContactTool } from '@/tools/uptimerobot/delete_alert_contact'
export { uptimeRobotDeleteMaintenanceWindowTool } from '@/tools/uptimerobot/delete_maintenance_window'
export { uptimeRobotDeleteMonitorTool } from '@/tools/uptimerobot/delete_monitor'
export { uptimeRobotDeletePspTool } from '@/tools/uptimerobot/delete_psp'
export { uptimeRobotGetAccountTool } from '@/tools/uptimerobot/get_account'
export { uptimeRobotGetAlertContactTool } from '@/tools/uptimerobot/get_alert_contact'
export { uptimeRobotGetIncidentTool } from '@/tools/uptimerobot/get_incident'
export { uptimeRobotGetMaintenanceWindowTool } from '@/tools/uptimerobot/get_maintenance_window'
export { uptimeRobotGetMonitorTool } from '@/tools/uptimerobot/get_monitor'
export { uptimeRobotGetPspTool } from '@/tools/uptimerobot/get_psp'
export { uptimeRobotListAlertContactsTool } from '@/tools/uptimerobot/list_alert_contacts'
export { uptimeRobotListIncidentsTool } from '@/tools/uptimerobot/list_incidents'
export { uptimeRobotListMaintenanceWindowsTool } from '@/tools/uptimerobot/list_maintenance_windows'
export { uptimeRobotListMonitorsTool } from '@/tools/uptimerobot/list_monitors'
export { uptimeRobotListPspsTool } from '@/tools/uptimerobot/list_psps'
export { uptimeRobotPauseMonitorTool } from '@/tools/uptimerobot/pause_monitor'
export { uptimeRobotStartMonitorTool } from '@/tools/uptimerobot/start_monitor'
export * from '@/tools/uptimerobot/types'
export { uptimeRobotUpdateMaintenanceWindowTool } from '@/tools/uptimerobot/update_maintenance_window'
export { uptimeRobotUpdateMonitorTool } from '@/tools/uptimerobot/update_monitor'
export { uptimeRobotUpdatePspTool } from '@/tools/uptimerobot/update_psp'
@@ -0,0 +1,74 @@
import type { ToolConfig } from '@/tools/types'
import {
ALERT_CONTACT_OUTPUT_PROPERTIES,
mapAlertContact,
UPTIMEROBOT_API_BASE,
type UptimeRobotListAlertContactsParams,
type UptimeRobotListAlertContactsResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotListAlertContactsTool: ToolConfig<
UptimeRobotListAlertContactsParams,
UptimeRobotListAlertContactsResponse
> = {
id: 'uptimerobot_list_alert_contacts',
name: 'UptimeRobot List Alert Contacts',
description: 'List the personal alert contacts in your UptimeRobot account',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
cursor: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor returned by a previous request',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.cursor != null) query.set('cursor', String(params.cursor))
const qs = query.toString()
return `${UPTIMEROBOT_API_BASE}/alert-contacts${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
const contacts = Array.isArray(data?.data) ? data.data : []
return {
success: true,
output: {
alertContacts: contacts.map(mapAlertContact),
nextLink: data?.nextLink ?? null,
},
}
},
outputs: {
alertContacts: {
type: 'array',
description: 'List of alert contacts',
items: { type: 'object', properties: ALERT_CONTACT_OUTPUT_PROPERTIES },
},
nextLink: {
type: 'string',
description: 'URL for the next page of results, or null on the last page',
optional: true,
},
},
}
@@ -0,0 +1,103 @@
import type { ToolConfig } from '@/tools/types'
import {
INCIDENT_SUMMARY_OUTPUT_PROPERTIES,
mapIncidentSummary,
UPTIMEROBOT_API_BASE,
type UptimeRobotListIncidentsParams,
type UptimeRobotListIncidentsResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotListIncidentsTool: ToolConfig<
UptimeRobotListIncidentsParams,
UptimeRobotListIncidentsResponse
> = {
id: 'uptimerobot_list_incidents',
name: 'UptimeRobot List Incidents',
description:
'List incidents across your UptimeRobot account (last 24 hours by default), with optional filters',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Filter incidents by monitor ID',
},
monitorName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter incidents by monitor name',
},
startedAfter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include incidents started after this ISO 8601 timestamp',
},
startedBefore: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include incidents started before this ISO 8601 timestamp',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor (incident ID) returned by a previous request',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.monitorId != null) query.set('monitor_id', String(params.monitorId))
if (params.monitorName) query.set('monitor_name', params.monitorName)
if (params.startedAfter) query.set('started_after', params.startedAfter)
if (params.startedBefore) query.set('started_before', params.startedBefore)
if (params.cursor) query.set('cursor', params.cursor)
const qs = query.toString()
return `${UPTIMEROBOT_API_BASE}/incidents${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
const incidents = Array.isArray(data?.data) ? data.data : []
return {
success: true,
output: {
incidents: incidents.map(mapIncidentSummary),
nextLink: data?.nextLink ?? null,
},
}
},
outputs: {
incidents: {
type: 'array',
description: 'List of incidents',
items: { type: 'object', properties: INCIDENT_SUMMARY_OUTPUT_PROPERTIES },
},
nextLink: {
type: 'string',
description: 'URL for the next page of results, or null on the last page',
optional: true,
},
},
}
@@ -0,0 +1,74 @@
import type { ToolConfig } from '@/tools/types'
import {
MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
mapMaintenanceWindow,
UPTIMEROBOT_API_BASE,
type UptimeRobotListMaintenanceWindowsParams,
type UptimeRobotListMaintenanceWindowsResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotListMaintenanceWindowsTool: ToolConfig<
UptimeRobotListMaintenanceWindowsParams,
UptimeRobotListMaintenanceWindowsResponse
> = {
id: 'uptimerobot_list_maintenance_windows',
name: 'UptimeRobot List Maintenance Windows',
description: 'List maintenance windows in your UptimeRobot account',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor returned by a previous request',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.cursor) query.set('cursor', params.cursor)
const qs = query.toString()
return `${UPTIMEROBOT_API_BASE}/maintenance-windows${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
const windows = Array.isArray(data?.data) ? data.data : []
return {
success: true,
output: {
maintenanceWindows: windows.map(mapMaintenanceWindow),
nextLink: data?.nextLink ?? null,
},
}
},
outputs: {
maintenanceWindows: {
type: 'array',
description: 'List of maintenance windows',
items: { type: 'object', properties: MAINTENANCE_WINDOW_OUTPUT_PROPERTIES },
},
nextLink: {
type: 'string',
description: 'URL for the next page of results, or null on the last page',
optional: true,
},
},
}
+116
View File
@@ -0,0 +1,116 @@
import type { ToolConfig } from '@/tools/types'
import {
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotListMonitorsParams,
type UptimeRobotListMonitorsResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotListMonitorsTool: ToolConfig<
UptimeRobotListMonitorsParams,
UptimeRobotListMonitorsResponse
> = {
id: 'uptimerobot_list_monitors',
name: 'UptimeRobot List Monitors',
description: 'List monitors in your UptimeRobot account, with optional filters and pagination',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of monitors per page (1-200, default 50)',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated statuses to filter by (PAUSED, STARTED, UP, LOOKS_DOWN, DOWN)',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Partial friendly-name filter',
},
url: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Partial URL filter',
},
tags: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated tags to filter by (case-sensitive, OR logic)',
},
groupId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Monitor group ID to filter by',
},
cursor: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor returned by a previous request',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.limit != null) query.set('limit', String(params.limit))
if (params.status) query.set('status', params.status)
if (params.name) query.set('name', params.name)
if (params.url) query.set('url', params.url)
if (params.tags) query.set('tags', params.tags)
if (params.groupId != null) query.set('groupId', String(params.groupId))
if (params.cursor != null) query.set('cursor', String(params.cursor))
const qs = query.toString()
return `${UPTIMEROBOT_API_BASE}/monitors${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
const monitors = Array.isArray(data?.data) ? data.data : []
return {
success: true,
output: {
monitors: monitors.map(mapMonitor),
nextLink: data?.nextLink ?? null,
},
}
},
outputs: {
monitors: {
type: 'array',
description: 'List of monitors',
items: { type: 'object', properties: MONITOR_OUTPUT_PROPERTIES },
},
nextLink: {
type: 'string',
description: 'URL for the next page of results, or null on the last page',
optional: true,
},
},
}
+74
View File
@@ -0,0 +1,74 @@
import type { ToolConfig } from '@/tools/types'
import {
mapPsp,
PSP_OUTPUT_PROPERTIES,
UPTIMEROBOT_API_BASE,
type UptimeRobotListPspsParams,
type UptimeRobotListPspsResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotListPspsTool: ToolConfig<
UptimeRobotListPspsParams,
UptimeRobotListPspsResponse
> = {
id: 'uptimerobot_list_psps',
name: 'UptimeRobot List Status Pages',
description: 'List the public status pages in your UptimeRobot account',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
cursor: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor returned by a previous request',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.cursor != null) query.set('cursor', String(params.cursor))
const qs = query.toString()
return `${UPTIMEROBOT_API_BASE}/psps${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => uptimeRobotHeaders(params.apiKey),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
const psps = Array.isArray(data?.data) ? data.data : []
return {
success: true,
output: {
psps: psps.map(mapPsp),
nextLink: data?.nextLink ?? null,
},
}
},
outputs: {
psps: {
type: 'array',
description: 'List of public status pages',
items: { type: 'object', properties: PSP_OUTPUT_PROPERTIES },
},
nextLink: {
type: 'string',
description: 'URL for the next page of results, or null on the last page',
optional: true,
},
},
}
@@ -0,0 +1,63 @@
import type { ToolConfig } from '@/tools/types'
import {
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetMonitorParams,
type UptimeRobotMonitorResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotPauseMonitorTool: ToolConfig<
UptimeRobotGetMonitorParams,
UptimeRobotMonitorResponse
> = {
id: 'uptimerobot_pause_monitor',
name: 'UptimeRobot Pause Monitor',
description: 'Pause an UptimeRobot monitor so it stops running checks',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the monitor to pause',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/monitors/${params.monitorId}/pause`,
method: 'POST',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { monitor: mapMonitor(data) },
}
},
outputs: {
monitor: {
type: 'object',
description: 'The paused monitor',
properties: MONITOR_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,63 @@
import type { ToolConfig } from '@/tools/types'
import {
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotGetMonitorParams,
type UptimeRobotMonitorResponse,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotStartMonitorTool: ToolConfig<
UptimeRobotGetMonitorParams,
UptimeRobotMonitorResponse
> = {
id: 'uptimerobot_start_monitor',
name: 'UptimeRobot Start Monitor',
description: 'Resume a paused UptimeRobot monitor so it starts running checks again',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the monitor to start',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/monitors/${params.monitorId}/start`,
method: 'POST',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { monitor: mapMonitor(data) },
}
},
outputs: {
monitor: {
type: 'object',
description: 'The started monitor',
properties: MONITOR_OUTPUT_PROPERTIES,
},
},
}
+969
View File
@@ -0,0 +1,969 @@
import { getErrorMessage } from '@sim/utils/errors'
import type { OutputProperty, ToolResponse } from '@/tools/types'
/** Base URL for the UptimeRobot v3 REST API. */
export const UPTIMEROBOT_API_BASE = 'https://api.uptimerobot.com/v3'
/** Every UptimeRobot tool authenticates with the account API key as a Bearer token. */
interface UptimeRobotBaseParams {
apiKey: string
}
/**
* Builds the standard Bearer auth headers shared by every UptimeRobot request.
*/
export function uptimeRobotHeaders(apiKey: string): Record<string, string> {
return {
Authorization: `Bearer ${apiKey}`,
Accept: 'application/json',
}
}
/**
* Extracts a human-readable error message from a non-OK UptimeRobot response.
* The v3 API returns `{ error: true, message: string }` on failures.
*/
export async function uptimeRobotError(response: Response): Promise<string> {
const text = await response.text()
try {
const parsed = JSON.parse(text)
if (parsed?.message) return String(parsed.message)
} catch {
// Fall through to the raw body.
}
return text || `UptimeRobot API error (HTTP ${response.status})`
}
// region Shared object shapes
export interface UptimeRobotTag {
id: number
name: string
color: string | null
}
export interface UptimeRobotAssignedAlertContact {
alertContactId: number
threshold: number
recurrence: number
}
export interface UptimeRobotLastIncident {
id: string
status: string | null
cause: number | null
reason: string | null
startedAt: string | null
duration: number | null
}
export interface UptimeRobotMonitor {
id: number
friendlyName: string
url: string | null
type: string | null
status: string | null
interval: number | null
timeout: number | null
port: number | null
keywordType: string | null
keywordValue: string | null
httpMethodType: string | null
authType: string | null
successHttpResponseCodes: string[]
checkSSLErrors: boolean | null
followRedirections: boolean | null
sslExpirationReminder: boolean | null
domainExpirationReminder: boolean | null
responseTimeThreshold: number | null
currentStateDuration: number | null
lastIncidentId: string | null
groupId: number | null
tags: UptimeRobotTag[]
assignedAlertContacts: UptimeRobotAssignedAlertContact[]
lastIncident: UptimeRobotLastIncident | null
createDateTime: string | null
}
export interface UptimeRobotMaintenanceWindow {
id: number
userId: number | null
name: string
interval: string | null
date: string | null
time: string | null
duration: number | null
autoAddMonitors: boolean | null
monitorIds: number[]
days: number[]
status: string | null
created: string | null
}
export interface UptimeRobotAlertContact {
id: number
friendlyName: string | null
type: string | null
value: string | null
customValue: string | null
status: string | null
enableNotificationsFor: number | string | null
sslExpirationReminder: boolean | null
}
export interface UptimeRobotPsp {
id: number
friendlyName: string
customDomain: string | null
isPasswordSet: boolean | null
monitorIds: number[]
tagIds: number[]
monitorsCount: number | null
status: string | null
urlKey: string | null
homepageLink: string | null
gaCode: string | null
icon: string | null
logo: string | null
noIndex: boolean | null
hideUrlLinks: boolean | null
subscription: boolean | null
}
export interface UptimeRobotIncidentSummary {
id: string
status: string | null
type: string | null
cause: number | null
reason: string | null
monitorId: number | null
monitorName: string | null
commentsCount: number | null
startedAt: string | null
resolvedAt: string | null
duration: number | null
includeInReports: boolean | null
}
export interface UptimeRobotIncidentRootCause {
url: string | null
httpResponseCode: number | null
responseDownloadUrl: string | null
}
export interface UptimeRobotIncidentDetail {
id: string
status: string | null
cause: number | null
reason: string | null
duration: number | null
startedAt: string | null
resolvedAt: string | null
rootCause: UptimeRobotIncidentRootCause | null
}
export interface UptimeRobotAccount {
email: string | null
fullName: string | null
monitorsCount: number | null
monitorLimit: number | null
smsCredits: number | null
plan: string | null
subscriptionStatus: string | null
subscriptionExpiresAt: string | null
}
// endregion
// region Raw API value coercion helpers
type Raw = Record<string, unknown>
function asString(value: unknown): string | null {
return typeof value === 'string' ? value : null
}
function asNumber(value: unknown): number | null {
return typeof value === 'number' ? value : null
}
function asBoolean(value: unknown): boolean | null {
return typeof value === 'boolean' ? value : null
}
function asEnum(value: unknown): string | null {
return typeof value === 'string' ? value : null
}
function asObject(value: unknown): Raw | null {
return value && typeof value === 'object' && !Array.isArray(value) ? (value as Raw) : null
}
function asArray(value: unknown): unknown[] {
return Array.isArray(value) ? value : []
}
// endregion
// region Request body builders
/** Splits a comma-separated string into trimmed, non-empty parts. */
function parseCsv(value: unknown): string[] | undefined {
if (Array.isArray(value)) return value.map((v) => String(v).trim()).filter(Boolean)
if (typeof value !== 'string') return undefined
const parts = value
.split(',')
.map((part) => part.trim())
.filter(Boolean)
return parts.length > 0 ? parts : undefined
}
/** Splits a comma-separated string of integers into a number array. */
function parseNumberCsv(value: unknown): number[] | undefined {
const parts = parseCsv(value)
if (!parts) return undefined
const numbers = parts.map(Number).filter((n) => !Number.isNaN(n))
return numbers.length > 0 ? numbers : undefined
}
/**
* Parses a JSON string (or passes through an already-parsed value). Throws a
* descriptive error on malformed JSON so a user-supplied value is never silently
* dropped from the request body.
*/
function parseJson(value: unknown, field: string): unknown {
if (value == null || value === '') return undefined
if (typeof value !== 'string') return value
try {
return JSON.parse(value)
} catch (error) {
throw new Error(`Invalid JSON in "${field}": ${getErrorMessage(error, 'could not parse')}`)
}
}
function assignDefined(body: Record<string, unknown>, key: string, value: unknown): void {
if (value !== undefined && value !== null && value !== '') {
body[key] = value
}
}
/**
* Builds the JSON body for create/update monitor requests. UptimeRobot uses the
* same field set for both; `PATCH` simply omits the fields the caller leaves out.
*/
export function buildMonitorBody(
params: Partial<UptimeRobotCreateMonitorParams>
): Record<string, unknown> {
const body: Record<string, unknown> = {}
assignDefined(body, 'friendlyName', params.friendlyName)
assignDefined(body, 'type', params.type)
assignDefined(body, 'url', params.url)
assignDefined(body, 'interval', params.interval)
// `checkTimeout` is the API's `timeout` (seconds). The param is renamed to
// avoid the tool runner's reserved `timeout` (outbound HTTP-client timeout).
assignDefined(body, 'timeout', params.checkTimeout)
assignDefined(body, 'port', params.port)
assignDefined(body, 'keywordType', params.keywordType)
assignDefined(body, 'keywordValue', params.keywordValue)
assignDefined(body, 'keywordCaseType', params.keywordCaseType)
assignDefined(body, 'httpMethodType', params.httpMethodType)
assignDefined(body, 'authType', params.authType)
assignDefined(body, 'httpUsername', params.httpUsername)
assignDefined(body, 'httpPassword', params.httpPassword)
assignDefined(body, 'gracePeriod', params.gracePeriod)
assignDefined(body, 'responseTimeThreshold', params.responseTimeThreshold)
assignDefined(body, 'checkSSLErrors', params.checkSSLErrors)
assignDefined(body, 'followRedirections', params.followRedirections)
assignDefined(body, 'sslExpirationReminder', params.sslExpirationReminder)
assignDefined(body, 'domainExpirationReminder', params.domainExpirationReminder)
assignDefined(body, 'groupId', params.groupId)
assignDefined(body, 'successHttpResponseCodes', parseCsv(params.successHttpResponseCodes))
assignDefined(body, 'tagNames', parseCsv(params.tagNames))
assignDefined(
body,
'assignedAlertContacts',
parseJson(params.assignedAlertContacts, 'assignedAlertContacts')
)
assignDefined(body, 'customHttpHeaders', parseJson(params.customHttpHeaders, 'customHttpHeaders'))
return body
}
/** Builds the JSON body for create/update maintenance window requests. */
export function buildMaintenanceWindowBody(
params: Partial<UptimeRobotCreateMaintenanceWindowParams> & { status?: string }
): Record<string, unknown> {
const body: Record<string, unknown> = {}
assignDefined(body, 'name', params.name)
assignDefined(body, 'interval', params.interval)
assignDefined(body, 'date', params.date)
assignDefined(body, 'time', params.time)
assignDefined(body, 'duration', params.duration)
assignDefined(body, 'autoAddMonitors', params.autoAddMonitors)
assignDefined(body, 'days', parseNumberCsv(params.days))
assignDefined(body, 'monitorIds', parseNumberCsv(params.monitorIds))
assignDefined(body, 'status', params.status)
return body
}
// endregion
// region Mappers (raw API JSON -> typed output objects)
export function mapMonitor(raw: Raw): UptimeRobotMonitor {
const lastIncident = asObject(raw.lastIncident)
return {
id: asNumber(raw.id) ?? 0,
friendlyName: asString(raw.friendlyName) ?? '',
url: asString(raw.url),
type: asEnum(raw.type),
status: asEnum(raw.status),
interval: asNumber(raw.interval),
timeout: asNumber(raw.timeout),
port: asNumber(raw.port),
keywordType: asEnum(raw.keywordType),
keywordValue: asString(raw.keywordValue),
httpMethodType: asEnum(raw.httpMethodType),
authType: asEnum(raw.authType),
successHttpResponseCodes: asArray(raw.successHttpResponseCodes).filter(
(code): code is string => typeof code === 'string'
),
checkSSLErrors: asBoolean(raw.checkSSLErrors),
followRedirections: asBoolean(raw.followRedirections),
sslExpirationReminder: asBoolean(raw.sslExpirationReminder),
domainExpirationReminder: asBoolean(raw.domainExpirationReminder),
responseTimeThreshold: asNumber(raw.responseTimeThreshold),
currentStateDuration: asNumber(raw.currentStateDuration),
lastIncidentId: asString(raw.lastIncidentId),
groupId: asNumber(raw.groupId),
tags: asArray(raw.tags).map((tag) => {
const t = asObject(tag) ?? {}
return {
id: asNumber(t.id) ?? 0,
name: asString(t.name) ?? '',
color: asString(t.color),
}
}),
assignedAlertContacts: asArray(raw.assignedAlertContacts).map((contact) => {
const c = asObject(contact) ?? {}
return {
alertContactId: asNumber(c.alertContactId) ?? 0,
threshold: asNumber(c.threshold) ?? 0,
recurrence: asNumber(c.recurrence) ?? 0,
}
}),
lastIncident: lastIncident
? {
id: asString(lastIncident.id) ?? '',
status: asEnum(lastIncident.status),
cause: asNumber(lastIncident.cause),
reason: asString(lastIncident.reason),
startedAt: asString(lastIncident.startedAt),
duration: asNumber(lastIncident.duration),
}
: null,
createDateTime: asString(raw.createDateTime),
}
}
export function mapMaintenanceWindow(raw: Raw): UptimeRobotMaintenanceWindow {
return {
id: asNumber(raw.id) ?? 0,
userId: asNumber(raw.userId),
name: asString(raw.name) ?? '',
interval: asEnum(raw.interval),
date: asString(raw.date),
time: asString(raw.time),
duration: asNumber(raw.duration),
autoAddMonitors: asBoolean(raw.autoAddMonitors),
monitorIds: asArray(raw.monitorIds).filter((id): id is number => typeof id === 'number'),
days: asArray(raw.days).filter((day): day is number => typeof day === 'number'),
status: asEnum(raw.status),
created: asString(raw.created),
}
}
export function mapAlertContact(raw: Raw): UptimeRobotAlertContact {
const notify = raw.enableNotificationsFor
return {
id: asNumber(raw.id) ?? 0,
friendlyName: asString(raw.friendlyName),
type: asEnum(raw.type),
value: asString(raw.value),
customValue: asString(raw.customValue),
status: asEnum(raw.status),
enableNotificationsFor:
typeof notify === 'number' || typeof notify === 'string' ? notify : null,
sslExpirationReminder: asBoolean(raw.sslExpirationReminder),
}
}
export function mapPsp(raw: Raw): UptimeRobotPsp {
return {
id: asNumber(raw.id) ?? 0,
friendlyName: asString(raw.friendlyName) ?? '',
customDomain: asString(raw.customDomain),
isPasswordSet: asBoolean(raw.isPasswordSet),
monitorIds: asArray(raw.monitorIds).filter((id): id is number => typeof id === 'number'),
tagIds: asArray(raw.tagIds).filter((id): id is number => typeof id === 'number'),
monitorsCount: asNumber(raw.monitorsCount),
status: asEnum(raw.status),
urlKey: asString(raw.urlKey),
homepageLink: asString(raw.homepageLink),
gaCode: asString(raw.gaCode),
icon: asString(raw.icon),
logo: asString(raw.logo),
noIndex: asBoolean(raw.noIndex),
hideUrlLinks: asBoolean(raw.hideUrlLinks),
subscription: asBoolean(raw.subscription),
}
}
export function mapIncidentSummary(raw: Raw): UptimeRobotIncidentSummary {
const monitor = asObject(raw.monitor) ?? {}
return {
id: asString(raw.id) ?? '',
status: asEnum(raw.status),
type: asEnum(raw.type),
cause: asNumber(raw.cause),
reason: asString(raw.reason),
monitorId: asNumber(monitor.id),
monitorName: asString(monitor.friendlyName),
commentsCount: asNumber(raw.commentsCount),
startedAt: asString(raw.startedAt),
resolvedAt: asString(raw.resolvedAt),
duration: asNumber(raw.duration),
includeInReports: asBoolean(raw.includeInReports),
}
}
export function mapIncidentDetail(raw: Raw): UptimeRobotIncidentDetail {
const rootCause = asObject(raw.rootCause)
return {
id: asString(raw.id) ?? '',
status: asEnum(raw.status),
cause: asNumber(raw.cause),
reason: asString(raw.reason),
duration: asNumber(raw.duration),
startedAt: asString(raw.startedAt),
resolvedAt: asString(raw.resolvedAt),
rootCause: rootCause
? {
url: asString(rootCause.url),
httpResponseCode: asNumber(rootCause.httpResponseCode),
responseDownloadUrl: asString(rootCause.responseDownloadUrl),
}
: null,
}
}
export function mapAccount(raw: Raw): UptimeRobotAccount {
const subscription = asObject(raw.activeSubscription) ?? {}
return {
email: asString(raw.email),
fullName: asString(raw.fullName),
monitorsCount: asNumber(raw.monitorsCount),
monitorLimit: asNumber(raw.monitorLimit),
smsCredits: asNumber(raw.smsCredits),
plan: asString(subscription.plan),
subscriptionStatus: asString(subscription.status),
subscriptionExpiresAt: asString(subscription.expirationDate),
}
}
// endregion
// region Output property definitions (shared by tool `outputs`)
export const MONITOR_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Monitor ID' },
friendlyName: { type: 'string', description: 'Friendly name of the monitor' },
url: { type: 'string', description: 'Monitored URL or host', nullable: true },
type: {
type: 'string',
description: 'Monitor type (HTTP, KEYWORD, PING, PORT, HEARTBEAT, DNS, API, UDP)',
nullable: true,
},
status: {
type: 'string',
description: 'Current status (UP, DOWN, PAUSED, etc.)',
nullable: true,
},
interval: { type: 'number', description: 'Check interval in seconds', nullable: true },
timeout: { type: 'number', description: 'Check timeout in seconds', nullable: true },
port: { type: 'number', description: 'Port for Port/UDP monitors', nullable: true },
keywordType: {
type: 'string',
description: 'Keyword match type for Keyword monitors',
nullable: true,
},
keywordValue: {
type: 'string',
description: 'Keyword to match for Keyword monitors',
nullable: true,
},
httpMethodType: { type: 'string', description: 'HTTP method used for the check', nullable: true },
authType: { type: 'string', description: 'HTTP authentication method', nullable: true },
successHttpResponseCodes: {
type: 'array',
description: 'HTTP response codes treated as success',
items: { type: 'string' },
},
checkSSLErrors: {
type: 'boolean',
description: 'Whether SSL/domain expiration errors are checked',
nullable: true,
},
followRedirections: {
type: 'boolean',
description: 'Whether redirects are followed',
nullable: true,
},
sslExpirationReminder: {
type: 'boolean',
description: 'Whether SSL expiration reminders are enabled',
nullable: true,
},
domainExpirationReminder: {
type: 'boolean',
description: 'Whether domain expiration reminders are enabled',
nullable: true,
},
responseTimeThreshold: {
type: 'number',
description: 'Response time threshold in milliseconds',
nullable: true,
},
currentStateDuration: {
type: 'number',
description: 'Seconds spent in the current state',
nullable: true,
},
lastIncidentId: { type: 'string', description: 'ID of the most recent incident', nullable: true },
groupId: { type: 'number', description: 'Monitor group ID (0 if ungrouped)', nullable: true },
createDateTime: { type: 'string', description: 'When the monitor was created', nullable: true },
tags: {
type: 'array',
description: 'Tags assigned to the monitor',
items: {
type: 'object',
properties: {
id: { type: 'number', description: 'Tag ID' },
name: { type: 'string', description: 'Tag name' },
color: { type: 'string', description: 'Tag color', nullable: true },
},
},
},
assignedAlertContacts: {
type: 'array',
description: 'Alert contacts assigned to the monitor',
items: {
type: 'object',
properties: {
alertContactId: { type: 'number', description: 'Alert contact ID' },
threshold: { type: 'number', description: 'Notification delay threshold in minutes' },
recurrence: { type: 'number', description: 'Repeat notification interval in minutes' },
},
},
},
lastIncident: {
type: 'object',
description: 'Details of the most recent incident',
nullable: true,
properties: {
id: { type: 'string', description: 'Incident ID' },
status: { type: 'string', description: 'Incident status', nullable: true },
cause: { type: 'number', description: 'Incident cause code', nullable: true },
reason: { type: 'string', description: 'Incident reason', nullable: true },
startedAt: { type: 'string', description: 'When the incident started', nullable: true },
duration: { type: 'number', description: 'Incident duration in seconds', nullable: true },
},
},
} as const satisfies Record<string, OutputProperty>
export const MAINTENANCE_WINDOW_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Maintenance window ID' },
userId: { type: 'number', description: 'Owner user ID', nullable: true },
name: { type: 'string', description: 'Maintenance window name' },
interval: {
type: 'string',
description: 'Recurrence interval (once, daily, weekly, monthly)',
nullable: true,
},
date: { type: 'string', description: 'Start date (YYYY-MM-DD)', nullable: true },
time: { type: 'string', description: 'Start time (HH:mm:ss)', nullable: true },
duration: { type: 'number', description: 'Duration in minutes', nullable: true },
autoAddMonitors: {
type: 'boolean',
description: 'Whether all monitors are auto-added',
nullable: true,
},
monitorIds: { type: 'array', description: 'Assigned monitor IDs', items: { type: 'number' } },
days: {
type: 'array',
description: 'Days for weekly/monthly recurrence',
items: { type: 'number' },
},
status: { type: 'string', description: 'Status (active or paused)', nullable: true },
created: {
type: 'string',
description: 'When the maintenance window was created',
nullable: true,
},
} as const satisfies Record<string, OutputProperty>
export const ALERT_CONTACT_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Alert contact ID' },
friendlyName: { type: 'string', description: 'Display name', nullable: true },
type: { type: 'string', description: 'Alert contact type', nullable: true },
value: { type: 'string', description: 'Contact value (e.g. email address)', nullable: true },
customValue: {
type: 'string',
description: 'Custom value for webhook-style contacts',
nullable: true,
},
status: { type: 'string', description: 'Activation status', nullable: true },
enableNotificationsFor: {
type: 'string',
description: 'Which monitor events trigger notifications',
nullable: true,
},
sslExpirationReminder: {
type: 'boolean',
description: 'Whether SSL expiration reminders are enabled',
nullable: true,
},
} as const satisfies Record<string, OutputProperty>
export const PSP_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Public status page ID' },
friendlyName: { type: 'string', description: 'Status page name' },
customDomain: { type: 'string', description: 'Custom domain', nullable: true },
isPasswordSet: {
type: 'boolean',
description: 'Whether the page is password protected',
nullable: true,
},
monitorIds: {
type: 'array',
description: 'Monitor IDs shown on the page',
items: { type: 'number' },
},
tagIds: { type: 'array', description: 'Tag IDs shown on the page', items: { type: 'number' } },
monitorsCount: { type: 'number', description: 'Number of monitors on the page', nullable: true },
status: { type: 'string', description: 'Status (ENABLED or PAUSED)', nullable: true },
urlKey: { type: 'string', description: 'Public URL key', nullable: true },
homepageLink: { type: 'string', description: 'Homepage link target', nullable: true },
gaCode: { type: 'string', description: 'Google Analytics code', nullable: true },
icon: { type: 'string', description: 'Icon URL', nullable: true },
logo: { type: 'string', description: 'Logo URL', nullable: true },
noIndex: {
type: 'boolean',
description: 'Whether search engine indexing is disabled',
nullable: true,
},
hideUrlLinks: {
type: 'boolean',
description: 'Whether the "Powered by" footer link is hidden',
nullable: true,
},
subscription: {
type: 'boolean',
description: 'Whether the subscribe feature is enabled',
nullable: true,
},
} as const satisfies Record<string, OutputProperty>
export const INCIDENT_SUMMARY_OUTPUT_PROPERTIES = {
id: { type: 'string', description: 'Incident ID' },
status: { type: 'string', description: 'Incident status', nullable: true },
type: { type: 'string', description: 'Incident type', nullable: true },
cause: { type: 'number', description: 'Incident cause code', nullable: true },
reason: { type: 'string', description: 'Incident reason', nullable: true },
monitorId: { type: 'number', description: 'Affected monitor ID', nullable: true },
monitorName: { type: 'string', description: 'Affected monitor name', nullable: true },
commentsCount: { type: 'number', description: 'Number of comments', nullable: true },
startedAt: { type: 'string', description: 'When the incident started', nullable: true },
resolvedAt: { type: 'string', description: 'When the incident resolved', nullable: true },
duration: { type: 'number', description: 'Incident duration in seconds', nullable: true },
includeInReports: {
type: 'boolean',
description: 'Whether the incident is included in reports',
nullable: true,
},
} as const satisfies Record<string, OutputProperty>
export const INCIDENT_DETAIL_OUTPUT_PROPERTIES = {
id: { type: 'string', description: 'Incident ID' },
status: { type: 'string', description: 'Incident status', nullable: true },
cause: { type: 'number', description: 'Incident cause code', nullable: true },
reason: { type: 'string', description: 'Incident reason', nullable: true },
duration: { type: 'number', description: 'Incident duration in seconds', nullable: true },
startedAt: { type: 'string', description: 'When the incident started', nullable: true },
resolvedAt: { type: 'string', description: 'When the incident resolved', nullable: true },
rootCause: {
type: 'object',
description: 'Root cause details for the incident',
nullable: true,
properties: {
url: { type: 'string', description: 'Checked URL', nullable: true },
httpResponseCode: {
type: 'number',
description: 'HTTP response code observed',
nullable: true,
},
responseDownloadUrl: {
type: 'string',
description: 'URL to download the captured response body',
nullable: true,
},
},
},
} as const satisfies Record<string, OutputProperty>
export const ACCOUNT_OUTPUT_PROPERTIES = {
email: { type: 'string', description: 'Account email', nullable: true },
fullName: { type: 'string', description: 'Account holder name', nullable: true },
monitorsCount: {
type: 'number',
description: 'Number of monitors in the account',
nullable: true,
},
monitorLimit: {
type: 'number',
description: 'Maximum number of monitors allowed',
nullable: true,
},
smsCredits: { type: 'number', description: 'Remaining SMS credits', nullable: true },
plan: { type: 'string', description: 'Subscription plan name', nullable: true },
subscriptionStatus: { type: 'string', description: 'Subscription status', nullable: true },
subscriptionExpiresAt: {
type: 'string',
description: 'Subscription expiration date',
nullable: true,
},
} as const satisfies Record<string, OutputProperty>
// endregion
// region Tool param/response interfaces
export interface UptimeRobotListMonitorsParams extends UptimeRobotBaseParams {
limit?: number
status?: string
name?: string
url?: string
tags?: string
groupId?: number
cursor?: number
}
export interface UptimeRobotListMonitorsResponse extends ToolResponse {
output: {
monitors: UptimeRobotMonitor[]
nextLink: string | null
}
}
export interface UptimeRobotGetMonitorParams extends UptimeRobotBaseParams {
monitorId: number
}
export interface UptimeRobotMonitorResponse extends ToolResponse {
output: {
monitor: UptimeRobotMonitor
}
}
export interface UptimeRobotCreateMonitorParams extends UptimeRobotBaseParams {
friendlyName: string
type: string
url?: string
interval: number
checkTimeout?: number
port?: number
keywordType?: string
keywordValue?: string
keywordCaseType?: number
httpMethodType?: string
authType?: string
httpUsername?: string
httpPassword?: string
gracePeriod?: number
successHttpResponseCodes?: string
checkSSLErrors?: boolean
followRedirections?: boolean
sslExpirationReminder?: boolean
domainExpirationReminder?: boolean
responseTimeThreshold?: number
tagNames?: string
assignedAlertContacts?: string
customHttpHeaders?: string
groupId?: number
}
export interface UptimeRobotUpdateMonitorParams extends Partial<UptimeRobotCreateMonitorParams> {
apiKey: string
monitorId: number
}
export interface UptimeRobotDeleteMonitorParams extends UptimeRobotBaseParams {
monitorId: number
}
export interface UptimeRobotDeleteResponse extends ToolResponse {
output: {
deleted: boolean
id: number | null
}
}
export interface UptimeRobotListIncidentsParams extends UptimeRobotBaseParams {
monitorId?: number
monitorName?: string
startedAfter?: string
startedBefore?: string
cursor?: string
}
export interface UptimeRobotListIncidentsResponse extends ToolResponse {
output: {
incidents: UptimeRobotIncidentSummary[]
nextLink: string | null
}
}
export interface UptimeRobotGetIncidentParams extends UptimeRobotBaseParams {
incidentId: string
}
export interface UptimeRobotIncidentResponse extends ToolResponse {
output: {
incident: UptimeRobotIncidentDetail
}
}
export interface UptimeRobotListMaintenanceWindowsParams extends UptimeRobotBaseParams {
cursor?: string
}
export interface UptimeRobotListMaintenanceWindowsResponse extends ToolResponse {
output: {
maintenanceWindows: UptimeRobotMaintenanceWindow[]
nextLink: string | null
}
}
export interface UptimeRobotGetMaintenanceWindowParams extends UptimeRobotBaseParams {
maintenanceWindowId: number
}
export interface UptimeRobotMaintenanceWindowResponse extends ToolResponse {
output: {
maintenanceWindow: UptimeRobotMaintenanceWindow
}
}
export interface UptimeRobotCreateMaintenanceWindowParams extends UptimeRobotBaseParams {
name: string
interval: string
date: string
time: string
duration: number
autoAddMonitors?: boolean
days?: string
monitorIds?: string
}
export interface UptimeRobotUpdateMaintenanceWindowParams
extends Partial<UptimeRobotCreateMaintenanceWindowParams> {
apiKey: string
maintenanceWindowId: number
status?: string
}
export interface UptimeRobotDeleteMaintenanceWindowParams extends UptimeRobotBaseParams {
maintenanceWindowId: number
}
export interface UptimeRobotListAlertContactsParams extends UptimeRobotBaseParams {
cursor?: number
}
export interface UptimeRobotListAlertContactsResponse extends ToolResponse {
output: {
alertContacts: UptimeRobotAlertContact[]
nextLink: string | null
}
}
export interface UptimeRobotGetAlertContactParams extends UptimeRobotBaseParams {
alertContactId: number
}
export interface UptimeRobotAlertContactResponse extends ToolResponse {
output: {
alertContact: UptimeRobotAlertContact
}
}
export interface UptimeRobotCreateAlertContactParams extends UptimeRobotBaseParams {
value: string
friendlyName?: string
enableNotificationsFor?: number
}
export interface UptimeRobotDeleteAlertContactParams extends UptimeRobotBaseParams {
alertContactId: number
}
export interface UptimeRobotListPspsParams extends UptimeRobotBaseParams {
cursor?: number
}
export interface UptimeRobotListPspsResponse extends ToolResponse {
output: {
psps: UptimeRobotPsp[]
nextLink: string | null
}
}
export interface UptimeRobotGetPspParams extends UptimeRobotBaseParams {
pspId: number
}
export interface UptimeRobotPspResponse extends ToolResponse {
output: {
psp: UptimeRobotPsp
}
}
export interface UptimeRobotCreatePspParams extends UptimeRobotBaseParams {
friendlyName: string
monitorIds?: string
status?: string
password?: string
customDomain?: string
hideUrlLinks?: boolean
noIndex?: boolean
logo?: unknown
icon?: unknown
}
export interface UptimeRobotUpdatePspParams extends Partial<UptimeRobotCreatePspParams> {
apiKey: string
pspId: number
}
export interface UptimeRobotDeletePspParams extends UptimeRobotBaseParams {
pspId: number
}
export interface UptimeRobotGetAccountParams extends UptimeRobotBaseParams {}
export interface UptimeRobotAccountResponse extends ToolResponse {
output: {
account: UptimeRobotAccount
}
}
// endregion
@@ -0,0 +1,114 @@
import type { ToolConfig } from '@/tools/types'
import {
buildMaintenanceWindowBody,
MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
mapMaintenanceWindow,
UPTIMEROBOT_API_BASE,
type UptimeRobotMaintenanceWindowResponse,
type UptimeRobotUpdateMaintenanceWindowParams,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotUpdateMaintenanceWindowTool: ToolConfig<
UptimeRobotUpdateMaintenanceWindowParams,
UptimeRobotMaintenanceWindowResponse
> = {
id: 'uptimerobot_update_maintenance_window',
name: 'UptimeRobot Update Maintenance Window',
description: 'Update an existing maintenance window. Only the provided fields are changed.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
maintenanceWindowId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the maintenance window to update',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New name of the maintenance window',
},
interval: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Recurrence interval: once, daily, weekly, or monthly',
},
date: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Start date in YYYY-MM-DD format',
},
time: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Start time in HH:mm:ss format',
},
duration: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Duration in minutes (minimum 1)',
},
days: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated days for weekly (1-7) or monthly (day-of-month, -1 for last day) windows',
},
monitorIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated monitor IDs to assign to the window',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Set to "active" to enable or "paused" to disable the maintenance window',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/maintenance-windows/${params.maintenanceWindowId}`,
method: 'PATCH',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
body: (params) => buildMaintenanceWindowBody(params),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { maintenanceWindow: mapMaintenanceWindow(data) },
}
},
outputs: {
maintenanceWindow: {
type: 'object',
description: 'The updated maintenance window',
properties: MAINTENANCE_WINDOW_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,192 @@
import type { ToolConfig } from '@/tools/types'
import {
buildMonitorBody,
MONITOR_OUTPUT_PROPERTIES,
mapMonitor,
UPTIMEROBOT_API_BASE,
type UptimeRobotMonitorResponse,
type UptimeRobotUpdateMonitorParams,
uptimeRobotError,
uptimeRobotHeaders,
} from '@/tools/uptimerobot/types'
export const uptimeRobotUpdateMonitorTool: ToolConfig<
UptimeRobotUpdateMonitorParams,
UptimeRobotMonitorResponse
> = {
id: 'uptimerobot_update_monitor',
name: 'UptimeRobot Update Monitor',
description: 'Update an existing UptimeRobot monitor. Only the provided fields are changed.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
monitorId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the monitor to update',
},
friendlyName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New friendly name',
},
url: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New URL or host to monitor',
},
interval: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'New check interval in seconds (minimum 30)',
},
checkTimeout: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'New check timeout in seconds, 0-60',
},
port: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'New port, 1-65535 (Port and UDP monitors)',
},
keywordType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Keyword match type: ALERT_EXISTS or ALERT_NOT_EXISTS',
},
keywordValue: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New keyword to look for',
},
httpMethodType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTTP method: HEAD, GET, POST, PUT, PATCH, DELETE, or OPTIONS',
},
authType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTTP authentication: NONE, HTTP_BASIC, DIGEST, or BEARER',
},
httpUsername: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username for HTTP authentication',
},
httpPassword: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Password for HTTP authentication',
},
successHttpResponseCodes: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated success HTTP response codes (e.g. "2xx,3xx")',
},
checkSSLErrors: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to check for SSL and domain expiration errors',
},
followRedirections: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to follow redirects',
},
sslExpirationReminder: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to send SSL certificate expiration reminders',
},
domainExpirationReminder: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to send domain expiration reminders',
},
responseTimeThreshold: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Response time threshold in milliseconds, 0-60000',
},
tagNames: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated tag names to assign to the monitor',
},
assignedAlertContacts: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'JSON array of alert-contact assignments, e.g. [{"alertContactId":123,"threshold":0,"recurrence":0}]',
},
customHttpHeaders: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'JSON object of custom HTTP headers to send with the request',
},
groupId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Monitor group ID to assign the monitor to (0 for no group)',
},
},
request: {
url: (params) => `${UPTIMEROBOT_API_BASE}/monitors/${params.monitorId}`,
method: 'PATCH',
headers: (params) => ({
...uptimeRobotHeaders(params.apiKey),
'Content-Type': 'application/json',
}),
body: (params) => buildMonitorBody(params),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
throw new Error(await uptimeRobotError(response))
}
const data = await response.json()
return {
success: true,
output: { monitor: mapMonitor(data) },
}
},
outputs: {
monitor: {
type: 'object',
description: 'The updated monitor',
properties: MONITOR_OUTPUT_PROPERTIES,
},
},
}
+124
View File
@@ -0,0 +1,124 @@
import type { ToolConfig } from '@/tools/types'
import {
PSP_OUTPUT_PROPERTIES,
type UptimeRobotPspResponse,
type UptimeRobotUpdatePspParams,
} from '@/tools/uptimerobot/types'
export const uptimeRobotUpdatePspTool: ToolConfig<
UptimeRobotUpdatePspParams,
UptimeRobotPspResponse
> = {
id: 'uptimerobot_update_psp',
name: 'UptimeRobot Update Status Page',
description:
'Update a public status page in UptimeRobot. Only the provided fields are changed; logo and icon images can be replaced.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'UptimeRobot API key',
},
pspId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'ID of the status page to update',
},
friendlyName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New name of the public status page',
},
monitorIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated monitor IDs to display on the page',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Status of the page: ENABLED (published) or PAUSED (unpublished)',
},
password: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Optional password protection for the page',
},
customDomain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom domain for the page (e.g. status.your-domain.com)',
},
hideUrlLinks: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to hide the "Powered by UptimeRobot" footer link',
},
noIndex: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to prevent search engines from indexing the page',
},
logo: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'Logo image (JPG/JPEG/PNG, max 150 KB)',
},
icon: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'Icon image (JPG/JPEG/PNG, max 150 KB)',
},
},
request: {
url: '/api/tools/uptimerobot/update-psp',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
apiKey: params.apiKey,
pspId: params.pspId,
friendlyName: params.friendlyName,
monitorIds: params.monitorIds,
status: params.status,
password: params.password,
customDomain: params.customDomain,
hideUrlLinks: params.hideUrlLinks,
noIndex: params.noIndex,
logo: params.logo,
icon: params.icon,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!data.success) {
throw new Error(data.error || 'Failed to update status page')
}
return {
success: true,
output: data.output,
}
},
outputs: {
psp: {
type: 'object',
description: 'The updated status page',
properties: PSP_OUTPUT_PROPERTIES,
},
},
}