Skip to main content
Glama
LKRCharon

Field Current

by LKRCharon

Field Current

Field Current is a small, self-hosted research library for keeping one narrow field current. It keeps checked paper metadata, abstracts, review decisions, author/affiliation evidence, and canonical BibTeX in one place, with a deliberately bounded read-only MCP surface for research agents. It runs as either one Node process with one SQLite file or two optional Cloudflare Workers backed by D1 and KV. The Node runtime supports an invite-only shared laboratory library with individual accounts, roles, browser sessions, and personal MCP tokens.

This is the research layer beside a PDF reader or reference manager, not a replacement for either one. It deliberately avoids Postgres, Redis, object storage, vector search, browser extensions, and word-processor plugins.

Existing installations retain the internal bibhub runtime identifiers for compatibility: database paths, environment variables, Docker volumes, systemd paths, Cloudflare resources, and MCP URLs do not change during the product rename.

What it includes

  • DBLP and arXiv title lookup with bounded responses, caching, and visible disagreements.

  • BibTeX import/export, deterministic cite keys, .bib/TeX audit, and safe re-key plans.

  • An arXiv discovery inbox. New works remain candidates until a curator or owner records a review.

  • Bidirectional citation cross-checks from existing works, with every seed relation retained.

  • Abstract display without downloading PDFs.

  • Optional author and paper-time institution evidence from OpenAlex.

  • A read-only MCP endpoint with exactly three tools: lookup, entries, and bib.

A fresh Node instance idles at roughly 115 MB RSS in the current test environment. Allow 256 MB RAM for a small installation. Disk use is the SQLite database plus a disposable metadata cache; Field Current does not store PDFs.

Related MCP server: rag-paper

Docker quick start

Requirements: Docker Engine with Compose.

cp .env.example .env
chmod 600 .env
docker compose build
docker compose run --rm bibhub npm run users -- \
  bootstrap-owner --db /data/bibhub.db --username owner --display-name "Lab owner"

The bootstrap command prints a random temporary password once. Save it, then start the service:

docker compose up -d
docker compose ps

Open http://127.0.0.1:8788, sign in, and replace the temporary password. There is no web self-registration and the first owner can only be created from the local CLI.

The container runs as a non-root user with a read-only root filesystem. Its database and cache live in the named volume bibhub-data; the HTTP port binds to loopback by default. Put Caddy, Tailscale, or a private tunnel in front of it if remote access is needed.

Stop and remove the process without deleting the library:

docker compose down

Do not add -v unless you intentionally want to delete the bibhub-data volume.

Bare Node

Requirements: Node 22.18+ or Node 24.11+.

npm ci --omit=dev
umask 077
npm run users -- bootstrap-owner --db ./bibhub.db \
  --username owner --display-name "Lab owner"
BIBHUB_PUBLIC_ORIGIN=http://127.0.0.1:8788 npm run serve

The default listener is 127.0.0.1:8788, the compatibility database name is ./bibhub.db, and the response cache is ./.cache. Relevant environment variables are:

Variable

Meaning

AUTH_TOKEN

Optional legacy/break-glass owner bearer token. BIBHUB_TOKEN remains a compatible Node alias. A new Node install uses accounts instead.

BIBHUB_PUBLIC_ORIGIN

Exact browser origin used for session and Origin checks; set the external HTTPS origin behind a proxy or tunnel.

MCP_READ_TOKEN

Optional shared MCP compatibility token. New Node installs use one library:read token per user.

BIBHUB_HOST / PORT

Listener, default 127.0.0.1:8788.

BIBHUB_DB

SQLite path.

BIBHUB_CACHE

Disposable DBLP/arXiv cache directory.

BIBHUB_WATCHLIST

JSON array of arXiv discovery queries; default [] disables topic discovery. Cloudflare Workers accepts at most 5 terms per sweep to stay within the Free D1 query budget.

BIBHUB_CITATION_DISCOVERY

Scheduled citation scans only; default false. Manual scans remain available.

BIBHUB_SWEEP_INTERVAL_HOURS

Node/Docker interval, default 24; 0 disables the timer.

OPENALEX_API_KEY

Optional free OpenAlex key for author enrichment and citation discovery.

SOURCE_CODE_URL

