# How to Get Started with the GitHub Copilot SDK for Java: Maven and Gradle Setup

> Master the GitHub Copilot SDK for Java with this guide. Learn Maven and Gradle setup, client instantiation, and programmatically use Copilot CLI from Java 17+.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: getting-started
- Published: 2026-07-18

---

**TLDR:** Add the `com.github:copilot-sdk-java` dependency to your [`pom.xml`](https://github.com/github/copilot-sdk/blob/main/pom.xml) or `build.gradle`, instantiate `CopilotClient`, call `start()`, create a `SessionConfig`, and use `session.sendAndWait()` to drive the Copilot CLI programmatically from Java 17+.

The **GitHub Copilot SDK for Java** turns the Copilot CLI into a programmable AI backend for your JVM applications. As implemented in the `github/copilot-sdk` repository, the SDK provides a typed Java façade over the CLI's JSON-RPC protocol, letting you spawn processes, manage chat sessions, and register custom tools directly from your code. Because it ships as a **multi-release JAR** compiled for Java 17+, the SDK automatically leverages virtual threads when running on JDK 25 without requiring any build changes.

## Maven and Gradle Configuration

### Adding the Dependency to Maven

Include the following in your [`pom.xml`](https://github.com/github/copilot-sdk/blob/main/pom.xml):

```xml
<dependency>
    <groupId>com.github</groupId>
    <artifactId>copilot-sdk-java</artifactId>
    <version>1.0.5-01</version> <!-- replace with the latest release -->
</dependency>

```

### Adding the Dependency to Gradle

Add the following to your `build.gradle`:

```groovy
implementation 'com.github:copilot-sdk-java:1.0.7-01'   // replace with the latest release

```

## Understanding the Three-Layer Architecture

Before writing code, it helps to understand how the SDK is structured according to the source code.

### Client Layer

The **`CopilotClient`** class, defined in [[`CopilotClient.java`](https://github.com/github/copilot-sdk/blob/main/CopilotClient.java)](https://github.com/github/copilot-sdk/blob/main/java/src/main/java/com/github/copilot/CopilotClient.java), manages the lifecycle of the Copilot CLI process or TCP connection. You instantiate it with `new CopilotClient()` and initialize the connection using `client.start()`. When the client starts, it either spawns a Copilot CLI subprocess by default or connects to an external server via TCP, then performs a protocol-version handshake via `connect` or legacy `ping` before any work begins.

### Session Layer

A session represents a single conversational chat with a model. You create one via `client.createSession()` or resume an existing one with `client.resumeSession()`. The `CopilotSession` class exposes event listeners through `session.on(...)` and message methods such as `session.send()` and `session.sendAndWait()`. Internally, the client tracks session IDs in a `sessions` map after receiving them from a `session.create` RPC payload.

### RPC and Tools Layer

Low-level JSON-RPC calls are wrapped in generated stubs such as `ServerRpc` and `SessionRpc`. The generated source files live under `java/src/generated/java/com/github/copilot/generated/rpc/`, including classes like [[`SessionOptionsUpdateParams.java`](https://github.com/github/copilot-sdk/blob/main/SessionOptionsUpdateParams.java)](https://github.com/github/copilot-sdk/blob/main/java/src/generated/java/com/github/copilot/generated/rpc/SessionOptionsUpdateParams.java). The SDK also supports custom tools through annotations or an experimental inline API, with design decisions recorded under `docs/adr/` and troubleshooting notes under `docs/troubleshooting/`.

## Quick-Start Java Example

The following program mirrors the quick-start flow shown in [[`java/README.md`](https://github.com/github/copilot-sdk/blob/main/java/README.md)](https://github.com/github/copilot-sdk/blob/main/java/README.md). It starts the client, creates a session with automatic permission approval, listens for assistant messages, and sends a prompt.

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.generated.AssistantMessageEvent;
import com.github.copilot.rpc.MessageOptions;
import com.github.copilot.rpc.PermissionHandler;
import com.github.copilot.rpc.SessionConfig;

public class CopilotDemo {
    public static void main(String[] args) throws Exception {
        // 1️⃣ Create the client (will spawn the CLI subprocess)
        try (var client = new CopilotClient()) {
            client.start().get();                       // ⬆️ connect to the CLI

            // 2️⃣ Create a session; approve every permission request automatically
            var session = client.createSession(
                new SessionConfig()
                    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
                    .setModel("gpt-5")                 // or any model name you have access to
            ).get();

            // 3️⃣ Listen for the assistant’s messages
            session.on(AssistantMessageEvent.class, ev ->
                System.out.println("Assistant: " + ev.getData().content())
            );

            // 4️⃣ Send a prompt and wait for the response
            session.sendAndWait(new MessageOptions().setPrompt("What is 2+2?")).get();
        }
    }
}

```

The flow is deliberate: start the client, configure the session, attach listeners, and then interact with the model.

## Registering Custom Tools

The SDK lets you expose Java methods as tools the model can invoke mid-conversation.

### Annotation-Based Tool Definition

Annotate a method with **`@CopilotTool`** and parameters with **`@CopilotToolParam`** from the `tool` package. The runtime injects a **`ToolInvocation`** instance so your method can access metadata such as `sessionId` and `toolCallId`.

```java
import com.github.copilot.tool.CopilotTool;
import com.github.copilot.tool.CopilotToolParam;
import com.github.copilot.rpc.ToolInvocation;

class MyTools {
    @CopilotTool("Echoes the supplied text")
    public String echo(
            @CopilotToolParam("Text to echo") String text,
            ToolInvocation inv) {                     // runtime context (sessionId, toolCallId)
        return "You said: " + text;
    }
}

```

### Experimental Inline Definition API

If you prefer to define tools programmatically at session construction time, use the **`ToolDefinition`** builder. This approach lets you skip permission prompts and configure deferral behavior inline.

```java
import com.github.copilot.rpc.ToolDefinition;
import com.github.copilot.tool.Param;

ToolDefinition search = ToolDefinition
    .from(
        "search_items",
        "Searches indexed items by keyword",
        Param.of(String.class, "keyword", "Search keyword"),
        kw -> "Searching for: " + kw)
    .skipPermission(true)               // bypass permission prompts
    .defer(ToolDefer.AUTO);

```

## Summary

- Add `com.github:copilot-sdk-java` to your **Maven** [`pom.xml`](https://github.com/github/copilot-sdk/blob/main/pom.xml) or **Gradle** `build.gradle` to import the GitHub Copilot SDK for Java.
- The SDK requires **Java 17+** and ships as a multi-release JAR that uses virtual threads automatically on JDK 25.
- Instantiate **`CopilotClient`**, call `start()`, then use `createSession()` to obtain a conversational session.
- Listen for events with `session.on()` and send prompts with `session.sendAndWait()`.
- Define custom tools via **`@CopilotTool`** annotations or the experimental **`ToolDefinition`** API.

## Frequently Asked Questions

### What Java version is required for the GitHub Copilot SDK for Java?

The SDK is compiled as a **multi-release JAR** targeting Java 17 and newer. If you run on JDK 25, the runtime automatically enables virtual threads; otherwise, it falls back to standard threading models without any code changes.

### How does CopilotClient connect to the Copilot CLI?

By default, `CopilotClient` spawns the Copilot CLI as a subprocess. Alternatively, you can configure it to connect over TCP to an external server. In both cases, it performs a protocol-version handshake via `connect` or legacy `ping` before marking the client as started.

### How do I handle permission requests during a session?

Pass a permission handler through `SessionConfig`. For example, `PermissionHandler.APPROVE_ALL` automatically approves every request, which is useful for local development. Production code should implement custom logic inside `setOnPermissionRequest()`.

### Where are the JSON-RPC types defined in the source code?

Generated RPC stubs such as [`SessionOptionsUpdateParams.java`](https://github.com/github/copilot-sdk/blob/main/SessionOptionsUpdateParams.java) and [`CreateSessionResponse.java`](https://github.com/github/copilot-sdk/blob/main/CreateSessionResponse.java) live under `java/src/generated/java/com/github/copilot/generated/rpc/`. These classes wrap the low-level JSON-RPC wire format in strongly typed Java objects used by `CopilotClient` and `CopilotSession`.