Back to Blog
Industry News

Building an AI Sourcing Agent on GitHunt

Share this article:

This guide is for developers building AI agents that source technical talent programmatically: recruiting copilots, sourcing bots, ATS integrations, or general-purpose agents that need to find and evaluate GitHub developers on demand.

1. What GitHunt gives your agent

GitHunt provides millisecond access to millions of developers available on GitHub, searchable by location, role, skills, and experience, with per-developer scoring (profile quality, tech stack match, activity) and contact details (email, company, location) where publicly available. Searches are fast enough to call from an agent loop without long waits or GitHub rate-limit exposure.

2. Setup

Option A: Hosted MCP (no API key)

GitHunt runs a hosted MCP server with browser sign-in (OAuth) - nothing to install, no key to manage:

https://mcp.githunt.ai/mcp
  • Claude (web, Desktop, Cowork, mobile): Settings → Connectors → Add custom connector → paste the URL, sign in when prompted.
  • Claude Code: claude mcp add --transport http githunt https://mcp.githunt.ai/mcp, then /mcp to complete sign-in.
  • Other clients: add it as a remote MCP server; the OAuth flow starts automatically.

Hosted MCP calls bill against the same monthly API quota as REST calls.

Get an API key (for REST or local MCP)

  1. Sign in at githunt.ai/account.
  2. Create a key under API Keys. The key is shown once at creation - store it immediately (ghk_live_<40 hex chars>).
  3. Keys can be rotated or revoked from the same page at any time.

Option B: Local MCP (API key)

Run the GitHunt MCP server with npx:

GITHUNT_API_KEY=ghk_live_your_key_here npx githunt-mcp

Claude Code / Claude Desktop config (.mcp.json or the equivalent MCP config file):

{
  "mcpServers": {
    "githunt": {
      "command": "npx",
      "args": ["githunt-mcp"],
      "env": {
        "GITHUNT_API_KEY": "ghk_live_your_key_here"
      }
    }
  }
}

This exposes three tools: search_developers, get_developer, analyze_profile.

Option C: Direct REST

Base URL: https://api.githunt.ai. Send the key on every request as either header:

Authorization: Bearer ghk_live_your_key_here

or

X-Api-Key: ghk_live_your_key_here

3. Tool definitions

Use these directly in your agent's tool-use configuration. Parameter shapes match the REST contracts exactly.

Anthropic tool-use format

[
  {
    "name": "search_developers",
    "description": "Search millions of developers available on GitHub by location, role, and skills. Use this FIRST when looking for candidates - it returns a ranked, scored list in milliseconds. Do not use for looking up a single known username (use get_developer instead).",
    "input_schema": {
      "type": "object",
      "properties": {
        "location": { "type": "string", "description": "Required. City, region, or country, e.g. 'Berlin' or 'Poland'." },
        "role": { "type": "string", "description": "Target role, e.g. 'backend engineer', 'devops', 'ML engineer'." },
        "skills": { "type": "array", "items": { "type": "string" }, "maxItems": 20, "description": "Specific technologies, e.g. ['kubernetes', 'go']." },
        "languages": { "type": "array", "items": { "type": "string" }, "maxItems": 10, "description": "Programming languages, e.g. ['python', 'rust']." },
        "minExperienceYears": { "type": "integer", "minimum": 0, "maximum": 50, "description": "Minimum estimated years of GitHub activity." },
        "isHireable": { "type": "boolean", "description": "Filter to profiles with GitHub's hireable flag set." },
        "strictSkills": { "type": "boolean", "description": "Require all listed skills to match, rather than any." },
        "maxResults": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25, "description": "Number of results to return. Start with the default (25) for a broad first pass." }
      },
      "required": ["location"]
    }
  },
  {
    "name": "get_developer",
    "description": "Fetch a single developer's full ranked profile by GitHub username. Use this after search_developers to get complete details (contact info, full score breakdown) on a specific shortlisted candidate. Fast - served from the same index as search.",
    "input_schema": {
      "type": "object",
      "properties": {
        "login": { "type": "string", "description": "GitHub username, e.g. 'octocat'." }
      },
      "required": ["login"]
    }
  },
  {
    "name": "analyze_profile",
    "description": "Run a deep, live analysis of a developer's GitHub profile (proficiency breakdown, extracted emails, role fit). This is SLOW and EXPENSIVE (live GitHub GraphQL calls) - only use it on a small number of finalists after you've narrowed down candidates with search_developers and get_developer, not on every search result.",
    "input_schema": {
      "type": "object",
      "properties": {
        "username": { "type": "string", "description": "GitHub username to analyze." }
      },
      "required": ["username"]
    }
  }
]

OpenAI function-calling format

