Skip to main content
Glama
kindrat86

mcp-deal-flow-signal

Get Startup Signal Profile

get_startup_signal
Read-onlyIdempotent

Retrieve a startup's engineering acceleration profile including commit velocity, contributor growth, new repos, signal classification, sector, stage, and geography. Ideal for vetting a named company before writing a deal memo.

Instructions

Return the full engineering-acceleration profile for a single tracked startup: commit velocity, velocity change, contributor count and growth, new-repo count, signal classification, sector, stage, geography, and GitHub URL.

WHEN TO USE:

  • The user names a specific company: 'tell me about Roboflow', 'what's Supabase's signal?', 'is Modular trending?', 'lookup SkyPilot'.

  • Preparing a deal memo, one-pager, or investor update about a named startup.

  • Verifying whether a startup is in the tracked universe before writing analysis.

DO NOT USE FOR:

  • Discovering unknown companies or fuzzy exploration ('any good AI startups?') — call get_trending_startups or search_startups_by_sector first, then drill in here.

  • Listing candidates in a sector — call search_startups_by_sector.

  • Explaining what the signalType means — call get_methodology.

BEHAVIOR:

  • Read-only, idempotent, no side effects.

  • Deterministic within a 7-day window: dataset refreshes every Monday ~09:00 UTC.

  • No authentication required.

  • Matching is case-insensitive and normalization-tolerant: whitespace, punctuation, and capitalization are stripped before comparison. 'Sky Pilot', 'skypilot', and 'SkyPilot' all resolve to the same entry. Accepts either the display name or the GitHub org slug.

  • On no match: returns structuredContent: { found: false, suggestion: ... }. This is an EXPECTED outcome (the startup is not in the tracked universe), NOT an error — do not retry, do not flag as failure. Instead surface the suggestion to the user and offer to run get_trending_startups or search_startups_by_sector.

  • On upstream failure: returns isError: true with HTTP status.

  • Open-world: only ~400 companies are tracked. This tool cannot add new ones — direct the user to the website submission form if needed.

PARAMETERS:

  • name (required, string, 1–100 chars) — Startup display name OR GitHub org name. Case-insensitive; punctuation and whitespace are ignored during matching.

RETURNS: { found: boolean, startup?: {...}, suggestion?: string, citation }. When found=true, startup contains rank, name, sector, stage, geography, commitVelocity14d, commitVelocityChange, contributors, contributorGrowth, newRepos, signalType, description, githubUrl, profileUrl. When found=false, suggestion explains how to discover the correct name.

TYPICAL WORKFLOW: get_trending_startups or search_startups_by_sector (discover) → pick a name → get_startup_signal(name) (deep-dive) → get_methodology (explain signal classification in the response).

LIMITATIONS: Only returns data for currently-tracked startups. No historical series — each call is the latest weekly snapshot only. No relationship data (investors, cap table, team) — pair with Crunchbase for those facets.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesStartup name or GitHub org name. Case-insensitive; punctuation and whitespace are ignored during matching.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
foundYes
startupNoA single startup ranked by engineering acceleration, as derived from public GitHub activity.
suggestionNoWhen found=false, a hint on how to discover the correct name or alternative tools to call.
citationNo

Implementation Reference

  • src/server.ts:381-450 (registration)
    Tool registration for 'get_startup_signal' in the TOOLS array (lines 381-450). Defines name, title, description, input/output schemas, and annotations.
      name: "get_startup_signal",
      title: "Get Startup Signal Profile",
      description: [
        "Return the full engineering-acceleration profile for a single tracked startup: commit velocity, velocity change, contributor count and growth, new-repo count, signal classification, sector, stage, geography, and GitHub URL.",
        "",
        "WHEN TO USE:",
        "- The user names a specific company: 'tell me about Roboflow', 'what's Supabase's signal?', 'is Modular trending?', 'lookup SkyPilot'.",
        "- Preparing a deal memo, one-pager, or investor update about a named startup.",
        "- Verifying whether a startup is in the tracked universe before writing analysis.",
        "",
        "DO NOT USE FOR:",
        "- Discovering unknown companies or fuzzy exploration ('any good AI startups?') — call `get_trending_startups` or `search_startups_by_sector` first, then drill in here.",
        "- Listing candidates in a sector — call `search_startups_by_sector`.",
        "- Explaining what the signalType means — call `get_methodology`.",
        "",
        "BEHAVIOR:",
        "- Read-only, idempotent, no side effects.",
        "- Deterministic within a 7-day window: dataset refreshes every Monday ~09:00 UTC.",
        "- No authentication required.",
        "- Matching is case-insensitive and normalization-tolerant: whitespace, punctuation, and capitalization are stripped before comparison. 'Sky Pilot', 'skypilot', and 'SkyPilot' all resolve to the same entry. Accepts either the display name or the GitHub org slug.",
        "- On no match: returns `structuredContent: { found: false, suggestion: ... }`. This is an EXPECTED outcome (the startup is not in the tracked universe), NOT an error — do not retry, do not flag as failure. Instead surface the suggestion to the user and offer to run `get_trending_startups` or `search_startups_by_sector`.",
        "- On upstream failure: returns `isError: true` with HTTP status.",
        "- Open-world: only ~400 companies are tracked. This tool cannot add new ones — direct the user to the website submission form if needed.",
        "",
        "PARAMETERS:",
        "- `name` (required, string, 1–100 chars) — Startup display name OR GitHub org name. Case-insensitive; punctuation and whitespace are ignored during matching.",
        "",
        "RETURNS: `{ found: boolean, startup?: {...}, suggestion?: string, citation }`. When `found=true`, `startup` contains rank, name, sector, stage, geography, commitVelocity14d, commitVelocityChange, contributors, contributorGrowth, newRepos, signalType, description, githubUrl, profileUrl. When `found=false`, `suggestion` explains how to discover the correct name.",
        "",
        "TYPICAL WORKFLOW: `get_trending_startups` or `search_startups_by_sector` (discover) → pick a name → `get_startup_signal(name)` (deep-dive) → `get_methodology` (explain signal classification in the response).",
        "",
        "LIMITATIONS: Only returns data for currently-tracked startups. No historical series — each call is the latest weekly snapshot only. No relationship data (investors, cap table, team) — pair with Crunchbase for those facets.",
      ].join("\n"),
      inputSchema: {
        type: "object" as const,
        properties: {
          name: {
            type: "string",
            description:
              "Startup name or GitHub org name. Case-insensitive; punctuation and whitespace are ignored during matching.",
            minLength: 1,
            maxLength: 100,
            examples: ["roboflow", "SkyPilot", "Supabase", "Hugging Face"],
          },
        },
        required: ["name"],
        additionalProperties: false,
      },
      outputSchema: {
        type: "object" as const,
        properties: {
          found: { type: "boolean" },
          startup: STARTUP_ITEM_SCHEMA,
          suggestion: {
            type: "string",
            description:
              "When found=false, a hint on how to discover the correct name or alternative tools to call.",
          },
          citation: { type: "string" },
        },
        required: ["found"],
      },
      annotations: {
        title: "Get Startup Signal Profile",
        readOnlyHint: true,
        destructiveHint: false,
        idempotentHint: true,
        openWorldHint: true,
      },
    },
  • Input schema requires a 'name' string (1-100 chars); output schema returns 'found' boolean, optional 'startup' object, optional 'suggestion' string, and 'citation'.
    inputSchema: {
      type: "object" as const,
      properties: {
        name: {
          type: "string",
          description:
            "Startup name or GitHub org name. Case-insensitive; punctuation and whitespace are ignored during matching.",
          minLength: 1,
          maxLength: 100,
          examples: ["roboflow", "SkyPilot", "Supabase", "Hugging Face"],
        },
      },
      required: ["name"],
      additionalProperties: false,
    },
  • Handler implementation for 'get_startup_signal': normalizes the input name to a slug, fetches /api/signals.json, matches across all sectors using case-insensitive normalized comparison, and returns the startup profile or a 'not found' response with a suggestion.
    case "get_startup_signal": {
      const inputName = (args as { name: string }).name;
      const slug = inputName
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-|-$/g, "");
    
      const data = (await fetchJSON("/api/signals.json")) as unknown as SignalsData;
      let found: Startup | null = null;
      let foundSector = "";
    
      for (const sector of data.sectors) {
        const match = sector.startups.find(
          (s) =>
            s.name
              .toLowerCase()
              .replace(/[^a-z0-9]+/g, "-")
              .replace(/^-|-$/g, "") === slug
        );
        if (match) {
          found = match;
          foundSector = sector.name;
          break;
        }
      }
    
      if (!found) {
        return {
          content: [
            {
              type: "text" as const,
              text: `Startup "${inputName}" not found. Try the GitHub org name exactly as it appears, or use get_trending_startups / search_startups_by_sector to browse.`,
            },
          ],
          structuredContent: {
            found: false,
            suggestion:
              "Try the exact GitHub org name, or call get_trending_startups / search_startups_by_sector to browse the tracked universe.",
            citation: data.meta.citation,
          },
        };
      }
    
      return {
        content: [
          {
            type: "text" as const,
            text: [
              `${found.name} — Engineering Signal Profile`,
              ``,
              `Sector: ${foundSector}`,
              `Stage: ${found.stage}`,
              `Geography: ${found.geography}`,
              `Commit Velocity (14d): ${found.commitVelocity14d}`,
              `Velocity Change: ${found.commitVelocityChange}`,
              `Contributors: ${found.contributors}`,
              `Contributor Growth: ${found.contributorGrowth}`,
              `New Repos (30d): ${found.newRepos}`,
              `Signal Type: ${found.signalType}`,
              `GitHub: ${found.githubUrl}`,
              found.websiteUrl ? `Website: ${found.websiteUrl}` : null,
              found.linkedinUrl ? `LinkedIn: ${found.linkedinUrl}` : null,
              found.profileUrl ? `Profile: ${found.profileUrl}` : null,
              ``,
              found.description || "",
              ``,
              `Source: ${BASE_URL}`,
              `Citation: ${data.meta.citation}`,
              ``,
              FOOTER,
            ]
              .filter(Boolean)
              .join("\n"),
          },
        ],
        structuredContent: {
          found: true,
          startup: {
            rank: 1,
            name: found.name,
            sector: foundSector,
            stage: found.stage,
            geography: found.geography,
            commitVelocity14d: found.commitVelocity14d,
            commitVelocityChange: found.commitVelocityChange,
            contributors: found.contributors,
            contributorGrowth: found.contributorGrowth,
            newRepos: found.newRepos,
            signalType: found.signalType,
            description: found.description,
            githubUrl: found.githubUrl,
            ...(found.websiteUrl ? { websiteUrl: found.websiteUrl } : {}),
            ...(found.linkedinUrl ? { linkedinUrl: found.linkedinUrl } : {}),
            profileUrl: found.profileUrl,
          },
          citation: data.meta.citation,
        },
      };
    }
