{
  "markdown": "# opensolr-mcp\n\nmcp-name: com.opensolr/opensolr-mcp\n\nMCP (Model Context Protocol) server for [Opensolr](https://opensolr.com) —\ngives any AI agent **managed Apache Solr search** as tools: hybrid\n(BM25 + kNN) retrieval, server-side GPU embeddings, document indexing, and\ngrounded RAG answers.\n\n**See it live (real news index, hybrid + AI answer):** https://search.opensolr.com/news__dense?q=how+am+I+supposed+to+save+money%3F\n\nNo embedding model to configure. No vector database to run. One API key.\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `opensolr_search` | Hybrid (keyword + semantic) or pure semantic search, with Solr filters |\n| `opensolr_search_by_image` | Search with a **photo** — Opensolr reads its visual labels, OCR text and any barcode/QR, then searches with those words (no image vector stored) |\n| `opensolr_ai_answer` | Grounded RAG answer: top hybrid hits become the LLM context — same pipeline as the hosted search UI |\n| `opensolr_add_documents` | Index plain text + metadata (embedded server-side) |\n| `opensolr_delete_documents` | Remove documents by id |\n| `opensolr_list_indexes` / `opensolr_index_info` | Inspect the account's indexes |\n| `opensolr_create_index` | Provision a vector-enabled index (`us`, `de`, `fi`) |\n| `opensolr_vector_regions` | Live list of vector-enabled regions |\n\n## Setup\n\nGet a free Opensolr account (free forever, no card) at\n[opensolr.com/register](https://opensolr.com/register) and copy your API key\nfrom **Account**.\n\n### Try it without an account\n\nThere is a public demo account. Point the package at it and everything in this\nREADME works immediately, with no signup:\n\n```bash\nexport OPENSOLR_EMAIL=mcp@opensolr.com\nexport OPENSOLR_API_KEY=420b8b23e7b12dc8ab838932145a5065\n```\n\n`mcp_demo_d1__dense` is already loaded with 300 news articles, so search, filtering\nand grounded answers work the moment you connect. You also get the full write path:\ncreate your own index on the account, ingest into it, query it, delete it.\n\nKnow what you are working with:\n\n- **Anything you create there is deleted after 3 days.** Automatically, without warning\n  or export. That includes indexes you created and every document in them.\n- **The account is shared with everyone reading this.** Your index is visible to them,\n  they can change or delete it, and you can do the same to theirs. Never put anything\n  real, private or client-owned in it.\n- **The limits are per index, and deliberately small.** 200 MB of bandwidth and 50 MB\n  of disk per index. Bandwidth is the one you will hit first: it covers a demo, a\n  tutorial and a proof of concept, and it will not carry an application.\n\nWhen you want an index that is private, yours and still there next week, get your own\nkey — [free forever, no card](https://opensolr.com/register) — and change the two\nvariables above. Nothing else in your code changes.\n\n### Claude Desktop / Claude Code\n\n```json\n{\n  \"mcpServers\": {\n    \"opensolr\": {\n      \"command\": \"uvx\",\n      \"args\": [\"opensolr-mcp\"],\n      \"env\": {\n        \"OPENSOLR_EMAIL\": \"you@example.com\",\n        \"OPENSOLR_API_KEY\": \"YOUR_OPENSOLR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n### Cursor / Windsurf / any MCP client\n\nSame shape — stdio transport, command `uvx opensolr-mcp` (or\n`pipx run opensolr-mcp`), with `OPENSOLR_EMAIL` and `OPENSOLR_API_KEY` in env.\n\n## Example agent session\n\n> **You:** Index our FAQ answers, then find everything about refunds.\n>\n> The agent calls `opensolr_add_documents(index=\"faq__dense\", texts=[...])`,\n> then `opensolr_search(index=\"faq__dense\", query=\"refund policy\", hybrid=True)`\n> — BM25 catches the exact word \"refund\", kNN catches \"giving customers their\n> money back\", and the scores fuse per document.\n\n## Search with a photo\n\n`opensolr_search_by_image` lets the agent search with a **picture** instead of a\ntext query. Opensolr reads the image three ways — visual labels (what it\ndepicts), OCR text (words printed on it), and any barcode / QR code — turns that\ninto words, and runs the normal search. No image vector is stored.\n\n```\nopensolr_search_by_image(index=\"catalog__dense\", image_path=\"/tmp/shelf.jpg\",\n                         using=\"auto\", k=5)\n# using: \"auto\" (engine's choice) | \"meaning\" (visual labels) |\n#        \"text\" (OCR only) | \"code\" (exact barcode/QR) | \"all\" (everything)\n# -> { \"read\": {text, mode, labels, codes}, \"results\": [...] }\n```\n\n`search_mode`, `mode`, `alpha`, `fresh_bias` and `filter_query` behave exactly as\nin `opensolr_search`.\n\n## Notes\n\n- Vector-enabled indexes run on Opensolr's Solr 9.x environments — currently\n  `us` (Chicago), `de` (Germany), `fi` (Finland), fetched live via\n  `opensolr_vector_regions`. Additional dedicated regions can be deployed on\n  request (paid add-on): [support@opensolr.com](mailto:support@opensolr.com).\n- Every index is also plain Apache Solr with the native `/select` API —\n  nothing is locked behind the tools.\n- Python sibling for LangChain: [`langchain-opensolr`](https://pypi.org/project/langchain-opensolr/) ·\n  Product page: [opensolr.com/langchain](https://opensolr.com/langchain)\n\n## How writing works (Data Ingestion API)\n\nWrites go through Opensolr's [Data Ingestion API](https://opensolr.com/learn/api-data-ingestion/204/data-ingestion-api-push-documents-to-your-opensolr-index-programmatically)\n— the same pipeline the Drupal and WordPress connectors use. It is\n**asynchronous**: documents are queued, then embeddings, sentiment, language\nand all crawler-identical derived fields are computed **server-side**, and\ndocuments become searchable within about a minute. Progress is visible in\n**Control Panel → Data Ingestion** — a per-job status board (queued /\nprocessing / completed / failed, with processed / success / failed document\ncounts per job) — and via the `ingest_status` API. Each document's\nidentity is its `uri` (the Solr id is `md5(uri)`): pass a real URL in\nmetadata (`{\"uri\": \"https://...\"}`), or a deterministic one is synthesized\nfrom your id. Re-submitting the same `uri` updates the document. Pass\n`{\"rtf\": True, \"uri\": \"https://.../file.pdf\"}` and the server extracts the\ntext from PDF/DOCX/XLSX for you.\n\n## Lexical-only mode\n\nDon't need vectors? Pure keyword search skips the embedding call entirely —\nzero AI quota, and it works on **any** Opensolr index, including non-vector\nones and older Solr versions.\n\n## Your index schema\n\nDocuments follow the Opensolr document model (`title`, `description`, `text`,\n`meta_*` custom fields). The whole schema, every field and every type suffix,\nis explained in the [Index Schema Reference](https://opensolr.com/opensolr-platform-user-documentation/schema-reference).\nTo see your own copy: **Control Panel → click your\nindex → Configuration → Edit File → schema.xml**. Prefer zero-effort data\nentry? Configure the **Web Crawler** in the Control Panel (Index Tools →\nWebCrawler): add your site URL, validate it, and Opensolr indexes the whole\nsite for you.\n\n\n### Search tuning\n\nRetrieval (search and RAG grounding) runs through the platform's tuned\npipeline: global defaults → your index's saved **Search Tuning** (Control\nPanel → Index Settings → Search Tuning: semantic↔lexical balance, field\nweights, minimum match, search mode, vector candidate pool, content quality\nboost) → optional per-call overrides via `tuning`:\n\n```\ntuning={\"search_mode\": \"keywords_required\", \"fw_title\": 0.2,\n        \"mm\": \"strict\", \"vector_topk\": 500, \"quality_boost\": 0.3}\n```\n\nDefaults match the platform's PHP configuration exactly — customize in the\nControl Panel once, or per call from code.\n\n#### Fresh Results Bias\n\nRank newer documents higher without hiding anything older. Every score is\nmultiplied by a recency curve on `creation_date` — full weight for a document\npublished today, about half after a year:\n\n```python\nstore.similarity_search_with_score(\"solar inverter warranty\", fresh_bias=True)\nclient.hybrid_search(index, query, fresh_bias=True)\nclient.ai_answer(index, question, tuning={\"fresh_bias\": 1})\n```\n\nIt **re-orders and never filters**: the hit count is identical either way,\nnothing old becomes unreachable, and a document with no `creation_date` simply\nkeeps its place instead of being pushed to the bottom. It applies to all three\nretrieval shapes — vector-only, keyword-only and the fused hybrid ranking —\nbecause the boost wraps the final score rather than one half of it. Off by\ndefault.\n\nThis is the same control visitors get as the **Fresh** toggle beside the sort\noptions on the hosted Opensolr search page, so a query behaves identically here\nand there.\n\n> `fresh_bias` and `freshness_boost` are two different knobs and the names\n> invite confusion. `freshness_boost` is a hard window in **days** — anything\n> older is filtered out and the hit count drops. `fresh_bias` filters nothing.\n\n## How it's tested\n\nEvery release is validated against **live Opensolr infrastructure** — no mocks:\n\n- **Unit tests** (offline): location aliases, filter→fq mapping, query building, escaping.\n- **End-to-end suite**: the full write path through the async Data Ingestion\n  queue (queued → server-side enrichment → searchable), semantic / hybrid /\n  lexical retrieval, metadata round-trip, filters, id round-trip (your ids\n  and the Solr `md5(uri)` ids), deletes by id and by query.\n- **Real-corpus validation**: searches run against a 340-document replica of\n  opensolr.com's own production search index. Verified: pure-semantic hits\n  with zero keyword overlap (\"how do I get my data back after a disaster\" →\n  backup &amp; restore docs), cross-lingual queries (Romanian query → English\n  content), exact-term surfacing in hybrid mode, all four hybrid modes, and\n  the full alpha range 0 → 1.\n- **PDF ingestion**: a real PDF ingested via `rtf:true` — server-side text\n  extraction (13k+ chars), automatic content-type detection, then retrieved\n  with a purely semantic query against its contents.\n\nThe tools are exercised live (search modes, ingestion with wait, status,\ndeletes, RAG answers) before every release. RAG grounding is verified\nend-to-end: a question answerable only from the ingested PDF returns the\ncorrect answer sourced from the PDF's extracted text.\n\nMIT license.\n",
  "bytes": 10122,
  "sha": "5a8396ed480c008430091cfe9459a6450d700a9dfcfa4acc95ddb3612a04874a",
  "repo_slug": "phpcip/opensolr-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_opensolr_opensolr_mcp_483d33aa/readme"
}