Indie Alternatives

io.github.WuDao0123由 GitHub 帳號 WuDao0123 發布v0.2.0更新於 Nov 5, 2026

Find indie-made tools and alternatives to big-name software. 1,500+ products. Logs unmet needs.

已驗證Streamable HTTP可網頁執行效率與工作流網頁搜尋與抓取

概覽

AI 產生的概覽

檢索收錄 1,500 多款獨立開發者產品的目錄,讓助理推薦工具或大牌軟體的替代方案,並可匿名記錄未被滿足的需求。

可以做什麼
  • 依需求(支援任何語言)搜尋獨立產品目錄,可依類別、定價與平台篩選
  • 依 id 取得某個產品的完整說明
  • 目錄中找不到合適結果時,匿名記錄該需求
  • 列出彙整後的未滿足需求,依請求次數排序(營運方可關閉)
適用情境
適合使用者詢問「有沒有做某件事的工具」、想要某個產品的替代方案,或需要軟體推薦時,讓回答立基於整理過的獨立開發者產品目錄,而非只憑模型記憶。
執行需求
透過 streamable HTTP 連線到 indiealternatives.dev 的遠端端點,不需安裝、帳號或 API 金鑰。另有從原始碼複製後執行的本機 stdio 或命令列版本,需要 Node.js 18+(SQLite 伺服器需 22.5+)。
安裝前請注意
記錄未滿足需求的工具會把文字送到第三方服務;伺服器要求助理先移除姓名、聯絡方式與連結,使用者拒絕時不得記錄,寫入前還會再次去識別化。本機安裝預設也會把需求送到託管服務,除非設定 INDIE_ALT_OFFLINE=1。自行架設會暴露由 ADMIN_TOKEN 保護的管理介面。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Indie Alternatives,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.WuDao0123%2Findie-alternatives/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "indie-alternatives": {
      "type": "http",
      "url": "https://indiealternatives.dev/mcp"
    }
  }
}

README

Indie Alternatives

English | 中文 · indiealternatives.dev · List your product

Indie-made alternatives to big-name software, inside any AI assistant:

  1. When a user asks "is there a tool that does X?" or "what's an alternative to Typeform?", the AI searches a catalog of products made by indie makers and recommends the best matches.
  2. When nothing fits, the need is logged anonymously, so indie makers can see what people want that doesn't exist yet.

Quick start

Add this MCP server URL to your AI assistant. No install, no API key:

https://indiealternatives.dev/mcp
ClientHow
ChatGPTSettings → Apps & Connectors → Advanced → Developer mode → Create → paste the URL, auth "None"
Claude (web / desktop)Settings → Connectors → Add custom connector → paste the URL
Claude Codeclaude mcp add --transport http indie-alternatives https://indiealternatives.dev/mcp
Cursor / Windsurf / Gemini CLI{ "mcpServers": { "indie-alternatives": { "url": "https://indiealternatives.dev/mcp" } } }
VS Code{ "servers": { "indie-alternatives": { "type": "http", "url": "https://indiealternatives.dev/mcp" } } } in .vscode/mcp.json

Then ask: "What's a good alternative to Typeform?" or "Is there a tool that turns screenshots into nice social images?"

Makers: list your product for free.

All integration styles

One codebase, every integration style:

IntegrationEndpoint / entryWorks with
MCP (local stdio)node dist/src/stdio.js (from a clone; npm package coming soon)Claude Desktop, Claude Code, Cursor, Windsurf, VS Code Copilot, Cline, Gemini CLI, Codex CLI, Zed, LM Studio, …
MCP (remote HTTP)https://indiealternatives.dev/mcpChatGPT (developer mode / apps), Claude custom connectors, Le Chat, Copilot Studio, and every client above that supports remote MCP
REST + OpenAPIhttps://indiealternatives.dev/openapi.jsonCustom GPTs (GPT Actions), Gemini / Vertex AI, Dify, n8n, Zapier, LangChain, …
Function callinghttps://indiealternatives.dev/functions.json?format=…Your own agent on the OpenAI / Anthropic / Gemini APIs
CLIindie-alternatives search "…"Any agent that can run shell commands

https://indiealternatives.dev/llms.txt describes the service for AIs that read web pages.

Tools

ToolRESTWhat it does
search_toolsGET /api/search?query=…Match a need (any language) against the catalog, with optional category / pricing / platform filters. matched: false means nothing suitable was found.
get_tool_detailsGET /api/products/{id}Full description of a product.
log_unmet_needPOST /api/needsRecord an unmet need anonymously.
list_unmet_needsGET /api/needsAggregated needs, most requested first (hide with HIDE_NEEDS_LIST=1).

