AI & Agents

How to Query the GitHub Copilot API with External Tool Context

Querying the Copilot API with external context allows developers to pass custom file systems, test outputs, and environmental metrics directly within request prompts. This step-by-step guide explains how to query github copilot api using external tool context, authenticate programmatically, invoke the chat completions endpoint, and structure context payloads for accurate code suggestions.

Fast.io Editorial Team 12 min read
How to Query the GitHub Copilot API with External Tool Context hero image

Why Standard Copilot Queries Lack Local Workspace Context

When a coding agent or automation script calls the GitHub Copilot API programmatically without injecting workspace context, it generates suggestions in a vacuum. A model operating without active workspace context produces generic code completions that ignore local file structures, internal API schemas, and active configuration settings. To align suggestions with a specific project, external tools must inject local environment telemetry directly into the chat prompt payload.

Querying the Copilot API with external context involves passing file structures, tool outputs, or runtime metrics within the prompt payload to align the model’s suggestions. This pattern is simplified by the Model Context Protocol, which establishes a standard communication layer between AI models and local or remote data sources. In standard development environments, the IDE automatically gathers context from open editor tabs and cursor positions. When developers query the API programmatically from a continuous integration check, a local script, or an external assistant, the responsibility of gathering and formatting this context falls entirely on the developer.

Without this context, the model lacks visibility into how different components of the codebase interact. For instance, if an agent is tasked with writing a new database query, it cannot write accurate code if it does not know the database schema or the existing table structures. The resulting output will likely contain hypothetical library imports, incorrect function names, and incompatible datatypes. Providing external context directly inside the API query payload ensures the model remains grounded in the realities of the active codebase.

This context gap is especially noticeable when running automated testing pipelines. An agent analyzing a failing test run needs to inspect not only the test file itself but also the error logs, dependency trees, and environmental configurations. A simple API query that only passes the failing test file will result in generic advice about fixing syntax. Passing the exact error stack trace and the active configuration parameters allows the model to pinpoint the exact line of code that triggered the failure.

How to Authenticate and Retrieve Copilot Session Tokens

Programmatic access to GitHub Copilot requires a dynamically generated session token. External tools cannot authenticate directly using a static GitHub personal access token against the chat completions endpoint. Instead, the integration pipeline must use a standard token exchange flow to retrieve a short-lived session token.

API integrations use standard Copilot authentication tokens, which are exchanged dynamically for short-lived session tokens. This authentication mechanism requires two steps:

  1. Obtain a standard GitHub user token, which typically starts with a ghu_ prefix. This token can be retrieved by running the GitHub CLI auth token command or through a web-based OAuth flow.
  2. Exchange this user token for a Copilot session token by making a GET request to the internal GitHub API token endpoint.

The internal token endpoint is located at https://api.github.com/copilot_internal/v2/token. When querying this endpoint, pass the GitHub user token in the Authorization header.

Here is an example request using curl:

curl -X GET https://api.github.com/copilot_internal/v2/token \
  -H "Authorization: token ghu_YOUR_GITHUB_USER_TOKEN"

The server responds with a JSON payload containing the short-lived session token:

{
  "token": "tid=12345abcdef...;exp=1700000000;...",
  "tracking_id": "ab12cd34ef56",
  "expires_in": 1500
}

The session token begins with tracking and expiration parameters and must be extracted from the token field. Because this token expires quickly, your integration scripts must monitor the expiration timestamp and repeat the exchange request to retrieve a fresh token.

Here is a Python example that manages this token cache and handles automatic renewal based on the expires_in field:

import time
import urllib.request
import json

class CopilotTokenManager:
    def __init__(self, github_token):
        self.github_token = github_token
        self.session_token = None
        self.expiry_time = 0

def get_token(self):
        if self.session_token and time.time() < self.expiry_time - 60:
            return self.session_token

req = urllib.request.Request(
            "https://api.github.com/copilot_internal/v2/token",
            headers={"Authorization": f"token {self.github_token}"}
        )

try:
            with urllib.request.urlopen(req) as response:
                data = json.loads(response.read().decode("utf-8"))
                self.session_token = data["token"]
                self.expiry_time = time.time() + int(data.get("expires_in", 1500))
                return self.session_token
        except Exception as e:
            raise RuntimeError(f"Token exchange failed: {e}")

