Creating a GitHub Copilot Extension: A Step-by-Step Guide
GitHub Copilot, the AI-powered coding assistant, has recently introduced Copilot Extensions to enhance its ecosystem. This feature, now in public beta, allows developers to create custom extensions that integrate with Copilot. In this blog post, we'll walk through the process of creating your first GitHub Copilot extension.
Before we begin, it's important to note that you need to have an active GitHub Copilot subscription to create and use Copilot extensions.
Creating the Endpoint for Your Copilot Extension
A Copilot extension is essentially a GitHub app with a specific endpoint. Let's set up the project and create this endpoint, which together will form your Copilot extension.
Setting Up Your Project
In this guide, we're using Hono.js as our web framework, but you can use any web framework or web server of your choice. The core concepts will remain the same regardless of the framework you choose. The only thing to be aware of about the SDK is, for the moment, the only languages supported are TypeScript and JavaScript.
Create a new Hono project using the Hono CLI:
npm create hono@latest
Follow the prompts to set up your project. This will create a new TypeScript project using Hono.js, a lightweight and fast web framework.
Install the preview SDK for Copilot extensions and Octokit's core package:
npm install @copilot-extensions/preview-sdk @octokit/core
%[https://github.com/copilot-extensions/preview-sdk.js]
Open your main file (e.g.,
src/index.ts
) and let's start by importing the necessary dependencies:import { Hono } from 'hono' import { Octokit } from "@octokit/core"; import { createAckEvent, createDoneEvent, createErrorsEvent, createTextEvent, getUserMessage, verifyAndParseRequest, } from "@copilot-extensions/preview-sdk"; const app = new Hono();
Implementing the Endpoint
Now, let's implement the endpoint that will handle requests from GitHub Copilot:
Create a root route that receives a form post,
/
. This is the endpoint that Copilot will interact with:app.post("/", async (c) => { // ... (we'll fill this in next) });
When a message comes in, you need to verify the request and parse the payload:
const body = await c.req.text(); const signature = c.req.header("github-public-key-signature") ?? ""; const keyID = c.req.header("github-public-key-identifier") ?? ""; const { isValidRequest, payload } = await verifyAndParseRequest( body, signature, keyID, { token: tokenForUser, } ); if (!isValidRequest) { console.error("Request verification failed"); c.header("Content-Type", "text/plain"); c.status(401); c.text("Request could not be verified"); return; }
After verifying the request, process the message and create a response. Here's a simple example that greets the user:
const octokit = new Octokit({ auth: tokenForUser }); const user = await octokit.request("GET /user"); const prompt = getUserMessage(payload); return c.text( createAckEvent() + createTextEvent( `Welcome ${user.data.login}! It looks like you asked the following question, "${prompt}". This is a GitHub Copilot extension template, so it's up to you to decide what you want to implement to answer prompts.` ) + createDoneEvent() );
This example uses the GitHub Octokit package to get the user's login name and greets them. The createTextEvent
function is used to create the response that GitHub Copilot will display.
Exposing Your Extension
To test your Copilot extension, you need to make it publicly accessible:
If using Visual Studio Code (VS Code), enable port forwarding. Note that the port is private by default, a good thing, but for our use case, we need to set it to public.
Alternatively, use tools like cloudflared or ngrok to expose a public URL.
In the provided code, the server is set up to run on port 3000:
const port = 3000;
console.log(`Server is running on port ${port}`);
serve({
fetch: app.fetch,
port,
});
It's worth mentioning that this setup is great for testing, but once you're ready to make your extension public, you'll need to deploy the web app (which acts as the GitHub app) to a publicly accessible location.
Creating a GitHub App
Create a new GitHub app on your personal account for testing purposes. Head to your settings page on GitHub, and at the bottom, to the left, click on the Developer Settings link. This will bring you to your GitHub apps. You can also directly navigate to your GitHub apps page at https://github.com/settings/apps.
General settings
Enter a GitHub App name, e.g. my copilot extension
Enter a URL for the homepage. This can be the same as the test URL for now.
Set the Callback URL (currently required). This can be the same as the test URL for now. Even if you're not using OAuth you still need to put a URL here. I'm told in future this may no longer be required.
Disable webhooks if they're enabled.
Make sure the app is initially accessible only to you. You can enable it for everyone when you're ready to make your GitHub Copilot extension publicly available.
Click the Create GitHub App button to create the GitHub app.
Permissions & events settings
Next up, we'll need to configure permissions. We want to provide the bare minimum permissions for a Copilot extension to work.
Expand the Account permissions sections and set the Copilot Chat permission to read-only. The default is No access.
Click Save changes. Don't be alarmed by the Are you sure you want to update permissions? message.
Copilot settings
Set the App Type to Agent. It's set to Disabled by default.
Set the URL to the root of the public URL you exposed via tunneling/port forwarding.
Click Save.
Congratulations! You've configured your first Copilot extension!
Install Your Copilot Extension
Before we can use the extension, it has to be installed.
Navigate to your GitHub apps in your developer settings.
Click the Edit button to edit the app.
Go to the Install App section of the GitHub app's settings.
Click the Install button to install the application
You're brought to an intermediary page to confirm the installation of the GitHub app. Click the Install button.
Your Copilot extension is installed for your GitHub account.
Testing Your Extension
You can test your Copilot extension in a few environments:
GitHub.com's Copilot chat
For these environments, follow these steps:
In the GitHub Copilot chat, type "@" to see available extensions.
Your extension should appear as, e.g. "@my-copilot-extension".
Select your extension and ask a question or perform an operation.
The Copilot extension will return a response of Welcome your_github_username! It looks like you asked the following question, "your_question". This is a GitHub Copilot extension template, so it's up to you to decide what you want to implement to answer prompts.
It won't respond to your specific question as that functionality has not been implemented. This is where you can explore the preview SDK or integrate with a third-party service to provide more meaningful responses.
A Real-World Example
I've created a proof-of-concept (POC) Copilot extension for OpenSauced, where I work, that demonstrates these principles in action.
This extension utilizes OpenSauced's StarSearch feature to provide open-source insights directly within Copilot.
Curious about StarSearch? ๐
This POC showcases how you can leverage external APIs and services to create powerful, context-aware extensions that enhance the Copilot experience.
Grab the GitHub Copilot Extension Template
If you're interested in starting your own GitHub Copilot Extension, I've created a template to help you get started quickly:
This template provides a solid foundation for building your extension, incorporating best practices and a basic structure to build upon. The template uses the Hono.js Node.js server, but it's worth noting that Hono.js offers various adapters for different deployment environments. You can use adapters for platforms like Netlify, Vercel, Cloudflare Workers, and more. For more information on Hono.js and its adapters, check out their Getting Started guide.
I also encourage you to take a peek at the examples in the copilot-extensions organization on GitHub, including some examples in the preview SDK:
These examples can provide inspiration and guidance as you develop your own extensions.
Take a deep dive into Copilot extensions and the preview SDK
For a deeper dive into the preview SDK and Copilot extensions in general, check out this video: "Let's build a Copilot extension!" Shout out to Gregor Martynus (@gr2m) and Francis Batac (@francisfuzz) for hanging with me!
This video provides valuable insights into the development process and can help you understand the nuances of working with Copilot extensions.
I also encourage you to check out the official GitHub Copilot documentation.
Wrapping up
Creating a GitHub Copilot extension opens up new possibilities for enhancing your development workflow. By following this guide, you can start building custom extensions that leverage the power of Copilot while adding your own unique functionality.
Remember, the Copilot Extensions feature is still in beta, so keep an eye out for updates and improvements as the ecosystem evolves. This is an exciting time to get involved and potentially shape the future of AI-assisted coding!
Until the next one!
Other places you can find me:
๐๏ธ One Tip a Week Newsletter ๐ฌ YouTube ๐ฌ Twitch ๐ฌ nickyt.live ๐ป GitHub ๐พ My Discord ๐ฆ Twitter/X ๐งต Threads ๐ My Website
Subscribe to my newsletter
Read articles from Nick Taylor directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nick Taylor
Nick Taylor
Hello! My name is Nick Taylor. I'm a Senior Software Engineer at OpenSauced. I'm a fan of Open Source and have a growing interest in serverless and edge computing. I'm not a big fan of spiders, but I know they're doing good work eating bugs. I also stream on Twitch. I am a big fan of TypeScript, JavaScript, Node, and all things frontend. Aside from programming, I enjoy contributing to open source, hitting the gym, snowboarding, and rugby a long time ago.