hiveround.com

search-investment-projects

Installation

Adds this website's skill for your agents

 

Summary

Discover live startup raises on Hiveround — filter by keyword, stage, and max raise via the site's MCP server (anonymous reads) or the ECP HTTP endpoints, returning slug, name, stage, sector, raise amount, founder handle, and listing URL. Read-only.

FIG. 01
FIG. 02
FIG. 03
FIG. 04
FIG. 05
SKILL.md
220 lines

Hiveround — Search Investment Projects

Purpose

Discover live startup raises on Hiveround — a marketplace where founders post their pitch as markdown and investors point agents at it. Return a list of currently-raising projects (slug, name, stage, sector, raise amount, one-liner, founder handle, listing URL) filtered by keyword, stage, and max raise, plus on-demand the full pitch.md body for any selected project. Read-only; no commitments, no intros sent, no auth required for the discovery path.

When to Use

  • Daily / hourly monitoring of new live raises in a given sector or stage band.
  • Building an investor pipeline: surface candidate projects, then call get_project for diligence.
  • Cross-checking what's "out there" before reaching out to founders directly.
  • Any read-only flow where you'd otherwise scrape the marketplace HTML — the site is explicitly designed to be queried by agents and exposes three structured paths (MCP, ECP JSON-LD, ECP Markdown) before you ever need a browser.

Workflow

Hiveround is an agent-first marketplace. The canonical path is the MCP server at https://hiveround.com/api/mcp — read tools (list_projects, search_projects, get_project) are anonymous, no API key required. A second equally-valid path is the Endpoint Context Protocol (ECP) HTTP layer, which serves the same data as JSON-LD (/api/ecp/projects) or agent-friendly Markdown (/api/ecp-md/projects) over plain GET. Use MCP when your runtime speaks JSON-RPC; use ECP when you only have an HTTP client. Do not drive the browser unless you need to sign in or post a project — the rendered /projects page is a thin Next.js shell over the same APIs and pays a ~50× cost premium for the same data.

1. (Optional) Confirm discovery surface

Every public route advertises the agent surface in Link response headers and at well-known paths. To bootstrap when nothing is hardcoded:

GET https://hiveround.com/.well-known/mcp/server-card.json   → MCP transport + tool list + auth
GET https://hiveround.com/.well-known/ecp                    → ECP route map
GET https://hiveround.com/.well-known/agent-skills/index.json → official Hermes skill manifest
GET https://hiveround.com/llms.txt                           → human/agent intro + live-raise summary

The server card declares anonymousReadAllowed: true for the read tools and pins the API-key prefix as hr_sk_ — verify both before assuming you need auth.

2. Search via MCP (recommended)

curl -X POST https://hiveround.com/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "search_projects",
      "arguments": {
        "q": "ai",
        "stage": "prototype",
        "max_raise_usd": 300000,
        "limit": 24
      }
    }
  }'

The MCP search_projects tool is the only layer that honours all three filters together (keyword + stage + max-raise) — the ECP HTTP query string drops max_raise silently (see gotcha). tools/list returns the live JSON schema for every argument; call it once at skill startup if you want to pin types defensively.

For the newest-first sweep without filters, call list_projects with { "limit": N } (default newest first). For diligence on a specific project, call get_project with { "slug": "<slug>" } — that response includes the full pitch.md description plus founder handle + GitHub URL when the founder isn't anonymous.

3. ECP fallback (when you only have HTTP GET)

If your runtime can't speak JSON-RPC, the ECP layer serves the same data over plain GET. Two distinct URLs — pick by what your consumer wants:

GET https://hiveround.com/api/ecp/projects?q=<kw>&stage=<stage>     → JSON-LD Collection
GET https://hiveround.com/api/ecp-md/projects?q=<kw>&stage=<stage>  → Markdown digest
GET https://hiveround.com/api/ecp/projects/{slug}                   → single project JSON-LD
GET https://hiveround.com/api/ecp-md/projects/{slug}                → single project Markdown

The JSON-LD shape per item: { slug, name, one_liner, description, stage, sector, status, logo_url, raise: { amount_usd, instrument, monthly_revenue_usd }, founder: { handle, display_name, github_url, profile_url }, posted_at, updated_at, links: { self, html, collection, mcp } }. The top-level Collection has count, page, page_size (default 24), filters (echoes only the params the server actually applied — useful for verifying acceptance), and items[].

4. Compose results

For each project of interest, emit slug, name, one_liner, stage, sector, raise.amount_usd, founder.handle (or null for anonymous), and links.html (the user-facing listing URL). If the caller wants diligence material, attach the full markdown description from get_project / /api/ecp-md/projects/{slug}.

Browser fallback

Skip unless you're posting a new project, signing in, or the MCP + ECP endpoints are unreachable. If you must browse:

  1. browse open https://hiveround.com/projects — the marketplace index.
  2. browse get markdown body — extract the listing list as Markdown.
  3. For a specific project: browse open https://hiveround.com/projects/<slug>, then browse get markdown body.

Never click a "request intro" button from the browser — that path expects an authenticated session and triggers an intro request. Use the MCP request_intro tool with an API key instead (out of scope for this read-only skill).

Site-Specific Gotchas

  • ECP HTTP filters only honor q and stage. Verified by sending max_raise=300000, sector=Fintech, limit=2&offset=2 — none echo back in the filters object on the response, and count is unchanged. The Markdown-route also accepts q/stage but not max_raise. For max-raise / sector filtering, use the MCP search_projects tool (server card explicitly documents these as supported there). The HTTP filters echo is your verification surface — always assert it contains every param you sent before trusting the result set.
  • Anonymous reads work on every read tool. Server card sets anonymousReadAllowed: true. The hr_sk_ Bearer key is only required for write tools (request_intro, watch_project, update_watch, list_watches, submit_commitment, acknowledge_commitment, update_commitment_status, send_intro_message, list_commitments, list_intros, read_intro_thread). Read tools — list_projects, search_projects, get_project — work without any headers beyond Content-Type and Accept. Don't waste a sign-in flow for a read-only skill.
  • MCP transport is streamable-http (post-only). A GET to /api/mcp returns the server-info envelope (handy for one-shot health checks: server.name, version, tools[], auth). Actual tool calls require POST with JSON-RPC 2.0 body. Include Accept: application/json, text/event-stream to support both single-response and streamed-event responses — the server is allowed to choose.
  • Content negotiation on the public /projects route is unreliable from headless clients. The ECP discovery doc says public routes serve Markdown when the caller isn't a browser (Sec-Fetch-Dest: document absent, no text/html in Accept), but real-world HTTP clients (curl, bb fetch, default Next.js fetch) often send Accept patterns that resolve to HTML anyway. Don't rely on content-negotiation against /projects — call the explicit /api/ecp-md/projects or /api/ecp/projects routes, which are content-typed by route, not by header.
  • Founder fields can be entirely null when the listing is "anonymous". Both founder.handle and founder.display_name come back as null (not omitted — the keys are present). Treat null as the "no founder linked" branch when emitting; don't fall back to the raise's GitHub URL or the project's domain. Observed on seminara and elastova; populated on watta, hiveround, arispay-executive-summary.
  • raise.amount_usd is a raw integer. Listings display "$150k" / "$2.0M" in UI text, but the JSON field is the integer dollar amount (e.g. 150000, 2000000). Format on emit, never re-parse the display string from the Markdown digest — it's already rounded and elides edge cases like odd amounts.
  • raise.instrument is a free-text string, not an enum. Observed value across all 5 live raises: "Open to discussion". Don't assume SAFE/priced-round/convertible classifications — surface the raw string and let the agent reason.
  • raise.monthly_revenue_usd is almost always null at prototype stage. Present in the schema but populated rarely. Filter on raise.amount_usd for headline raise size; don't use monthly_revenue_usd as a maturity proxy without checking presence.
  • Pagination params are page and page_size on the Collection, not limit/offset. limit/offset are silently dropped on the ECP HTTP layer (confirmed — count: 5 returns unchanged with limit=2&offset=2). Use page=2&page_size=24 instead. Default page_size=24. The MCP list_projects / search_projects tools accept limit (per the server card examples in /mcp) — these are different parameter conventions; check the layer you're hitting.
  • stage values observed: prototype, launched. Server card doesn't enumerate the full set. Treat anything else returned as a forward-compatible additional value (don't hard-error).
  • sector is free-form per posting. Observed: Enterprise SaaS, AI & Agents, Fintech, and absent on watta (the field is omitted entirely, not null). When grouping by sector, treat missing as "Unspecified" rather than excluding.
  • status: "open" does NOT appear on the listing-card markdown — only on the JSON-LD shape. The /api/ecp-md/projects digest leaves status off the per-item block (you have to read the prototype · Enterprise SaaS · anonymous · raising $150k summary line and infer). For programmatic status checks, use the JSON-LD route.
  • Cloudflare fronts the origin. Every response carries Cf-Cache-Status, Cf-Ray, etc. The dynamic OG-image route (/opengraph-image) is unreliable and frequently returns 502 — don't rely on it for thumbnails. The static listing pages cache fine; the dynamic image route does not.
  • No rate-limit observed at low volume, but the /llms-full.txt corpus is 100KB+ and re-fetching it tight-loop is uncivil. Pull it once per session, cache locally; let MCP/ECP handle the incremental queries.
  • The /api/mcp GET envelope only lists tool names, not schemas. For actual argument types, call tools/list over POST or read /.well-known/mcp/server-card.json. The server-card lists 14 tools (more than the public landing page's 10) — submit_commitment, acknowledge_commitment, update_commitment_status, list_commitments exist but require auth and are out of scope for read-only search.

Expected Output

{
  "query": { "q": "ai", "stage": "prototype", "max_raise_usd": 300000 },
  "source": "mcp:search_projects",
  "count": 3,
  "page": 1,
  "page_size": 24,
  "projects": [
    {
      "slug": "seminara",
      "name": "Seminara",
      "one_liner": "AI-hosted session platform for education-led sales and onboarding through real-time voice interaction and orchestration.",
      "stage": "prototype",
      "sector": "Enterprise SaaS",
      "status": "open",
      "raise": {
        "amount_usd": 150000,
        "instrument": "Open to discussion",
        "monthly_revenue_usd": null
      },
      "founder": {
        "handle": null,
        "display_name": null,
        "github_url": null,
        "profile_url": null
      },
      "listing_url": "https://hiveround.com/projects/seminara",
      "mcp_get_project_slug": "seminara"
    },
    {
      "slug": "watta",
      "name": "watta",
      "one_liner": "AI workout tracker for rowers. Photograph the erg screen — we read every number off it, score the effort 0–100, and roll training into clubs and leaderboards.",
      "stage": "prototype",
      "sector": null,
      "status": "open",
      "raise": {
        "amount_usd": 250000,
        "instrument": "Open to discussion",
        "monthly_revenue_usd": null
      },
      "founder": {
        "handle": "stevemilton",
        "display_name": "Steve Milton",
        "github_url": "https://github.com/stevemilton",
        "profile_url": "https://hiveround.com/u/stevemilton"
      },
      "listing_url": "https://hiveround.com/projects/watta",
      "mcp_get_project_slug": "watta"
    }
  ]
}

When the caller wants the full pitch for diligence, attach a pitch_markdown field per project, sourced from get_project / /api/ecp-md/projects/{slug}:

{
  "slug": "watta",
  "pitch_markdown": "# watta.\n\nai workout tracker for rowers. take a photo of the erg screen — we\nread every number off it, score the effort 0–100, and roll your\ntraining into clubs and leaderboards.\n\nlive on the app store ..."
}

When the search returns nothing:

{
  "query": { "q": "biotech", "stage": "launched", "max_raise_usd": 100000 },
  "source": "mcp:search_projects",
  "count": 0,
  "projects": []
}