Exact HTTPS source URL for this running revision; required before exposing an AGPL network instance.

SOURCE_REVISION

Full 40- or 64-hex Git commit ID served by SOURCE_CODE_URL; required with it.

deploy/bibhub.service.example and deploy/bibhub.env.example provide a hardened systemd setup.

Laboratory accounts

One Node deployment is one shared laboratory library. Accounts control who may act on it; they do not create private copies of papers.

Role

Access

reader

Browse, search, export BibTeX, and use read-only MCP.

curator

Reader access plus save/import and candidate review.

owner

Curator access plus discovery, OpenAlex refresh, and local user administration.

Invite users from the host. Generated temporary passwords are printed once and must be changed on first sign-in:

npm run users -- invite --db ./bibhub.db --actor owner \
  --username alice --display-name "Alice" --role curator
npm run users -- list --db ./bibhub.db
npm run users -- disable --db ./bibhub.db --actor owner --username alice

Passwords use salted Node scrypt; the database stores only password material, session hashes, and API-token hashes. Browser sessions are HttpOnly, SameSite=Strict, and Secure when BIBHUB_PUBLIC_ORIGIN is HTTPS. Unsafe cookie-authenticated requests must match that configured Origin. Disabling a user or changing their password invalidates their sessions and API tokens. There is no public registration or “first visitor becomes admin” route.

The canonical paper rows remain global. A future multiple-direction feature should add tracks and membership/link tables around those works; the compatibility repos field is a collection label, not a tenant or permission boundary.

L40-style shared-server deployment

On a shared compute server, keep the release and SQLite/WAL on a local data filesystem rather than a nearly-full system disk or network filesystem. Run the process as a dedicated Unix user, bind only to 127.0.0.1, and put an HTTPS reverse proxy or outbound tunnel in front. A typical layout is:

/data/field-current/releases/<source-revision>
/data/field-current/state/bibhub.db
/data/field-current/state/cache/

Set BIBHUB_PUBLIC_ORIGIN to the exact external HTTPS origin. Do not expose the Node port on 0.0.0.0; MCP is served by the same process at /mcp. Back up the SQLite database with the built-in online backup command and verify the snapshot before every upgrade.

Discovery topics

No topic is enabled by default, so a new installation does not make scheduled arXiv requests. Node and Docker accept up to 20 queries; Cloudflare Workers accepts up to 5 so one sweep stays inside the Free D1 query budget. Each query may be at most 120 characters:

BIBHUB_WATCHLIST='["database provenance","scientific metadata"]'

Node and Docker run configured discovery once per interval when either the watchlist or scheduled citation discovery is enabled; the default is 24 hours after process start. npm run sweep performs one configured discovery pass and exits. The Cloudflare build runs its configured discovery daily. A match enters the review inbox; it never enters the formal library automatically.

Citation discovery

Citation discovery uses checked library entries as seeds and looks in both directions: works referenced by a seed and works that cite it. Results enter the same review inbox; they are never promoted into the formal library without an explicit review. When several seeds find the same candidate, the inbox keeps every seed and relation instead of creating duplicate candidates.

The browser's Scan citations action runs one authenticated seed at a time. Keeping the deployed Worker batch at one leaves headroom under Workers Free CPU and D1 query limits; the self-hosted Node endpoint may opt into a batch of up to three with its limit parameter. The same action is available over HTTP:

curl -X POST 'http://127.0.0.1:8788/api/citations/scan?limit=1' \
  -H "Authorization: Bearer $AUTH_TOKEN"

That bearer example is for Cloudflare or a deliberately configured legacy owner token. On a multi-user Node instance, owners use the browser session; personal MCP tokens are read-only and are rejected on this write route.

Manual scans are available whenever a free OPENALEX_API_KEY is configured, regardless of BIBHUB_CITATION_DISCOVERY. Set that flag to true only if scheduled scans are wanted. On Cloudflare, keep citation discovery on its dedicated BIBHUB_CITATION_CRON trigger rather than combining it with the arXiv sweep; the supplied Wrangler config uses 06:20 and 06:50 UTC.

