Build Your First Copilot-Powered App
In this tutorial, you'll use the Copilot SDK for Java to build a command-line assistant. You'll start with the basics, add streaming responses, then add custom tools - giving Copilot the ability to call your code.
What you'll build:
You: What's the weather like in Seattle?
Copilot: Let me check the weather for Seattle...
Currently 62°F and cloudy with a chance of rain.
Typical Seattle weather!
You: How about Tokyo?
Copilot: In Tokyo it's 75°F and sunny. Great day to be outside!
Prerequisites
Before you begin, make sure you have:
- Java 17+ installed
- GitHub Copilot CLI installed and authenticated (Installation guide)
Verify the CLI is working:
copilot --version
Step 1: Install the SDK
If you want to test a -SNAPSHOT version, you may have to clone the project's repository and install the library locally with mvn install.
Apache Maven
Add the dependency to your pom.xml:
<dependency>
<groupId>io.github.copilot-community-sdk</groupId>
<artifactId>copilot-sdk</artifactId>
<version>1.0.4</version>
</dependency>
Gradle
Add the dependency to your build.gradle:
implementation 'io.github.copilot-community-sdk:copilot-sdk:1.0.4'
JBang (Quick Start)
For the fastest way to try the SDK without setting up a project, use JBang. Create a file named HelloCopilot.java with the following header, and then proceed to Step 2 by appending the proposed content into this same file.
//DEPS io.github.copilot-community-sdk:copilot-sdk:1.0.4
Step 2: Send Your First Message
Create a new file and add the following code. This is the simplest way to use the SDK.
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
public class HelloCopilot {
public static void main(String[] args) throws Exception {
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig().setModel("gpt-4.1")
).get();
var response = session.sendAndWait(
new MessageOptions().setPrompt("What is 2 + 2?")
).get();
System.out.println(response.getData().getContent());
}
}
}
Run the code with your preferred build tool or IDE.
Or run it directly with JBang:
jbang HelloCopilot.java
You should see:
2 + 2 = 4
Congratulations! You just built your first Copilot-powered app.
Step 3: Add Streaming Responses
Right now, you wait for the complete response before seeing anything. Let's make it interactive by streaming the response as it's generated.
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import java.util.concurrent.CompletableFuture;
public class StreamingExample {
public static void main(String[] args) throws Exception {
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setStreaming(true)
).get();
var done = new CompletableFuture<Void>();
// Listen for response chunks
session.on(event -> {
if (event instanceof AssistantMessageDeltaEvent delta) {
System.out.print(delta.getData().getDeltaContent());
} else if (event instanceof SessionIdleEvent) {
System.out.println(); // New line when done
done.complete(null);
}
});
session.send(
new MessageOptions().setPrompt("Tell me a short joke")
).get();
done.get(); // Wait for completion
}
}
}
Run the code again. You'll see the response appear word by word.
Step 4: Add a Custom Tool
Now for the powerful part. Let's give Copilot the ability to call your code by defining a custom tool. We'll create a simple weather lookup tool.
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import java.util.*;
import java.util.concurrent.*;
public class ToolExample {
public static void main(String[] args) throws Exception {
try (var client = new CopilotClient()) {
client.start().get();
// Define a tool that Copilot can call
var getWeather = ToolDefinition.create(
"get_weather",
"Get the current weather for a city",
Map.of(
"type", "object",
"properties", Map.of(
"city", Map.of(
"type", "string",
"description", "The city name"
)
),
"required", List.of("city")
),
invocation -> {
Map<String, Object> params = invocation.getArguments();
String city = (String) params.get("city");
// In a real app, you'd call a weather API here
String[] conditions = {"sunny", "cloudy", "rainy", "partly cloudy"};
int temp = new Random().nextInt(30) + 50;
String condition = conditions[new Random().nextInt(conditions.length)];
return CompletableFuture.completedFuture(Map.of(
"city", city,
"temperature", temp + "°F",
"condition", condition
));
}
);
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setStreaming(true)
.setTools(List.of(getWeather))
).get();
var done = new CompletableFuture<Void>();
session.on(event -> {
if (event instanceof AssistantMessageDeltaEvent delta) {
System.out.print(delta.getData().getDeltaContent());
} else if (event instanceof SessionIdleEvent) {
System.out.println();
done.complete(null);
}
});
session.send(
new MessageOptions().setPrompt("What's the weather like in Seattle and Tokyo?")
).get();
done.get();
}
}
}
Run it and you'll see Copilot call your tool to get weather data, then respond with the results!
Step 5: Build an Interactive Assistant
Let's put it all together into a useful interactive assistant:
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class WeatherAssistant {
public static void main(String[] args) throws Exception {
try (var client = new CopilotClient();
var scanner = new Scanner(System.in)) {
client.start().get();
var getWeather = ToolDefinition.create(
"get_weather",
"Get the current weather for a city",
Map.of(
"type", "object",
"properties", Map.of(
"city", Map.of(
"type", "string",
"description", "The city name"
)
),
"required", List.of("city")
),
invocation -> {
Map<String, Object> params = invocation.getArguments();
String city = (String) params.get("city");
String[] conditions = {"sunny", "cloudy", "rainy", "partly cloudy"};
int temp = new Random().nextInt(30) + 50;
String condition = conditions[new Random().nextInt(conditions.length)];
return CompletableFuture.completedFuture(Map.of(
"city", city,
"temperature", temp + "°F",
"condition", condition
));
}
);
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setStreaming(true)
.setTools(List.of(getWeather))
).get();
System.out.println("🌤️ Weather Assistant (type 'exit' to quit)");
System.out.println(" Try: 'What's the weather in Paris?'\n");
var done = new AtomicReference<CompletableFuture<Void>>();
// Register listener once, outside the loop
session.on(event -> {
if (event instanceof AssistantMessageDeltaEvent delta) {
System.out.print(delta.getData().getDeltaContent());
} else if (event instanceof SessionIdleEvent) {
System.out.println();
var f = done.get();
if (f != null) f.complete(null);
}
});
while (true) {
System.out.print("You: ");
String input = scanner.nextLine();
if ("exit".equalsIgnoreCase(input.trim())) {
break;
}
done.set(new CompletableFuture<>());
System.out.print("Assistant: ");
session.send(new MessageOptions().setPrompt(input)).get();
done.get().get();
}
}
}
}
What's Next?
You've learned the core concepts of the Copilot SDK:
- ✅ Creating a client and session
- ✅ Sending messages and receiving responses
- ✅ Streaming for real-time output
- ✅ Custom tools for extending Copilot's capabilities
- ✅ Building interactive applications
Explore more:
- Documentation - Basic usage and session management
- Advanced Usage - Tools, BYOK, infinite sessions, and more
- MCP Servers - Connect to Model Context Protocol servers
Troubleshooting
“Copilot CLI not found”
Make sure the GitHub Copilot CLI is installed and in your PATH:
copilot --version
If not installed, follow the GitHub Copilot CLI installation guide.
“Authentication failed”
The CLI needs to be authenticated with your GitHub account:
copilot auth login
“Connection timeout”
Check your internet connection and firewall settings. The SDK communicates with GitHub's Copilot service.
