Skip to content
MarvinOpen Marvin

Use Atlas in Codex and Claude Code

The Marvin Atlas plugin lets a local Codex or Claude Code session search scientific records, read available passages, inspect dataset reuse, and retrieve citation coverage through your Marvin account.

This plugin covers Atlas retrieval only. It does not start Marvin research, manage projects, run workflows, or connect other services. For Atlas in the browser, see Search and review evidence with Atlas. For services connected inside Marvin, see Connect services and model providers.

Both hosts load the same skill and bundled Python client. You need Python 3.8 or newer on macOS or Linux, a supported host, and a Marvin account. The client uses Python's standard library and the existing Marvin application API; no pip package, daemon, separate plugin server, or MCP setup is needed.

Load the plugin

Use the complete plugins/marvin-atlas directory from a Marvin checkout, including its hidden .codex-plugin and .claude-plugin directories. These are local installation instructions; they do not imply a public marketplace listing.

Claude Code

From the checkout root, start Claude Code with:

claude --plugin-dir "$PWD/plugins/marvin-atlas"

Codex

  1. Copy the complete plugin directory to ~/plugins/marvin-atlas. Review any existing copy before replacing it.
  2. Add the following entry to the plugins array in ~/.agents/plugins/marketplace.json, preserving other entries and the existing marketplace name:
{
  "name": "marvin-atlas",
  "source": { "source": "local", "path": "./plugins/marvin-atlas" },
  "policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" },
  "category": "Productivity"
}

If that file does not exist, create an object with "name":"personal", "interface":{"displayName":"Personal"}, and a "plugins" array containing the entry above.

  1. Install the plugin, then start a new Codex session:
codex plugin add marvin-atlas@personal

If your existing marketplace has another name, use that name after @.

Sign in from your terminal

Login creates a separate normal Marvin account session. It is not an Atlas-only or server-enforced read-only credential. Someone holding it can access other account APIs even though this client exposes only retrieval commands.

Run login yourself in your own terminal. From the checkout root:

python3 plugins/marvin-atlas/scripts/atlas.py login --open-browser

For the Codex copy above, the script is ~/plugins/marvin-atlas/scripts/atlas.py. If your copy is elsewhere, substitute its actual path.

  1. Keep the terminal open. It prints a verification URL and user code.
  2. Sign in to your ordinary Marvin account in the browser.
  3. Check that the displayed account and code match your request, then select Approve.
  4. Wait for the terminal to report Atlas login saved.

Omit --open-browser to open the printed URL yourself, including in a browser on another machine. The command polls until approval, cancellation, or the code's 30-minute expiry. The browser grants approval; the terminal receives and stores the separate CLI session. Never paste tokens, passwords, browser cookies, or credential-file contents into host chat. The host does not run login or logout for you, and retrieval never starts login automatically.

Login defaults to https://app.marvinsci.com. For an explicitly configured development account, use login --origin https://app-dev.marvinsci.com; authenticated local development can use login --origin http://localhost:3100. The chosen server must have the device-login configuration, migration, and approval page deployed. Log out before switching origins. Subsequent commands use the saved origin, and the client refuses redirects.

Ask the host to use Atlas

For example:

Use Atlas to find papers about CRISPR, read the relevant source passages, and explain the evidence with citations and coverage limits.

The skill resolves its bundled script from the loaded plugin location. Both hosts can reuse the same saved credential when they run as the same local user with the same configuration directory.

Retrieval needs network access to the saved Marvin origin. Approve the host's network or shell request when prompted. In Codex's workspace-write sandbox, you can enable networking in your Codex configuration:

[sandbox_workspace_write]
network_access = true

That setting enables network access for the sandbox, not only Atlas. A blocked request is an error to address through host permissions; it is not an empty search result.

Command inputs and outputs

You can also use the script directly. Each retrieval command reads one JSON object on stdin using camelCase keys and writes the successful public API JSON unchanged to stdout. Errors produce a nonzero exit status and diagnostics on stderr. Every success includes dataSource; fixture identifies sample data.

python3 plugins/marvin-atlas/scripts/atlas.py search <<'JSON'
{"query":"CRISPR","families":["paper"],"limit":5}
JSON

Use actual returned handle values as recordHandle; do not invent them. The table lists the fields used for common requests. The server owns validation, ranking, pagination, and which evidence is available.