Every tool can also be called with POST /api/call/{tool_name}, with the arguments as the request body.

The service tells the AI how to use it (MCP instructions, OpenAPI info.description, llms.txt): when to search, when to log, and to strip personal info before logging.

Privacy

  • A record contains only: a random id, the need text, optional domain / platform / budget, the date (day only), and a fingerprint used to group similar needs.
  • Never stored: user identity, conversation content, IP, User-Agent, exact timestamps. The HTTP server keeps no access log.
  • The server redacts again before writing: emails, phone numbers, links, IPs, ID and card numbers, @handles, messenger IDs and "my name is …" are replaced with placeholders like [email] and [phone].
  • The tool description asks the AI to rewrite the need generically first, and not to log if the user declines.
  • Local installs (npx indie-alternatives-mcp, the CLI) read the latest catalog from https://indiealternatives.dev/catalog.json (falling back to the bundled copy) and send unmet needs to https://indiealternatives.dev/api/needs, so needs from every install are pooled for makers. Only the redacted need fields are sent. Set INDIE_ALT_OFFLINE=1 to keep everything on your machine.
  • Usage stats on the hosted service are daily counters only (e.g. "searches today", "searches with no match", "connections from client X"). Nothing per user or per request is stored.
  • Makers' optional contact email from the submission form is kept private and used only for the review.

Install

Node.js 18+.

bash
npm installnpm run buildnpm test

1. Local MCP clients (run it yourself)

Most people should use the hosted URL above. To run locally from a clone (npm install && npm run build), almost every MCP client uses the same config, in a different file. The npm package (npx -y indie-alternatives-mcp) is coming soon:

json
{  "mcpServers": {    "indie-alternatives": {      "command": "node",      "args": ["/absolute/path/indie-alternatives/dist/src/stdio.js"]    }  }}

(Once the npm package is out: "command": "npx", "args": ["-y", "indie-alternatives-mcp"].)

ClientHow
Claude DesktopEdit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), paste the config, restart
Claude Codeclaude mcp add indie-alternatives -- node /absolute/path/indie-alternatives/dist/src/stdio.js
Cursor.cursor/mcp.json in the project or ~/.cursor/mcp.json
Windsurf~/.codeium/windsurf/mcp_config.json
VS Code (GitHub Copilot).vscode/mcp.json: rename mcpServers to servers and add "type": "stdio"
Cline / Roo CodeMCP Servers panel → Configure
Gemini CLI~/.gemini/settings.json
Codex CLI~/.codex/config.toml:
[mcp_servers.indie-alternatives]
command = "node"
args = ["/absolute/path/indie-alternatives/dist/src/stdio.js"]
Zedcontext_servers in settings.json
LM StudioProgram → Install → Edit mcp.json

Config locations change often; check each client's docs.

To collect needs from everyone's local installs in one place, add "env": { "NEEDS_WEBHOOK_URL": "https://indiealternatives.dev/api/needs" }.

2. Deploy the remote server

Cloudflare Workers + D1 (what indiealternatives.dev runs on)

bash
npx wrangler loginnpx wrangler d1 create indie-alternatives          # copy the database_id into wrangler.jsoncnpm run db:migrate                                  # create the tables in D1npx wrangler secret put ADMIN_TOKEN                 # a long random string, for the review APInpm run deploy

Workers Logs are disabled in wrangler.jsonc to keep the no-access-log promise. To serve on your own domain, add it to Cloudflare DNS and uncomment routes in wrangler.jsonc.

Local development, no Cloudflare account needed: npm run db:migrate:local && npm run dev:worker (put ADMIN_TOKEN=… in .dev.vars).

Node / Docker (self-hosting)

bash
PORT=8787 PUBLIC_URL=https://your-domain DATABASE_FILE=./data.db ADMIN_TOKEN=… npm run start:http

DATABASE_FILE (SQLite via node:sqlite, Node 22.5+) enables maker submissions, the review API and stats; without it, needs go to a JSONL file. Or with Docker:

bash
docker build -t indie-alternatives .docker run -d -p 8787:8787 -e PUBLIC_URL=https://your-domain -e ADMIN_TOKEN=… -v indie-alternatives-data:/data indie-alternatives

For local testing, ngrok http 8787 or cloudflared tunnel --url http://localhost:8787 gives you a temporary HTTPS URL.

