Identify integer sequences by terms, search the OEIS, read formulas, programs, b-files, cross-refs.
Identify integer sequences by terms, search the OEIS, read formulas, programs, b-files, cross-refs via MCP. STDIO or Streamable HTTP.
Integer sequences from the On-Line Encyclopedia of Integer Sequences (OEIS). Identify a sequence from a few observed terms, search with OEIS's own query syntax, read an entry's formulas, generating functions, and programs, page through extended terms from its b-file, and walk its cross-references. Answers come from the OEIS entries themselves, each linked to its page. Runs as a stdio process or a local Streamable HTTP server, with no API key.
| Tool | Description |
|---|---|
oeis_identify_sequence | Identify sequences that contain a run of consecutive terms, in OEIS relevance order, with the index where the run begins |
oeis_search_sequences | Search with OEIS query syntax: words, quoted phrases, term lists, and prefixes such as keyword: and author: |
oeis_get_sequence | Fetch one entry by A-number: terms, offset, keywords, formulas, programs, comments, references, links, and cross-references |
oeis_get_terms | List terms a(n) with their indices from the entry's b-file, or from its data line when it has none |
oeis_get_cross_refs | List the sequences an entry cross-references, or the entries that mention it |
oeis_list_reference | Decode keyword flags, search syntax, and identifier and offset conventions, with no upstream call |
| Resource | Description |
|---|---|
oeis://sequence/{aNumber} | One entry by A-number as JSON, always whole |
The same record is available through oeis_get_sequence for clients that only call tools.
oeis_identify_sequence toolterms: up to 60 consecutive terms separated by commas or spaces (a bracketed list or a trailing ... is accepted), each an integer of at most 200 digits or _ for one unknown term; matchSigns (default false) ignores signs unless setstart 0–100 in steps of 10; each row carries matchStartIndex, the n where the run begins in that entry's data line (absent when the run isn't there)notice says which and how to retry: drop leading terms, divide out a common factor, or add termsoeis_search_sequences toolquery (1–1,000 characters) is sent as written: words, "quoted phrases", term lists, prefixes such as keyword:, author:, name:, formula:, xref:, and id:, | for OR, and a leading - to excludesort: relevance (default), number, created, or modified; 10 per page, start 0–100 in steps of 10totalCount and effectiveQuery, the query as OEIS parsed it; the zero-hit notice names any prefix that is not an OEIS prefixoeis_get_sequence toolname, terms, offset / firstIndex, keywords, author, legacyIds, referenceCount, revision, created / modified, url, and bFileUrl, plus eight sections: comments, formulas, examples, programs, references, links, crossReferences, extensionskind: "outline" returns the core fields with a sized sections list; pass sections (e.g. ["formulas", "programs"]) to get the chosen ones whatever their sizesequence_not_found; withdrawn (dead), reserved, and recycled entries come back with a noticeoeis_get_terms toolfromIndex (default: the first available index) and limit 1–1,000 (default 100); a slice also stops at about 100,000 bytes, and nextFromIndex continues itsource: "bfile" reads the first 1 MiB of the entry's b-file, with bFileCut: true when the file is larger; source: "data" means the entry has no b-file and the terms are its data line{ n, value }, value an exact decimal string; an unknown A-number fails as sequence_not_foundoeis_get_cross_refs tooldirection: "outgoing" (default) lists the A-numbers named in the entry's cross-reference lines, with the note written beside each and the lines verbatim; "incoming" lists the entries that mention the A-numberstart 0–100 in steps of 10; every row carries url, and resolved rows add the name, terms, offset, and keywordsresolved: false with a retry notice instead of failing; sequence_not_found applies to outgoing onlyoeis_list_reference tooltopic: keywords (flags such as nonn, core, tabl, cons), search_syntax (prefixes, operators, wildcards, sort orders, paging), or identifiers (A-numbers, legacy M/N numbers, offsets, b-files)entries (name, description) and notes from static tablesoeis://sequence/{aNumber} resourceapplication/json: the record oeis_get_sequence returns with kind: "full", never outlinedaNumber takes the same forms as the tools (oeis://sequence/A108 reads A000108); an unknown A-number fails as sequence_not_foundBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
OEIS-specific:
A000045, a000045, A45, 45, and an oeis.org sequence URL all resolve in every tool; a legacy M/N book number is pointed to oeis_search_sequences..., the Unicode minus sign, and mixed comma and space separatorsAgent-friendly output:
truncated, shown, and cap, plus totalCount and effectiveQuery where OEIS reports them, and one notice composed from the input (drop leading terms, a common factor, an unrecognized prefix, the next start)sequence_not_found, pacer_shed, and upstream_rate_limited, the rate-limit errors carrying retryAfter when one is known; an outgoing cross-reference page whose name lookup fails still returns every A-number, marked resolved: falsekind: "full" | "outline", source: "bfile" | "data", and per-row resolved, so callers branch on data, not string parsinghttps://oeis.org/A###### URL; contributor-written text renders as blockquotes and code fences, and only http and https link URLs are keptoeis.org asks automated clients to wait 10 seconds between requests. The server keeps to that: it sends one upstream request at a time and starts each at least 10 seconds after the last, across every tool. Results are cached in memory, so a repeated lookup returns at once and costs oeis.org nothing: records for 24 hours (then revalidated with a conditional request), search pages for 1 hour, and b-file reads for 7 days.
A call with nothing cached waits its turn in the queue. When the wait would pass OEIS_QUEUE_MAX_WAIT_MS (default 30,000 ms), the call fails with pacer_shed and a retryAfter instead of hanging. If oeis.org answers 429, the server holds every queued call back before trying again, and reports upstream_rate_limited once its retries are spent.
retryAfter.start ≤ 100); A000045's 6,161 incoming references, for example, are reachable only through their first 110.prime) or a two-term run. The server reports it but cannot page it.oeis_get_terms reads at most the first 1 MiB of a b-file.oeis_get_cross_refs outgoing shares the start ≤ 100 bound, so an entry naming more than 110 distinct A-numbers lists only the first 110; lines still names them all.OEIS content is licensed CC BY-SA 4.0 under the OEIS End-User License Agreement. When you reuse it, credit "The On-Line Encyclopedia of Integer Sequences" with a link to https://oeis.org/ or to the sequence page; every record the server returns carries its https://oeis.org/A###### URL for that purpose. ShareAlike applies: adaptations of OEIS content must be shared under the same license.
This server is an independent project and is not affiliated with or endorsed by the OEIS Foundation.
Add the following to your MCP client configuration file.
{
"mcpServers": {
"oeis-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/oeis-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"oeis-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/oeis-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"oeis-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/oeis-mcp-server:latest"]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/oeis-mcp-server.git
cd oeis-mcp-server
bun install
cp .env.example .env
# optional: adjust OEIS_QUEUE_MAX_WAIT_MS, the transport, or the log level
| Variable | Description | Default |
|---|---|---|
OEIS_QUEUE_MAX_WAIT_MS | Longest a call waits in the oeis.org request queue before failing with pacer_shed and a retryAfter, in ms. Each call's 50 s deadline also has to cover the request itself, so waits stop at about 35,000 ms whatever the setting. | 30000 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. | stateless |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.). | info |
LOGS_DIR | Directory for log files (Node.js only). | <app-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry. | false |
See .env.example for every server setting and the common framework overrides.
Build and run the production version:
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point: registers the tools and resource, sets the server instructions, and starts the OEIS service. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools | Tool definitions (*.tool.ts). Six tools. |
src/mcp-server/resources | Resource definitions. The oeis://sequence/{aNumber} resource. |
src/mcp-server/shared | Schemas shared across definitions (A-number input, paging, summary rows) and Markdown helpers for contributor-written text. |
src/services/oeis | oeis.org client: pacer, retries, fetch boundaries, LRU cache, record normalization, and the internal-format parser. |
tests/ | Unit tests mirroring the src/ structure; upstream responses come from fixtures, never the live site. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging and ctx.enrich for notices, totals, and paging contextsrc/mcp-server/*/definitions/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/oeis-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-oeis-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/oeis-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/oeis-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.