How to Define Custom Agent Names, Prompts, and Scoped Tools in the Copilot SDK
Define custom agents in the Copilot SDK by passing a name and systemPrompt to the Agent constructor, then attach scoped tools created with the tool() factory whose scope property exactly matches the agent's name.
The GitHub Copilot SDK provides a builder-style API for defining custom agent names, prompts, and scoped tools that give each autonomous assistant a distinct identity and behavior. According to the github/copilot-sdk source code, these behaviors are controlled through core configuration points stored in src/agent.ts, src/types.ts, and src/tool.ts. These modules expose type-safe interfaces that let you bind tools to a single agent and inject custom reasoning instructions directly into the model's system message.
Setting a Custom Agent Name
An agent name is the unique identifier passed as the name option to the Agent constructor in src/agent.ts. The SDK stores this value in the request payload under metadata.name, and the Copilot UI renders it as the agent's visible label.
import { Agent } from "@github/copilot-sdk";
const weatherAssistant = new Agent({
name: "my-weather-assistant",
systemPrompt: "You are a helpful weather assistant.",
tools: [],
});
Defining the System Prompt
The system prompt is supplied via the systemPrompt field—or the instructions alias—on the agent configuration defined in src/types.ts. At runtime, the SDK injects this text into the system message of the underlying chat completion request, making it the single source of truth for agent tone, constraints, and reasoning boundaries.
const weatherAssistant = new Agent({
name: "my-weather-assistant",
systemPrompt: `You are a helpful weather assistant.
Answer concisely and cite the data returned by tools.`,
tools: [],
});
Creating Scoped Tools
Scoped tools are functions created with the tool() factory exported from src/tool.ts. Each tool accepts a scope property that must exactly match an agent's name; the runtime uses this metadata to make the tool visible only to that agent. Without a scope, the tool becomes globally available to every agent in the same workspace, which increases the risk of accidental misuse.
import { tool } from "@github/copilot-sdk";
const weatherTool = tool({
name: "getWeather",
description: "Fetches the current weather for a city.",
parameters: {
city: { type: "string", description: "Name of the city" },
},
scope: "my-weather-assistant",
handler: async ({ city }) => {
// Fetch and return weather data
return { temperature: 72, unit: "F" };
},
});
Complete Working Example
The following example combines a custom agent name, a strict system prompt, and a scoped tool as implemented in github/copilot-sdk. The scope field on the tool matches the agent's name, so only my-translator-agent can invoke the translate function.
import { Agent, tool } from "@github/copilot-sdk";
const translateTool = tool({
name: "translate",
description: "Translate text to a target language.",
parameters: {
text: { type: "string", description: "Text to translate" },
to: { type: "string", description: "Target language code (e.g. 'es')" },
},
scope: "my-translator-agent",
handler: async ({ text, to }) => {
// Implementation omitted for brevity
return `Translated (${to}): ${text}`;
},
});
const translatorAgent = new Agent({
name: "my-translator-agent",
systemPrompt: `You are a professional translator.
Never fabricate translations—only return the output from the tool.`,
tools: [translateTool],
});
export default translatorAgent;
This pattern keeps your AI assistants modular and secure. src/agent.ts handles agent initialization and name resolution, src/tool.ts enforces the scope contract and wires handlers, and src/types.ts exports the AgentConfig and ToolConfig types that verify these relationships at compile time.
Summary
- Pass a
nameto theAgentconstructor insrc/agent.tsto set the agent's identity and UI label. - Supply a
systemPromptto inject high-level instructions into the model's system message viasrc/types.ts. - Create tools with the
tool()factory insrc/tool.tsand set theirscopeto match the agent'snameto restrict invocation rights. - Combine all three properties to build isolated, purpose-driven agents that cannot accidentally call each other's tools.
Frequently Asked Questions
What happens if a tool's scope does not match any agent name?
The runtime treats the tool as globally available to any agent in the same workspace. It will not be restricted to a single agent, which increases the risk of cross-agent misuse according to the logic in src/tool.ts.
Can one agent have multiple scoped tools?
Yes. The tools array on the Agent constructor accepts any number of tool objects. You can scope every tool to the same agent name or mix scoped and unscoped tools depending on your access requirements.
Is the system prompt required when creating an agent?
The systemPrompt field is strongly recommended because it provides the only direct mechanism for constraining model behavior. Without it, the agent relies entirely on default reasoning patterns and tool descriptions defined in src/types.ts.
Can multiple agents share the same tool if they use the same scope?
No. The scope property is designed to create a one-to-one relationship between a tool and a single agent name. If you need a tool to be shared, omit the scope field so it becomes globally available, or create separate scoped instances for each agent in src/tool.ts.
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 →