/healthz should return {"ok": true}.

Makers: submissions and review

Makers submit at /submit (HTML form) or POST /api/submissions (JSON: name, url, tagline, optional description, categories, tags, pricing, platforms, maker, contact). Submissions wait for review; duplicates and already-listed URLs are rejected. After approval the product is searchable immediately, and makers can show the badge at /badge.svg.

Review API (Authorization: Bearer $ADMIN_TOKEN):

bash
curl -H "authorization: Bearer $ADMIN_TOKEN" https://indiealternatives.dev/api/admin/submissions            # ?status=pending|approved|rejected|allcurl -X POST -H "authorization: Bearer $ADMIN_TOKEN" -H "content-type: application/json" \     -d '{"tags":["typeform alternative","online form"]}' https://indiealternatives.dev/api/admin/submissions/<id>/approve   # body: optional field fixescurl -X POST -H "authorization: Bearer $ADMIN_TOKEN" -d '{"note":"not indie"}' https://indiealternatives.dev/api/admin/submissions/<id>/rejectcurl -X DELETE -H "authorization: Bearer $ADMIN_TOKEN" https://indiealternatives.dev/api/admin/products/<id>curl -H "authorization: Bearer $ADMIN_TOKEN" "https://indiealternatives.dev/api/admin/stats?days=30"       # anonymous daily counterscurl -H "authorization: Bearer $ADMIN_TOKEN" https://indiealternatives.dev/api/admin/needs                  # all unmet needs, grouped

The home page shows the most requested unmet needs publicly, but only needs asked at least 3 times.

3. Remote MCP clients

ClientHow
ChatGPTSettings → Apps & Connectors → Advanced, enable developer mode → Create, URL https://indiealternatives.dev/mcp, auth "None"
Claude (web / desktop)Settings → Connectors → Add custom connector, URL https://indiealternatives.dev/mcp
Cursor / VS Code / Windsurf / Gemini CLIUse "url": "https://indiealternatives.dev/mcp" instead of command + args (VS Code also needs "type": "http")
Le Chat, Copilot Studio, …Add the same URL in their connector / MCP settings

4. Platforms without MCP: import OpenAPI

Custom GPT (GPT Actions): Create a GPT → Configure → Create new action → Import from URL: https://indiealternatives.dev/openapi.json. Auth "None" (or "API Key / Bearer" if you set MCP_AUTH_TOKEN). Add to the GPT instructions:

When the user asks whether there is a tool for something, call search_tools first. If nothing fits, call log_unmet_need to record the need anonymously, after removing all personal information.

Dify: Tools → Custom → Create custom tool → import https://indiealternatives.dev/openapi.json.

n8n / Zapier / others: call the REST endpoints with an HTTP node, or import the OpenAPI spec.

Gemini (Vertex AI Agent Builder): add an OpenAPI tool with the same URL.

5. Your own agent: function calling definitions

bash
curl https://indiealternatives.dev/functions.json?format=openai            # OpenAI Chat Completions toolscurl https://indiealternatives.dev/functions.json?format=openai-responses  # OpenAI Responses API toolscurl https://indiealternatives.dev/functions.json?format=anthropic         # Claude Messages API toolscurl https://indiealternatives.dev/functions.json?format=gemini            # Gemini functionDeclarations

These also work with any OpenAI-compatible model API. When the model returns a tool call, POST the arguments to https://indiealternatives.dev/api/call/{tool_name} and hand the result back to the model.

Example (Python, OpenAI format):

python
import json, requestsfrom openai import OpenAI
BASE = "https://indiealternatives.dev"tools = requests.get(f"{BASE}/functions.json?format=openai").json()client = OpenAI()messages = [{"role": "user", "content": "Is there a tool that adds nice backgrounds to screenshots?"}]
while True:    msg = client.chat.completions.create(model="gpt-5", messages=messages, tools=tools).choices[0].message    messages.append(msg)    if not msg.tool_calls:        print(msg.content)        break    for call in msg.tool_calls:        result = requests.post(f"{BASE}/api/call/{call.function.name}", json=json.loads(call.function.arguments)).json()        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

6. CLI

bash
npm link    # optional: install indie-alternatives as a global commandindie-alternatives search "add a nice background to screenshots"indie-alternatives details shottrindie-alternatives log "turn meeting recordings into notes with action items"indie-alternatives needs

Output is JSON, so any agent that runs shell commands can use it.

Configuration (environment variables)