Behavior5/5

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

Discloses read-only, idempotent, deterministic nature; no-auth requirement; case-insensitive and normalization-tolerant matching; no-match behavior (found:false, not error); open-world limitation (only ~400 companies). Annotations already provide readOnlyHint, idempotentHint, openWorldHint, but description adds crucial context (7-day refresh cycle, no historical series, expected non-error for unmatched names). No contradiction.

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?

Well-structured with clear sections (WHEN TO USE, DO NOT USE, BEHAVIOR, PARAMETERS, RETURNS, TYPICAL WORKFLOW, LIMITATIONS). Information is front-loaded with return fields. Slightly verbose but each sentence contributes. Could condense some behavioral details but still efficient.

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

Completeness5/5

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

Comprehensive for a single-parameter tool with output schema described in RETURNS. Includes typical workflow linking to sibling tools, limitations (no historical data, no relationship info), and explicitly explains error handling (no-match vs. upstream failure). Output schema is described inline, so no missing pieces.

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

Parameters4/5

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

Schema covers the single parameter 'name' with description and examples. Description adds meaning: explains case-insensitivity, normalization (punctuation/whitespace stripping), and that it accepts either display name or GitHub org slug. Length constraints (1–100) are mentioned in description but not in schema. Overall adds value beyond schema.

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?

Clearly states it returns a full engineering-acceleration profile for a single tracked startup, listing specific fields. Distinguishes from sibling tools by focusing on individual startup deep-dive vs. discovery or methodology.

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

Usage Guidelines5/5

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

Explicit WHEN TO USE (named company queries, deal memos) and DO NOT USE sections (discovery, sector listing, method explanation), with direct references to alternative tools (get_trending_startups, search_startups_by_sector, get_methodology).

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/kindrat86/mcp-deal-flow-signal'

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