[
  {
    "type": "function",
    "function": {
      "name": "search_developers",
      "description": "Search millions of developers available on GitHub by location, role, and skills. Use this FIRST when looking for candidates - it returns a ranked, scored list in milliseconds. Do not use for looking up a single known username (use get_developer instead).",
      "parameters": {
        "type": "object",
        "properties": {
          "location": { "type": "string", "description": "Required. City, region, or country, e.g. 'Berlin' or 'Poland'." },
          "role": { "type": "string", "description": "Target role, e.g. 'backend engineer', 'devops', 'ML engineer'." },
          "skills": { "type": "array", "items": { "type": "string" }, "maxItems": 20, "description": "Specific technologies, e.g. ['kubernetes', 'go']." },
          "languages": { "type": "array", "items": { "type": "string" }, "maxItems": 10, "description": "Programming languages, e.g. ['python', 'rust']." },
          "minExperienceYears": { "type": "integer", "minimum": 0, "maximum": 50, "description": "Minimum estimated years of GitHub activity." },
          "isHireable": { "type": "boolean", "description": "Filter to profiles with GitHub's hireable flag set." },
          "strictSkills": { "type": "boolean", "description": "Require all listed skills to match, rather than any." },
          "maxResults": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25, "description": "Number of results to return. Start with the default (25) for a broad first pass." }
        },
        "required": ["location"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "get_developer",
      "description": "Fetch a single developer's full ranked profile by GitHub username. Use this after search_developers to get complete details (contact info, full score breakdown) on a specific shortlisted candidate. Fast - served from the same index as search.",
      "parameters": {
        "type": "object",
        "properties": {
          "login": { "type": "string", "description": "GitHub username, e.g. 'octocat'." }
        },
        "required": ["login"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "analyze_profile",
      "description": "Run a deep, live analysis of a developer's GitHub profile (proficiency breakdown, extracted emails, role fit). This is SLOW and EXPENSIVE (live GitHub GraphQL calls) - only use it on a small number of finalists after you've narrowed down candidates with search_developers and get_developer, not on every search result.",
      "parameters": {
        "type": "object",
        "properties": {
          "username": { "type": "string", "description": "GitHub username to analyze." }
        },
        "required": ["username"]
      }
    }
  }
]

4. Recommended agent flow

  1. Search broad. Call search_developers with location (and role/skills if known) at the default maxResults of 25. This is cheap and fast - favor a wide first pass over a narrow one.
  2. Shortlist by score. Rank the returned results by score (and the tech_stack_score / activity_score breakdown if your criteria weight one more heavily). Keep the top 3-10 candidates.
  3. Get full detail. Call get_developer for each shortlisted login to pull complete contact info and the full score breakdown before presenting candidates.
  4. Analyze finalists only. Reserve analyze_profile for the 1-3 strongest candidates you're about to act on (reach out, add to a pipeline) - it's a live GitHub call and materially slower/costlier than the other two tools.

Worked example transcript

User: Find me a senior backend engineer in Poland who knows Go and Kubernetes.

Agent calls search_developers:
  { "location": "Poland", "role": "backend engineer", "skills": ["go", "kubernetes"], "minExperienceYears": 5 }

Response (abridged):
  { "data": { "matchedCount": 41, "totalCount": 1247,
      "results": [
        { "login": "jkowalski", "score": 91, "profile_score": 26, "tech_stack_score": 38, "activity_score": 22, "matching_keywords": "go, kubernetes, docker", "github_experience": 7, "location": "Warsaw, Poland", "bio": "Backend @ fintech, Go/k8s", "last_active_date": "2026-07-18", "commit_frequency_label": "Very Active", "commits_per_month": 42, "top_repositories": [{ "name": "k8s-operator", "stars": 1240, "language": "Go" }], "top_oss_contributions": [{ "repository": "kubernetes/kubernetes", "tier_label": "Elite", "commits": 15, "language": "Go" }] },
        { "login": "annanowak", "score": 87, ... },
        ... 23 more ...
      ] } }

Agent picks the top 3 by score, calls get_developer("jkowalski") for full contact info,
then calls analyze_profile("jkowalski") to confirm proficiency depth before recommending
the candidate to the user.

5. Handling errors and quotas

Every response includes meta.quota: { used, limit, month } - read it after every call so your agent can throttle itself before hitting a hard limit, not just after.

  • 429 quota_exceeded: back off. Read the Retry-After header (seconds) and wait at least that long before retrying. Don't retry immediately in a loop.
  • 401 unauthorized: the key is missing, malformed, or revoked. Stop and surface this to the user - don't retry with the same key.
  • 400 invalid_request / 404 not_found: fix the request (e.g. missing location, unknown login) rather than retrying as-is.
  • 500 internal: safe to retry once with backoff; if it persists, treat it as a service issue.

Quota by plan

PlanMonthly calls
Free (trial)50
Pro1000
EnterpriseUnlimited

All plans are additionally capped at 2000 API calls/day as an abuse guard, regardless of monthly quota (negotiable on Enterprise).

If your agent is approaching its monthly quota, direct the user to githunt.ai pricing to upgrade. For volume beyond the Enterprise plan or a higher daily cap, contact GitHunt directly through the account team.

6. Data and etiquette notes

  • Data is sourced from public GitHub profiles and activity; GitHunt does not access private repositories or non-public information.
  • Contact developers respectfully and relevantly - a GitHunt match is a lead, not consent to unsolicited high-volume outreach.
  • The daily call cap (2000/day on every plan) is enforced server-side specifically to prevent mass scraping; design your agent to work within it rather than around it.

Ready to build? Grab a key at githunt.ai/account, skim the API reference, and connect the hosted MCP server at https://mcp.githunt.ai/mcp.