java-spring MCP server
Commit 21 Okt 2026Menyediakan AI agent dengan Javadoc JDK terbaru, dokumentasi Spring Boot, dan metadata Maven Central dalam format markdown yang bersih.
Juga dikenal sebagai KEEPEE/java-spring-mcp
- Stars
- 0
- Tools
- 11
- Unduhan, 30 hari
- —
- Versi terbaru
- —
- Commit terakhir
- 21 Okt 2026
- Lisensi
- MIT
Apa itu java-spring MCP?
java-spring adalah MCP server. Menyediakan AI agent dengan Javadoc JDK terbaru, dokumentasi Spring Boot, dan metadata Maven Central dalam format markdown yang bersih. Server ini menyediakan 11 tool, seperti java_docs, java_search, maven_package.
Ringkasan dibuat dari README proyek
Tentang java-spring MCP server
MCP server ini memungkinkan AI coding agent untuk mengakses Javadoc JDK secara live, dokumentasi Spring Boot, serta metadata Maven Central. Server ini menggantikan pengetahuan model bahasa besar yang sering kali kedaluwarsa atau mengalami halusinasi dengan data real-time yang diambil langsung dari sumber resmi. Dengan mengembalikan format markdown yang bersih, server ini memastikan kode Java dan Spring yang dihasilkan menggunakan API terbaru, bukan yang sudah deprecated.
Developer dapat menggunakan server ini secara lokal via stdio melalui client seperti Claude Desktop, Cursor, atau Cline. Server ini memerlukan Python 3.10 atau versi terbaru dan menggunakan uv untuk instalasi. Server ini memiliki indeks pencarian lokal yang mencakup sekitar 4.700 class JDK dan seluruh sebelas bagian referensi Spring Boot, yang diperbarui setiap tujuh hari. Untuk menjaga efisiensi, server ini menggunakan cache SQLite TTL untuk pencarian berulang yang instan dan menyertakan lapisan politeness untuk menghormati robots.txt serta batasan request.
Tool spesifik yang tersedia meliputi java_docs untuk resolusi identifier, spring_search_concepts untuk mencari dokumentasi melalui heading, dan maven_package untuk mengambil metadata artifact. Server ini juga menyediakan spring_dependency untuk menghasilkan blok Maven atau Gradle yang siap pakai untuk kebutuhan spesifik seperti JPA atau OAuth2.
Apa yang bisa Anda lakukan dengannya
- 1Resolusi dokumentasi class JDK spesifikAI agent dapat mengambil dokumentasi markdown yang tepat untuk class Java tertentu guna memastikan penggunaan method yang benar.
- 2Pencarian konsep Spring BootDeveloper dapat melakukan query untuk topik Spring Boot seperti auto-configuration atau security untuk mendapatkan hasil terperingkat dari manual resmi.
- 3Generate dependency Spring BootAnda dapat meminta agent untuk menemukan koordinat starter yang benar untuk kebutuhan spesifik seperti JPA.
- 4Mengambil metadata artifact MavenAgent dapat mencari versi terbaru dan metadata untuk package Maven tertentu.
Ditulis berdasarkan README proyek. Setiap use case diperiksa terhadap kutipan dari README tersebut.
Tool java-spring MCP 11
Terdeteksi dari READMEjava_docsjava_searchmaven_packagejava_statushealth_checkspring_search_conceptsspring_referencespring_guidesspring_initializrspring_dependencyspring_versions
| java_docs | — | |
| java_search | — | |
| maven_package | — | |
| java_status | — | |
| health_check | — | |
| spring_search_concepts | — | |
| spring_reference | — | |
| spring_guides | — | |
| spring_initializr | — | |
| spring_dependency | — | |
| spring_versions | — |
Konfigurasi
JAVA_SPRING_MCP_CACHE_DIRJAVA_SPRING_MCP_POLITENESS_DISABLED
| Nama | Deskripsi | Tipe |
|---|---|---|
| JAVA_SPRING_MCP_CACHE_DIR | — | |
| JAVA_SPRING_MCP_POLITENESS_DISABLED | — |
README
Lihat di GitHubjava-spring-mcp
An MCP (Model Context Protocol) server that gives AI coding agents live JDK javadoc, Spring Boot reference documentation and Maven Central metadata instead of whatever the model happens to remember. Pages are scraped from the official sites at request time, cached locally, and returned as clean markdown — so generated Java and Spring code targets real, current APIs rather than deprecated or invented ones.
- JDK classes — scraped live from docs.oracle.com (all 41 modules:
java.base,java.sql,java.desktop,java.net.http, …), ~4,700 classes with their module recorded, so a bareHttpClientresolves tojava.net.httpand not to a guess - Spring Boot documentation — a first-class layer over the official Spring Boot reference (all 11 sections:
using,features,actuator,security,testing,web,data,io,messaging,packaging,index), the Getting Started guides, Spring Initializr and the release notes. It searches section titles and the headings inside each page, which is what a topic query such asdata jpaactually needs. - Maven Central — artifact metadata from the official search API plus a javadoc.io link
- Local search index over every JDK class plus the Spring sections, rebuilt at most every 7 days, with a stale fallback when the network fails
- SQLite TTL cache so repeated lookups are instant
- Politeness layer — robots.txt (RFC 9309), per-host throttle incl.
Crawl-delay,Retry-After, conditional GET and request budgets (details)
The eleven tools
Java tools:
| Tool | What it does |
|---|---|
java_docs |
Resolve one identifier (java.util.List, HttpClient, spring:using) to a single documentation page as markdown. |
java_search |
Ranked name search over the local index of all JDK classes and Spring Boot reference sections. |
maven_package |
Maven Central artifact metadata: newest matching version, the version list, the central.sonatype.com page and a javadoc.io link. |
java_status |
Real health check: index size/age, cache stats, live probes of docs.oracle.com, docs.spring.io and search.maven.org, and politeness counters. |
health_check |
Server liveness and version. |
Spring tools (added for the Spring documentation layer — see Replacing @enokdev/springdocs-mcp):
| Tool | What it does |
|---|---|
spring_search_concepts |
Ranked hits over the reference manual's nav titles and in-page headings, each hit with a quoted excerpt. Answers auto-configuration, profiles, actuator, web, data jpa, security. |
spring_reference |
One reference section or subsection as clean markdown, with topic-style heading filtering and a version selector. |
spring_guides |
List the spring.io guides catalogue, or fetch one guide as markdown. |
spring_initializr |
Spring Initializr metadata: the Boot and Java versions it offers, project types, and the dependency catalogue (filterable). |
spring_dependency |
A need ("jpa", "oauth2 client") → the starter coordinates Spring Initializr itself generates, with paste-ready Maven and Gradle blocks. |
spring_versions |
Release / migration notes for a Spring project, grouped into breaking changes, new features, deprecations and the rest. |
Every tool returns a plain dict. Failures come back as {"error": …, "suggestion": …} — a bad lookup never raises into the MCP layer, and no tool delegates to another tool.
Requirements
- Python 3.10 or newer (developed and tested on 3.12)
uvfor the one-command install below (uvxships with it)- The MCP Python SDK 1.x is pinned (
mcp>=1.2.0,<2.0); this package does not support the mcp 2.x rename ofFastMCP
Install & run
One command — no checkout, no token
uvx --from git+https://github.com/KEEPEE/java-spring-mcp.git java-spring-docs
This builds the package in an isolated environment and starts the stdio MCP server. It prints nothing on purpose: stdout is the protocol channel. Stop it with Ctrl-C.
After the repository is updated, force uv to re-resolve the commit:
uvx --refresh --from git+https://github.com/KEEPEE/java-spring-mcp.git java-spring-docs
Local checkout — fastest startup, editable while developing
git clone https://github.com/KEEPEE/java-spring-mcp.git
cd java-spring-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/java-spring-docs # stdio MCP server
MCP client configuration
Generic stdio client (Claude Desktop, Cursor, Cline, …)
{
"mcpServers": {
"java-spring": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/KEEPEE/java-spring-mcp.git",
"java-spring-docs"
]
}
}
}
With an explicit cache directory (any env you set is passed straight through to the server):
{
"mcpServers": {
"java-spring": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/KEEPEE/java-spring-mcp.git",
"java-spring-docs"
],
"env": {
"JAVA_SPRING_MCP_CACHE_DIR": "/tmp/java-spring-cache"
}
}
}
}
DeepSeek Harness (cordis-style plugin list)
- id: mcp-java-spring
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: java-spring
transport: stdio
command: uvx
args:
[
'--from',
'git+https://github.com/KEEPEE/java-spring-mcp.git',
'java-spring-docs'
]
To skip the build at client start, point command at the console script of a checkout instead — command: /path/to/java-spring-mcp/.venv/bin/java-spring-docs with args: [].
Tools reference
java_docs(identifier, topic=None, max_tokens=8000)
Resolves an identifier to one documentation page. Identifier forms, tried in this order:
| Form | Meaning |
|---|---|
spring, spring:using |
Spring Boot reference section (spring alone = the index section) |
java.util.List, java.net.http.HttpClient |
fully-qualified class; the module is read from the search index, falling back to java.base plus a fixed module list |
HttpClient |
exact-name lookup in the local index (a class beats an interface on ambiguity), then fetch |
topic keeps only the section whose heading contains it (methods, method summary, fields, constructors, …) plus the page title and description; if nothing matches, the full page is returned with a note listing the available headings. max_tokens is a rough budget (1 token ≈ 4 characters): the markdown is cut at a line boundary and truncated is set.
Returns {"type", "identifier", "url", "title", "content", "truncated", "cached"}, plus an optional note. type is jdk_class or spring_section.
// java_docs({ "identifier": "java.net.http.HttpClient", "max_tokens": 250 })
// a bare name would also work: "HttpClient" resolves to this same module
{
"type": "jdk_class",
"identifier": "java.net.http.HttpClient",
"url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.net.http/java/net/http/HttpClient.html",
"content": "# Class HttpClient\n\n```java\npublic abstract class HttpClient extends Object implements AutoCloseable\n```\n\nAn HTTP Client.\n\nAn `HttpClient` can be used to send requests and retrieve their responses … [truncated: showing ~243 of ~9883 estimated tokens]",
"truncated": true,
"cached": false,
"title": "Class HttpClient"
}
// java_docs({ "identifier": "spring:using", "max_tokens": 250 })
{
"type": "spring_section",
"identifier": "spring:using",
"url": "https://docs.spring.io/spring-boot/reference/using/index.html",
"content": "# Developing with Spring Boot\n\nThis section goes into more detail about how you should use Spring Boot. … ## Contents\n\n- [Build Systems](…)\n- [Structuring Your Code](…) … [truncated: showing ~226 of ~429 estimated tokens]",
"truncated": true,
"cached": false,
"title": "Developing with Spring Boot"
}
A topic that matches nothing tells you what the page does have:
// java_docs({ "identifier": "java.util.List", "topic": "nonexistent-section", "max_tokens": 120 })
{
"type": "jdk_class",
"identifier": "java.util.List",
"url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/List.html",
"content": "# Interface List<E>\n\n```java\npublic interface List<E> extends SequencedCollection<E>\n``` … [truncated: showing ~113 of ~1040 estimated tokens]",
"truncated": true,
"cached": true,
"title": "Interface List<E>",
"note": "no section matching 'nonexistent-section'; available headings: Interface List<E>, Unmodifiable Lists, Method Summary, Methods declared in interface Collection, Methods declared in interface Iterable, …"
}
A name that exists nowhere is reported honestly — Oracle answers a wrong class with a redirect, not a 404, so the request budget is what stops the search (see budgets):
// java_docs({ "identifier": "com.example.NopeXYZ" })
{
"error": "could not fetch javadoc for 'com.example.NopeXYZ': request budget exhausted for scope 'tool:java_docs'",
"suggestion": "the per-call request budget (6) ran out while guessing modules; try java_search('com.example.NopeXYZ') to find the right package/module"
}
java_search(query, limit=8)
Ranks the local index by name similarity (exact > prefix > substring > fuzzy). Returns {"query", "count", "results": [{name, package, module, kind, url, score}], "index_stale"}. kind is class, interface, enum, record, annotation or spring_section.
// java_search({ "query": "http client", "limit": 3 })
{
"query": "http client",
"count": 3,
"results": [
{ "name": "HttpClient", "package": "java.net.http", "module": "java.net.http", "kind": "class", "url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.net.http/java/net/http/HttpClient.html", "score": 14.0 },
{ "name": "HttpClient.Builder", "package": "java.net.http", "module": "java.net.http", "kind": "interface", "url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.net.http/java/net/http/HttpClient.Builder.html", "score": 14.0 },
{ "name": "HttpClient.Redirect","package": "java.net.http", "module": "java.net.http", "kind": "enum", "url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.net.http/java/net/http/HttpClient.Redirect.html", "score": 14.0 }
],
"index_stale": false
}
Spring sections are ranked in the same list, so one search covers both halves of the index:
// java_search({ "query": "spring using", "limit": 3 })
{
"query": "spring using",
"count": 3,
"results": [
{ "name": "Spring Boot: Using", "package": "using", "module": "spring-boot", "kind": "spring_section", "url": "https://docs.spring.io/spring-boot/reference/using/index.html", "score": 14.0 },
{ "name": "Spring", "package": "javax.swing","module": "java.desktop","kind": "class", "url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.desktop/javax/swing/Spring.html", "score": 12.909 },
{ "name": "SpringLayout", "package": "javax.swing","module": "java.desktop","kind": "class", "url": "https://docs.oracle.com/en/java/javase/26/docs/api/java.desktop/javax/swing/SpringLayout.html", "score": 9.882 }
],
"index_stale": false
}
maven_package(artifact_id, group_id=None, version=None, max_tokens=6000)
Maven Central metadata. artifact_id is the artifact to look up; group_id pins the group when several projects share an artifact name; version selects one release from the result list. Returns {"group_id", "artifact_id", "version", "versions", "url", "javadoc_url", "cached"} — versions is the newest 20 coordinates, url the central.sonatype.com page and javadoc_url the javadoc.io page. max_tokens is reserved for future javadoc content fetching and currently has no effect.
// maven_package({ "artifact_id": "guava", "group_id": "com.google.guava" })
{
"group_id": "com.google.guava",
"artifact_id": "guava",
"version": "33.4.8-jre",
"versions": ["33.4.8-jre", "33.4.8-android", "33.4.7-jre", "33.4.7-android", "33.4.6-jre", "… 20 entries in total"],
"url": "https://central.sonatype.com/artifact/com.google.guava/guava",
"javadoc_url": "https://www.javadoc.io/doc/com.google.guava/guava",
"cached": false
}
Without group_id the search API ranks by relevance, so a bare spring-boot legitimately resolves to whichever project Maven Central scores highest — pass the group when you mean a specific one:
// maven_package({ "artifact_id": "spring-boot" })
{ "group_id": "org.apache.camel.springboot", "artifact_id": "spring-boot", "version": "4.20.0", "…": "…" }
An unknown coordinate is an error dict, not an empty result:
// maven_package({ "artifact_id": "nope-not-a-real-artifact-xyz" })
{
"error": "maven lookup failed: artifact not found on Maven Central",
"suggestion": "No results for 'nope-not-a-real-artifact-xyz'. Verify the coordinates, or retry without a group id: maven_package('nope-not-a-real-artifact-xyz')"
}
java_status()
Probes docs.oracle.com, docs.spring.io and search.maven.org with a light GET (10 s timeout) and reports the index and cache state. overall is ok, degraded or error. The politeness block is diagnostics only and never changes overall.
// java_status()
{
"server": "java-spring-mcp",
"version": "0.2.0",
"checks": {
"search_index": { "status": "ok", "entries": 4716, "built_at": "2026-10-07T06:52:16.422162+00:00", "stale": false },
"cache": { "status": "ok", "entries": 9, "expired": 0 },
"docs_oracle_com": { "status": "ok", "http_status": 200 },
"docs_spring_io": { "status": "ok", "http_status": 200 },
"search_maven_org":{ "status": "ok", "http_status": 200 }
},
"overall": "ok",
"politeness": {
"status": "ok", "disabled": false,
"requests": 15, "robots_requests": 3, "robots_rows": 3, "robots_fetches": 3, "robots_cache_hits": 13,
"blocked_by_robots": 0, "throttle_waits": 9, "throttle_sleep_s": 3.338,
"host_delays": { "docs.oracle.com": 0.0, "docs.spring.io": 0.0, "search.maven.org": 0.0 },
"budgets": { "tool:java_docs": [6, 6], "tool:maven_package": [1, 6] },
"budget_denied": 1, "conditional": 0, "conditional_skipped": 0, "revalidated_304": 0,
"redirect_hops": 3, "retries_429": 0, "retries_transport": 0, "stalls": 0, "errors": 0
}
}
health_check()
{"status": "ok", "server": "java-spring-mcp", "version": "0.2.0"} — no network, no cache; safe as a liveness probe.
Spring tools reference
These six tools are the Spring documentation layer. They read four hosts — docs.spring.io (reference manual), spring.io (guides), start.spring.io (Initializr) and api.github.com (release notes) — and every one of them is budgeted, throttled and cached like the Java tools.
spring_search_concepts(query, version=None, limit=8, max_tokens=4000)
The question a Spring agent actually asks is by topic, not by page: "how do profiles work?", "what does the actuator give me?", "JPA with Spring Boot?". This tool ranks the reference manual's navigation titles (296 pages, read from the section index) and the headings inside the pages themselves, and quotes the text under each hit.
Ranking is the same ladder as java_search (exact word > prefix > substring, every query word must match), weighted by field (title > slug > section > parent) with a bonus for reference pages over how-to pages. When the titles cannot answer the query, the tool fetches up to HEADING_PAGE_LIMIT (4) candidate pages, harvests their h2–h4 headings plus a short excerpt for each, and adds those as hits. Harvested headings are cached, so the same query a second time costs zero requests.
Returns {"query", "hit_count", "hits", "index", "version", "docs_base", "pages_read", "headings_harvested", "truncated"}. Each hit is {title, url, section, version, score, matched_on, excerpt, excerpt_source, nav_depth, is_reference_page} (+ heading_level and page_title for a heading hit). matched_on is title, path or heading.
// spring_search_concepts({ "query": "auto-configuration", "max_tokens": 400 }) // live, cold: 3 requests
{
"query": "auto-configuration",
"hit_count": 5,
"hits": [
{ "title": "Auto-configuration", "url": "https://docs.spring.io/spring-boot/reference/using/auto-configuration.html", "section": "using", "version": "4.1.1", "score": 6.9, "matched_on": "title", "excerpt": "Auto-configuration is non-invasive. At any point, you can start to define your own configuration to replace specific parts of the auto-configuration. For example, if you add your own DataSource bean, the default embedded database support…", "excerpt_source": "page", "nav_depth": 3, "is_reference_page": true },
{ "title": "Creating Your Own Auto-configuration", "url": "https://docs.spring.io/spring-boot/reference/features/developing-auto-configuration.html", "section": "features", "version": "4.1.1", "score": 6.9, "matched_on": "title", "excerpt": "Classes that implement auto-configuration are annotated with @AutoConfiguration . This annotation itself is meta-annotated with @Configuration …", "excerpt_source": "page", "nav_depth": 3, "is_reference_page": true },
{ "title": "Auto-configuration Packages", "url": "https://docs.spring.io/spring-boot/reference/using/auto-configuration.html#using.auto-configuration.packages", "section": "using", "version": "4.1.1", "score": 6.9, "matched_on": "heading", "excerpt": "Auto-configuration packages are the packages that various auto-configured features look in by default when scanning for things such as entities and Spring Data repositories. …", "excerpt_source": "page", "nav_depth": 3, "is_reference_page": true, "heading_level": "h2", "page_title": "Auto-configuration" }
],
"index": { "cached": false },
"version": "4.1.1",
"docs_base": "https://docs.spring.io/spring-boot/reference",
"pages_read": 2,
"headings_harvested": 21,
"truncated": false
}
Measured live for the six topics that the third-party Spring MCP server could not answer: auto-configuration 5 hits (2 pages read, 21 headings harvested), profiles 4, actuator 5, web 5, data jpa 5, security 5 — and the identical second call of each returns the same hits with pages_read: 0 and no requests at all (0.01 s).
data jpa is the case that proves the heading pass is needed: no page is called "data jpa", so the answer comes from a heading — JPA and Spring Data JPA at reference/data/sql.html#data.sql.jpa-and-spring-data.
spring_reference(section, subsection=None, version=None, max_tokens=8000)
One reference page as clean markdown, with the same topic filtering as java_docs. section is a reference section (web, data, using, actuator, …); subsection is a page inside it. Hyphens and spaces are the same thing, so ("web", "graceful shutdown") resolves to reference/web/graceful-shutdown.html.
version selects the docs tree: None → https://docs.spring.io/spring-boot/reference, "4.1" or "4.1.1" → https://docs.spring.io/spring-boot/4.1.1/reference. A value that is not major.minor[.patch] is rejected rather than guessed at.
Returns the same payload as java_docs (type: "spring-reference") plus version, headings (the page's own outline) and alternatives when several pages matched.
// spring_reference({ "section": "data", "subsection": "sql", "max_tokens": 200 }) // live
{
"type": "spring-reference",
"identifier": "data:sql",
"url": "https://docs.spring.io/spring-boot/reference/data/sql.html",
"title": "SQL Databases",
"content": "# SQL Databases\n\nThe [Spring Framework](https://spring.io/projects/spring-framework) provides extensive support for work… [truncated: showing ~127 of ~11614 estimated tokens]",
"truncated": true,
"cached": false,
"version": "4.1.1",
"headings": ["h2 Configure a DataSource", "h3 Embedded Database Support", "h3 Connection to a Production Database", "h2 JPA and Spring Data JPA", "…"]
}
When the subsection names a heading rather than a page, the tool says so instead of pretending:
// spring_reference({ "section": "web", "subsection": "profiles" }) // live
{
"…": "…",
"url": "https://docs.spring.io/spring-boot/reference/features/profiles.html",
"note": "'profiles' is not a page under 'web'; it lives at /spring-boot/reference/features/profiles.html (matched by page name)"
}
An unknown section lists what does exist instead of returning nothing:
// spring_reference({ "section": "nope" }) // live
{
"error": "unknown Spring documentation section: no Spring Boot documentation section named 'nope'",
"suggestion": "spring_search_concepts('<topic>') lists the sections that exist",
"candidates": [ { "title": "Developing with Spring Boot", "url": "https://docs.spring.io/spring-boot/reference/using/index.html" }, "… 12 section landing pages …" ]
}
spring_guides(guide=None, topic=None, max_tokens=8000)
No arguments (or topic=) lists the guides catalogue; guide= fetches one guide as markdown. The catalogue is read from https://spring.io/page-data/guides/page-data.json, because https://spring.io/guides itself is a client-rendered page: fetched over HTTP it answers 308 → /guides/ and then contains zero links. If page-data ever stops working, the tool falls back to https://spring.io/sitemap-index.xml (allowed by spring.io's robots.txt) and says so in a note, because a sitemap gives URLs only and titles have to be derived from the slug. guide_count is the number of guides actually returned, so it drops with max_tokens (68 at 8000, 58 at 4000, 22 at 1500).
// spring_guides({}) // live: 68 guides, 1 request (cold); 0 requests warm
{
"type": "spring-guide-catalogue",
"source": "page-data",
"url": "https://spring.io/page-data/guides/page-data.json",
"guide_count": 68,
"guides": [
{ "title": "Messaging with Redis", "url": "https://spring.io/guides/gs/messaging-redis/", "slug": "messaging-redis", "type": "getting-started", "category": ["Spring Data", "Redis"], "description": "Learn how to use Redis as a message broker." },
"…"
],
"truncated": true,
"cached": false
}
guide= accepts a slug (spring-boot), a kind+slug (gs/spring-boot, topicals/spring-boot-3), a path (/guides/gs/spring-boot/) or a full URL — all resolve to the same canonical guide URL. The markdown keeps the guide body and drops the site chrome (nav, footer, social links, "report an issue").
Pertanyaan tentang java-spring MCP
Tool apa yang disediakan java-spring MCP?
Server ini menyediakan 11 tool, termasuk java_docs, java_search, maven_package, java_status, health_check.
Bagaimana server menangani pembaruan dokumentasi?
Halaman diambil (scraped) dari situs resmi saat ada permintaan dan disimpan dalam cache SQLite TTL lokal untuk memastikan kecepatan dan kemutakhiran data.
Bisakah saya mencari class JDK dan bagian Spring secara bersamaan?
Ya, tool java_search melakukan pencarian nama terperingkat melalui indeks lokal yang mencakup seluruh class JDK dan bagian referensi Spring Boot.