Skip to content

cosmotron_mcp.tools.citations

get_fixed_citations

get_fixed_citations(session_dir: str) -> dict

Evaluate the fixed citation registry against this session's evidence.

Deterministic, read-only — no LLM call, no network access, never modifies session_context.json/manifest.json/plan.json. Reads results/artefact_registry.json, manifest.json, and tool_call_log.jsonl and checks each entry in cosmotron_mcp.citations_registry.FIXED_CITATIONS against its trigger (which tools ran, which survey, which sampler, …). Only fired entries are returned — nothing is invented for a step that didn't run.

Call this as step (a) of the (optional, post-review) citations gate; pass its components_detected to @literature_scout in citation mode so it never re-cites something already covered here, then pass its citations list straight into write_citations_md.

Parameters:

Name Type Description Default
session_dir str

Session workspace directory.

required

Returns:

Type Description
dict

dict with keys: citations (list of

dict

{component, kind, text, link, arxiv|bibcode|url}link is

dict

always a resolved, clickable arXiv/ADS/repository URL),

dict

components_detected (list of fired component names), session_dir.

Source code in cosmotron_mcp/server.py
@mcp.tool()
@sync_budget_guard
def get_fixed_citations(session_dir: str) -> dict:
    """Evaluate the fixed citation registry against this session's evidence.

    Deterministic, read-only — no LLM call, no network access, never modifies
    session_context.json/manifest.json/plan.json. Reads
    ``results/artefact_registry.json``, ``manifest.json``, and
    ``tool_call_log.jsonl`` and checks each entry in
    ``cosmotron_mcp.citations_registry.FIXED_CITATIONS`` against its trigger
    (which tools ran, which survey, which sampler, …). Only fired entries are
    returned — nothing is invented for a step that didn't run.

    Call this as step (a) of the (optional, post-review) citations gate; pass
    its ``components_detected`` to ``@literature_scout`` in ``citation`` mode
    so it never re-cites something already covered here, then pass its
    ``citations`` list straight into ``write_citations_md``.

    Args:
        session_dir: Session workspace directory.

    Returns:
        ``dict`` with keys: ``citations`` (list of
        ``{component, kind, text, link, arxiv|bibcode|url}`` — ``link`` is
        always a resolved, clickable arXiv/ADS/repository URL),
        ``components_detected`` (list of fired component names), ``session_dir``.
    """
    _require_human_gates(session_dir)
    result = _get_fixed_citations(session_dir)
    _log_tool_call(session_dir, "get_fixed_citations", {})
    return result

write_citations_md

write_citations_md(session_dir: str, fixed_citations: dict, session_citations: list | str | None = None) -> dict

Write CITATIONS.md — the sole sanctioned path for this file.

Never hand-assemble CITATIONS.md elsewhere (same invariant as assemble_sacc_from_session for SACC). Merges fixed_citations (from get_fixed_citations) with an optional session_citations (the ## Session citations block from @literature_scout's citation mode — pass its raw text or a pre-parsed list), rendering every fixed entry with its resolved arXiv/ADS/repository link. Each session citation line is validated — it must carry a verifiable arXiv id or URL (or be the literal NOT FOUND sentinel); a line with neither (e.g. a prose justification instead of an actual citation, the failure mode a small local model produces when it skips the literature search) is dropped, not written, and reported in the return's dropped_session_citations. Deduplicates by arXiv id/URL across both lists. Writes {session_dir}/CITATIONS.md and registers it (artefact type citations_md). Omits the "Session-specific literature" section entirely when session_citations is None/empty (e.g. the orchestrator skipped dispatching the scout because there were no session-specific methodology strings to look up).

Parameters:

Name Type Description Default
session_dir str

Session workspace directory.

required
fixed_citations dict

The dict returned by get_fixed_citations.

required
session_citations list | str | None

Optional @literature_scout citation-mode output (raw text block, list of rendered lines, or list of {methodology, citation} dicts).

None

Returns:

Type Description
dict

dict with keys: path, n_fixed, n_session,

dict

dropped_session_citations (list of {line, reason} for any

dict

session citation rejected for lacking a verifiable link), session_dir.

Source code in cosmotron_mcp/server.py
@mcp.tool()
@sync_budget_guard
def write_citations_md(
    session_dir: str,
    fixed_citations: dict,
    session_citations: list | str | None = None,
) -> dict:
    """Write CITATIONS.md — the sole sanctioned path for this file.

    Never hand-assemble CITATIONS.md elsewhere (same invariant as
    ``assemble_sacc_from_session`` for SACC). Merges ``fixed_citations``
    (from ``get_fixed_citations``) with an optional ``session_citations`` (the
    ``## Session citations`` block from ``@literature_scout``'s ``citation``
    mode — pass its raw text or a pre-parsed list), rendering every fixed
    entry with its resolved arXiv/ADS/repository link. Each session citation
    line is validated — it must carry a verifiable arXiv id or URL (or be the
    literal ``NOT FOUND`` sentinel); a line with neither (e.g. a prose
    justification instead of an actual citation, the failure mode a small
    local model produces when it skips the literature search) is **dropped,
    not written**, and reported in the return's ``dropped_session_citations``.
    Deduplicates by arXiv id/URL across both lists. Writes
    ``{session_dir}/CITATIONS.md`` and registers it (artefact type
    ``citations_md``). Omits the "Session-specific literature" section
    entirely when ``session_citations`` is `None`/empty (e.g. the orchestrator
    skipped dispatching the scout because there were no session-specific
    methodology strings to look up).

    Args:
        session_dir: Session workspace directory.
        fixed_citations: The dict returned by ``get_fixed_citations``.
        session_citations: Optional ``@literature_scout`` citation-mode
            output (raw text block, list of rendered lines, or list of
            ``{methodology, citation}`` dicts).

    Returns:
        ``dict`` with keys: ``path``, ``n_fixed``, ``n_session``,
        ``dropped_session_citations`` (list of ``{line, reason}`` for any
        session citation rejected for lacking a verifiable link), ``session_dir``.
    """
    _require_human_gates(session_dir)
    result = _write_citations_md(session_dir, fixed_citations,
                                  session_citations=session_citations)
    _log_tool_call(session_dir, "write_citations_md", {
        "session_citations": bool(session_citations),
    })
    return result