OpenAlex citation data is useful for finding omissions, not for authoritative citation counts: coverage can be incomplete, delayed, or missing for an otherwise valid work. Seeds without a DOI, arXiv identity, or verified OpenAlex authorship snapshot are checkpointed as unsupported; their formal entries are not changed. Field Current treats the configured key as free-only: before every actual OpenAlex list or search attempt, including retries, it checks the endpoint-specific cost against the free daily allowance and keeps a US$0.10 reserve. Citation scans also use a database lease so manual and scheduled batches cannot race. Prepaid balance is never read or used.

Import and command-line tools

The browser can look up and save an individual work or paste a complete .bib into a collection. The same batch import is available over the authenticated API:

curl -X POST http://127.0.0.1:8788/api/import \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary "$(jq -n --rawfile bib refs.bib --arg repo reading-list '{bib:$bib,repo:$repo}')"

The curl example uses the optional legacy owner token. The normal multi-user Node path is an owner/curator browser session, so a leaked MCP token can never import or review papers.

Local, read-mostly bibliography tools need no running server:

npm run cli -- selftest
npm run cli -- key --author "Vaswani, Ashish" --year 2017 --title "Attention Is All You Need"
npm run cli -- lookup "Attention Is All You Need"
npm run cli -- audit --bib refs.bib --tex paper.tex
npm run cli -- rekey --bib refs.bib --tex paper.tex

audit exits non-zero on missing, uncited, duplicate, or off-rule keys. rekey only prints a plan unless --apply is supplied, then rewrites the BibTeX and every supplied TeX file from one checked plan. The cite-key policy is documented in docs/citation-rules.md.

The database column and API parameter are still named repos/repo for compatibility; the browser presents these values as collections.

Backups

Create a consistent SQLite online backup while the Node service is running:

npm run backup
npm run verify:backup -- /path/to/bibhub-2026-08-06T06-20-00Z.sqlite

By default the snapshot is written under a backups/ directory beside the live database, with mode 0600. In Docker, run docker compose exec bibhub npm run backup; the snapshot stays in the persistent /data volume. Copy verified snapshots to a second machine or encrypted storage (docker compose cp bibhub:/data/backups/<file>.sqlite ./ copies one out). Restore only while Field Current is stopped: move the old database and its -wal/-shm sidecars aside together, install a verified snapshot at the configured database path, then start the service and check /readyz.

Optional author and affiliation evidence

Author enrichment is an explicit authenticated write, never a side effect of an MCP read. If OPENALEX_API_KEY is unset, the library continues to work and enrichment reports that it is disabled. Configure only a free OpenAlex key; Field Current contains no paid provider or billing fallback. Every billable list or search attempt stops before the protected US$0.10 free reserve.

curl -X POST http://127.0.0.1:8788/api/authorships?limit=5 \
  -H "Authorization: Bearer $AUTH_TOKEN"

Affiliations are institutions reported on a particular paper record, not a claim about an author's current employer. Stored evidence includes source work and author identifiers, retrieval time, match method, ROR/OpenAlex institution identifiers, and raw affiliation strings. Missing evidence means “not checked”; an empty checked result means the source supplied no affiliation.

Agents request the same analysis through entries({view:"authors", author:"..."}). Results keep paper abstracts, coauthors, venues, collections, coverage, and work-scoped institutions together so an agent does not have to infer employment from a name.

Cloudflare deployment

Cloudflare is optional. The public Wrangler template contains no account or resource IDs. Keep the instance copy ignored so automatic provisioning cannot add your IDs to a public commit:

npm ci
if [ ! -e wrangler.production.jsonc ] && [ ! -e wrangler.mcp.production.jsonc ]; then
  cp wrangler.jsonc wrangler.production.jsonc
  cp wrangler.mcp.jsonc wrangler.mcp.production.jsonc
  chmod 600 wrangler.production.jsonc wrangler.mcp.production.jsonc
else
  echo "keeping existing instance configs"
fi
npm run types
npm run check
npm test
npm run deploy

The copy step is for a brand-new instance only. During an upgrade, keep both ignored production files: they contain the bindings that point at the existing D1, KV, service, and rate-limit resources. Replacing either file can bind the next deploy to an empty resource.

The first deploy creates the D1 database and KV namespace and writes their IDs only into the ignored wrangler.production.jsonc. API access remains fail-closed until a secret is set. Initialize the database, then add the token:

