Lune Research

com.luneresearchPublished by luneresearch.comOfficial publisherv3.0.1Updated Nov 6, 2026

Search peer-reviewed papers and research methodology guidance from your AI agent.

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingKnowledge & Memory

Overview

AI-generated overview

Lune Research lets an assistant search full-text peer-reviewed papers, trace citations, extract comparison tables, verify claims and look up…

What you can do
  • Search and browse papers: natural-language search, multi-angle literature sweeps, semantically related papers, conference lists and per-venue paper listings
  • Read and trace: full text of one paper as markdown or JSON, and the citation graph in either direction
  • Analyse across papers: pull the same typed fields out of up to 50 papers, fact-check claims against the corpus with verbatim quotes, and judge whether gathered evidence is sufficient
  • Methodology: search curated guidance on experiment design, evaluation, writing and venues, and read a full guidance document
  • Send feedback about Lune itself, only after the user agrees
When to use it
Useful when answers need peer-reviewed citations: literature reviews, related-work sections, tracing what a paper builds on or what built on it, comparing methods across papers, checking a draft's claims, or getting grounded advice on research methodology.
Requirements
Either the hosted Streamable HTTP endpoint or the local npm package run with npx, which needs Node.js 22 or newer. A credential is required for tool calls: an OAuth sign-in through the browser on the hosted endpoint, or a Lune access key supplied as LUNE_API_KEY (stdio) or in the Authorization header. Network access to Lune's servers.
Before you install
Tool calls need a Lune access key or OAuth sign-in, and usage is billed against a team's plan, daily allowance and credits; an OAuth connection bills the signed-in person's personal team. Keep the key out of shell history and process lists. send_feedback transmits the user's message to the Lune team, so confirm before calling. The hosted endpoint also offers request_capability, which reports a needed capability to Lune once analytics opt-out is confirmed.

Installation

In SourceWeft

  1. Open Lune Research in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/com.luneresearch%2Flune/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "lune-research": {
      "type": "http",
      "url": "https://mcp.luneresearch.com/"
    }
  }
}

README

@retrograde-labs/lune-mcp-server

The official Lune Research MCP server. It lets an AI agent search the full text of papers from top-tier venues, follow citations, and look up curated research-methodology guidance, so its answers can cite each paper by title, authors and venue.

Install

Hosted (recommended). Add this URL to any client that speaks Streamable HTTP:

https://mcp.luneresearch.com

A client that supports MCP authorization signs you in through the browser, so there is no token to paste or rotate. In Claude Code:

bash
claude mcp add --transport http --scope user lune https://mcp.luneresearch.com

Then run /mcp inside Claude Code, choose lune, and sign in through the browser tab that opens.

A client without OAuth support sends a Lune access key in the Authorization header instead. Create one on the Credentials page: open API keys and click New key. This request lists the tools, which makes it a quick way to check a key. It reads the key from LUNE_API_KEY, set from your password manager or a file only you can read:

bash
printf 'Authorization: Bearer %s\n' "$LUNE_API_KEY" |  curl https://mcp.luneresearch.com \    -H @- \    -H "Content-Type: application/json" \    -H "Accept: application/json, text/event-stream" \    -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The key reaches curl on its input, so it stays out of your shell history and the process list.

Setup notes for specific apps are in the docs: web AI apps such as ChatGPT, Claude and Perplexity, and local AI agents such as Cursor, VS Code and Codex.

Local stdio. For clients that only speak stdio, run the package directly and hand it an access key. It needs Node.js 22 or newer:

json
{  "mcpServers": {    "lune": {      "command": "npx",      "args": ["-y", "@retrograde-labs/lune-mcp-server"],      "env": { "LUNE_API_KEY": "lune_your_access_key" }    }  }}

The server reads LUNE_API_KEY from the environment and writes diagnostics to stderr, never stdout, so JSON-RPC framing stays intact.

Tools

Thirteen tools. Most follow a prefix: search_* finds candidates, get_* retrieves something you already have a handle on, and list_* browses. The hosted endpoint also offers request_capability, once Lune has confirmed the user has not opted out of its analytics: an agent calls it to tell Lune about a capability it needed and could not find, and its reply says whether Lune accepted the request. The stdio package does not include it.

Finding papers

ToolWhat it does
search_papersHybrid vector + BM25 search over the corpus
search_papers_manyMany query variants in one call, merged by reciprocal rank fusion
search_related_papersThe nearest neighbors of a paper you already have
list_conferencesIndexed venues, optionally filtered by category
get_conference_papersOne venue's papers, paginated

Reading them

ToolWhat it does
get_paper_fulltextParsed full text, as markdown or JSON
get_paper_citationsThe citation graph, in either direction

Working across many at once

ToolWhat it does
extract_from_papersPull the same structured fields out of a set of papers
verify_claimsCheck each claim against the corpus, with a verbatim quote when one exists
gather_evidenceJudge whether the evidence is sufficient yet, and name what is missing

Research methodology

ToolWhat it does
search_research_guidanceThe curated methodology and reproducibility corpus
get_research_guidance_docThe full text of one guidance document

Feedback

ToolWhat it does
send_feedbackPasses the user's feedback about Lune to the team, once the user agrees

Prompts

Six prompts, which many MCP clients list as slash commands. Each one hands the agent a brief for a common research task and names the tools to call, so the task takes one command instead of a plan you have to spell out.

PromptWhat it doesArguments
/literature_reviewSurvey a topic: the main themes, foundational and recent work, and open gapstopic (+ venues, since_year)
/find_related_workRead your abstract, then find the prior work to cite and distinguish yourself fromabstract (+ venues)
/compare_papersBuild a comparison table across papers, read out of their full texttopic (+ columns)
/verify_draftCheck each claim in a draft, with a verbatim quote when one existsdraft
/trace_citationsTrace a paper's lineage: what it stands on, what stands on itpaper
/research_methodologyGrounded advice on experiment design, ablations, evaluation, rebuttals, venuesquestion

Authentication

The hosted endpoint answers discovery (initialize, tools/list, prompts/list and resources/list) without a credential, so an agent can see the tools before anyone signs in. Running a tool takes one credential, as Authorization: Bearer <credential>. The stdio package reads an access key from LUNE_API_KEY instead. The credential is one of these:

  • An OAuth access token, which an MCP client obtains by signing you in through the browser. Hosted endpoint only.
  • A Lune access key (lune_...), created on the Credentials page under API keys. Works on both transports.

An OAuth connection always bills the signed-in person's personal team, drawing on its plan, daily allowance and credits. An access key bills the team it was created in, so a key is how a shared team's plan pays for an agent. How requests are counted is in quotas and billing.

OAuth for connector builders

Most MCP clients run this flow on their own. If you are building a connector, the details follow. auth.md walks through each request with curl.

A tool call without a credential answers 401 with this challenge:

http
WWW-Authenticate: Bearer resource_metadata="https://mcp.luneresearch.com/.well-known/oauth-protected-resource", scope="papers:read guidance:read account:read"

The protected-resource document it points to names the authorization server in authorization_servers[0]. That server is https://api.luneresearch.com, the authorization server for MCP connectors. It publishes RFC 8414 metadata at https://api.luneresearch.com/.well-known/oauth-authorization-server and has no OpenID Connect discovery document.

EndpointURL
Issuerhttps://api.luneresearch.com
Authorizationhttps://api.luneresearch.com/oauth/authorize
Tokenhttps://api.luneresearch.com/oauth/token
Client registration (RFC 7591)https://api.luneresearch.com/oauth/register
Revocation (RFC 7009)https://api.luneresearch.com/oauth/revoke
JWKShttps://api.luneresearch.com/.well-known/jwks.json
Authorization server metadatahttps://api.luneresearch.com/.well-known/oauth-authorization-server
Protected resource metadatahttps://mcp.luneresearch.com/.well-known/oauth-protected-resource

The flow:

  1. Register a client. Dynamic client registration is the only way to get a client_id; there are no pre-registered client IDs. Clients are public, so there is no secret and the token endpoint auth method is none. A platform that cannot register on the fly can do it once by hand and keep the client_id:

    bash
    curl -X POST https://api.luneresearch.com/oauth/register \  -H "Content-Type: application/json" \  -d '{"client_name": "My connector", "redirect_uris": ["https://example.com/oauth/callback"]}'
  2. Send the person to the authorization endpoint with response_type=code, client_id, redirect_uri, scope, state, code_challenge, code_challenge_method=S256 and resource. PKCE with S256 is required, and so are state and scope.

  3. Handle the callback. After the person signs in and approves, Lune redirects to your redirect_uri with code, state and iss=https://api.luneresearch.com (RFC 9207). Check that state is the one you sent and that iss equals the issuer. If the person declines, the redirect carries error=access_denied with the same state and iss.

  4. Exchange the code. POST grant_type=authorization_code, code, redirect_uri, client_id, code_verifier and resource to the token endpoint as application/x-www-form-urlencoded.

  5. Call the server with Authorization: Bearer <access_token>. Once the token expires the server answers 401 with error="invalid_token". To refresh, POST grant_type=refresh_token and refresh_token to the token endpoint.