VariableDefaultDescription
CATALOG_FILEbundled data/products.jsonCatalog JSON file path(s), comma-separated
CATALOG_URLlocal installs: https://indiealternatives.dev/catalog.jsonRemote catalog JSON URL(s), cached 10 minutes, comma-separated; can be combined with CATALOG_FILE
NEEDS_FILE~/.indie-alternatives/needs.jsonlWhere anonymous needs are written (when no database is used)
NEEDS_WEBHOOK_URLlocal installs: https://indiealternatives.dev/api/needsAlso POST every need here, to aggregate needs from many installs
INDIE_ALT_OFFLINE—1 makes local installs use only the bundled catalog and never send needs anywhere
DATABASE_FILE—Node HTTP server: SQLite file for needs, stats, submissions and approved products
ADMIN_TOKEN—Enables the review / stats API at /api/admin/*
HIDE_NEEDS_LIST—1 disables list_unmet_needs (recommended for public deployments)
PORT / HOST8787 / 0.0.0.0HTTP listen address
PUBLIC_URLinferred from headersPublic base URL used in OpenAPI and llms.txt; set it behind a reverse proxy
MCP_AUTH_TOKEN—Require Authorization: Bearer <token> on /mcp and /api/*; docs (/openapi.json, /functions.json, /llms.txt) stay public. ChatGPT connectors can't send a fixed token, so leave it unset for ChatGPT

Bring your own catalog

data/products.json is the catalog served at indiealternatives.dev (1,500+ products). To run your own directory, replace it with an array (or { "products": [...] }) of:

json
{  "id": "unique-id",  "name": "Product name",  "url": "https://...",  "tagline": "One-line pitch",  "description": "Longer description",  "categories": ["Category"],  "tags": ["keywords drive matching", "add synonyms", "in any language"],  "pricing": "free | freemium | paid | commission",  "platforms": ["web", "macos", "windows", "linux", "ios", "android", "self-hosted"],  "maker": "optional: who made it"}

To use a database or another API, implement CatalogSource in src/types.ts (a single load() method). Same for need storage: implement NeedStore (append() / list()), e.g. with Postgres or Supabase.

NEEDS_WEBHOOK_URL receives one record per request:

json
{ "id": "…", "need": "auto-generate subtitles for videos", "category": "Video", "day": "2026-11-05", "fingerprint": "373ca764a387d209" }

How matching works

No external services, everything runs locally: Latin-script text is split into words, CJK text into bigrams, filler words ("is there a tool", "recommend") are dropped, and products are scored with weights name > tags > tagline > categories > description. matched requires at least 60% of the meaningful part of the query to be covered. For a large catalog, swap src/search.ts for vector search; the interface stays the same.

Layout

src/  core.ts      tool definitions and implementation (shared by every integration)  server.ts    MCP server  stdio.ts     local MCP entry  app.ts       HTTP app on web-standard Request/Response: /mcp, /api/*, docs, pages, submissions, admin  http.ts      Node HTTP entry (adapts node:http to app.ts)  worker.ts    Cloudflare Workers entry (D1 storage)  pages.ts     home page, submission form, badge  rest.ts      OpenAPI, function calling and llms.txt generation  catalog.ts   runtime-neutral catalog helpers  sql.ts       D1 / SQLite stores (needs, stats, submissions, products)  sqlite-node.ts  node:sqlite adapter  cli.ts       CLI entry  search.ts    scoring  text.ts      tokenizer (Latin + CJK)  privacy.ts   redaction and need fingerprints  sources.ts   catalog sources and need stores (file, URL, webhook)migrations/          D1 schemawrangler.jsonc       Cloudflare Workers configdata/products.json   sample catalogtest/                testsDockerfile           container build

License

MIT

來源:README.md,提交 260168b

工具

3

search_tools

Find indie-made tools and alternatives

Call when the user asks whether there is a tool for X, or for an alternative to a product. Matches the need against a catalog of indie-made products and returns the most relevant ones. matched=false means nothing suitable was found; then call log_unmet_need to record the need anonymously.

輸入參數limitquery必填pricingcategoryplatform

get_tool_details

Get tool details

Get the full description of a product by the id returned from search_tools.

輸入參數id必填

log_unmet_need

Log an unmet need anonymously

Call when no tool in the catalog meets the user's need. Records the need anonymously so indie makers can discover what to build. Send only the need itself: no names, company names, contact details, links or account handles. The server redacts again and never stores identity, IP or exact time.

輸入參數need必填budgetcategoryplatform

版本歷史

1
  1. v0.2.0最新Nov 5, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分