npm run db:remote
npx wrangler secret put AUTH_TOKEN -c wrangler.production.jsonc
npx wrangler secret put OPENALEX_API_KEY -c wrangler.production.jsonc  # optional, free key only

Before exposing the AGPL version, add the same immutable SOURCE_CODE_URL and SOURCE_REVISION string variables to both private Wrangler configs. Existing main-Worker configs must also add /source to assets.run_worker_first. The main page's /source route and the MCP initialization metadata must identify the same running source.

Both deployment commands run a fail-closed source preflight before Wrangler. It checks both ignored production configs, even when only one Worker is being deployed. Run the same check without deploying with npm run source:preflight. In a Git checkout, the local Field Current source scope must be clean; unrelated files elsewhere in a containing monorepo are outside the check. A standalone source export without .git still receives all config checks.

The preflight cannot prove that an external SOURCE_CODE_URL contains the running files, and does not compare its revision with a private monorepo's unrelated HEAD. The publisher remains responsible for exporting the exact running source, committing it to the public repository, and putting that public commit ID in both production configs.

Set BIBHUB_WATCHLIST in the private config if scheduled topic discovery is wanted. Set BIBHUB_CITATION_DISCOVERY to true only if scheduled citation scans are wanted, then redeploy. The citation flag does not disable authenticated manual scans. Cloudflare's free-plan limits can change; verify the current plan before relying on it. The application does not bind R2 or require a payment method.

For a database created before the public migration ledger, inspect and apply only the needed one-time files described in manual-upgrades/README.md. Fresh databases need only npm run db:remote; the Node server applies the same ordered migration files at startup and refuses to listen if one fails or an already-applied file has changed.

Read-only MCP Worker

The MCP Worker follows protocol version 2026-07-28 using the TypeScript SDK v2 and Streamable HTTP at /mcp. Its public capability surface is fixed:

Tool

Access

lookup

Read-only DBLP/arXiv verification.

entries

Read-only paper search and bounded author/affiliation analysis.

bib

Read-only canonical BibTeX rendering.

It has no D1, KV, assets, cron, or general fetch binding. A named service binding can call only the main Worker's ReadEntrypoint methods, and MCP_READ_TOKEN is separate from the write-capable AUTH_TOKEN.

Deploy the main Worker first. Before continuing, store the generated MCP token in a password manager or configure the client that will use it; the shell variable is deliberately removed after deployment and cannot be recovered from Cloudflare:

npm run types:mcp
npm run check
mcp_read_token="$(openssl rand -base64 48)"
printf 'Save this MCP token now:\n%s\n' "$mcp_read_token"
printf 'MCP_READ_TOKEN=%s\n' "$mcp_read_token" \
  | npm run deploy:mcp -- --secrets-file /dev/stdin
unset mcp_read_token

For a new account, choose an unused integer namespace_id in the private MCP config before deploying. Existing instances must retain their current private namespace instead of copying the public example again.

Clients call https://bibhub-mcp.<your-workers-subdomain>.workers.dev/mcp with Authorization: Bearer <MCP_READ_TOKEN>.

Self-hosted Node MCP

The Node server exposes the same stateless MCP 2026-07-28 endpoint at /mcp, backed by a separate read-only SQLite connection. A signed-in user creates a named MCP token in the account panel, copies it once, and configures the client with:

Authorization: Bearer fcpat_...

Each token is independently revocable, limited to library:read, and rate-limited separately. The three-tool boundary remains lookup, entries, and bib; the token is rejected on HTTP write routes even when its owner is a curator or owner.

This personal access-token lane is intended for preconfigured laboratory clients. It is not an interactive OAuth authorization server. For arbitrary third-party MCP clients that need browser sign-in, deploy a standards-compliant OAuth 2.1 authorization server and Protected Resource Metadata in front of the endpoint; do not invent a token exchange or pass another service's access token through Field Current.

HTTP routes

