All files / src/tools rankings.ts

100% Statements 10/10
100% Branches 2/2
100% Functions 3/3
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66            2x 12x                                                       5x 5x   4x         3x       4x 1x     4x                 1x          
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import * as z from "zod/v4";
import type { IsAgentReadyClient } from "../client.js";
import { formatScanSummary } from "../format.js";
import { toTextResult, toErrorResult } from "../tool-result.js";
 
export const registerRankingTools = (server: McpServer, client: IsAgentReadyClient): void => {
  server.registerTool(
    "get_rankings",
    {
      title: "Get AI Readiness Rankings",
      description:
        "Get a paginated, sorted list of website AI readiness scores. Supports filtering by grade range (high/mid/low), search by domain name, and sorting by score, domain, or newest.",
      annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
      inputSchema: z.object({
        page: z.number().int().min(1).default(1).describe("Page number (default: 1)"),
        per_page: z
          .number()
          .int()
          .min(1)
          .max(100)
          .default(25)
          .describe("Results per page (1-100, default: 25)"),
        grade_range: z
          .enum(["high", "mid", "low"])
          .optional()
          .describe("Filter by grade range: high (A/A+), mid (B/C), low (D/F)"),
        search: z.string().optional().describe("Search by domain name"),
        sort: z
          .enum(["score_desc", "score_asc", "domain", "newest"])
          .default("score_desc")
          .describe("Sort order (default: score_desc)"),
      }),
    },
    async ({ page, per_page, grade_range, search, sort }) => {
      try {
        const result = await client.getRankings({ page, per_page, grade_range, search, sort });
 
        const lines = [
          `AI Readiness Rankings — Page ${result.page}/${result.total_pages} (${result.total} total)`,
          "",
          ...result.entries.map(
            (entry, i) =>
              `${(result.page - 1) * result.per_page + i + 1}. ${formatScanSummary(entry)}`,
          ),
        ];
 
        if (result.entries.length === 0) {
          lines.push("No results found.");
        }
 
        return toTextResult(lines.join("\n"), {
          type: "rankings",
          page: result.page,
          per_page: result.per_page,
          total: result.total,
          total_pages: result.total_pages,
          entries: result.entries,
        });
      } catch (error) {
        return toErrorResult(error);
      }
    },
  );
};