{"id":"9c849ed5-03f6-429c-a2c3-779d893e1dcc","shortId":"WYHpwq","kind":"skill","title":"find-web-developer","tagline":"Use whenever the user wants to find, shortlist, vet, or enrich US web development firms — building, refreshing, or rebuilding marketing sites, landing pages, ecommerce, WordPress/Webflow/Shopify, headless CMS, microsites, and web frontend work. Triggers on \"find a web developer f","description":"# find-web-developer\n\nDrive the **ServiceGraph API** (`https://api.servicegraph.co`) to find,\nshortlist, and enrich US web development firms. The catalog tags\n~14k firms with `service_provided:web-development` under\n`industry:it_services` (web-development is the second-largest\nservice tag in the catalog).\n\n**Always pin both `industry:it_services` and\n`service_provided:web-development`.** Platforms (WordPress, Webflow,\nShopify, Next.js, etc.) and verticals (B2B, ecommerce, agency-vs-\nstudio) are NOT separate tags — they're keyword substring matches\non firm text.\n\nAny HTTP client works (curl, fetch, requests). Examples below use curl.\n\n## Sibling skills — defer when scope is different\n\nIf the user's ask involves any of the following, defer:\n\n- **Custom backend / API / internal tools / mobile app / distributed\n  systems** → `find-software-developer`. The end-product is software\n  beyond a standard website.\n- **Broader marketing strategy and execution beyond the site build**\n  (paid media, content strategy, full digital agency engagement) →\n  `find-marketing-agency`.\n- **SEO-only work on an existing site** → `find-seo-agency`. Web devs\n  build sites; SEO agencies optimize them. Some overlap exists; if\n  the user wants new pages built AND optimized, this skill is fine.\n\nIf unsure, this skill is correct for \"build / rebuild / refresh a\nwebsite\" tasks. The deferral kicks in when the deliverable is\nnon-website software or non-build marketing work.\n\n## MCP server (preferred for authed calls)\n\nIf your agent harness has the **ServiceGraph MCP server** loaded\n(`https://mcp.servicegraph.co`), prefer its tools for the **authed**\ntier (`/search`, `/get`, `/stats`). The MCP server uses OAuth 2.1 +\nPKCE — the host harness handles credentials in its own audited\nsandbox, so there's no `.env.local`, no shell dispatch, and no token\nvalue ever enters the LLM context.\n\nFor the **anonymous** tier (`/tags`, `/check`, `/explore`), MCP is\n**not** preferred — every MCP tool requires OAuth (the server has no\nanonymous tier), so plain curl against the REST URL is the simpler\npath for discovery calls. Use the REST patterns below for those.\n\nThe MCP tools 1:1-map to the public REST endpoints — same backend,\nsame quota, same data:\n\n| MCP tool | REST endpoint | Anon? | Recommended path |\n|---|---|---|---|\n| `list_tags` | `GET /v1/tags` | yes | curl |\n| `check_filter` | `GET /v1/check` | yes | curl |\n| `explore_firms` | `GET /v1/explore` | yes | curl |\n| `search_firms` | `GET /v1/search` | no | MCP if loaded, else curl + OTP |\n| `get_firm` | `GET /v1/get/:id` | no | MCP if loaded, else curl + OTP |\n| `catalog_stats` | `GET /v1/stats` | no | MCP if loaded, else curl + OTP |\n\n**Detection**: if you see any MCP tools with `servicegraph` in the\nname (the harness-specific prefix varies — agents pattern-match the\nsubstring), the ServiceGraph MCP server is loaded. Prefer those\ntools for the authed tier; complete any auth flow the harness\ninitiates if needed. If no `servicegraph` MCP tools are present,\nfall through to the REST + OTP flow below for the authed tier.\n\n## The four-tier funnel\n\n| Tier | Auth | Cost | Use it for |\n|---|---|---|---|\n| `GET /v1/tags` | none | free | **First call of every session.** Discover legal field names, kinds, operators, values. |\n| `GET /v1/check?filter=...` | none | free | Validate a filter before spending an explore/search call. |\n| `GET /v1/explore?filter=...` | none | free, IP-throttled | Scope: count + breakdowns. Use to size the candidate pool before quota-spending. |\n| `GET /v1/search?filter=...` | bearer | 200 unique firms / month free | Brief firm cards. **No url, no contact info.** Use for ranking / shortlisting. |\n| `GET /v1/get/:id` | bearer | 50 unique firms / month free | Full bundle: url, phone, email, social, legal name, address. **Only call for shortlisted firms.** |\n| `POST /v1/research` | paid | not in MVP | Deferred — skip. |\n\n**Quota rule that matters**: `/search` and `/get` charge per *unique\nfirm viewed per calendar month*, not per call. Re-paging the same\nquery is free. Two different filters that overlap charge once for\nthe overlap. Re-fetching a firm you already pulled this month is free.\n\n## Session-start ritual\n\nBefore constructing any filter, call:\n\n```\nGET https://api.servicegraph.co/v1/tags?include_values=1\n```\n\nCache the response for the conversation. Confirm `web-development` is\npresent in the `service_provided` taxonomy. The parser silently\naccepts unknown tags and returns zero results, so verifying the tag\nname once per session prevents silent failures.\n\nField kinds you'll use most:\n- **categorical**: `industry` (always `it_services`), `state`, `pricing_model`, `company_size_signal`, `geography_served` — op `:`\n- **tag_set_with_evidence**: `service_provided` (always include `web-development`, optionally with `@high` evidence) — op `:` with optional `@evidence`\n- **numeric**: `rating`, `review_count_total`, `founded_year` — ops `= >= <= > <`\n- **presence**: `has:phone`, `has:clutch`, `has:rating`, `has:linkedin_company`, …\n- **keyword**: free-text substring across firm name / brand / title / meta / legal_name. Bareword in the filter becomes a keyword.\n\n## Auth\n\n`/tags`, `/check`, and `/explore` are anonymous. `/search` and `/get`\nrequire a bearer token.\n\n**Security model — keep the token out of the LLM context.**\n\n- **Never** read `.env`, `.env.local`, or any other credential file\n  into your context. The token's literal value should never appear\n  in the conversation.\n- Use shell dispatch for every authed request so the token flows\n  directly from the user's environment / dotenv file into the\n  `Authorization` header without round-tripping through the LLM.\n- **Always ask the user once per session** before using a detected\n  token, even if it's already in their shell or `.env.local`.\n\n**Resolution rule**:\n\n1. **Detect** whether a token is available — without reading its\n   value. Run a shell check that only inspects exit codes:\n\n   ```bash\n   ( [ -n \"${SERVICEGRAPH_TOKEN:-}\" ] \\\n     || grep -qs '^SERVICEGRAPH_TOKEN=' .env.local \\\n     || grep -qs '^SERVICEGRAPH_TOKEN=' .env )\n   ```\n\n   Exit code `0` = token is available somewhere; non-zero = no token.\n\n2. **Confirm with the user** before the first authed call this session:\n\n   > \"I found a `SERVICEGRAPH_TOKEN` in your environment / `.env.local`.\n   > OK to use it for ServiceGraph API requests this session?\"\n\n   If the user says no, stay on the anonymous tiers (`/tags`, `/check`,\n   `/explore`) and skip authed calls. Don't re-ask later unless the\n   user asks for authed work.\n\n3. **Dispatch via shell** — every authed call goes through a shell\n   wrapper so the literal token never enters the conversation:\n\n   ```bash\n   # If exported in the shell environment:\n   curl -H \"Authorization: Bearer $SERVICEGRAPH_TOKEN\" \\\n        'https://api.servicegraph.co/v1/search?filter=...'\n\n   # If in .env.local — source it inside a subshell so it doesn't\n   # leak into the parent shell either:\n   ( set -a; . ./.env.local; set +a;\n     curl -H \"Authorization: Bearer $SERVICEGRAPH_TOKEN\" \\\n          'https://api.servicegraph.co/v1/search?filter=...' )\n   ```\n\n   Capture the response body to a tmp file or jq-process it, but do\n   NOT echo the request command with the token expanded.\n\n4. **OTP flow** if no token is detected — capture the new token\n   directly into `.env.local` without surfacing its value to the LLM:\n\n   ```bash\n   # 1. trigger the email — agent prompts the user for $EMAIL\n   curl -fsS -X POST 'https://api.servicegraph.co/v1/auth/request-otp' \\\n     -H 'Content-Type: application/json' \\\n     -d \"{\\\"email\\\":\\\"$EMAIL\\\"}\"\n\n   # 2. exchange the code — agent prompts the user for $CODE.\n   #    The ?format=env query param returns SERVICEGRAPH_TOKEN=<token>\n   #    as plain text appended to .env.local — no jq needed. The -f\n   #    flag makes curl exit non-zero on 4xx so a wrong code doesn't\n   #    pollute the file (the error mirror is also a `# comment` line,\n   #    safe to ignore even if it lands).\n   curl -fsS -X POST 'https://api.servicegraph.co/v1/auth/verify-otp?format=env' \\\n     -H 'Content-Type: application/json' \\\n     -d \"{\\\"email\\\":\\\"$EMAIL\\\",\\\"code\\\":\\\"$CODE\\\",\\\"name\\\":\\\"claude-cli\\\"}\" \\\n     >> .env.local\n\n   # 3. confirm capture without revealing the value\n   grep -q '^SERVICEGRAPH_TOKEN=' .env.local && echo \"OTP token captured.\"\n   ```\n\n   After a successful capture, the user has implicitly consented\n   (they just completed the flow), so proceed to dispatch (step 3).\n   The token is now persistent in `.env.local` for future sessions.\n\n5. If a `/search` or `/get` returns `401 unauthorized` mid-session,\n   the token expired or was revoked — re-run the OTP flow.\n\n## Filter DSL\n\nOne query parameter, GitHub-search-style.\n\n```\nfilter   := orExpr\norExpr   := andExpr (\"OR\" andExpr)*\nandExpr  := notExpr ((\"AND\")? notExpr)*    # whitespace = implicit AND\nnotExpr  := (\"NOT\" | \"-\") notExpr | atom\natom     := \"(\" filter \")\" | predicate\npredicate:= IDENT op valueOrList | bareword\nop       := \":\" | \"=\" | \">=\" | \"<=\" | \">\" | \"<\"\nvalueOrList := value (\",\" value)*\nvalue    := IDENT | NUMBER | tagAtEvidence\ntagAtEvidence := IDENT \"@\" (\"low\"|\"medium\"|\"high\")\nbareword := IDENT | NUMBER          # → keyword:<bareword>\n```\n\n**Four rules that bite:**\n\n1. **AND binds tighter than OR.** `a OR b c` parses as `a OR (b AND c)`.\n   Use parens.\n2. **Comma list = OR within one predicate.** `state:CA,NY,TX` matches\n   any of the three.\n3. **Negation is `-x` or `NOT x`.** Negative literals inside a comma\n   list are **not** allowed: `state:CA,-NY` is rejected. Use\n   `state:CA -state:NY`.\n4. **Bareword = keyword search.** Any IDENT or NUMBER not followed by\n   an operator becomes a free-text substring across name / brand /\n   title / meta / legal_name. Multiple barewords AND.\n\n**Web-dev examples** (validate yours with `/v1/check`):\n\n```\nindustry:it_services service_provided:web-development\nindustry:it_services service_provided:web-development@high state:CA webflow\nindustry:it_services service_provided:web-development shopify ecommerce\nindustry:it_services service_provided:web-development wordpress\nindustry:it_services service_provided:web-development headless next.js\nindustry:it_services service_provided:web-development@high rating>=4 has:clutch\nindustry:it_services service_provided:web-development b2b\n```\n\nWhen in doubt about whether a filter parses, hit `/v1/check?filter=...`\nfirst — it's free and returns the canonical normalized form.\n\n**Platform / vertical / framework → keyword mapping** (none of these\nare structured tags — keyword them):\n\n| User mentions | Add as keyword |\n|---|---|\n| WordPress | `wordpress` |\n| Webflow | `webflow` |\n| Shopify / Shopify Plus | `shopify` |\n| Squarespace / Wix | `squarespace` / `wix` |\n| Headless / JAMstack / Next.js / Gatsby | `headless`, `next.js`, `gatsby` |\n| Sanity / Contentful / Strapi | `sanity`, `contentful`, `strapi` |\n| Ecommerce / D2C / DTC | `ecommerce`, `d2c` |\n| B2B / SaaS / fintech | `b2b`, `saas`, `fintech` |\n\n## firm_id contract\n\n`firm_id` is a stable 12-hex-char handle:\n\n```\nfirm_id = sha256(apex.lower().rstrip(\".\")).hexdigest()[:12]\n```\n\n`apex` is the registered domain (`focuslabllc.com`, not\n`www.focuslabllc.com/work`). Anyone with an apex list can compute\nfirm_ids locally and call `/v1/get/:id` directly — no `/search`\nneeded for BYO enrichment.\n\n```python\nimport hashlib\ndef firm_id(apex):\n    return hashlib.sha256(apex.lower().rstrip(\".\").encode()).hexdigest()[:12]\n```\n\n```bash\necho -n \"focuslabllc.com\" | tr 'A-Z' 'a-z' \\\n  | openssl dgst -sha256 -hex | awk '{print substr($2,1,12)}'\n```\n\n## Recipes\n\n### A. Marketing landing page (the baseline)\n\nUser: *\"Web developer to build our marketing landing page.\"*\n\n```\nGET /v1/explore?filter=industry:it_services+service_provided:web-development\n# → pool size + breakdowns\n\nGET /v1/search?filter=industry:it_services+service_provided:web-development&limit=10\n# → 10 brief cards; user picks 3\n\nGET /v1/get/<firm_id>     # ×3\n# → urls, phones, emails for outreach\n```\n\n### B. Webflow agency in a state\n\nUser: *\"Three Webflow agencies in California for our marketing site.\"*\n\n`webflow` is a bareword (keyword), not a tag:\n\n```\nGET /v1/search?filter=industry:it_services+service_provided:web-development+webflow+state:CA&limit=10\n```\n\n### C. Shopify ecommerce rebuild\n\nUser: *\"Rebuild our ecommerce site on Shopify with custom theme work.\"*\n\n```\nGET /v1/search?filter=industry:it_services+service_provided:web-development+shopify+ecommerce\n```\n\nFor Shopify Plus specifically, add `plus` as an additional bareword.\n\n### D. WordPress site refresh / maintenance\n\nUser: *\"WordPress dev shop to maintain and refresh our company site.\"*\n\n```\nGET /v1/search?filter=industry:it_services+service_provided:web-development+wordpress\n```\n\n### E. Headless CMS / Next.js\n\nUser: *\"Headless CMS implementation specialists for our Next.js site.\"*\n\n```\nGET /v1/search?filter=industry:it_services+service_provided:web-development+headless+next.js\n```\n\nIf the result is sparse, drop `next.js` first — `headless` alone\ncaptures the architectural pattern; specific frameworks vary.\n\n### F. Indirect intent — \"redesign and rebuild our site\"\n\nUser: *\"Our site is dated and slow — we need someone to redesign and\nrebuild it.\"*\n\nThat's a web-dev procurement ask. Translate:\n\n```\nGET /v1/explore?filter=industry:it_services+service_provided:web-development\n# → confirm pool + breakdowns\n\nGET /v1/search?filter=industry:it_services+service_provided:web-development&limit=10&order_by=relevance\n```\n\nIf the user gave a constraint elsewhere (location, platform, budget\nproxy via `pricing_model`), add it. Otherwise present top-10 by\nrelevance and ask for constraints.\n\n### G. Quality threshold + platform\n\nUser: *\"Three web development studios with at least 4-star ratings,\nShopify Plus experience.\"*\n\n```\nGET /v1/search?filter=industry:it_services+service_provided:web-development@high+rating>=4+shopify+plus&limit=10\n```\n\n### H. BYO apex list — enrich domains the user already has\n\nUser pastes 8–20 web-dev shop domains. For each:\n\n1. Compute `firm_id` locally (see contract above).\n2. `GET /v1/get/<firm_id>` — full bundle if in catalog, 404 (not\n   charged) if not.\n3. Aggregate, present, flag the not-found ones to the user. A 404\n   here often means the firm isn't tagged with web-development\n   specifically — it might be in the catalog under another tag.\n\n## Gotchas\n\n- **Always pin both `industry:it_services` AND `service_provided:web-development`.** Without the industry pin, web-development as a tag also appears on some marketing-agency rows; without the service pin, you'd return all IT-services firms.\n- **Defer to `find-software-developer` for non-website software.** Internal tools, custom CRMs, mobile apps (iOS/Android), backend/API work, distributed systems — these are software-developer territory. The boundary: is the end-product a public website, or something else?\n- **Defer to `find-marketing-agency` for full marketing engagements.** \"Build our site AND run our marketing\" is broader than this skill — fire find-marketing-agency, which has web-design as a sub-service tag too.\n- **Platforms (WordPress, Webflow, Shopify, Next.js) are NOT structured tags.** Keyword them.\n- **Frameworks (React, Vue, Astro, Gatsby) are NOT structured tags either.** Keyword them.\n- **`looks_not_pro_services` 404 is not a bug.** A `firm_id` may exist in `/search` but 404 on `/get` if it's been flagged. Skip and continue; not charged.\n- **`/v1/explore` k=20 suppression.** When fewer than 20 firms match, the response is `{\"count\": \"<20\", \"suppressed\": true, \"breakdowns\": {}}`. Drilling further makes the count smaller. Broaden or escalate to `/v1/search`.\n- **Briefs from `/search` do NOT include `apex`, `url`, `phone_primary`, `email_primary`, `legal_name`, or address.** If the user asks for contact info, you must `/get/:id`. Do not pretend to have it from the brief.\n- **Catalog is US-only B2B.** Refuse offshore asks (\"Manila\", \"Karachi\"), individual freelancers, and DIY/code-help asks (\"debug this CSS\").\n- **CMS/hosting/builder product comparisons aren't procurement.** \"WordPress vs Webflow vs Squarespace\" is a knowledge question, not a firm shortlist.\n- **Multi-word phrases must be split into separate barewords.** `headless cms` parses as two AND'd keywords.\n- **Quota is per-user-per-month, deduped on first view.** Re-views are free; re-pagination is free.\n\n## Errors\n\nAll errors return JSON: `{\"error\": {\"code\": \"...\", \"message\": \"...\"}}`.\n\n| Status | Code | What to do |\n|---|---|---|\n| 400 | `filter_parse_error` | Payload includes `position`. Fix the filter, re-validate with `/v1/check`. |\n| 400 | `filter_required` | Empty filter where one is required. |\n| 400 | `invalid_firm_id` | firm_id must be 12 lowercase hex chars. Re-derive. |\n| 401 | `unauthorized` | Token missing/expired. Re-run OTP. |\n| 404 | `not_found` | Firm not in catalog or flagged. Not charged. Skip and continue. |\n| 429 | `rate_limited` | Honor `Retry-After` header / `retry_after` field. |\n| 429 | `monthly_quota_exhausted` | Switch to `/v1/explore`-only mode for the rest of the month. Tell the user. |\n\nAuthed responses carry `X-RateLimit-*` and `X-Quota-*` headers. Surface\nthe remaining-month value to the user when it gets low so they can\nbudget.\n\n## End-to-end example\n\nUser: *\"Three Webflow agencies in California for our marketing site,\nideally with at least a 4-star rating and a Clutch profile.\"*\n\n```\n# 1. Discover fields (once per session)\nGET /v1/tags?include_values=1\n# Confirms 'web-development' is a valid service_provided tag.\n\n# 2. Validate the filter and scope the pool (free, no auth)\nGET /v1/check?filter=industry:it_services+service_provided:web-development@high+webflow+state:CA+rating>=4+has:clutch\n# → {\"valid\": true, \"normalized\": \"...\"}\n\nGET /v1/explore?filter=industry:it_services+service_provided:web-development@high+webflow+state:CA+rating>=4+has:clutch\n# → {\"count\": 18, \"breakdowns\": {...}}\n# Note: count<20 → suppressed. Broaden by dropping has:clutch or rating>=4.\n\nGET /v1/explore?filter=industry:it_services+service_provided:web-development+webflow+state:CA+rating>=4\n# → {\"count\": 41, \"breakdowns\": {...}}\n\n# 3. Search briefs\nGET /v1/search?filter=...&limit=10\n# Header: Authorization: Bearer $SERVICEGRAPH_TOKEN\n# → 10 brief cards.\n\n# 4. Present briefs to user, get their pick of 3.\n\n# 5. Pull full bundles for the 3 picks\nGET /v1/get/<firm_id>     # ×3\n# → urls, phones, emails for outreach\n```\n\nEnd of session: report `X-Quota-Remaining-Month` so the user knows how\nmuch budget is left.","tags":["find","web","developer","servicegraph","nostrband","agent-skills","ai-agents","b2b-data","claude-code-marketplace","claude-code-plugins","claude-code-skills","claude-plugins"],"capabilities":["skill","source-nostrband","skill-find-web-developer","topic-agent-skills","topic-ai-agents","topic-b2b-data","topic-claude-code-marketplace","topic-claude-code-plugins","topic-claude-code-skills","topic-claude-plugins","topic-claude-skills","topic-mcp-server","topic-openapi","topic-professional-services","topic-vendor-discovery"],"categories":["ServiceGraph"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/nostrband/ServiceGraph/find-web-developer","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add nostrband/ServiceGraph","source_repo":"https://github.com/nostrband/ServiceGraph","install_from":"skills.sh"}},"qualityScore":"0.530","qualityRationale":"deterministic score 0.53 from registry signals: · indexed on github topic:agent-skills · 160 github stars · SKILL.md body (18,567 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:56:04.166Z","embedding":null,"createdAt":"2026-05-06T12:58:11.917Z","updatedAt":"2026-05-18T18:56:04.166Z","lastSeenAt":"2026-05-18T18:56:04.166Z","tsv":"'-10':1976 '/.env.local':1066 '/check':334,804,991 '/explore':335,806,992 '/get':293,632,811,1285,2262,2327 '/search':292,630,809,1283,1649,2258,2304 '/stats':294 '/tags':333,803,990 '/v1/auth/request-otp''':1141 '/v1/auth/verify-otp?format=env''':1218 '/v1/check':405,541,1456,1537,2442,2606 '/v1/explore':411,554,1706,1928,2273,2506,2628,2662 '/v1/get':428,596,1645,1739,2050,2715 '/v1/research':619 '/v1/search':417,575,1720,1771,1802,1841,1866,1942,2002,2301,2684 '/v1/search?filter=...''':1045,1077 '/v1/stats':440 '/v1/tags':399,525,2580 '/v1/tags?include_values=1':686 '/work':1632 '0':939 '1':375,376,903,1125,1359,1687,2040,2573,2583 '10':1731,1732,1785,1953,2018,2687,2693 '12':1611,1622,1667,1688,2460 '14k':65 '18':2647 '2':949,1150,1378,1686,2048,2594 '2.1':300 '20':2032,2275,2280,2287,2651 '200':578 '3':1010,1234,1269,1394,1737,1740,2061,2680,2705,2712,2716 '4':1102,1420,1516,1995,2014,2566,2621,2643,2660,2676,2696 '400':2428,2443,2452 '401':1287,2467 '404':2056,2074,2247,2260,2475 '41':2678 '429':2489,2500 '4xx':1187 '5':1280,2706 '50':599 '8':2031 'a-z':1673,1676 'accept':707 'across':787,1439 'add':1564,1818,1971 'addit':1822 'address':612,2317 'agenc':113,195,200,212,218,1748,1755,2126,2186,2207,2554 'agency-v':112 'agent':276,466,1129,1154 'aggreg':2062 'allow':1409 'alon':1887 'alreadi':668,895,2027 'also':1201,2120 'alway':90,733,751,879,2098 'andexpr':1316,1318,1319 'anon':393 'anonym':331,349,808,988 'anoth':2095 'anyon':1633 'apex':1623,1636,1660,2021,2308 'apex.lower':1619,1663 'api':51,159,976 'api.servicegraph.co':52,685,1044,1076,1140,1217 'api.servicegraph.co/v1/auth/request-otp''':1139 'api.servicegraph.co/v1/auth/verify-otp?format=env''':1216 'api.servicegraph.co/v1/search?filter=...''':1043,1075 'api.servicegraph.co/v1/tags?include_values=1':684 'app':163,2156 'appear':845,2121 'append':1171 'application/json':1146,1223 'architectur':1890 'aren':2360 'ask':150,880,1001,1006,1925,1980,2321,2346,2353 'astro':2234 'atom':1329,1330 'audit':310 'auth':272,290,483,487,511,519,802,854,957,995,1008,1015,2518,2604 'author':870,1039,1071,2689 'avail':909,942 'awk':1683 'b':1367,1373,1746 'b2b':110,1527,1597,1600,2343 'backend':158,384 'backend/api':2158 'bareword':795,1337,1351,1421,1447,1765,1823,2385 'baselin':1695 'bash':923,1030,1124,1668 'bearer':577,598,814,1040,1072,2690 'becom':799,1433 'beyond':176,185 'bind':1361 'bite':1358 'bodi':1081 'boundari':2169 'brand':790,1441 'breakdown':563,1718,1940,2290,2648,2679 'brief':583,1733,2302,2337,2682,2694,2698 'broaden':2297,2653 'broader':180,2199 'budget':1966,2545,2737 'bug':2251 'build':20,188,215,244,265,1700,2191 'built':230 'bundl':605,2052,2709 'byo':1652,2020 'c':1368,1375,1786 'ca':1386,1411,1417,1475,1783,2619,2641,2674 'cach':687 'calendar':639 'california':1757,2556 'call':273,364,529,552,614,643,682,958,996,1016,1644 'candid':568 'canon':1546 'captur':1078,1110,1236,1249,1253,1888 'card':585,1734,2695 'carri':2520 'catalog':63,89,437,2055,2093,2338,2481 'categor':731 'char':1614,2463 'charg':633,657,2058,2272,2485 'check':402,917 'claud':1231 'claude-c':1230 'cli':1232 'client':130 'clutch':776,1518,2571,2623,2645,2657 'cms':31,1854,1858,2387 'cms/hosting/builder':2357 'code':922,938,1153,1159,1191,1227,1228,2421,2424 'comma':1379,1405 'command':1097 'comment':1203 'compani':739,781,1838 'comparison':2359 'complet':485,1261 'comput':1639,2041 'confirm':693,950,1235,1938,2584 'consent':1258 'constraint':1962,1982 'construct':679 'contact':589,2323 'content':191,1144,1221,1587,1590 'content-typ':1143,1220 'context':328,825,837 'continu':2270,2488 'contract':1605,2046 'convers':692,848,1029 'correct':242 'cost':520 'count':562,767,2286,2295,2646,2650,2677 'credenti':306,833 'crms':2154 'css':2356 'curl':132,138,353,401,407,413,423,435,446,1037,1069,1135,1181,1212 'custom':157,1798,2153 'd':1147,1224,1824,2133,2392 'd2c':1593,1596 'data':388 'date':1907 'debug':2354 'dedup':2401 'def':1657 'defer':141,156,624,2140,2181 'deferr':251 'deliver':256 'deriv':2466 'design':2212 'detect':448,889,904,1109 'dev':214,1451,1831,1923,2035 'develop':4,18,42,47,60,72,79,101,169,696,755,1464,1472,1484,1494,1503,1513,1526,1698,1715,1729,1780,1811,1850,1875,1937,1951,1990,2011,2086,2109,2116,2145,2166,2587,2615,2637,2671 'dgst':1680 'differ':145,653 'digit':194 'direct':860,1114,1647 'discov':533,2574 'discoveri':363 'dispatch':319,851,1011,1267 'distribut':164,2160 'diy/code-help':2352 'doesn':1056,1192 'domain':1627,2024,2037 'dotenv':866 'doubt':1530 'drill':2291 'drive':48 'drop':1883,2655 'dsl':1305 'dtc':1594 'e':1852 'echo':1094,1246,1669 'ecommerc':28,111,1486,1592,1595,1788,1793,1813 'either':1063,2240 'els':422,434,445,2180 'elsewher':1963 'email':608,1128,1134,1148,1149,1225,1226,1743,2312,2719 'empti':2446 'encod':1665 'end':172,2173,2547,2549,2722 'end-product':171,2172 'end-to-end':2546 'endpoint':382,392 'engag':196,2190 'enrich':15,57,1653,2023 'enter':325,1027 'env':828,936,1162 'env.local':316,829,900,931,969,1048,1116,1173,1233,1245,1276 'environ':865,968,1036 'error':1198,2415,2417,2420,2431 'escal':2299 'etc':107 'even':891,1208 'ever':324 'everi':340,531,853,1014 'evid':748,759,763 'exampl':135,1452,2550 'exchang':1151 'execut':184 'exhaust':2503 'exist':207,223,2256 'exit':921,937,1182 'expand':1101 'experi':2000 'expir':1294 'explor':408 'explore/search':551 'export':1032 'f':43,1178,1895 'failur':724 'fall':501 'fetch':133,664 'fewer':2278 'field':535,725,2499,2575 'file':834,867,1085,1196 'filter':403,542,547,555,576,654,681,798,1304,1313,1331,1534,1538,1707,1721,1772,1803,1842,1867,1929,1943,2003,2429,2437,2444,2447,2597,2607,2629,2663,2685 'find':2,11,39,45,54,167,198,210,2143,2184,2205 'find-marketing-ag':197,2183,2204 'find-seo-ag':209 'find-software-develop':166,2142 'find-web-develop':1,44 'fine':236 'fintech':1599,1602 'fire':2203 'firm':19,61,66,126,409,415,426,580,584,601,617,636,666,788,1603,1606,1616,1640,1658,2042,2079,2139,2253,2281,2374,2454,2456,2478 'first':528,956,1539,1885,2403 'fix':2435 'flag':1179,2064,2267,2483 'flow':488,507,859,1104,1263,1303 'focuslabllc.com':1628,1671 'follow':155,1429 'form':1548 'format':1161 'found':769,962,2068,2477 'four':515,1355 'four-tier':514 'framework':1551,1893,2231 'free':527,544,557,582,603,651,673,784,1436,1542,2409,2414,2602 'free-text':783,1435 'freelanc':2350 'frontend':35 'fss':1136,1213 'full':193,604,2051,2188,2708 'funnel':517 'futur':1278 'g':1983 'gatsbi':1582,1585,2235 'gave':1960 'geographi':742 'get':398,404,410,416,425,427,439,524,540,553,574,595,683,1705,1719,1738,1770,1801,1840,1865,1927,1941,2001,2049,2540,2579,2605,2627,2661,2683,2701,2714 'github':1310 'github-search-styl':1309 'goe':1017 'gotcha':2097 'grep':927,932,1241 'h':1038,1070,1142,1219,2019 'handl':305,1615 'har':277,304,462,490 'harness-specif':461 'hashlib':1656 'hashlib.sha256':1662 'header':871,2496,2528,2688 'headless':30,1504,1579,1583,1853,1857,1876,1886,2386 'hex':1613,1682,2462 'hex-char':1612 'hexdigest':1621,1666 'high':758,1350,1473,1514,2012,2616,2638 'hit':1536 'honor':2492 'host':303 'http':129 'id':429,597,1604,1607,1617,1641,1646,1659,2043,2254,2328,2455,2457 'ideal':2561 'ident':1334,1343,1347,1352,1425 'ignor':1207 'implement':1859 'implicit':1257,1324 'import':1655 'includ':752,2307,2433,2581 'indirect':1896 'individu':2349 'industri':74,93,732,1457,1465,1477,1487,1496,1506,1519,1708,1722,1773,1804,1843,1868,1930,1944,2004,2101,2112,2608,2630,2664 'info':590,2324 'initi':491 'insid':1051,1403 'inspect':920 'intent':1897 'intern':160,2151 'invalid':2453 'involv':151 'ios/android':2157 'ip':559 'ip-throttl':558 'isn':2080 'it-servic':2136 'jamstack':1580 'jq':1088,1175 'jq-process':1087 'json':2419 'k':2274 'karachi':2348 'keep':818 'keyword':122,782,801,1354,1422,1552,1560,1566,1766,2229,2241,2393 'kick':252 'kind':537,726 'know':2734 'knowledg':2370 'land':26,1211,1692,1703 'largest':84 'later':1002 'leak':1058 'least':1994,2564 'left':2739 'legal':534,610,793,1444,2314 'limit':1730,1784,1952,2017,2491,2686 'line':1204 'linkedin':780 'list':396,1380,1406,1637,2022 'liter':841,1024,1402 'll':728 'llm':327,824,878,1123 'load':283,421,433,444,477 'local':1642,2044 'locat':1964 'look':2243 'low':1348,2541 'lowercas':2461 'maintain':1834 'mainten':1828 'make':1180,2293 'manila':2347 'map':377,1553 'market':24,181,199,266,1691,1702,1760,2125,2185,2189,2197,2206,2559 'marketing-ag':2124 'match':124,469,1389,2282 'matter':629 'may':2255 'mcp':268,281,296,336,341,373,389,419,431,442,453,474,497 'mcp.servicegraph.co':284 'mean':2077 'media':190 'medium':1349 'mention':1563 'messag':2422 'meta':792,1443 'microsit':32 'mid':1290 'mid-sess':1289 'might':2089 'mirror':1199 'missing/expired':2470 'mobil':162,2155 'mode':2508 'model':738,817,1970 'month':581,602,640,671,2400,2501,2514,2533,2730 'much':2736 'multi':2377 'multi-word':2376 'multipl':1446 'must':2326,2380,2458 'mvp':623 'n':924,1670 'name':459,536,611,718,789,794,1229,1440,1445,2315 'need':493,1176,1650,1911 'negat':1395,1401 'never':826,844,1026 'new':228,1112 'next.js':106,1505,1581,1584,1855,1863,1877,1884,2224 'non':259,264,945,1184,2148 'non-build':263 'non-websit':258,2147 'non-zero':944,1183 'none':526,543,556,1554 'normal':1547,2626 'not-found':2066 'note':2649 'notexpr':1320,1322,1326,1328 'number':1344,1353,1427 'numer':764 'ny':1387,1412,1419 'oauth':299,344 'offshor':2345 'often':2076 'ok':970 'one':1306,1383,2069,2449 'op':744,760,771,1335,1338 'openssl':1679 'oper':538,1432 'optim':219,232 'option':756,762 'order':1954 'orexpr':1314,1315 'otherwis':1973 'otp':424,436,447,506,1103,1247,1302,2474 'outreach':1745,2721 'overlap':222,656,661 'page':27,229,646,1693,1704 'pagin':2412 'paid':189,620 'param':1164 'paramet':1308 'paren':1377 'parent':1061 'pars':1369,1535,2388,2430 'parser':705 'past':2030 'path':361,395 'pattern':368,468,1891 'pattern-match':467 'payload':2432 'per':634,638,642,720,884,2397,2399,2577 'per-user-per-month':2396 'persist':1274 'phone':607,774,1742,2310,2718 'phrase':2379 'pick':1736,2703,2713 'pin':91,2099,2113,2131 'pkce':301 'plain':352,1169 'platform':102,1549,1965,1986,2220 'plus':1573,1816,1819,1999,2016 'pollut':1194 'pool':569,1716,1939,2601 'posit':2434 'post':618,1138,1215 'predic':1332,1333,1384 'prefer':270,285,339,478 'prefix':464 'presenc':772 'present':500,698,1974,2063,2697 'pretend':2331 'prevent':722 'price':737,1969 'primari':2311,2313 'print':1684 'pro':2245 'proceed':1265 'process':1089 'procur':1924,2362 'product':173,2174,2358 'profil':2572 'prompt':1130,1155 'provid':69,98,702,750,1461,1469,1481,1491,1500,1510,1523,1712,1726,1777,1808,1847,1872,1934,1948,2008,2106,2592,2612,2634,2668 'proxi':1967 'public':380,2176 'pull':669,2707 'python':1654 'q':1242 'qs':928,933 'qualiti':1984 'queri':649,1163,1307 'question':2371 'quota':386,572,626,2394,2502,2527,2728 'quota-spend':571 'rank':593 'rate':765,778,1515,1997,2013,2490,2568,2620,2642,2659,2675 'ratelimit':2523 're':121,645,663,1000,1299,2406,2411,2439,2465,2472 're-ask':999 're-der':2464 're-fetch':662 're-pag':644 're-pagin':2410 're-run':1298,2471 're-valid':2438 're-view':2405 'react':2232 'read':827,911 'rebuild':23,245,1789,1791,1900,1916 'recip':1689 'recommend':394 'redesign':1898,1914 'refresh':21,246,1827,1836 'refus':2344 'regist':1626 'reject':1414 'relev':1956,1978 'remain':2532,2729 'remaining-month':2531 'report':2725 'request':134,855,977,1096 'requir':343,812,2445,2451 'resolut':901 'respons':689,1080,2284,2519 'rest':356,367,381,391,505,2511 'result':713,1880 'retri':2494,2497 'retry-aft':2493 'return':711,1165,1286,1544,1661,2134,2418 'reveal':1238 'review':766 'revok':1297 'ritual':677 'round':874 'round-trip':873 'row':2127 'rstrip':1620,1664 'rule':627,902,1356 'run':914,1300,2195,2473 'saa':1598,1601 'safe':1205 'sandbox':311 'saniti':1586,1589 'say':983 'scope':143,561,2599 'search':414,1311,1423,2681 'second':83 'second-largest':82 'secur':816 'see':451,2045 'seo':202,211,217 'seo-on':201 'separ':118,2384 'serv':743 'server':269,282,297,346,475 'servic':68,76,85,95,97,701,735,749,1459,1460,1467,1468,1479,1480,1489,1490,1498,1499,1508,1509,1521,1522,1710,1711,1724,1725,1775,1776,1806,1807,1845,1846,1870,1871,1932,1933,1946,1947,2006,2007,2103,2105,2130,2138,2217,2246,2591,2610,2611,2632,2633,2666,2667 'servicegraph':50,280,456,473,496,925,929,934,964,975,1041,1073,1166,1243,2691 'session':532,675,721,885,960,979,1279,1291,2578,2724 'session-start':674 'set':746,1064,1067 'sha256':1618,1681 'shell':318,850,898,916,1013,1020,1035,1062 'shop':1832,2036 'shopifi':105,1485,1571,1572,1574,1787,1796,1812,1815,1998,2015,2223 'shortlist':12,55,594,616,2375 'sibl':139 'signal':741 'silent':706,723 'simpler':360 'site':25,187,208,216,1761,1794,1826,1839,1864,1902,1905,2193,2560 'size':566,740,1717 'skill':140,234,240,2202 'skill-find-web-developer' 'skip':625,994,2268,2486 'slow':1909 'smaller':2296 'social':609 'softwar':168,175,261,2144,2150,2165 'software-develop':2164 'someon':1912 'someth':2179 'somewher':943 'sourc':1049 'source-nostrband' 'spars':1882 'specialist':1860 'specif':463,1817,1892,2087 'spend':549,573 'split':2382 'squarespac':1575,1577,2367 'stabl':1610 'standard':178 'star':1996,2567 'start':676 'stat':438 'state':736,1385,1410,1416,1418,1474,1751,1782,2618,2640,2673 'status':2423 'stay':985 'step':1268 'strapi':1588,1591 'strategi':182,192 'structur':1558,2227,2238 'studio':115,1991 'style':1312 'sub':2216 'sub-servic':2215 'subshel':1053 'substr':123,471,786,1438,1685 'success':1252 'suppress':2276,2288,2652 'surfac':1118,2529 'switch':2504 'system':165,2161 'tag':64,86,119,397,709,717,745,1559,1769,2082,2096,2119,2218,2228,2239,2593 'tagatevid':1345,1346 'task':249 'taxonomi':703 'tell':2515 'territori':2167 'text':127,785,1170,1437 'theme':1799 'three':1393,1753,1988,2552 'threshold':1985 'throttl':560 'tier':291,332,350,484,512,516,518,989 'tighter':1362 'titl':791,1442 'tmp':1084 'token':322,815,820,839,858,890,907,926,930,935,940,948,965,1025,1042,1074,1100,1107,1113,1167,1244,1248,1271,1293,2469,2692 'tool':161,287,342,374,390,454,480,498,2152 'top':1975 'topic-agent-skills' 'topic-ai-agents' 'topic-b2b-data' 'topic-claude-code-marketplace' 'topic-claude-code-plugins' 'topic-claude-code-skills' 'topic-claude-plugins' 'topic-claude-skills' 'topic-mcp-server' 'topic-openapi' 'topic-professional-services' 'topic-vendor-discovery' 'total':768 'tr':1672 'translat':1926 'trigger':37,1126 'trip':875 'true':2289,2625 'two':652,2390 'tx':1388 'type':1145,1222 'unauthor':1288,2468 'uniqu':579,600,635 'unknown':708 'unless':1003 'unsur':238 'url':357,587,606,1741,2309,2717 'us':16,58,2341 'us-on':2340 'use':5,137,298,365,521,564,591,729,849,887,972,1376,1415 'user':8,148,226,863,882,953,982,1005,1132,1157,1255,1562,1696,1735,1752,1790,1829,1856,1903,1959,1987,2026,2029,2072,2320,2398,2517,2537,2551,2700,2733 'valid':545,1453,2440,2590,2595,2624 'valu':323,539,842,913,1120,1240,1340,1341,1342,2534,2582 'valueorlist':1336,1339 'vari':465,1894 'verifi':715 'vertic':109,1550 'vet':13 'via':1012,1968 'view':637,2404,2407 'vs':114,2364,2366 'vue':2233 'want':9,227 'web':3,17,34,41,46,59,71,78,100,213,695,754,1450,1463,1471,1483,1493,1502,1512,1525,1697,1714,1728,1779,1810,1849,1874,1922,1936,1950,1989,2010,2034,2085,2108,2115,2211,2586,2614,2636,2670 'web-design':2210 'web-dev':1449,1921,2033 'web-develop':70,77,99,694,753,1462,1470,1482,1492,1501,1511,1524,1713,1727,1778,1809,1848,1873,1935,1949,2009,2084,2107,2114,2585,2613,2635,2669 'webflow':104,1476,1569,1570,1747,1754,1762,1781,2222,2365,2553,2617,2639,2672 'websit':179,248,260,2149,2177 'whenev':6 'whether':905,1532 'whitespac':1323 'within':1382 'without':872,910,1117,1237,2110,2128 'wix':1576,1578 'word':2378 'wordpress':103,1495,1567,1568,1825,1830,1851,2221,2363 'wordpress/webflow/shopify':29 'work':36,131,204,267,1009,1800,2159 'wrapper':1021 'wrong':1190 'www.focuslabllc.com':1631 'www.focuslabllc.com/work':1630 'x':1137,1214,1397,1400,2522,2526,2727 'x-quota':2525 'x-quota-remaining-month':2726 'x-ratelimit':2521 'year':770 'yes':400,406,412 'z':1675,1678 'zero':712,946,1185","prices":[{"id":"54521de8-7106-4124-bdd9-1f8ef4a85f3c","listingId":"9c849ed5-03f6-429c-a2c3-779d893e1dcc","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"nostrband","category":"ServiceGraph","install_from":"skills.sh"},"createdAt":"2026-05-06T12:58:11.917Z"}],"sources":[{"listingId":"9c849ed5-03f6-429c-a2c3-779d893e1dcc","source":"github","sourceId":"nostrband/ServiceGraph/find-web-developer","sourceUrl":"https://github.com/nostrband/ServiceGraph/tree/main/skills/find-web-developer","isPrimary":false,"firstSeenAt":"2026-05-06T12:58:11.917Z","lastSeenAt":"2026-05-18T18:56:04.166Z"}],"details":{"listingId":"9c849ed5-03f6-429c-a2c3-779d893e1dcc","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"nostrband","slug":"find-web-developer","github":{"repo":"nostrband/ServiceGraph","stars":160,"topics":["agent-skills","ai-agents","b2b-data","claude-code-marketplace","claude-code-plugins","claude-code-skills","claude-plugins","claude-skills","mcp-server","openapi","professional-services","vendor-discovery"],"license":"mit","html_url":"https://github.com/nostrband/ServiceGraph","pushed_at":"2026-05-07T12:11:52Z","description":"AI Agent skills for a structured catalog of 100k+ US professional-services firms","skill_md_sha":"9d11185595584383b737280f2b7cc1fda4f91792","skill_md_path":"skills/find-web-developer/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/nostrband/ServiceGraph/tree/main/skills/find-web-developer"},"layout":"multi","source":"github","category":"ServiceGraph","frontmatter":{"name":"find-web-developer","license":"MIT","description":"Use whenever the user wants to find, shortlist, vet, or enrich US web development firms — building, refreshing, or rebuilding marketing sites, landing pages, ecommerce, WordPress/Webflow/Shopify, headless CMS, microsites, and web frontend work. Triggers on \"find a web developer for a marketing landing page\", \"shortlist three Webflow agencies in California\", \"rebuild our ecommerce site on Shopify\", or \"pull contact info for these 8 web dev shop domains\", even when described indirectly (redesign and rebuild our site, ship a microsite). Drives the ServiceGraph API (api.servicegraph.co) — a 100k+ US firm catalog filterable by industry, services, location, size, ratings. Defer to find-software-developer for custom backend/API/mobile/internal-tool work — anything beyond a website. Defer to find-marketing-agency when scope spans broader marketing beyond the build. Skip in-house web-engineer hires, \"how do I build X\" DIY questions, hosting/CMS-product comparisons, non-US firms, individual freelancers."},"skills_sh_url":"https://skills.sh/nostrband/ServiceGraph/find-web-developer"},"updatedAt":"2026-05-18T18:56:04.166Z"}}