Skip to main content
Glama
VisualSentinel

Visual Sentinel MCP Server

Official

vs_monitors_list

List monitors in your authenticated organization. Filter by status, type, or paginate to view specific monitoring targets.

Instructions

List monitors in the authenticated organization. Optional filters narrow by status, type, or paginate.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusNoFilter: UP, DOWN, PAUSED, MAINTENANCE.
typeNoFilter by monitor type: HTTP, HTTPS, KEYWORD, PING, PORT, DNS, SSL, VISUAL, CONTENT, API, GRAPHQL, WEBSOCKET.
pageNoPage number (default 1).
limitNoItems per page (default 50, max 200).

Implementation Reference

  • The handler function for vs_monitors_list. It calls client.request('GET', '/api/monitors') with optional query params: status, type, page, limit.
    handler: async (args, client) =>
      client.request('GET', '/api/monitors', {
        query: {
          status: pickString(args, 'status'),
          type: pickString(args, 'type'),
          page: pickNumber(args, 'page'),
          limit: pickNumber(args, 'limit'),
        },
      }),
  • The inputSchema for vs_monitors_list, defining optional properties: status, type, page, limit.
    inputSchema: {
      type: 'object',
      properties: {
        status: { ...STR, description: 'Filter: UP, DOWN, PAUSED, MAINTENANCE.' },
        type: {
          ...STR,
          description:
            'Filter by monitor type: HTTP, HTTPS, KEYWORD, PING, PORT, DNS, SSL, VISUAL, CONTENT, API, GRAPHQL, WEBSOCKET.',
        },
        page: { ...INT, description: 'Page number (default 1).' },
        limit: { ...INT, description: 'Items per page (default 50, max 200).' },
      },
      additionalProperties: false,
    },
  • src/tools.ts:156-184 (registration)
    The full tool registration entry in the TOOLS array, including name, description, inputSchema, requiresAuth, and handler.
    {
      name: 'vs_monitors_list',
      description:
        'List monitors in the authenticated organization. Optional filters narrow by status, type, or paginate.',
      inputSchema: {
        type: 'object',
        properties: {
          status: { ...STR, description: 'Filter: UP, DOWN, PAUSED, MAINTENANCE.' },
          type: {
            ...STR,
            description:
              'Filter by monitor type: HTTP, HTTPS, KEYWORD, PING, PORT, DNS, SSL, VISUAL, CONTENT, API, GRAPHQL, WEBSOCKET.',
          },
          page: { ...INT, description: 'Page number (default 1).' },
          limit: { ...INT, description: 'Items per page (default 50, max 200).' },
        },
        additionalProperties: false,
      },
      requiresAuth: true,
      handler: async (args, client) =>
        client.request('GET', '/api/monitors', {
          query: {
            status: pickString(args, 'status'),
            type: pickString(args, 'type'),
            page: pickNumber(args, 'page'),
            limit: pickNumber(args, 'limit'),
          },
        }),
    },
  • src/tools.ts:41-398 (registration)
    The findTool function is used to look up tools by name, and the ListToolsRequestSchema handler registers all tools including vs_monitors_list.
    function requireString(args: Record<string, unknown>, key: string): string {
      const v = pickString(args, key);
      if (!v) throw new Error(`Argument "${key}" (string) is required.`);
      return v;
    }
    
    export const TOOLS: ToolDefinition[] = [
      // -------------------------------------------------------------------------
      // Public tools (no auth)
      // -------------------------------------------------------------------------
      {
        name: 'vs_health',
        description:
          'Check whether Visual Sentinel itself is up. Returns the service health status. No authentication required.',
        inputSchema: {
          type: 'object',
          properties: {},
          additionalProperties: false,
        },
        requiresAuth: false,
        handler: async (_args, client) => client.request('GET', '/api/health', { auth: false }),
      },
    
      {
        name: 'vs_dns_check',
        description:
          'Resolve DNS records (A, AAAA, MX, NS, TXT, CNAME) for a domain using Visual Sentinel\'s public DNS lookup tool. No authentication required.',
        inputSchema: {
          type: 'object',
          properties: {
            domain: { ...STR, description: 'Domain to resolve, e.g. example.com (without protocol).' },
            recordType: {
              ...STR,
              description: 'Optional: limit to one record type. One of: A, AAAA, MX, NS, TXT, CNAME, SOA. Default: all.',
            },
          },
          required: ['domain'],
          additionalProperties: false,
        },
        requiresAuth: false,
        handler: async (args, client) =>
          client.request('GET', '/api/tools/dns-check', {
            auth: false,
            query: {
              domain: requireString(args, 'domain'),
              recordType: pickString(args, 'recordType'),
            },
          }),
      },
    
      {
        name: 'vs_ssl_check',
        description:
          'Inspect a TLS/SSL certificate for a hostname: issuer, subject, validity dates, SAN list, key algorithm, and certificate chain. No authentication required.',
        inputSchema: {
          type: 'object',
          properties: {
            host: { ...STR, description: 'Hostname to inspect, e.g. example.com (without protocol).' },
            port: { ...INT, description: 'TCP port. Default 443.' },
          },
          required: ['host'],
          additionalProperties: false,
        },
        requiresAuth: false,
        handler: async (args, client) =>
          client.request('GET', '/api/tools/ssl-check', {
            auth: false,
            query: { host: requireString(args, 'host'), port: pickNumber(args, 'port') },
          }),
      },
    
      {
        name: 'vs_speed_test',
        description:
          'Run a one-shot performance check against a URL: TTFB, total load time, transfer size, status code, and redirect chain. No authentication required.',
        inputSchema: {
          type: 'object',
          properties: {
            url: { ...STR, description: 'Full URL to test, including protocol (https://...).' },
          },
          required: ['url'],
          additionalProperties: false,
        },
        requiresAuth: false,
        handler: async (args, client) =>
          client.request('GET', '/api/tools/speed-test', {
            auth: false,
            query: { url: requireString(args, 'url') },
          }),
      },
    
      {
        name: 'vs_website_check',
        description:
          'Quick health check for a URL: HTTP status, response time, server header, content snippet, and basic SSL state. No authentication required.',
        inputSchema: {
          type: 'object',
          properties: {
            url: { ...STR, description: 'Full URL to test, including protocol (https://...).' },
          },
          required: ['url'],
          additionalProperties: false,
        },
        requiresAuth: false,
        handler: async (args, client) =>
          client.request('GET', '/api/tools/website-check', {
            auth: false,
            query: { url: requireString(args, 'url') },
          }),
      },
    
      // -------------------------------------------------------------------------
      // Authenticated tools (require VS_API_KEY)
      // -------------------------------------------------------------------------
      {
        name: 'vs_monitors_list',
        description:
          'List monitors in the authenticated organization. Optional filters narrow by status, type, or paginate.',
        inputSchema: {
          type: 'object',
          properties: {
            status: { ...STR, description: 'Filter: UP, DOWN, PAUSED, MAINTENANCE.' },
            type: {
              ...STR,
              description:
                'Filter by monitor type: HTTP, HTTPS, KEYWORD, PING, PORT, DNS, SSL, VISUAL, CONTENT, API, GRAPHQL, WEBSOCKET.',
            },
            page: { ...INT, description: 'Page number (default 1).' },
            limit: { ...INT, description: 'Items per page (default 50, max 200).' },
          },
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', '/api/monitors', {
            query: {
              status: pickString(args, 'status'),
              type: pickString(args, 'type'),
              page: pickNumber(args, 'page'),
              limit: pickNumber(args, 'limit'),
            },
          }),
      },
    
      {
        name: 'vs_monitors_get',
        description:
          'Fetch a single monitor by id, including its current status, last check, and configuration.',
        inputSchema: {
          type: 'object',
          properties: {
            id: { ...STR, description: 'Monitor id (cuid).' },
          },
          required: ['id'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', `/api/monitors/${encodeURIComponent(requireString(args, 'id'))}`),
      },
    
      {
        name: 'vs_monitors_create',
        description:
          'Create a new monitor. Provide at least name, url, and type. Returns the created monitor including its assigned id.',
        inputSchema: {
          type: 'object',
          properties: {
            name: { ...STR, description: 'Display name for the monitor.' },
            url: { ...STR, description: 'Full URL to monitor (or hostname for PING/PORT/DNS/SSL).' },
            type: {
              ...STR,
              description:
                'Monitor type: HTTP, HTTPS, KEYWORD, PING, PORT, DNS, SSL, VISUAL, CONTENT, API, GRAPHQL, WEBSOCKET.',
            },
            interval: { ...INT, description: 'Check interval in seconds (60, 300, 600, 1800, 3600).' },
            timeout: { ...INT, description: 'Per-check timeout in seconds (default 30).' },
            method: { ...STR, description: 'HTTP method for HTTP/HTTPS monitors (default GET).' },
            keyword: { ...STR, description: 'Keyword to assert for KEYWORD monitors.' },
            port: { ...INT, description: 'TCP port for PORT monitors.' },
          },
          required: ['name', 'url', 'type'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('POST', '/api/monitors', {
            body: {
              name: requireString(args, 'name'),
              url: requireString(args, 'url'),
              type: requireString(args, 'type'),
              interval: pickNumber(args, 'interval'),
              timeout: pickNumber(args, 'timeout'),
              method: pickString(args, 'method'),
              keyword: pickString(args, 'keyword'),
              port: pickNumber(args, 'port'),
            },
          }),
      },
    
      {
        name: 'vs_monitors_check_now',
        description:
          'Trigger an immediate check for a monitor (in addition to its scheduled cadence). Returns the freshly-collected check result.',
        inputSchema: {
          type: 'object',
          properties: {
            id: { ...STR, description: 'Monitor id.' },
          },
          required: ['id'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('POST', `/api/monitors/${encodeURIComponent(requireString(args, 'id'))}/check`),
      },
    
      {
        name: 'vs_monitors_uptime',
        description:
          'Fetch the uptime percentage and outage breakdown for a monitor over a window (default last 30 days).',
        inputSchema: {
          type: 'object',
          properties: {
            id: { ...STR, description: 'Monitor id.' },
            window: {
              ...STR,
              description: 'Window: 24h, 7d, 30d, 90d, 365d. Default 30d.',
            },
          },
          required: ['id'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', `/api/monitors/${encodeURIComponent(requireString(args, 'id'))}/uptime`, {
            query: { window: pickString(args, 'window') },
          }),
      },
    
      {
        name: 'vs_incidents_list',
        description:
          'List incidents for the authenticated organization. Filter by status (OPEN/RESOLVED), monitor id, or paginate.',
        inputSchema: {
          type: 'object',
          properties: {
            status: { ...STR, description: 'OPEN or RESOLVED.' },
            monitorId: { ...STR, description: 'Filter to one monitor.' },
            page: { ...INT },
            limit: { ...INT, description: 'Default 50, max 200.' },
          },
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', '/api/incidents', {
            query: {
              status: pickString(args, 'status'),
              monitorId: pickString(args, 'monitorId'),
              page: pickNumber(args, 'page'),
              limit: pickNumber(args, 'limit'),
            },
          }),
      },
    
      {
        name: 'vs_incidents_get',
        description: 'Fetch a single incident with its full check history and root-cause hints.',
        inputSchema: {
          type: 'object',
          properties: {
            id: { ...STR, description: 'Incident id.' },
          },
          required: ['id'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', `/api/incidents/${encodeURIComponent(requireString(args, 'id'))}`),
      },
    
      {
        name: 'vs_alerts_list',
        description:
          'List alerts for the authenticated organization. Filter by status (UNACKNOWLEDGED/ACKNOWLEDGED/RESOLVED) or paginate.',
        inputSchema: {
          type: 'object',
          properties: {
            status: { ...STR, description: 'UNACKNOWLEDGED, ACKNOWLEDGED, or RESOLVED.' },
            page: { ...INT },
            limit: { ...INT, description: 'Default 50, max 200.' },
          },
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', '/api/alerts', {
            query: {
              status: pickString(args, 'status'),
              page: pickNumber(args, 'page'),
              limit: pickNumber(args, 'limit'),
            },
          }),
      },
    
      {
        name: 'vs_alerts_acknowledge',
        description: 'Acknowledge an alert by id. Acknowledgement is recorded with the calling API key\'s user.',
        inputSchema: {
          type: 'object',
          properties: {
            id: { ...STR, description: 'Alert id.' },
            note: { ...STR, description: 'Optional acknowledgement note (visible in alert history).' },
          },
          required: ['id'],
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('POST', `/api/alerts/${encodeURIComponent(requireString(args, 'id'))}/acknowledge`, {
            body: { note: pickString(args, 'note') },
          }),
      },
    
      {
        name: 'vs_status_pages_list',
        description: 'List public-facing status pages owned by the authenticated organization.',
        inputSchema: {
          type: 'object',
          properties: {},
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (_args, client) => client.request('GET', '/api/status-pages'),
      },
    
      {
        name: 'vs_servers_list',
        description: 'List servers (origins) registered in the authenticated organization.',
        inputSchema: {
          type: 'object',
          properties: {
            page: { ...INT },
            limit: { ...INT, description: 'Default 50.' },
          },
          additionalProperties: false,
        },
        requiresAuth: true,
        handler: async (args, client) =>
          client.request('GET', '/api/servers', {
            query: { page: pickNumber(args, 'page'), limit: pickNumber(args, 'limit') },
          }),
      },
    ];
    
    export function findTool(name: string): ToolDefinition | undefined {
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, and the description adds minimal behavioral context. It does not disclose authentication details (beyond 'authenticated organization'), rate limits, or pagination behavior beyond what the schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (one sentence) and front-loaded with the main action. It is not verbose, though it could include a bit more context without sacrificing conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description does not describe the return value or format. For a list tool, it lacks details on what fields are returned or how to handle results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameters are well-documented in the schema. The description summarizes filters (status, type, paginate) but adds no new meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List monitors in the authenticated organization' with specific verb and resource. It mentions optional filters but does not differentiate from sibling tools like 'vs_monitors_get' or 'vs_monitors_create'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives. The description only implies usage with optional filters but does not specify prerequisites or exclude scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VisualSentinel/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server