How to Create Custom Context Providers for Continue: A Complete Implementation Guide
You can create custom context providers for Continue by implementing the IContextProvider interface with a description property and getContextItems method, then registering your provider via registerCustomContextProvider in the VS Code extension or through your config.json file.
Continue is an open-source AI coding assistant that lets you augment LLM prompts with context items fetched from any data source. Creating custom context providers allows you to integrate internal documentation, proprietary APIs, or specialized knowledge bases directly into your AI workflow using the @ mention syntax.
Understanding the IContextProvider Interface
Every custom context provider must implement the IContextProvider interface defined in [core/index.d.ts](https://github.com/continuedev/continue/blob/main/core/index.d.ts). This contract ensures that Continue can uniformly discover, display, and execute your provider across the VS Code extension and GUI.
The interface requires two core members:
description: AContextProviderDescriptionobject containing metadata such astitle(displayed in the dropdown),type(one of"normal","query", or"submenu"), and optionalextrasfor UI hints like icons or placeholders.getContextItems(query): An async method that receives the user's query string and returns aPromise<GetContextItem[]>containing the snippets to inject into the prompt.
Implementing Your First Custom Context Provider
Step 1: Create the Provider Class
Create a new TypeScript file for your provider. In this example, we build a provider that fetches data from an external REST API.
// src/context/providers/MyProvider.ts
import { IContextProvider, ContextProviderDescription, GetContextItem } from "core";
export class MyProvider implements IContextProvider {
get description(): ContextProviderDescription {
return {
title: "MyProvider",
type: "normal",
extras: {
placeholder: "Enter search term...",
icon: "search",
},
};
}
async getContextItems(query: string): Promise<GetContextItem[]> {
const response = await fetch(
`https://my.api/lookup?q=${encodeURIComponent(query)}`
);
const data = await response.json();
return data.results.map((r: any) => ({
title: r.title,
id: r.id,
content: r.snippet,
metadata: { source: "my-api" },
}));
}
}
Step 2: Configure the Provider Description
The description object controls how your provider appears in the Continue UI. The title field becomes the @ command users type (e.g., @MyProvider). Available types are:
normal: Standard query-based providers.query: Providers that handle structured query parsing.submenu: Providers that display nested selection options.
Optional extras include placeholder text for the input field and icon for visual identification.
Registering Custom Context Providers
Once implemented, you must register your provider with the Continue runtime. Choose the method that fits your deployment scenario.
Method A: Programmatic Registration in VS Code
For VS Code extension development, import your provider and call registerCustomContextProvider inside the extension activation routine in [extensions/vscode/src/extension/VsCodeExtension.ts](https://github.com/continuedev/continue/blob/main/extensions/vscode/src/extension/VsCodeExtension.ts):
import { MyProvider } from "./src/context/providers/MyProvider";
export function activate(context: vscode.ExtensionContext) {
const extension = new VsCodeExtension();
extension.registerCustomContextProvider(new MyProvider());
}
This stores the provider in the runtime configuration, making it available across sessions.
Method B: Configuration via config.json
For CLI or SDK usage, declare your provider in config.json. The ConfigHandler will dynamically import the module at runtime:
{
"customContextProviders": [
{
"module": "./src/context/providers/MyProvider.ts",
"className": "MyProvider"
}
]
}
After registration, reload the extension or restart Continue. Your provider now appears in the @ dropdown and can be invoked with syntax like @MyProvider <query>.
Complete Example: GitHub Issues Integration
Here is a production-ready example that integrates GitHub Issues into your Continue workflow.
// src/context/providers/GithubIssuesProvider.ts
import { IContextProvider, ContextProviderDescription, GetContextItem } from "core";
export class GithubIssuesProvider implements IContextProvider {
get description(): ContextProviderDescription {
return {
title: "GitHub Issues",
type: "normal",
extras: {
placeholder: "repo:owner/name <search term>",
icon: "github",
},
};
}
async getContextItems(query: string): Promise<GetContextItem[]> {
const [repo, term] = query.split(" ", 2);
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(term)}+repo:${repo}`;
const res = await fetch(url, {
headers: { Accept: "application/vnd.github+json" },
});
const json = await res.json();
return json.items.map((issue: any) => ({
title: `#${issue.number}: ${issue.title}`,
id: issue.id,
content: issue.body ?? "",
metadata: { url: issue.html_url, state: issue.state },
}));
}
}
Usage in the editor:
@GitHub Issues repo:facebook/react button component
The provider returns matching issues, and Continue embeds the issue bodies into the prompt sent to the LLM.
Architecture and Lifecycle
Understanding the execution flow helps debug complex providers. When a user types @ProviderName query, the following occurs:
- Parsing: The TipTap editor in [
gui/src/components/mainInput/TipTapEditor/utils/renderPromptv1.ts](https://github.com/continuedev/continue/blob/main/gui/src/components/mainInput/TipTapEditor/utils/renderPromptv1.ts) parses the@mention and extracts the provider name and query string. - Resolution: The system looks up the matching
ContextProviderDescriptionin the registry, which includes both default providers and custom ones registered viaregisterCustomContextProvider. - Execution: The provider's
getContextItemsmethod is called with the query string. - Request Building: The returned
GetContextItemobjects are merged into theGetContextRequest[]payload. - Streaming: [
gui/src/redux/thunks/streamResponse.ts](https://github.com/continuedev/continue/blob/main/gui/src/redux/thunks/streamResponse.ts) sends the final payload to the language model, including your custom context items.
Summary
- Implement
IContextProvider: Create a class withdescriptionmetadata and an asyncgetContextItemsmethod defined incore/index.d.ts. - Register your provider: Use
registerCustomContextProviderinextensions/vscode/src/extension/VsCodeExtension.tsfor VS Code, or declare it inconfig.jsonfor CLI/SDK usage. - Leverage async operations: Fetch data from REST APIs, databases, or local file systems within
getContextItems. - Debug with metadata: Include optional metadata in returned items to trace context sources in complex workflows.
- Invoke with @ syntax: Users trigger your provider by typing
@YourProviderName <query>in the chat input.
Frequently Asked Questions
What TypeScript types do I need to import for a custom context provider?
Import IContextProvider, ContextProviderDescription, and GetContextItem from the core package. These types are defined in core/index.d.ts and ensure your provider conforms to the expected contract for title display and item retrieval.
Can I access external APIs or databases from my context provider?
Yes. The getContextItems method is async, allowing you to fetch data from REST APIs, query databases, or read local files before returning the results. Simply return an array of objects matching the GetContextItem structure with title, id, content, and optional metadata.
How do I debug issues with my custom context provider?
Include diagnostic information in the metadata field of your returned context items. You can also trace the provider execution flow through gui/src/components/mainInput/TipTapEditor/utils/renderPromptv1.ts, where the system resolves @ mentions and builds the prompt payload that gets sent to the LLM.
What is the difference between "normal", "query", and "submenu" provider types?
The type field in ContextProviderDescription controls UI behavior. "normal" providers accept direct text queries, "query" providers may implement specialized parsing for structured search syntax, and "submenu" providers display nested selection interfaces rather than immediate text input. Choose based on how users should interact with your data source.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →