06 · Modernizing Apps
Module 6 — Modernizing apps with Copilot CLI
Section titled “Module 6 — Modernizing apps with Copilot CLI”| ← Previous: Adding a new feature | Next: Managing Copilot’s infrastructure → |
|---|
Modernizing a brownfield service is a research problem before it’s a coding problem, and an orchestration problem once the research is done. Then, the cycle continues.
The temptation with an agent is to point it at an old service and say “upgrade this” — the same open-ended prompt that sent Copilot wandering on the barcode feature. The discipline that made the barcode feature work applies here too: assess the ground truth, plan against real sources, build a safety net, migrate in small reviewable steps, validate each one, and write down what you learned so the next upgrade is faster.
This module walks that loop against AssetTrack’s oldest service. You’ll give Copilot better signal with a language server and a documentation MCP server, use /research to produce a migration plan you can defend, protect the change with tests, and drive the upgrade with a custom migrator agent. Along the way you’ll build reusable assets — an agent, a saved plan, a playbook, an extended test hook — so the second legacy service costs a fraction of the first.
What you will learn
Section titled “What you will learn”By the end of this module you will be able to:
- Explain why a standard modernization process still applies when an agent does the work, and how to keep an upgrade small and reviewable.
- Configure a Language Server Protocol (LSP) server so Copilot reasons about Java from the compiler instead of from text search.
- Register a documentation MCP server so Copilot grounds framework claims in first-party docs rather than stale training data.
- Use
/researchto produce a citation-backed migration plan and save it as a reusable asset. - Establish a test safety net that gives fast signal when a change breaks behavior, so the upgrade can move quickly.
- Author a custom migrator agent that executes the upgrade in reviewable phases, and capture a playbook that accelerates the next service.
Scenario
Section titled “Scenario”AssetTrack is a polyglot system, and two of its Java services are a generation behind. audit-svc and auth-svc both run on Java 17 and Spring Boot 3.5 — a supported but no-longer-current generation — while the platform’s target is the current supported generation, Java 21 and Spring Boot 4.1. The services aren’t vulnerable today: their dependencies are pinned to CVE-clean versions, and the hard rule is that no branch of this upgrade may ship a known-vulnerable package. But staying a generation back means missing the current framework’s defaults, its language and runtime features, and the security posture that comes from tracking the latest supported line. The mandate is to bring them forward onto the current runtime and framework generation without ever regressing that clean dependency baseline.
You won’t do both at once. You’ll modernize audit-svc first because it’s the smaller, better-bounded service — it has no security-token code and no third-party JSON or JWT dependencies — so the upgrade is close to mechanical and you can learn the shape of the work with fewer moving parts. Then you’ll turn what you learn into assets — a migrator agent and a written playbook — that make auth-svc a repeat rather than a fresh start. auth-svc is where the real dependency-security lesson lives: its jjwt token library drags a vulnerable transitive Jackson 2 under Spring Boot 4, and clearing that is the centerpiece of the second upgrade. workforce-svc already runs on Java 21, so the runtime jump is well-trodden ground; the Spring Boot 4 major is new ground for all of them.
Modernization is still a process, even with an agent
Section titled “Modernization is still a process, even with an agent”The reason “upgrade this service” fails as a prompt is the same reason it fails as a plan for a human: an upgrade is a sequence of decisions, and skipping the decisions doesn’t make them go away — it just moves them into the diff where they’re expensive to find. A framework major that raises the minimum runtime, a namespace that gets renamed out from under your imports, a dependency that no longer resolves: each is a fork in the road, and an agent with no plan takes them at random.
The loop that keeps that under control is the ordinary one that careful teams already use for a risky upgrade, and an agent doesn’t change it:
- Assess — establish what the service actually is today: its runtime, framework version, dependencies, and the shape of its code.
- Plan — turn the target into a sequence of small, ordered steps, grounded in the real migration guides rather than guesses.
- Protect — put a test safety net in place so you can tell immediately when a change alters behavior.
- Migrate — apply one step at a time, keeping each change small enough to review.
- Validate — build and test after every step so a regression surfaces against the step that caused it, not ten steps later.
- Document — capture the decisions and the recipe so the next service reuses the thinking instead of rediscovering it.
Agents change the speed of each step, not the steps themselves. An agent can assess a service and apply a mechanical migration far faster than doing it by hand — which makes the plan, the safety net, and the validation matter more than ever, because a fast agent makes a wrong assumption expensive just as fast. This is also the shape of the purpose-built modernization tooling you’ll meet at the end of the module — GitHub’s own Java modernization agent runs an assess-plan-execute pipeline, which is the same loop productized. Learning it by hand first is what lets you drive that tooling well later.
Model choice during the upgrade process
Section titled “Model choice during the upgrade process”GitHub Copilot provides access to numerous models of various levels, including the ability to bring your own key. This allows you to choose the right model for the job.
As you work through the application modernization flow, you’ll move back and forth between higher-end tasks, like planning and research, to lower-end tasks, like writing code and generating tests. With /model you can switch to an appropriate model depending on the needs of the current ask, both saving time and reducing the credit usage necessary to complete the operation. For example, you might choose Claude Opus 4.8 to build the plan, then assign an agent using MAI-Flash-1 to implement the code as defined in the plan.
Giving Copilot better signal: LSP and documentation MCP
Section titled “Giving Copilot better signal: LSP and documentation MCP”Before Copilot makes upgrade changes, it needs a strong signal about both the code it is changing and the framework it is targeting. It should understand the code the way a compiler does, and understand the target framework the way its maintainers document it. Two extension points provide that signal.
A Language Server Protocol (LSP) server gives Copilot structured code intelligence — go-to-definition, find-references, hover types, workspace symbol search — from the language’s own analyzer rather than from text matching. On a modernization that precision matters: when Copilot needs to know every caller of a method whose signature changed, or whether a renamed symbol is fully rewired, an LSP answers from the compiler’s model of the code, and it does so with compact structured results instead of reading whole files into the conversation. Copilot CLI uses a configured LSP automatically whenever one is available for the language in play.
- An MCP server extends what Copilot can do; a documentation MCP server points that extension at first-party docs. Model Context Protocol (MCP) is an open standard for giving a model access to external tools and data, and Copilot CLI ships with the GitHub MCP server built in. For a Spring Boot major upgrade the documentation that matters is the frameworks’ own, and the most direct way to reach it is GitMCP, an open-source server that turns any public GitHub repository into a documentation surface. Point it at
spring-projects/spring-bootand Copilot reads Spring’s own docs straight from the source, with no account or API key — and because it’s open source you can self-host it. Pointing Copilot at a live docs surface is what keeps its framework claims tied to current guidance instead of whatever version happened to be current when its training data was frozen. For a framework major upgrade where the whole point is that things changed, that freshness is the difference between advice you can trust and advice you have to re-verify by hand.
Where LSP and MCP configuration live
Section titled “Where LSP and MCP configuration live”Copilot CLI loads LSP configuration from, in priority order, a project-level .github/lsp.json, any installed plugins, and a user-level ~/.copilot/lsp-config.json. A project-level file is the right choice for a shared course repo because it travels with the clone, so every contributor gets the same code intelligence — as long as the language server itself is installed in their environment. Each entry maps a language server to the file extensions it handles. MCP servers are configured separately and added with the /mcp add command inside a session, or with copilot mcp add from your shell.
Exercise 1: Configure a Java LSP and a documentation MCP server
Section titled “Exercise 1: Configure a Java LSP and a documentation MCP server”You’ll give Copilot structured intelligence for AssetTrack’s Java code and a first-party documentation surface for the framework research that follows. The fastest way to set up an LSP correctly is the lsp-setup skill, which detects your OS, installs the right server, and writes the configuration for you.
Install the Java language server
Section titled “Install the Java language server”Start with the code signal: install the Eclipse JDT language server through the lsp-setup skill and commit its configuration so the whole team shares the same view of the code.
-
Return to your codespace. If you closed it, navigate to your repository on GitHub.com, select Code > Codespaces, then reopen your existing codespace.
-
Open a terminal by selecting Ctrl + `, then start Copilot CLI from the repository root by running
copilot --yolo. -
If prompted, trust the project folder by selecting Yes, and remember this folder for future sessions.
-
Run
/models, select Auto from the list, and select Enter. -
Ask Copilot to install the skill directly from the Awesome GitHub Copilot collection by entering the prompt:
Install the lsp-setup skill from awesome-copilotCopilot fetches the skill and writes it into the project skills directory as
.github/skills/lsp-setup/. -
Start a new chat with
/newso Copilot loads the newly installed skill. Confirm it’s available by running/skills list— you should seelsp-setupin the list — then start the setup by entering the prompt:setup lsp -
When asked which language, choose Java. When asked about scope, choose the repository-level configuration so it’s written to
.github/lsp.jsonand shared with the team. The exact prompts vary depending on the approach Copilot takes, so follow the remaining prompts and use your best judgment to install the server. -
When setup finishes, load the configuration by running
/lsp reload, then confirm the server starts by running/lsp test java. You should see thejavaserver start and report ready.The skill writes a
.github/lsp.jsonthat registers the Eclipse JDT Language Server (jdtls) for Java. It looks like this:{"lspServers": {"java": {"command": "jdtls","args": [],"fileExtensions": {".java": "java"}}}}
- To complete the installation, exit Copilot CLI by using the command
/exit, then/exitagain, then re-open Copilot by runningcopilot --yolo.
With .github/lsp.json committed and jdtls installed, every contributor now gets the same compiler-backed view of AssetTrack’s Java code.
Register a documentation MCP server
Section titled “Register a documentation MCP server”Now add the framework signal: register GitMCP, pointed at Spring Boot’s own repository, so Copilot can read first-party documentation while it works.
- In the same session, run
/mcp addto open the registration form. - Complete the form for the GitMCP documentation server, using Tab to move between fields:
- Server Name:
gitmcp-spring-boot - Server type: HTTP
- URL:
https://gitmcp.io/spring-projects/spring-boot
- Server Name:
- Select Ctrl + S to save, then Esc to leave the form.
- Confirm the server loaded by running
/mcp listand checking thatgitmcp-spring-bootappears alongside the built-in GitHub server. - Select Esc to exit the MCP configuration screen.
GitMCP for Spring Boot is now registered, so Copilot can pull Spring Boot’s own documentation on demand as it plans and applies the upgrade.
Both the language server and the documentation MCP server are part of AssetTrack’s AI infrastructure from now on.
Planning the migration with /research
Section titled “Planning the migration with /research”A framework major upgrade is exactly the kind of decision /research exists to support: it needs current, cross-referenced sources, and the cost of getting it wrong is high. The /research slash command runs a specialized agent that investigates your codebase, relevant GitHub repositories, and the web, then produces a cited Markdown report. Unlike a normal chat answer, the report is saved to disk, so it becomes an artifact you can review, save into the repo, and hand to a teammate.
A good research prompt for a migration names the service, the current stack, the target, and the specific decisions the plan has to make — the runtime jump, the framework version, the namespace change, the data-access approach — and asks for phases and risks rather than a yes/no answer. A weak prompt (“how do I upgrade this?”) gives the agent nothing to optimize against, and the report drifts toward a generic checklist. Because the research agent works autonomously and documents its assumptions rather than stopping to ask, the more constraints you give it up front, the more useful the report.
Treat the result as evidence, not as the decision. The upgrade touches real things: Spring Boot 4 builds on Spring Framework 7 and raises the minimum Java version, so the runtime and the framework move together; Spring Boot 4 defaults to Jackson 3 — the new tools.jackson namespace — and no longer manages Jackson 2, so anything still resolving a Jackson 2 artifact needs a deliberate decision rather than a silent transitive pull; and the target is the current framework generation, not a data-layer rewrite — so keep audit-svc’s working JdbcTemplate code in this upgrade and record the larger move to Spring Data JPA as a separate follow-on rather than smuggling a rewrite into a framework bump. A good report will surface each of these with a source; your job is to confirm the sources are real and current before you let the plan drive code.
Exercise 2: Get a research-backed migration plan for audit-svc
Section titled “Exercise 2: Get a research-backed migration plan for audit-svc”The plan you’ll drive the rest of the module from was produced by a real /research run — the research prompt in the tip below, pointed at audit-svc — and then trimmed so Copilot can consult it without re-reading a 700-line report every time it needs the recipe. It’s a representative artifact: citation-backed, phased, and grounded in the actual contoso-inventory source. You’ll pull it into the repo now so it becomes the first reusable asset of the modernization, then verify it before it drives any code.
-
In your main session, have Copilot find the representative plan in the course repository and save it into your repo. Copilot CLI ships with the GitHub MCP server, so it can locate the file by repository and name rather than a brittle raw URL:
Using the built-in GitHub MCP server, find the audit-svc migration plan in the github-samples/advanced-copilot-cli repository — it's the resource file under content/resources for modernizing audit-svc. Read its contents and save them to docs/modernization/audit-svc-plan.md in this repo. Save it as-is — don't summarize or reformat it. -
Open
docs/modernization/audit-svc-plan.mdand read the phases. Check it against the ground truth so you trust it before it drives code: it names a specific Spring Boot 4.1 parent rather than a generic “4.x”, it accounts for the Jackson 2→3 default that Spring Boot 4 brings, and it keeps the existingJdbcTemplatedata access rather than folding a JPA rewrite into the upgrade. Verify a couple of the cited links resolve. This is the contract the migrator agent works against, so if any phase reads too vaguely to hand to a teammate, ask Copilot to deepen it — ambiguity here becomes drift later.
Creating a test safety net
Section titled “Creating a test safety net”A modernization is a unique kind of code update: the whole point is that behavior stays the same while the framework underneath it migrates completely. That’s exactly the situation tests were built for. A suite that pins the current behavior turns every phase of the upgrade into a yes/no question, “Did the parent bump, the base-image change, or a moved import alter what the service does?”, and answers it in seconds instead of in a production incident weeks later. Without that signal you’re reading diffs and hoping; with it, you can let a fast agent make sweeping changes and know immediately when one lands wrong.
Two layers of tests catch different failures, and a real upgrade wants both:
- Regression tests at the service — unit and integration tests that exercise
audit-svc’s endpoints and its data access. These are the inner loop: they run in seconds after every phase and pinpoint the exact change that broke a behavior, so a regression is fixed against the phase that caused it rather than untangled ten phases later. - End-to-end tests across the system — a Playwright suite you built earlier that drives AssetTrack through the UI. A framework major can leave a service’s own tests green while breaking how it integrates with the rest of the system; the e2e layer is the outer net that catches a contract that shifted at the seams.
The catch is that audit-svc has no tests today, which is common for exactly the services most in need of modernizing. So the first move isn’t the upgrade — it’s building enough of a net to make the upgrade observable. You capture the current behavior before you change the framework, so the tests describe “what audit-svc does on Spring Boot 3.5,” and then hold that description constant as you move it to 4.1. Tests written after an upgrade only prove the new code is self-consistent; tests written before it prove you didn’t change behavior on the way.
Exercise 3: Build a test safety net for audit-svc
Section titled “Exercise 3: Build a test safety net for audit-svc”Now put that into practice: capture audit-svc’s current behavior in tests before you touch the framework, so the upgrade has a baseline to be measured against.
-
Still in your main session, have Copilot add the tests and run them, so the safety net is green before anything changes:
audit-svc has no tests. Before we modernize it, add a safety net that captures its current behavior. Add a Spring Boot context-load test like workforce-svc's WorkforceApplicationTests, plus integration tests that exercise the AuditController endpoints and the AuditRepository queries and assert the current JSON responses. Configure the tests to use an isolated temporary SQLite database instead of the real AUDIT_DB_PATH so they don't touch /data/audit.db. Then run them with mvn test from services/audit-svc and confirm they pass on the current Spring Boot 3.5 code before we change anything. -
Confirm Copilot reports the suite passing against the old version. This is the baseline: if the upgrade changes behavior, these are the tests that will tell you.
When you’re done, audit-svc has a green safety net on Spring Boot 3.5 — the behavioral baseline the migrator agent has to keep satisfying phase by phase.
Driving the upgrade with a custom migrator agent
Section titled “Driving the upgrade with a custom migrator agent”You could run the migration from your main session, but a modernization is a good candidate for a dedicated custom agent, because a written scope and a small tool surface keep the work reviewable and repeatable. A migrator agent whose instructions pin it to one service — its source, its build, and the repo wiring that service depends on — stays out of the frontend and the other services, and because its behavior is written down, you can point it at the next legacy service without re-explaining the job.
One caveat, stated honestly: that scope is an instruction the agent follows, not a sandbox. A custom agent’s tools control the kinds of actions it can take — read, edit, run commands — but edit and execute still reach the whole repository. The agent keeps to the service it’s migrating and that service’s wiring because its instructions say so. That is exactly why the approval gate matters, and why the finishing edits it makes to shared files, like the test router and package.json, are ones to read most closely.
The migrator’s instructions encode the process, not a specific service: read the saved plan, apply one phase at a time, run the service’s tests after each phase, stop after each phase and wait for your approval before starting the next, and report rather than pressing on when a phase fails. Once the phases are approved and green it finishes the job the way a careful person would — running the end-to-end suite as a final gate, wiring the service into the repo’s test router and dev script, and writing a status report — so what comes out the other end is a fully migrated service, not just an edited pom.xml. That approval gate is what keeps a fast agent honest: validation between phases is where a framework upgrade catches its own mistakes, and it only helps if you read the diff before waving the agent on.
Exercise 4: Modernize audit-svc with the migrator agent
Section titled “Exercise 4: Modernize audit-svc with the migrator agent”You’ll author a Java migrator custom agent, run it through the saved plan one reviewable phase at a time, and capture what you learned so the next service reuses it.
Author the migrator agent
Section titled “Author the migrator agent”Now encode the process itself in a reusable agent whose written scope keeps the migration reviewable and lets you rerun it on the next service.
-
Ask Copilot to write the agent definition from the migration plan you saved, so the process the research captured becomes the agent’s instructions instead of a list you re-describe by hand:
Read docs/modernization/audit-svc-plan.md, then create a custom agent at .github/agents/java-migrator.agent.md named "Java migrator" with read, edit, and execute tools that follows that plan to modernize one service and its wiring at a time — never another service or the frontend. It works one phase at a time, running the service's Maven tests after each phase and stopping for my approval before the next, then runs the Playwright end-to-end suite (npm run test:e2e) as a final gate. Finish with a testing status report confirming both layers pass on the target stack. -
Open
.github/agents/java-migrator.agent.mdand review it. Confirm the scope (one service plus its wiring, never another service’s source or the frontend), the read/edit/execute tools, the phase-by-phase rule that stops for your approval and runs the service’s tests between phases, the finishing work it does once the phases are green — the end-to-end gate, the test-router route, and the dev-script cleanup — and the closing testing status report that confirms both the unit and end-to-end suites passed on the updated framework and runtime. -
Reset to a clean conversation with
/newso Copilot picks up the new agent, then confirm it with/agent. You should seeJava migratorin the list. Select Esc to exit the agent menu.
The Java migrator agent now exists as a repository scoped asset — one you’ll use to drive your migrations.
Run the migration phase by phase
Section titled “Run the migration phase by phase”Drive the upgrade through the saved plan, approving one phase at a time and reading the diffs — watching most closely where the agent touches shared files. The agent runs the migration end to end; your job is the review at each gate.
-
Switch to the agent with
/agentand selectJava migrator, and select Enter. -
Tell the agent to perform the upgrade of audit-svc by using the following prompt:
Modernize services/audit-svc following the guidelines provided in the agent, and give me a final status report at the end. The baseline test suite from the previous exercise is already in place, so confirm it passes and start from the toolchain phase.Watch the agent work the loop: it bumps the
spring-boot-starter-parentto Spring Boot4.1.0and thejava.versionfrom17to21, re-points thejackson-bomcurrency pin at a CVE-clean Jackson 3 (Boot 4.1.0 otherwise resolves a still-vulnerable Jackson3.1.4), and builds and tests after each phase. When the LSP is active, notice that it locates callers and symbols precisely rather than grepping. -
Read the agent’s testing status report. It should name the stack the service now targets — Java 21 and Spring Boot 4.1.0 — and confirm both layers ran and passed against it: the per-phase
audit-svcunit and integration tests, and the final end-to-end suite.
Capture the playbook and update the agent
Section titled “Capture the playbook and update the agent”As highlighted previously, app modernization follows a cycle of research, coding and orchestration. As you complete one cycle, learnings should be documented and updates made to the tools used. Now that you’ve updated the first service, let’s document any learnings, and ensure the agent is updated to reflect any needed changes. Writing docs and editing the agent definition are outside the migrator’s scope, so switch back to your default agent with /agent before you start.
-
Turn what you just learned into a short playbook so the next service reuses the recipe. Ask Copilot to write it from the actual work, not from theory, by sending the following prompt:
Using the the learnings and process we just followed, let's create an updated migration-playbook.md file that will supersede the original. Bring over anything applicable generalized from the original research, and any lessons from the upgrade you just performed. -
Ask Copilot to update the agent with any learnings it has that might improve the process by using the following prompt:
Let's perform a similar update to the agent definition as well. Identify any areas of the agent's definition that could be improved upon. -
Review the newly generated
migration-playbook.mdand updatedjava-migrator.agent.mdfiles, making any changes you believe are necessary for clarity’s sake.
When you’re done, audit-svc runs on Java 21 and Spring Boot 4.1, its tests are green, and it has moved a full generation forward from Java 17 / Spring Boot 3.5 — and you’ve produced four assets that outlast this one service: the Java migrator agent, the saved plan, the playbook, and a test router that now guards the modernized service.
Exercise 5: Reuse the assets on the next service
Section titled “Exercise 5: Reuse the assets on the next service”Modernizing the first service was the expensive part. The second one is where building assets pays off: the same agent and the same playbook are most of the work already done — and because the playbook already captured the recipe, you don’t need a second research pass to rediscover it. auth-svc starts from the same Java 17 / Spring Boot 3.5 baseline as audit-svc, but it carries this module’s real dependency-security lesson: it issues JWTs with the jjwt library, and under Spring Boot 4 jjwt’s serializer drags in a vulnerable transitive Jackson 2 — exactly the dependency the framework upgrade stops managing for you. Clearing it without regressing the clean baseline is the substance of this upgrade: bump jjwt from 0.11.5 to 0.12.7 (its -api, -impl, and -gson artifacts) and swap the jjwt-jackson serializer for jjwt-gson, whose CVE-clean Gson dependency (2.13.2) removes Jackson 2 from auth-svc entirely.
-
Start a new session in Copilot to load the changes we just made by using the
/newcommand. -
Build the safety net first, the same way you did for
audit-svc. Have Copilot write the tests and confirm they pass against the current version so you have a baseline before anything changes:Add safety net tests for auth-svc: a context-load test plus integration tests for the TokenController that assert a token is issued and validates, using an isolated temporary database. Run them with mvn test and confirm they pass on the current version. -
Enable the Java migrator agent by using the
/agentcommand in Copilot, selectingjava-migrator, then selecting Enter. -
Run the newly updated agent and playbook to modernize
auth-svcby using the following prompt:Modernize services/auth-svc following the guidelines provided in the agent, and give me a final status report at the end. The baseline test suite from the previous exercise is already in place, so confirm it passes and start from the toolchain phase.The agent performs the upgrade, following the steps lessons from your research and the first migration process.
-
Once the work is complete, ask Copilot to create a PR with your new agent, playbook, and newly upgraded services by using the following prompt:
Group all the changes we made into logically grouped commits. Then create a new pull request with a summary of what we built.
When you’re done, both legacy services are on the modern stack, and the second upgrade reused the migrator agent, the playbook, and the router pattern instead of rediscovering them — the payoff of starting small, learning, and documenting rather than writing one-off prompts. That’s how the process compounds.
Summary
Section titled “Summary”You modernized AssetTrack’s oldest service without letting the agent improvise, by running the same process a careful engineer would. In this module, you:
- Configured a Java LSP so Copilot reasoned about the code from the compiler, and registered a GitMCP documentation MCP server pointed at Spring Boot’s own repository so its framework claims came from current, first-party docs.
- Used
/researchto produce a citation-backed, phased migration plan and saved it into the repo as a reusable asset. - Built a test safety net that captured the service’s behavior before the upgrade, giving fast signal at every phase and an end-to-end check across the system.
- Built a scoped
Java migratoragent that applied the upgrade in reviewable phases, validated by its own unit and end-to-end tests. - Reused the agent, a captured playbook, and an extended test router to modernize the second service faster than the first, then shipped both upgrades as a single reviewed pull request.
The throughline is that AI changes the cost of each step, not the need for the steps. Assess, plan, protect, migrate, validate, and document is what keeps a fast agent producing an upgrade you can review — and the assets you build doing it are what make the next one cheap. Next, you’ll take the agents, skills, and MCP servers you’ve built and distribute them across the whole organization in the next module.
Resources
Section titled “Resources”- Adding LSP servers for GitHub Copilot CLI
- Eclipse JDT Language Server (
jdtls) - Adding MCP servers for GitHub Copilot CLI
- Researching with GitHub Copilot CLI
- Creating custom agents for GitHub Copilot CLI
- Spring Boot 4.0 migration guide
- Spring Framework 7 reference
- Jackson 3
- GitHub Copilot modernization plugin
| ← Previous: Adding a new feature | Next: Managing Copilot’s infrastructure → |
|---|