Node /api/* routes accept an authenticated user session and enforce the role table above; read-only personal tokens may call GET routes only. Cloudflare and compatibility-mode Node deployments use their configured bearer token. Static assets and /healthz do not. The Node/Docker /readyz endpoint is unauthenticated for local health checks; Cloudflare /readyz requires AUTH_TOKEN so an unauthenticated caller cannot spend D1 reads. Health responses contain no database path, counts, or instance settings. /source is public by design and redirects only to the configured exact Corresponding Source revision.

Method and path

Purpose

GET /source

Redirect to the exact Corresponding Source for the running AGPL version.

POST /api/auth/login / POST /api/auth/logout

Create or revoke a Node browser session.

GET /api/me / POST /api/auth/change-password

Read the current account or replace a temporary password.

GET/POST/DELETE /api/tokens...

Manage the current user's read-only MCP tokens.

GET /api/lookup?title=...

Compare DBLP and arXiv metadata.

GET /api/entries?q=...&repo=...

Browse checked entries.

POST /api/entries

Add or update one checked entry.

POST /api/import

Import a BibTeX batch into a collection.

GET /api/bib?repo=...

Export BibTeX.

POST /api/audit / POST /api/rekey

Audit or plan/apply cite-key changes.

GET /api/candidates?state=new&limit=50&offset=0

Read a page of the discovery inbox.

POST /api/candidates/review

Record import/ignore and atomically promote imports.

POST /api/citations/scan?limit=1

Cross-check citations from checked library seeds.

POST /api/sweep

Run discovery on demand.

POST /api/authorships?limit=...

Refresh optional OpenAlex evidence.

Public-source boundary

The source distribution contains no library records, production resource IDs, review history, token, API key, database, cache, or author evidence. npm run public:check rejects common instance files, project-specific names, literal credentials, and Cloudflare resource IDs before release.

Do not publish this directory with inherited repository history: old commits can retain data that no longer exists in the current tree. Export the checked tree into a new repository with a new first commit and a public/noreply Git identity. Do not zip the working directory; ignored files are present locally. Export a safe, history-free tree with:

npm run export:public -- ../field-current-public

The command refuses to overwrite an existing destination, copies an explicit allowlist, and runs the public check again inside the exported tree. Initialize a new repository there and make a new first commit with a public/noreply Git identity.

Development

npm ci
npm run build:css
npm run types
npm run types:mcp
npm run check
npm test
npm run public:check
npm run export:public -- /path/to/new-empty-directory

The Node and Worker paths share bibliography, source, rendering, and validation modules. Keep MCP limited to lookup, entries, and bib; write operations belong only to the main authenticated service.

License and corresponding source

Field Current is licensed under AGPL-3.0-only; see LICENSE, NOTICE, and THIRD_PARTY_NOTICES. This directory is an independently licensed subproject when it appears inside a larger repository.

If you run a modified version and let users interact with it over a network, AGPL section 13 requires that those users receive a prominent, no-charge opportunity to obtain that running version's Corresponding Source. Field Current exposes /source in the web UI and publishes the same source location in MCP server metadata. Before exposing an instance, set both:

SOURCE_CODE_URL='https://code.example/field-current/tree/<full-commit-id>'
SOURCE_REVISION='<full-commit-id>'

The URL must identify the source for the version actually running, including a fork's modifications. A tag, moving branch, signed URL, or abbreviated hash is insufficient: the revision must be a full Git SHA-1 or SHA-256 object ID and an exact path segment of the query-free HTTPS URL. If either value is absent or invalid, /source fails closed with 503. Bibliographic records, notes, PDFs, credentials, and other instance data are not part of the software source distribution.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Read-only MCP server for your local Zotero library. Browse collections, inspect paper metadata, and extract full-text from PDFs via FastMCP tools.
    4
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    A local-first paper RAG server that enables searching and managing academic PDFs via MCP tools, supporting metadata enrichment and citation graphs.
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    MCP server for downloading academic papers from DOI or title, resolving references, and generating citations. Supports batch downloads, multiple mirrors, and optional Unpaywall integration.
    11
    1
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    A MCP server for searching and downloading academic papers from arXiv, PubMed, bioRxiv, and more. It integrates with LLMs like Claude Desktop for paper discovery.
    MIT

View all related MCP servers

Related MCP Connectors

  • Academic research MCP server for paper search, citation checks, graphs, and deep research.

  • Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.

  • Search and download academic papers from arXiv, PubMed, bioRxiv, medRxiv, Google Scholar, Semantic…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LKRCharon/field-current'

If you have feedback or need assistance with the MCP directory API, please join our Discord server