Requirements and limits:

  • Request exactly papers:read guidance:read account:read, the scopes the protected-resource document lists. Together they cover every tool.
  • Send resource=https://mcp.luneresearch.com on both the authorization request and the token request. Without it the access token is bound to your client_id instead of the server, and requests on protocol version 2026-07-28 fail with 401 invalid_token, which the person sees as a sign-in loop. Older protocol versions still accept such a token, but only for a transition period.
  • Redirect URIs must use https, http on 127.0.0.1, [::1] or localhost, or a private-use scheme such as cursor://, and must not contain a fragment. The authorization request must repeat a registered URI exactly, port included.
  • An authorization code expires after 10 minutes and works once; a failed exchange uses it up. Access tokens are RS256 JWTs that expire after one hour (expires_in: 3600).
  • Every refresh returns a new refresh token. Store it and drop the old one. Each refresh token is valid for 90 days, so a connection in regular use does not expire. Presenting a refresh token more than 30 seconds after it was replaced revokes every refresh token in that chain, and the person has to connect again. Access tokens already issued keep working until they expire.
  • To disconnect, POST token=<refresh_token> (form-encoded) to the revocation endpoint.

Scopes

papers:read covers the paper corpus, full text and citations, guidance:read covers the research-guidance corpus, and account:read reads your identity and usage.

A credential that lacks the scope a tool needs fails differently depending on its type. An OAuth token gets HTTP 403 with a challenge that names only the missing scope, so the client can ask the person to approve it:

http
WWW-Authenticate: Bearer error="insufficient_scope", error_description="The papers:read scope is required for this request.", resource_metadata="https://mcp.luneresearch.com/.well-known/oauth-protected-resource", scope="papers:read"

An access key gets a tool error that names the missing scope and tells the agent to have you create a key that includes it.

Revoking access

Revoke access keys under API keys and connected apps under OAuth clients on the Credentials page. OAuth connections are listed under your personal team, so select it first. A revoked access key stops working within five minutes. Revoking an app cancels its refresh tokens at once, but the access token it already holds keeps working until it expires, at most an hour later.

Transports

TransportWhereMCP protocol versions
Streamable HTTPhttps://mcp.luneresearch.com2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07
stdionpx -y @retrograde-labs/lune-mcp-server2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07

About the hosted endpoint:

  • /mcp and /v1/mcp answer too, for older installs. Discovery follows the path, so a client on /mcp is pointed at https://mcp.luneresearch.com/.well-known/oauth-protected-resource/mcp. A token bound to any of the three URLs works on all three.
  • Requests are stateless. Each one carries its own credential and there is no session ID, so a client that has been idle for hours keeps working without re-initializing.
  • MCP traffic is POST only. GET and DELETE return 405, so there is no SSE stream to open, and the server sends no notifications of its own. A browser that opens the bare URL is redirected to the docs instead.
  • Send Accept: application/json, text/event-stream. On older protocol versions, a request that leaves out either type gets 406.
  • A request with an Origin header gets 403 unless that origin is on the server's allowlist, so connect from a server or a native client rather than from a web page.
  • JSON-RPC batches, which only older protocol versions use, may hold up to 50 messages. A request body may be up to 1 MB.
  • The Registry manifest is served at https://mcp.luneresearch.com/.well-known/mcp/server.json.

Links

Support

Bug reports and feature requests go to the issue tracker. For account questions, email [email protected]. To report a security issue, follow SECURITY.md.

License

MIT

Source: README.md at commit a376bbf

Tools

13

search_papers

Search papers