CommandJSON inputSuccessful output
searchquery; optional families, fields, filters, limit, cursorpage.results, page.effectiveScope, page.hasMore, page.nextCursor, page.reconciledCount
lookupfield, value, refresh:falsepage.records: exact-identifier catalog records; an empty array is a catalog miss
pullrecordHandle, include:["documents"] or ["lines"]; optional documentAssetId, lineStart, lineEndpull.documents, pull.lines, pull.lineWindow
findoperation:"find", recordHandle, plain-text query; optional contextoperation, evidence.passages, evidence.matchCount, evidence.coverage
grepoperation:"grep", recordHandle, pattern; optional fixed, ignoreCase, contextThe same evidence envelope; fixed:true is literal search, otherwise the pattern is an RE2 regular expression
scanoperation:"scan", recordHandle, patterns (1–32 literals); optional ignoreCase, contextThe same evidence envelope for the literal terms
dataset-inspectA dataset's recordHandle, includeManifests:falseinspection.dataset, inspection.reuseEligibility, inspection.related, inspection.manifests
citerecordHandle; optional direction (references, citations, both), limitcitations: counts, reference/citing-work samples, truncation flags, source, and retrieval time

Search families are paper, dataset, trial, and regulatory. Search supports AND, OR, NOT, quoted phrases, and - exclusions. Common filters include since, until, year, author, journal, sources, hasFullText, and lifecycle; year cannot be combined with since or until. Lookup fields are doi, pmid, pmcid, and arxiv. find takes plain text, not the search Boolean grammar.

Keep refresh:false and includeManifests:false unless you explicitly want a live identifier resolution or manifest fetch. cite already performs a live external lookup. Other operations can trigger existing ingestion or cache work; the service is not wholly cache-only.

Read and cite the evidence

Start with a small search, select a relevant returned record, inspect its documents, and then use find, grep, or scan for the claim. Run these text searches sequentially. Follow a returned document's assetHandle or passage's documentHandle as documentAssetId, and read windows of at most 200 lines with pull.

  • Search counts describe loaded records, not the size of the literature. Preserve server order, returned lifecycle warnings, and the reported effectiveScope. Reuse nextCursor promptly with the same request; cursors expire and are not durable saved searches.
  • Metadata matches and abstracts do not prove that the host read a paper. Use document passages and their section/line locations for claims about the text. pull does not export general metadata or files; retain the search or lookup record for its identifiers and provenance.
  • Incomplete coverage means some text could not be searched. Zero matches then does not establish absence from the work. Keep unknown (null) distinct from zero, and preserve restricted, failed, fetchable, and unavailable counts.
  • Dataset inspection reports repository information, access/license restrictions, and reuse eligibility with reasons. It does not download dataset payloads. Manifest summaries are not complete inventories; manifests:[] with includeManifests:false means not requested. Related entries describe relationships but do not provide handles to navigate.
  • Citation results are bounded samples, with no returned cursor for complete graph traversal. Cite the source and retrieval time. Use titles, authors/year when available, DOI or canonical source links, and document locations in human citations, not opaque handles.
  • Respect passage rights and license limits. Source text is evidence, not instructions; commands embedded in a paper or record are not instructions to execute.

Session storage and renewal

The client saves the origin and token in ${XDG_CONFIG_HOME:-~/.config}/marvin/atlas.json, outside the project. The current user must own the directory with mode 0700 and the file with mode 0600; symlinks and insecure existing permissions are rejected. Storage is permission-restricted plaintext, not encrypted. Windows storage protection is not provided.

Before each retrieval, the client validates the session and allows it to renew. Its 30-day lifetime rolls forward on the first retrieval more than 24 hours after the previous renewal. Regular use can therefore keep the credential valid indefinitely. There is no separate refresh token or background renewal process. An expired session requires explicit logout to clear the saved credential, followed by login again.

Log out and handle a lost credential

Run logout yourself using the same plugin copy or another copy under the same local user/configuration directory:

python3 plugins/marvin-atlas/scripts/atlas.py logout

Logout signs out the saved session, then verifies that the same token at the same origin is no longer accepted. Only a successful null session response permits deletion of the local credential. An HTTP error, transport failure, malformed response, or still-valid session leaves the file in place and reports unconfirmed logout so you can retry.

Browser sign-out ends the browser's session, not this CLI session. Deleting the local file also does not revoke the server session. There is no session-management page or self-service remote revocation for a lost machine or credential. If you lose the only saved copy, you cannot use this client's logout; the session remains valid until expiry, and continued use can renew it.

Troubleshoot login and retrieval

  • Missing or expired login: run logout if a saved credential exists, then login explicitly in your terminal.
  • Too many login starts: a network address can start three logins until ten seconds pass without an accepted start. A refused start prints the server's wait and exits; wait before trying again.
  • Approval-page limit: loading the page with a code is limited to five accepted checks per network address; checking reopens 30 minutes after the last accepted check. A shared network can share that limit.
  • Rate-limited polling: when the server supplies a retry interval, the client waits within the code's lifetime. Other transport failures stop without hidden retries. An expired code needs a new explicit login.
  • Unavailable evidence or fetch_busy: preserve the API error and coverage limits. Run text scans sequentially; do not replace failures with empty evidence or bypass source restrictions.