# OpenAlexScholar Integration Process for Literature Citations in MathModelAgent

> Integrate OpenAlexScholar into MathModelAgent for literature citations. Discover the process: email validation, API setup, paper search, caching, and citation injection for academic papers.

- Repository: [Sanjin/mathmodelagent](https://github.com/jihe520/mathmodelagent)
- Tags: how-to-guide
- Published: 2026-03-04

---

**The OpenAlexScholar integration process in MathModelAgent involves email validation, API client initialization, paper search with abstract reconstruction, Redis caching, and citation injection into the Writer agent's generated academic papers.**

MathModelAgent leverages **OpenAlexScholar** as a backend service to fetch scholarly metadata and supply literature citations for automated academic writing. The integration pipeline transforms user-provided credentials into a functional citation retrieval system that reconstructs abstracts, caches results, and formats references for LaTeX output. This article examines the complete implementation from the Vue.js frontend through the FastAPI backend to the Writer agent that consumes the citation data.

## Prerequisites: Configuring the OpenAlex Email

The integration begins with collecting a valid email address to access OpenAlex's "polite pool." In [`frontend/src/stores/apiKeys.ts`](https://github.com/jihe520/mathmodelagent/blob/main/frontend/src/stores/apiKeys.ts), the application maintains a reactive reference `openalexEmail` that persists the user's credentials.

When the user submits their email through the API Key dialog, the frontend invokes the validation endpoint. The [`frontend/src/apis/apiKeyApi.ts`](https://github.com/jihe520/mathmodelagent/blob/main/frontend/src/apis/apiKeyApi.ts) module calls **POST `/validate-openalex-email`**, which the backend handles in [`backend/app/routers/modeling_router.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/routers/modeling_router.py). The router verifies the address by making a test request to `https://api.openalex.org/works?mailto={email}` and stores the validated email in `settings.OPENALEX_EMAIL` for global access.

```typescript
// frontend/src/stores/apiKeys.ts
export const openalexEmail = ref<string>('')

// Validation flow
await validateOpenalexEmail({ email: form.openalex_email })

```

```python

# backend/app/routers/modeling_router.py

@router.post("/validate-openalex-email", response_model=ValidateOpenalexEmailResponse)
async def validate_openalex_email(request: ValidateOpenalexEmailRequest):
    url = f"https://api.openalex.org/works?mailto={request.email}"
    async with httpx.AsyncClient() as client:
        resp = await client.get(url, timeout=5)
        resp.raise_for_status()
    return ValidateOpenalexEmailResponse(valid=True, message="Email is valid")

```

## Initializing the OpenAlex Client

The core client implementation resides in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py). The `OpenAlexScholar` class initializes with a `task_id` for cache isolation and the validated `email` for API authentication. The constructor sets the `base_url` to `https://api.openalex.org` and prepares a custom `User-Agent` header containing the mailto parameter.

```python

# backend/app/tools/openalex_scholar.py

class OpenAlexScholar:
    def __init__(self, task_id: str, email: str = None):
        self.base_url = "https://api.openalex.org"
        self.email = email
        self.task_id = task_id
        self.headers = {"User-Agent": f"OpenAlexScholar/1.0 (mailto:{email})"} if email else {}

```

## Searching and Reconstructing Paper Metadata

The `search_papers(query, limit)` method executes the primary literature retrieval logic. It constructs a request to the `/works` endpoint with a `select` parameter specifying fields including `abstract_inverted_index`, `authorships`, `cited_by_count`, and `publication_year`.

OpenAlex returns abstracts as inverted index objects rather than plain text. The client calls `_get_abstract_from_index()` to reconstruct readable abstracts from this token-position mapping. Each work is then wrapped into a `ScholarMessage` schema defined in [`backend/app/schemas/response.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/schemas/response.py).

```python

# backend/app/tools/openalex_scholar.py

async def search_papers(self, query: str, limit: int = 8) -> List[Dict[str, Any]]:
    params = {
        "search": query,
        "per_page": limit,
        "select": (
            "id,title,display_name,authorships,cited_by_count,doi,"
            "publication_year,biblio,abstract_inverted_index"
        ),
        "mailto": self.email
    }
    
    response = requests.get(
        f"{self.base_url}/works", 
        params=params, 
        headers=self.headers
    )
    response.raise_for_status()
    data = response.json()
    
    # Reconstruct abstracts from inverted index

    for work in data.get("results", []):
        work["abstract"] = self._get_abstract_from_index(
            work.get("abstract_inverted_index")
        )
    return data["results"]

```

## Caching Strategy with Redis

To avoid redundant API calls during iterative paper generation, the integration employs **Redis caching** via [`backend/app/services/redis_manager.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/services/redis_manager.py). The `search_papers` method caches results using a key pattern `f"openalex:{self.task_id}"`, ensuring that subsequent invocations for the same modeling task retrieve literature from the cache rather than the OpenAlex API.

This caching layer significantly improves performance when the Writer agent refines citations or regenerates sections of the academic paper.

## Injecting Citations into Academic Papers

The [`backend/app/core/agents/writer_agent.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/agents/writer_agent.py) consumes the OpenAlexScholar service to enrich generated content. When the **Writer agent** processes a modeling task, it instantiates `OpenAlexScholar` with the current `task.id` and global email settings. The agent calls `search_papers()` with the problem description as the query, then formats the returned metadata into citation strings suitable for academic papers.

```python

# backend/app/core/agents/writer_agent.py

class WriterAgent:
    async def generate_paper(self, task: Task):
        openalex = OpenAlexScholar(task.id, settings.OPENALEX_EMAIL)
        citations = await openalex.search_papers(
            task.problem_description, 
            limit=10
        )
        
        # Format for LaTeX/Markdown

        formatted_refs = [
            f"{c['authorships'][0]['author']['display_name']} "
            f"({c['publication_year']}). {c['title']}."
            for c in citations
        ]
        
        # Inject into LLM prompt

        paper = await self.llm.generate(
            prompt=self._build_prompt(task, formatted_refs)
        )
        return paper

```

## Summary

- **Email Validation**: The integration requires a validated OpenAlex email stored in [`frontend/src/stores/apiKeys.ts`](https://github.com/jihe520/mathmodelagent/blob/main/frontend/src/stores/apiKeys.ts) and verified via [`backend/app/routers/modeling_router.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/routers/modeling_router.py) before any API calls execute.
- **Client Architecture**: `OpenAlexScholar` in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py) manages the HTTP session, User-Agent headers, and abstract reconstruction from inverted index data.
- **Metadata Extraction**: The `search_papers()` method queries `https://api.openalex.org/works` with explicit field selection and reconstructs readable abstracts using `_get_abstract_from_index()`.
- **Performance Optimization**: Redis caching through [`backend/app/services/redis_manager.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/services/redis_manager.py) stores results per `task_id` to minimize external API requests.
- **Agent Integration**: The Writer agent in [`backend/app/core/agents/writer_agent.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/agents/writer_agent.py) instantiates the scholar client, retrieves relevant papers based on the problem description, and injects formatted citations into the final academic output.

## Frequently Asked Questions

### Why does OpenAlexScholar require an email address?

OpenAlex provides a "polite pool" of resources for users who identify themselves via the `mailto` parameter. The integration stores this email in `settings.OPENALEX_EMAIL` and includes it in every request header to ensure reliable API access and comply with OpenAlex's usage policies.

### How does the system handle abstract reconstruction?

The OpenAlex API returns abstracts as `abstract_inverted_index` objects, which map tokens to their positions in the text. The `_get_abstract_from_index()` method in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py) reverses this mapping to reconstruct the original abstract text before wrapping it in the `ScholarMessage` schema.

### What happens if the same query runs multiple times during paper generation?

The `search_papers()` method caches results in Redis using the key pattern `openalex:{task_id}`. Subsequent calls with the same task identifier retrieve data from the cache rather than making redundant requests to the OpenAlex API, improving response times and reducing rate limit consumption.

### Which agent is responsible for formatting the citations?

The **Writer agent** located in [`backend/app/core/agents/writer_agent.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/agents/writer_agent.py) instantiates `OpenAlexScholar`, retrieves relevant papers based on the problem description, and formats the `authorships`, `publication_year`, and `title` fields into citation strings suitable for LaTeX or Markdown academic papers.