> ## Documentation Index
> Fetch the complete documentation index at: https://docs.llmquantdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Paper Search

> Semantic search over the LLMQuant Quant Paper corpus — find research papers, then load specific sections on demand.

<Note icon="sparkles">
  **Available as MCP tools**: `paper_search` + `paper_read` — call directly from Claude / Cursor / any MCP client. See [MCP Server](/en/integration/mcp-server) for the 60-second setup.
</Note>

<Badge color="green" icon="circle-check">Live</Badge>
 
<Badge color="blue" size="sm">1 credit · search</Badge>
 
<Badge color="gray" size="sm">free · read</Badge>

## What it does for your agent

`paper_search` returns the most relevant Quant Paper knowledge cards for a natural-language query — research on factors, anomalies, microstructure, ML for finance, and more. Use it as a **literature entry point**: when an agent needs to ground a claim in academic work ("is the momentum crash effect real?", "what does the factor zoo paper actually say?"), call `paper_search` to surface candidate `paperCardId`s + `availableSections`, then `paper_read` to load the exact sections that answer the question.

The vectors are built from `title + abstract + summary + tags`, so a card-level hit is a green light to call `paper_read` for sections — `paper_search` deliberately does **not** return full text.

## Agent flow

```mermaid theme={null}
sequenceDiagram
  participant Agent
  participant MCP as data-mcp
  Agent->>MCP: paper_search(query, topK=5)
  MCP-->>Agent: items[] · paperCardId · summary · availableSections
  Note over Agent: scan summaries + section manifest
  alt summary is enough
    Agent->>Agent: answer from summary + tags
  else need specific sections
    Agent->>MCP: paper_read(paperCardId, sections=[keys])
    MCP-->>Agent: sections[].content (Markdown)
  else need full paper
    Agent->>MCP: paper_read(paperCardId, sections=["all"])
    MCP-->>Agent: full sections[] in order
  end
```

## Response

### `paper_search` response

<ResponseField name="data" type="PaperCard[]" required>
  Ranked array of paper cards (highest relevance first).

  <Expandable title="PaperCard fields">
    <ResponseField name="paperCardId" type="string" required>
      Stable identifier. Pass to `paper_read` to load section content.
    </ResponseField>

    <ResponseField name="sourcePaperId" type="string" required>
      Identifier from the original source (e.g. arXiv ID).
    </ResponseField>

    <ResponseField name="title" type="string" required>
      Paper title.
    </ResponseField>

    <ResponseField name="authors" type="string[]" required>
      List of paper authors.
    </ResponseField>

    <ResponseField name="abstract" type="string" required>
      Original abstract of the paper.
    </ResponseField>

    <ResponseField name="summary" type="string" required>
      LLM-generated 2–3 sentence summary. **Use this to decide whether to spend a `paper_read` call** on full sections.
    </ResponseField>

    <ResponseField name="tags" type="string[]" required>
      Research topic tags (e.g. `factor`, `momentum`, `deep-learning`).
    </ResponseField>

    <ResponseField name="availableSections" type="object[]" required>
      Section manifest. Each entry has `section_key`, `section_type`, `title`, `char_count`, `section_order`. Use the `section_key` values when calling `paper_read`.
    </ResponseField>

    <ResponseField name="sectionCount" type="number" required>
      Total number of available sections.
    </ResponseField>

    <ResponseField name="fullTextCharCount" type="number" required>
      Total character count across all sections.
    </ResponseField>

    <ResponseField name="pdfUrl" type="string" required>
      Direct URL to the paper PDF.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta.creditsUsed" type="number">Credits consumed by this call (always `1` for search).</ResponseField>
<ResponseField name="meta.remainingCredits" type="number">Account credits remaining.</ResponseField>

```json title="200 OK · paper_search" expandable theme={null}
{
  "data": [
    {
      "paperCardId": "card_abc123",
      "sourcePaperId": "arxiv:1404.4944",
      "title": "Momentum Crashes",
      "authors": ["Kent Daniel", "Tobias J. Moskowitz"],
      "abstract": "Despite their strong positive abnormal returns, momentum strategies experience infrequent but severe crashes...",
      "summary": "Documents that momentum portfolios crash following bear-market rebounds. The crashes are forecastable in real time using market-state and volatility variables.",
      "tags": ["factor", "momentum", "crash"],
      "availableSections": [
        { "section_key": "introduction", "section_type": "introduction", "title": "Introduction", "char_count": 18420, "section_order": 1 },
        { "section_key": "methodology", "section_type": "method", "title": "Methodology", "char_count": 22150, "section_order": 2 }
      ],
      "sectionCount": 6,
      "fullTextCharCount": 102345,
      "pdfUrl": "https://arxiv.org/pdf/1404.4944"
    }
  ],
  "meta": { "creditsUsed": 1, "remainingCredits": 99 }
}
```

### `paper_read` response