Searches full-text, peer-reviewed papers from top-tier venues. Use for questions about academic papers, research topics, literature reviews, surveys, “what's been published on X”, named methods, or any claim that should be backed by a peer-reviewed citation. Returns each paper's metadata and the passages that matched. Hybrid semantic + lexical search over titles, abstracts, and full text. Phrase the query the way a researcher would describe the topic in prose, not a keyword bag. Triggering questions: “what's the latest on diffusion guidance”, “which papers compare against SimPO” (requirements beyond the topic are checked per paper: `conditions`, evidence first in `contexts`). `paper_id` is a handle for YOU to fetch full text via `get_paper_fulltext`; never show it to the user: cite papers by title, authors, and venue. `rerank_score` is the calibrated Cohere Rerank v3.5 relevance (0..1), null when the reranker did not run (a lone term, or a failure); `score` is uncalibrated: keep the hits' order. The top-level `best_score` and `low_confidence` derive from `rerank_score`: `low_confidence` marks weaker matches, so rephrase for stronger ones and still cite a hit that fits; with no reranked hit, `best_score` is null and `low_confidence` false, so judge each hit yourself. Each hit carries metadata, abstract, ids, and `contexts` spans to ground or quote from; `detail: false` returns concise hits with one `snippet`. Page with `offset` (re-call with offset += limit while `has_more` is true and `conditions` match page 1's; offset + limit <= 50). Order with `sort_by` (relevance / date / citations, within the ranked shortlist, not the corpus). Narrow with `year_min` / `year_max` / `venues`.

Parametersyearlimitqueryrequireddetailoffsetvenuessort_byyear_maxyear_minconference

search_papers_many

Search papers (multi-query)

Use for a LITERATURE SWEEP or survey: a research question broad enough to need several angles, e.g. "what's been done on X", a related-work section, or a state-of-the-field summary. One call returns one merged, ranked list of the papers the angles found, with the passages that matched. For a single focused question, use `search_papers` instead. Runs 1 to 25 query variants in ONE call and gets back a single deduped, RRF-merged ranked list with per-paper provenance (`matched_queries`: which of your queries, by index into the echoed `queries`, surfaced each paper, and at what rank): supply several genuinely different angles on the topic (rephrasings, sub-questions, alternate terminology) and the server fuses their ranked lists so the merged result covers more of the corpus than any single query would. Each variant runs the same hybrid retrieval as `search_papers` (Cohere Embed v4 + BM25 + Cohere Rerank v3.5) without its server-side rewrites, because your variants are the expansion: spell out abbreviations and synonyms in the variants themselves. Filters (`conference`, `year`, `year_min`, `year_max`, `venues`) are SHARED across all queries. The envelope reports `queries_run` and, for any variant whose pipeline failed, `queries_failed` (so one bad variant never sinks the batch). `has_more` is always false: the merged shortlist is bounded; widen the query set or filters for more coverage. Each hit carries metadata, abstract, ids, and the matched `contexts` spans to ground or quote from; `detail: false` returns concise hits with one `snippet`. `paper_id` is a handle for YOU to fetch full text via `get_paper_fulltext`; cite papers by title, authors, and venue, never by id. Billing: each query variant counts as one search against your quota (an 8-query call costs 8), since the server runs a full search pipeline per variant; prefer a focused set of genuinely distinct angles over padding the list.

Parametersyearlimitrequireddetailrequiredvenuesqueriesrequiredyear_maxyear_minconference

get_paper_fulltext

Get paper full text

Use this when the user asks “what does the methods/results section say”, wants to quote a specific section, or when the abstract isn't enough to verify a claim. Heavy: only call once a paper looks relevant from `search_papers`, `search_related_papers`, or `get_paper_citations`. `format=markdown` returns one rendered document; `format=json` returns a structured section list. Pass `sections` (case-insensitive headings, e.g. ["Methods"]) to fetch only those sections instead of the whole document.

Parametersformatpaper_idrequiredsections

get_paper_citations

Get paper citations

Use this when the user asks “what does this paper build on”, “what built on this”, traces influence chains, asks for follow-up work, or wants the lineage of an idea. `direction=cited_by` returns indexed papers that cite this one; `direction=cites` returns this paper's parsed references (which may or may not be in the corpus). Each edge carries `contexts`, the citing sentences with their section, which show HOW a work is used (baseline, method borrowed, result disputed). Page with `limit` / `offset`; the response reports `total` and `has_more` so you can walk a large citation set.

Parameterslimitoffsetpaper_idrequireddirection

list_conferences

List conferences

Use this when the user asks “what conferences does Lune track”, “is venue X covered”, or wants a category-level browse (e.g. AI/ML, security, databases, software/systems). Pass `category` as a keyword (`ai`, `security`, ...) to narrow; it matches the conference's research area.

Parameterscategory

get_conference_papers

Get conference papers

Use this when the user asks for papers from a specific conference (optionally a year), e.g. “most-cited NeurIPS 2024 papers”, “show me CCS 2025 accepted papers”, or “what's new in security at IEEE S&P this year”. `sort` is `recency` (newest first, default) or `citations` (most-cited first); page with `limit` / `offset`.

Parameterssortyearlimitoffsetconferencerequired

extract_from_papers

Extract structured fields from papers

Pull a structured table out of up to 50 papers in ONE call: you define the columns (`fields`: each a snake_case `name`, a `type`, and an optional `description`) and an `instruction`, and the server reads each paper's full text and returns one typed row per paper. Use this when you need the SAME facts across many papers, e.g. "dataset, model size, and reported accuracy for each of these papers": one call reads every paper and returns the table. Pass `sections` (case-insensitive headings, e.g. ["Results"]) to focus extraction and cut noise. The model is instructed to use only what each paper states, not to infer; a field it can't ground may be absent or null. Each row carries `truncated` (true when the paper's text overflowed the budget and the tail was dropped, so treat it as partial). A paper with no parsed full text, or one the model couldn't extract, is reported in `papers_failed` (with a `reason`) instead of sinking the batch, so `papers_processed` == rows + failures. Heavy: one model call per paper, so extract only papers you already judged relevant from a search or citation result. For the raw text of a single paper, use get_paper_fulltext instead.

Parametersfieldsrequiredsectionspaper_idsrequiredinstructionrequired

verify_claims

Verify claims against the corpus

Fact-check 1 to 25 natural-language claims against Lune's peer-reviewed corpus in ONE call. For each claim the server retrieves the most relevant passages and an LLM judges the claim ONLY against those passages (never outside knowledge), returning one verdict per claim: `supported`, `unsupported`, or `insufficient_evidence`. Use this to ground a draft before you assert it, to vet a user's claim, or to check your own answer against the literature. Every verdict carries a `verbatim_quote` copied EXACTLY from a retrieved passage (or null when nothing could be quoted, e.g. an insufficient_evidence verdict) plus `supporting_paper_ids` (the corpus papers the verdict relied on); both are verified server-side, the quote is guaranteed to be a real substring of a retrieved passage and the ids are guaranteed to be real retrieved candidates, so you can cite the quote directly without re-checking. Also returns a `confidence` (0..1) and short `reasoning` per claim. Filters (`conference`, `year`, `year_min`, `year_max`, `venues`) scope the evidence search and are shared across every claim; `context` is optional shared framing for the judge. `paper_id`s are fetch handles for get_paper_fulltext, not for showing to the user, cite papers by title, authors, and venue.

Parametersyearclaimsrequiredvenuescontextyear_maxyear_minconference

gather_evidence

Gather evidence and judge sufficiency

Use for a multi-part research task when you need to know whether your gathered evidence is SUFFICIENT, what is still MISSING, and what to search next, without the tool writing the answer. Pass the goal in `task` and your first search angles in `queries`; the server runs one corpus search per angle, decomposes the task into evidence requirements (or use your own via `requirements`), and returns each requirement as covered / partial / missing with the exact `evidence_spans` (verbatim quotes) that support it, plus `next_queries` for the gaps. Default `max_iterations=1` is a one-shot assessment billed len(queries); set `max_iterations>1` AND `max_total_queries>len(queries)` to authorize bounded server-side follow-up searches (billed `max_total_queries`, capped at 25). Optionally pass a `draft` to get per-sentence support checks against the gathered spans. Every covered requirement and supported draft sentence carries a verbatim quote verified server-side, so you can cite it directly. You write the answer; cite papers by title, authors, and venue, not by paper_id.

Parameterstaskrequiredyeardraftvenuesqueriesrequiredyear_maxyear_minconferencerequirementsmax_iterationsrequiredmax_total_queries

search_research_guidance

Search research guidance

Use before recommending experimental design, ablation strategy, evaluation metrics, baselines, reproducibility, paper structure, related-work organisation, venue choice, response-to-reviewers, scientific writing, or methodology in general. Searches the Lune guidance corpus, curated from senior researchers, reproducibility checklists, venue-reviewer guidance, and author tutorials, so methodology advice can cite vetted sources. Triggering questions: “how should I design an ablation for X”, “what's a good evaluation setup for retrieval”, “how do I respond to reviewer 2”, “what's the reproducibility checklist for NeurIPS”, “how should I structure the related-work section”, “what venue should I target for a systems paper on X”. Returns top-K excerpts with source attribution; cite every entry you draw on.

Parameterslimitqueryrequired

get_research_guidance_doc

Get research guidance document

Use this AFTER `search_research_guidance` when you need the full text of a guidance document (not just the matched excerpt), for example to quote a passage or follow a checklist end-to-end. Pass the `doc_id` from a search hit.

Parametersdoc_idrequired

send_feedback

Send feedback to Lune

Sends the user's feedback about Lune to the Lune team. Use it when the user says something about Lune itself (papers it missed, results that did not fit, an error, something that helped, an idea): offer to pass it on, show the user the message you would send, and call this only after they agree. Set `allow_training` only if they also agreed that Lune may train models on it, after telling them they can withdraw that at any time in their Lune account settings. Write the message from what the user said about Lune, leaving out unrelated conversation and personal details.

Parametersmessagerequiredcategoryrequiredallow_training

Version history

2
  1. v3.0.1LatestNov 6, 2026
  2. v2.2.0Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts