Skip to main content
Glama

Search Government Contracts

search_contracts

Search federal contract awards by agency, vendor, NAICS code, or keyword to retrieve award details including value, period of performance, and competition type.

Instructions

Search federal contract awards by agency, vendor, NAICS code, or keyword. Returns award details including value, period of performance, and competition type. Cost: $0.018 per query. Source: USAspending.gov, updated daily.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
agencyNoAwarding agency name or abbreviation (e.g. DOD, HHS)
vendorNoVendor/contractor name (partial match)
naicsNoNAICS code filter
keywordNoKeyword search in award description
min_valueNoMinimum award value in USD
limitNoMaximum results (default 25)

Implementation Reference

  • The async handler function that executes the search_contracts tool logic: calls apiGet to /api/v1/contracts with query parameters (agency, vendor, naics, keyword, min_value, limit), handles errors, formats the response with count and JSON data.
    async ({ agency, vendor, naics, keyword, min_value, limit }) => {
      const res = await apiGet<ContractQueryResponse>("/api/v1/contracts", {
        agency,
        vendor,
        naics,
        keyword,
        min_value,
        limit: limit ?? 25,
      });
    
      if (!res.ok) {
        return {
          content: [
            {
              type: "text" as const,
              text: `API error (${res.status}): ${JSON.stringify(res.data)}`,
            },
          ],
          isError: true,
        };
      }
    
      const { count, data } = res.data;
      const warn = stalenessWarning(res);
      const summary = `${warn}Found ${count} contract award(s).`;
      const json = JSON.stringify(data, null, 2);
    
      return {
        content: [{ type: "text" as const, text: `${summary}\n\n${json}` }],
      };
    },
  • Input schema for search_contracts tool using Zod: optional fields for agency, vendor, naics, keyword, min_value (number), limit (1-100 integer).
    inputSchema: {
      agency: z
        .string()
        .optional()
        .describe("Awarding agency name or abbreviation (e.g. DOD, HHS)"),
      vendor: z
        .string()
        .optional()
        .describe("Vendor/contractor name (partial match)"),
      naics: z
        .string()
        .optional()
        .describe("NAICS code filter"),
      keyword: z
        .string()
        .optional()
        .describe("Keyword search in award description"),
      min_value: z
        .number()
        .optional()
        .describe("Minimum award value in USD"),
      limit: z
        .number()
        .int()
        .min(1)
        .max(100)
        .optional()
        .describe("Maximum results (default 25)"),
    },
  • Registration of the search_contracts tool via server.registerTool('search_contracts', ...) with title/description, inputSchema, and handler.
    server.registerTool(
      "search_contracts",
      {
        title: "Search Government Contracts",
        description:
          "Search federal contract awards by agency, vendor, NAICS code, or keyword. " +
          "Returns award details including value, period of performance, and competition type. " +
          "Cost: $0.018 per query. Source: USAspending.gov, updated daily.",
        inputSchema: {
          agency: z
            .string()
            .optional()
            .describe("Awarding agency name or abbreviation (e.g. DOD, HHS)"),
          vendor: z
            .string()
            .optional()
            .describe("Vendor/contractor name (partial match)"),
          naics: z
            .string()
            .optional()
            .describe("NAICS code filter"),
          keyword: z
            .string()
            .optional()
            .describe("Keyword search in award description"),
          min_value: z
            .number()
            .optional()
            .describe("Minimum award value in USD"),
          limit: z
            .number()
            .int()
            .min(1)
            .max(100)
            .optional()
            .describe("Maximum results (default 25)"),
        },
      },
      async ({ agency, vendor, naics, keyword, min_value, limit }) => {
        const res = await apiGet<ContractQueryResponse>("/api/v1/contracts", {
          agency,
          vendor,
          naics,
          keyword,
          min_value,
          limit: limit ?? 25,
        });
    
        if (!res.ok) {
          return {
            content: [
              {
                type: "text" as const,
                text: `API error (${res.status}): ${JSON.stringify(res.data)}`,
              },
            ],
            isError: true,
          };
        }
    
        const { count, data } = res.data;
        const warn = stalenessWarning(res);
        const summary = `${warn}Found ${count} contract award(s).`;
        const json = JSON.stringify(data, null, 2);
    
        return {
          content: [{ type: "text" as const, text: `${summary}\n\n${json}` }],
        };
      },
    );
  • src/index.ts:53-53 (registration)
    Top-level registration call to registerContractTools(server) which registers all contract tools including search_contracts.
    registerContractTools(server);
  • The apiGet helper function used by the handler to make HTTP GET requests to the Verilex API with headers and payment token support.
    export async function apiGet<T = unknown>(
      path: string,
      params?: Record<string, string | number | undefined>,
    ): Promise<ApiResponse<T>> {
      const url = buildUrl(path, params);
    
      const headers: Record<string, string> = {
        Accept: "application/json",
        "User-Agent": "verilex-mcp-server/0.1.0",
      };
    
      // Forward x402 payment token if present in env (for paid endpoints)
      const paymentToken = process.env.VERILEX_PAYMENT_TOKEN;
      if (paymentToken) {
        headers["X-Payment-Token"] = paymentToken;
      }
    
      const res = await fetch(url, { headers });
      const data = (await res.json()) as T;
    
      const stale = res.headers.get("X-Data-Stale");
      const lastUpdated = res.headers.get("X-Data-Last-Updated");
      const ageSeconds = res.headers.get("X-Data-Age-Seconds");
    
      return {
        ok: res.ok,
        status: res.status,
        data,
        stale: stale === "true",
        lastUpdated: lastUpdated ?? undefined,
        ageSeconds: ageSeconds ? Number(ageSeconds) : undefined,
      };
    }
Behavior3/5

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

No annotations are present, so the description carries the full burden. It discloses cost and data source but omits details on authentication, rate limits, pagination, or error handling. The read-only nature is implied but not stated.

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

Conciseness5/5

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

Two sentences with clear front-loading of purpose. Every sentence contributes essential information (search criteria, return details, cost, source). No redundancy.

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

Completeness4/5

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

With no output schema, the description partially covers return fields but lacks structure details. It addresses cost and source adequately. Minor gaps in pagination and error handling, but sufficient for a search tool with 6 optional parameters.

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 coverage is 100%, so the baseline is 3. The description only lists filter options without adding meaning beyond the schema, such as how parameters interact or formatting details.

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

Purpose5/5

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

The description clearly states it searches federal contract awards by multiple criteria (agency, vendor, NAICS, keyword) and returns specific details. It distinguishes itself from sibling tools like 'lookup_contract' by emphasizing broad search capabilities.

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

Usage Guidelines3/5

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

The description implies usage through listing search options and mentions cost and source, but lacks explicit guidance on when to use this tool versus alternatives like 'lookup_contract' or when not to use it.

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/carrierone/verilexdata-mcp'

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