<ResponseField name="data" type="PaperReadResult" required>
  The selected sections of one paper card.

  <Expandable title="PaperReadResult fields">
    <ResponseField name="paperCardId" type="string" required>Stable identifier.</ResponseField>
    <ResponseField name="sourcePaperId" type="string" required>Identifier from the original source.</ResponseField>
    <ResponseField name="title" type="string" required>Paper title.</ResponseField>
    <ResponseField name="authors" type="string[]" required>List of paper authors.</ResponseField>
    <ResponseField name="abstract" type="string" required>Original abstract.</ResponseField>
    <ResponseField name="summary" type="string" required>LLM summary.</ResponseField>
    <ResponseField name="tags" type="string[]" required>Topic tags.</ResponseField>
    <ResponseField name="pdfUrl" type="string" required>Direct URL to the paper PDF.</ResponseField>

    <ResponseField name="availableSections" type="object[]" required>
      Section manifest (same shape as in `paper_search`).
    </ResponseField>

    <ResponseField name="sectionCount" type="number" required>Total number of available sections.</ResponseField>
    <ResponseField name="fullTextCharCount" type="number" required>Total character count across all sections.</ResponseField>

    <ResponseField name="sections" type="object[]" required>
      The requested sections, in `section_order`. Each entry has `section_key`, `section_type`, `title`, `content` (Markdown), `char_count`, `section_order`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta.creditsUsed" type="number">Always `0` for read.</ResponseField>
<ResponseField name="meta.remainingCredits" type="number">Account credits remaining.</ResponseField>

## Notes

<Tip>
  **Two-step lookup is canonical**: `paper_search` returns IDs + summaries + section manifest cheaply (1 credit), then `paper_read` loads only the section(s) you actually need (free). Read top-1's `introduction` + `methodology` first; pull more sections only when you need to verify a specific claim.
</Tip>

<Tip>
  Decide which sections to read **before** calling `paper_read` by inspecting `availableSections[i].char_count` from `paper_search`. Avoid `["all"]` for long papers — pull 1-2 targeted sections to keep agent context small.
</Tip>

<Warning>
  Queries longer than **2,000 characters** are rejected with `400`. Summarize long agent context before calling.
</Warning>

<Warning>
  `topK` is capped at **10** for `paper_search`. Higher values are silently clamped.
</Warning>

<Warning>
  `paper_search` returns **card-level metadata only** — no full text. To get section content, you must call `paper_read`.
</Warning>

## Direct invocation

<Accordion title="HTTP / SDK examples" icon="terminal">
  <CodeGroup>
    ```typescript MCP (Claude / Cursor) theme={null}
    // 1) Search
    {
      "method": "tools/call",
      "params": {
        "name": "paper_search",
        "arguments": { "query": "momentum crash", "topK": 5 }
      }
    }

    // 2) Read targeted sections from the top hit
    {
      "method": "tools/call",
      "params": {
        "name": "paper_read",
        "arguments": {
          "paperCardId": "card_abc123",
          "sections": ["introduction", "methodology"]
        }
      }
    }
    ```

    ```python Python (HTTP) theme={null}
    import os, requests

    base = "https://api.llmquantdata.com"
    headers = {
        "Authorization": f"Bearer {os.environ['LLMQUANT_API_KEY']}",
        "Content-Type": "application/json",
    }

    # 1) Search
    hits = requests.post(
        f"{base}/api/paper/search",
        headers=headers,
        json={"query": "momentum crash", "topK": 5},
    ).json()["data"]

    # 2) Read targeted sections from the top hit
    top = hits[0]
    paper = requests.post(
        f"{base}/api/paper/read",
        headers=headers,
        json={
            "paperCardId": top["paperCardId"],
            "sections": ["introduction", "methodology"],
        },
    ).json()["data"]

    for section in paper["sections"]:
        print(f"## {section['title']} ({section['char_count']} chars)")
        print(section["content"][:500])
    ```

    ```bash cURL theme={null}
    # 1) Search
    curl -X POST "https://api.llmquantdata.com/api/paper/search" \
      -H "Authorization: Bearer $LLMQUANT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "momentum crash", "topK": 5}'

    # 2) Read targeted sections
    curl -X POST "https://api.llmquantdata.com/api/paper/read" \
      -H "Authorization: Bearer $LLMQUANT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"paperCardId": "card_abc123", "sections": ["introduction", "methodology"]}'
    ```
  </CodeGroup>
</Accordion>

## Full parameter reference

<AccordionGroup>
  <Accordion title="paper_search — request parameters" icon="magnifying-glass">
    <ParamField body="query" type="string" required>
      Natural-language search query. Max 2,000 characters.
    </ParamField>

    <ParamField body="topK" type="number" default={5}>
      Maximum results to return. Range `1–10`.
    </ParamField>
  </Accordion>

  <Accordion title="paper_read — request parameters" icon="book-open">
    <ParamField body="paperCardId" type="string" required>
      The `paperCardId` returned by `paper_search`.
    </ParamField>

    <ParamField body="sections" type="string[]" default={["all"]}>
      Section keys from `availableSections[].section_key`. Pass `["all"]` (the default when omitted) to read every section.
    </ParamField>
  </Accordion>
</AccordionGroup>

## Related

<Columns cols={2}>
  <Card title="Wiki Search" icon="book" href="/en/api/knowledge/wiki-search">
    Same two-step pattern over the curated Quant Wiki corpus (concepts, formulas, factors).
  </Card>

  <Card title="MCP Server setup" icon="plug" href="/en/integration/mcp-server">
    Connect Claude / Cursor / any harness in 60 seconds.
  </Card>
</Columns>
