Skip to main content
Glama

Screen Companies

screen_companies

Filter companies using financial metrics, industry codes, IP activity, litigation status, and risk scores to identify targets matching specific criteria.

Instructions

Screen companies using financial, industry, IP, and litigation filters. Combine SIC industry codes, revenue/asset brackets, shell risk scores, patent/trademark/litigation flags, and short interest levels. Cross-references SEC, OTC, Patents, Trademarks, and PACER datasets.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sic_codeNoSIC industry code (e.g. '7372' for software)
industryNoIndustry keyword search (partial match)
min_revenueNoMinimum revenue in USD
max_revenueNoMaximum revenue in USD
min_assetsNoMinimum total assets in USD
max_assetsNoMaximum total assets in USD
max_shell_riskNoMaximum shell risk score (0-100)
min_filing_recencyNoMinimum filing recency score (0-100)
has_patentsNoFilter to companies with patent activity
has_trademarksNoFilter to companies with trademark registrations
has_litigationNoFilter to companies with court cases
min_short_interestNoMinimum short interest ratio
sort_byNoSort field: revenue, assets, shell_risk, filing_recency, short_interest
limitNoMaximum results (default 25, max 100)

Implementation Reference

  • Handler logic for screen_companies tool execution.
      async (params) => {
        const queryParams: Record<string, string | number | undefined> = {
          sic_code: params.sic_code,
          industry: params.industry,
          min_revenue: params.min_revenue,
          max_revenue: params.max_revenue,
          min_assets: params.min_assets,
          max_assets: params.max_assets,
          max_shell_risk: params.max_shell_risk,
          min_filing_recency: params.min_filing_recency,
          has_patents: params.has_patents != null ? String(params.has_patents) : undefined,
          has_trademarks: params.has_trademarks != null ? String(params.has_trademarks) : undefined,
          has_litigation: params.has_litigation != null ? String(params.has_litigation) : undefined,
          min_short_interest: params.min_short_interest,
          sort_by: params.sort_by,
          limit: params.limit ?? 25,
        };
    
        const res = await apiGet<{ dataset: string; count: number; data: Record<string, unknown>[] }>(
          "/api/v1/companies/screen",
          queryParams,
        );
    
        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 summary = `Found ${count} company/companies matching filters.`;
        const json = JSON.stringify(data, null, 2);
    
        return {
          content: [{ type: "text" as const, text: `${summary}\n\n${json}` }],
        };
      },
    );
  • Input schema definition for the screen_companies tool.
    {
      title: "Screen Companies",
      description:
        "Screen companies using financial, industry, IP, and litigation filters. " +
        "Combine SIC industry codes, revenue/asset brackets, shell risk scores, " +
        "patent/trademark/litigation flags, and short interest levels. " +
        "Cross-references SEC, OTC, Patents, Trademarks, and PACER datasets.",
      inputSchema: {
        sic_code: z
          .string()
          .optional()
          .describe("SIC industry code (e.g. '7372' for software)"),
        industry: z
          .string()
          .optional()
          .describe("Industry keyword search (partial match)"),
        min_revenue: z
          .number()
          .optional()
          .describe("Minimum revenue in USD"),
        max_revenue: z
          .number()
          .optional()
          .describe("Maximum revenue in USD"),
        min_assets: z
          .number()
          .optional()
          .describe("Minimum total assets in USD"),
        max_assets: z
          .number()
          .optional()
          .describe("Maximum total assets in USD"),
        max_shell_risk: z
          .number()
          .int()
          .min(0)
          .max(100)
          .optional()
          .describe("Maximum shell risk score (0-100)"),
        min_filing_recency: z
          .number()
          .int()
          .min(0)
          .max(100)
          .optional()
          .describe("Minimum filing recency score (0-100)"),
        has_patents: z
          .boolean()
          .optional()
          .describe("Filter to companies with patent activity"),
        has_trademarks: z
          .boolean()
          .optional()
          .describe("Filter to companies with trademark registrations"),
        has_litigation: z
          .boolean()
          .optional()
          .describe("Filter to companies with court cases"),
        min_short_interest: z
          .number()
          .optional()
          .describe("Minimum short interest ratio"),
        sort_by: z
          .string()
          .optional()
          .describe("Sort field: revenue, assets, shell_risk, filing_recency, short_interest"),
        limit: z
          .number()
          .int()
          .min(1)
          .max(100)
          .optional()
          .describe("Maximum results (default 25, max 100)"),
      },
  • Registration of the screen_companies tool in the MCP server.
    server.registerTool(
      "screen_companies",
      {
        title: "Screen Companies",
        description:
          "Screen companies using financial, industry, IP, and litigation filters. " +
          "Combine SIC industry codes, revenue/asset brackets, shell risk scores, " +
          "patent/trademark/litigation flags, and short interest levels. " +
          "Cross-references SEC, OTC, Patents, Trademarks, and PACER datasets.",
        inputSchema: {
          sic_code: z
            .string()
            .optional()
            .describe("SIC industry code (e.g. '7372' for software)"),
          industry: z
            .string()
            .optional()
            .describe("Industry keyword search (partial match)"),
          min_revenue: z
            .number()
            .optional()
            .describe("Minimum revenue in USD"),
          max_revenue: z
            .number()
            .optional()
            .describe("Maximum revenue in USD"),
          min_assets: z
            .number()
            .optional()
            .describe("Minimum total assets in USD"),
          max_assets: z
            .number()
            .optional()
            .describe("Maximum total assets in USD"),
          max_shell_risk: z
            .number()
            .int()
            .min(0)
            .max(100)
            .optional()
            .describe("Maximum shell risk score (0-100)"),
          min_filing_recency: z
            .number()
            .int()
            .min(0)
            .max(100)
            .optional()
            .describe("Minimum filing recency score (0-100)"),
          has_patents: z
            .boolean()
            .optional()
            .describe("Filter to companies with patent activity"),
          has_trademarks: z
            .boolean()
            .optional()
            .describe("Filter to companies with trademark registrations"),
          has_litigation: z
            .boolean()
            .optional()
            .describe("Filter to companies with court cases"),
          min_short_interest: z
            .number()
            .optional()
            .describe("Minimum short interest ratio"),
          sort_by: z
            .string()
            .optional()
            .describe("Sort field: revenue, assets, shell_risk, filing_recency, short_interest"),
          limit: z
            .number()
            .int()
            .min(1)
            .max(100)
            .optional()
            .describe("Maximum results (default 25, max 100)"),
        },
      },
      async (params) => {
        const queryParams: Record<string, string | number | undefined> = {
          sic_code: params.sic_code,
          industry: params.industry,
          min_revenue: params.min_revenue,
          max_revenue: params.max_revenue,
          min_assets: params.min_assets,
          max_assets: params.max_assets,
          max_shell_risk: params.max_shell_risk,
          min_filing_recency: params.min_filing_recency,
          has_patents: params.has_patents != null ? String(params.has_patents) : undefined,
          has_trademarks: params.has_trademarks != null ? String(params.has_trademarks) : undefined,
          has_litigation: params.has_litigation != null ? String(params.has_litigation) : undefined,
          min_short_interest: params.min_short_interest,
          sort_by: params.sort_by,
          limit: params.limit ?? 25,
        };
    
        const res = await apiGet<{ dataset: string; count: number; data: Record<string, unknown>[] }>(
          "/api/v1/companies/screen",
          queryParams,
        );
    
        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 summary = `Found ${count} company/companies matching filters.`;
        const json = JSON.stringify(data, null, 2);
    
        return {
          content: [{ type: "text" as const, text: `${summary}\n\n${json}` }],
        };
      },
    );
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions data sources (SEC, OTC, Patents, etc.) and filtering capabilities but doesn't describe critical behaviors like whether this is a read-only operation, if it has rate limits, what the output format looks like, or any performance characteristics. For a complex screening tool with 14 parameters, this is a significant gap.

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 efficiently structured in two sentences: the first states the purpose and filter types, the second lists data sources. It's front-loaded with the core functionality and avoids unnecessary words. However, it could be slightly more concise by integrating the data sources into the first sentence.

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?

Given the tool's complexity (14 parameters, no annotations, no output schema), the description is incomplete. It lacks information on behavioral traits (e.g., read-only vs. mutation, rate limits), output format, error handling, and usage context relative to siblings. For a screening tool that likely returns a list of companies, the absence of output details is a notable gap.

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 the schema already documents all 14 parameters thoroughly. The description adds minimal value beyond the schema by listing filter categories (financial, industry, IP, litigation) and data sources, but doesn't provide additional syntax, format details, or usage examples for the parameters. Baseline 3 is appropriate when the schema does the heavy lifting.

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 the tool's purpose: 'Screen companies using financial, industry, IP, and litigation filters.' It specifies the action (screen) and resource (companies) with the types of filters used. However, it doesn't explicitly differentiate from sibling tools like 'search_sec_companies' or 'query_otc_companies,' which prevents a perfect score.

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?

The description provides no guidance on when to use this tool versus alternatives. With many sibling tools available (e.g., 'search_sec_companies,' 'query_otc_companies'), there's no indication of when this screening tool is preferred over other search or query tools. It mentions data sources but not usage context.

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