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_projectfor 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:
browse open https://hiveround.com/projects— the marketplace index.browse get markdown body— extract the listing list as Markdown.- For a specific project:
browse open https://hiveround.com/projects/<slug>, thenbrowse 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
qandstage. Verified by sendingmax_raise=300000,sector=Fintech,limit=2&offset=2— none echo back in thefiltersobject on the response, andcountis unchanged. The Markdown-route also acceptsq/stagebut notmax_raise. For max-raise / sector filtering, use the MCPsearch_projectstool (server card explicitly documents these as supported there). The HTTPfiltersecho 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. Thehr_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 beyondContent-TypeandAccept. Don't waste a sign-in flow for a read-only skill. - MCP transport is
streamable-http (post-only). A GET to/api/mcpreturns 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. IncludeAccept: application/json, text/event-streamto support both single-response and streamed-event responses — the server is allowed to choose. - Content negotiation on the public
/projectsroute is unreliable from headless clients. The ECP discovery doc says public routes serve Markdown when the caller isn't a browser (Sec-Fetch-Dest: documentabsent, notext/htmlinAccept), 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/projectsor/api/ecp/projectsroutes, which are content-typed by route, not by header. - Founder fields can be entirely null when the listing is "anonymous". Both
founder.handleandfounder.display_namecome back asnull(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 onseminaraandelastova; populated onwatta,hiveround,arispay-executive-summary. raise.amount_usdis 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.instrumentis 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_usdis almost always null at prototype stage. Present in the schema but populated rarely. Filter onraise.amount_usdfor headline raise size; don't usemonthly_revenue_usdas a maturity proxy without checking presence.- Pagination params are
pageandpage_sizeon the Collection, notlimit/offset.limit/offsetare silently dropped on the ECP HTTP layer (confirmed —count: 5returns unchanged withlimit=2&offset=2). Usepage=2&page_size=24instead. Defaultpage_size=24. The MCPlist_projects/search_projectstools acceptlimit(per the server card examples in/mcp) — these are different parameter conventions; check the layer you're hitting. stagevalues 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).sectoris free-form per posting. Observed:Enterprise SaaS,AI & Agents,Fintech, and absent onwatta(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/projectsdigest leaves status off the per-item block (you have to read theprototype · Enterprise SaaS · anonymous · raising $150ksummary 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.txtcorpus 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/mcpGET envelope only lists tool names, not schemas. For actual argument types, calltools/listover 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_commitmentsexist 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": []
}