This token manager caches the session token locally and automatically requests a new one when the current session is within sixty seconds of expiring. This setup ensures that your automated pipelines do not crash mid-execution due to authorization timeouts. Once retrieved, this session token must be passed in the Authorization header as a Bearer token on all subsequent requests to the completions endpoint.

How to Query GitHub Copilot API Using External Tool Context

With a valid Copilot session token, your external tools can make post requests directly to the completions API. The chat completions service is hosted at https://api.githubcopilot.com/chat/completions. This endpoint behaves similarly to the OpenAI chat completions standard, allowing you to use standard HTTP clients to construct requests.

To query this endpoint successfully, your request must include three essential headers:

  • Authorization: Pass your short-lived session token as a Bearer token.
  • Copilot-Integration-Id: Set this header to vscode-chat or a similar official integration identifier to authorize the query.
  • Content-Type: Set to application/json.

If you omit the integration identifier, the Copilot gateway will reject the request with an authentication error. The body of the request must specify the target LLM model and include the messages array.

Here is a Python example that performs the entire request process:

import json
import urllib.request

copilot_token = "YOUR_COPILOT_SESSION_TOKEN"
url = "https://api.githubcopilot.com/chat/completions"

headers = {
    "Authorization": f"Bearer {copilot_token}",
    "Copilot-Integration-Id": "vscode-chat",
    "Content-Type": "application/json"
}

payload = {
    "model": "gpt-4o",
    "messages": [
        {
            "role": "user",
            "content": "Explain how to query the GitHub Copilot API."
        }
    ],
    "temperature": 0.3,
    "stream": False
}

req = urllib.request.Request(
    url,
    data=json.dumps(payload).encode("utf-8"),
    headers=headers,
    method="POST"
)

try:
    with urllib.request.urlopen(req) as response:
        result = json.loads(response.read().decode("utf-8"))
        print(result["choices"][0]["message"]["content"])
except Exception as e:
    print(f"Request failed: {e}")

If you enable streaming by setting the stream parameter to true, the server returns the response in a Server-Sent Events stream. The response chunks are delivered as lines prefixed with data:, followed by a JSON payload. The script must parse these lines and extract the text token until it receives the data: [DONE] termination marker. The request format allows developers to communicate with Copilot from arbitrary environments, including command-line interfaces and local test systems. To receive project-specific suggestions, you must enrich this request payload with external context.

Structuring the Payload to Inject Tool Metrics and File Maps

Injecting custom context requires formatting the messages array to carry files, schemas, and diagnostics alongside the user prompt. To keep suggestions accurate, the prompt payload must organize this data using clear structural boundaries, such as XML tags or Markdown blocks.

For example, a request payload that passes a database schema and local terminal output to the API would look like this:

{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "system",
      "content": "You are a coding assistant. Ground your suggestions in the provided workspace context."
    },
    {
      "role": "user",
      "content": "Context injection allows tools to pass external workspace telemetry to improve suggestion accuracy. Below is the current system context:

<file_context>
File: src/database.js
Content:
const db = require('db-connector');
// Active database connection goes here
</file_context>

<tool_output>
Test runner error:
Error: Connection timed out after 5000ms at src/database.js:12
</tool_output>

Review the file and debug the connection error."
    }
  ],
  "temperature": 0.2
}

When building this payload, you must respect the constraints of the model's context window. Passing excessively large files or raw terminal streams can exhaust your tokens and slow down response generation. A practical pattern is to parse the workspace files locally, filter out binary assets, and only inject relevant text snippets.

Client systems often truncate tool outputs that exceed a small size limit, keep your context payloads concise. For example, if you are passing test logs, extract the relevant stack trace and error message rather than copying the entire output stream. Structuring your context in this manner ensures the Copilot engine receives high-value signals, resulting in accurate suggestions.

You can automate this assembly process using a local preparation script. Here is a Python pattern that walks your workspace, ignores binary extensions, reads the text files, and packages them into the XML payload structure:

import os

def package_context(root_dir, target_exts=None):
    if target_exts is None:
        target_exts = {".js", ".py", ".json", ".md", ".yml"}
    context_blocks = []
    nl = chr(10)
    for root, _, files in os.walk(root_dir):
        if any(p in root.split(os.sep) for p in [".git", "node_modules", "__pycache__"]):
            continue
        for file in files:
            ext = os.path.splitext(file)[1]
            if ext in target_exts:
                filepath = os.path.join(root, file)
                try:
                    with open(filepath, "r", encoding="utf-8") as f:
                        content = f.read()
                        rel_path = os.path.relpath(filepath, root_dir)
                        block = "<file_context>" + nl + f"File: {rel_path}" + nl + "Content:" + nl + content + nl + "</file_context>"
                        context_blocks.append(block)
                except Exception:
                    continue
    return (nl + nl).join(context_blocks)

This helper function structures the file context automatically and isolates code paths to ensure the prompt payload stays organized and readable for the model.

Fastio features

Persist and index your coding agent context

Connect your custom developer tools to a remote MCP server. Keep your files versioned, searchable, and shared between agents and humans. Starts with a 14-day free trial.

Managing Coding Agent Context with Fast.io Workspaces

While local scripts querying the Copilot API are useful for individual tasks, they do not provide a shared space for teams. When multiple developers and coding agents work on the same codebase, keeping context local leads to sync issues and scattered files. To resolve this, teams can use Fast.io as a shared cloud substrate where humans and agents collaborate.

Instead of running local sync clients that conflict with high-frequency agent writes, teams can import files into a secure Fast.io workspace. Fast.io supports server-to-server cloud imports from Google Drive, Dropbox, OneDrive, and Box using OAuth, preserving the folder structure. Once imported, you can enable Intelligence Mode. Fast.io automatically indexes the workspace documents, allowing agents to perform hybrid semantic search and Q&A with page-level citations.

Agents connect to these workspaces programmatically using the remote Fast.io MCP server. Fast.io exposes its MCP tools at https://mcp.fast.io/mcp or https://mcp.fast.io/mcp/key for key-based authentication. This allows agents to query workspace data, read documentation, and edit files without maintaining local storage. You can read more about setting up agent access in the Fast.io storage for agents guide.

For example, you can configure the Fast.io MCP server in an agent's configuration file, such as cline_mcp_settings.json:

{
  "mcpServers": {
    "fastio-workspace": {
      "url": "https://mcp.fast.io/mcp/key",
      "type": "streamableHttp",
      "disabled": false,
      "headers": {
        "Authorization": "Bearer YOUR_FASTIO_API_KEY"
      }
    }
  }
}

This remote configuration allows the agent to read and write files directly in the shared workspace. All file edits are tracked using file version history, meaning you can review changes and restore prior versions at any time. Every action is recorded in the append-only audit log to maintain transparency.

Agents can use Metadata Views to turn workspace files into structured databases. By defining a natural language schema through the MCP interface, agents can extract metadata fields such as counterparties, contract values, or code dependency versions. This data is populated into a filterable grid without requiring manual entry or OCR rules.

Once the agent completes its tasks, it can hand the work back to a human. Fast.io supports ownership transfer, allowing an agent to set up the workspace, import files, and transfer organization ownership to a human admin via a claim link.

Creating a user account is free, but doing real work requires an organization on a paid subscription. Every organization starts with a 14-day free trial that requires a credit card. Plans are Starter at 29 USD monthly, Business at 99 USD monthly, and Growth at 299 USD monthly. Once the transfer is complete, the human team has full control over the versioned, searchable workspace. Teams can get started by opening the Fast.io pricing page and initiating a trial workspace.

Frequently Asked Questions

How do I call the GitHub Copilot API programmatically?

You can query the GitHub Copilot API programmatically by first exchanging a personal GitHub OAuth token (with a ghu_ prefix) for a short-lived Copilot session token at `https://api.github.com/copilot_internal/v2/token`. You then pass this session token in the Authorization header as a Bearer token when making a POST request to `https://api.githubcopilot.com/chat/completions`, along with a Copilot-Integration-Id header.

Can you pass custom context to the Copilot API?

Yes, you can pass custom context to the GitHub Copilot API by structuring the prompt payload inside the messages array. Developers inject structured XML-style tags, such as `<workspace_context>`, `<file_tree>`, or `<tool_output>`, directly into system or user messages. Alternatively, you can connect Copilot to a remote Model Context Protocol (MCP) server that provides the model with action-based tool access to your external files.

What endpoints does GitHub Copilot use?

GitHub Copilot uses `https://api.github.com/copilot_internal/v2/token` to handle the token exchange process and authenticate API sessions. It then routes text-generation and code completion requests to the chat completions endpoint at `https://api.githubcopilot.com/chat/completions`, which mirrors the standard OpenAI chat payload format.

Related Resources

Fastio features

Persist and index your coding agent context

Connect your custom developer tools to a remote MCP server. Keep your files versioned, searchable, and shared between agents and humans. Starts with a 14-day free trial.