diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 00000000..7833d074
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,884 @@
+# Build Your First Copilot-Powered App
+
+In this tutorial, you'll use the Copilot SDK 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:
+
+- **GitHub Copilot CLI** installed and authenticated ([Installation guide](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli))
+- Your preferred language runtime:
+ - **Node.js** 18+ or **Python** 3.8+ or **Go** 1.21+ or **.NET** 8.0+
+
+Verify the CLI is working:
+
+```bash
+copilot --version
+```
+
+## Step 1: Install the SDK
+
+
+Node.js / TypeScript
+
+First, create a new directory and initialize your project:
+
+```bash
+mkdir copilot-demo && cd copilot-demo
+npm init -y
+```
+
+Then install the SDK and TypeScript runner:
+
+```bash
+npm install @github/copilot-sdk tsx
+```
+
+
+
+
+Python
+
+```bash
+pip install github-copilot-sdk
+```
+
+
+
+
+Go
+
+First, create a new directory and initialize your module:
+
+```bash
+mkdir copilot-demo && cd copilot-demo
+go mod init copilot-demo
+```
+
+Then install the SDK:
+
+```bash
+go get github.com/github/copilot-sdk/go
+```
+
+
+
+
+.NET
+
+First, create a new console project:
+
+```bash
+dotnet new console -n CopilotDemo && cd CopilotDemo
+```
+
+Then add the SDK:
+
+```bash
+dotnet add package GitHub.Copilot.SDK
+```
+
+
+
+## Step 2: Send Your First Message
+
+Create a new file and add the following code. This is the simplest way to use the SDK—about 5 lines of code.
+
+
+Node.js / TypeScript
+
+Create `index.ts`:
+
+```typescript
+import { CopilotClient } from "@github/copilot-sdk";
+
+const client = new CopilotClient();
+const session = await client.createSession({ model: "gpt-4.1" });
+
+const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
+console.log(response?.data.content);
+
+await client.stop();
+process.exit(0);
+```
+
+Run it:
+
+```bash
+npx tsx index.ts
+```
+
+
+
+
+Python
+
+Create `main.py`:
+
+```python
+import asyncio
+from copilot import CopilotClient
+
+async def main():
+ client = CopilotClient()
+ await client.start()
+
+ session = await client.create_session({"model": "gpt-4.1"})
+ response = await session.send_and_wait({"prompt": "What is 2 + 2?"})
+
+ print(response.data.content)
+
+ await client.stop()
+
+asyncio.run(main())
+```
+
+Run it:
+
+```bash
+python main.py
+```
+
+
+
+
+Go
+
+Create `main.go`:
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+
+ copilot "github.com/github/copilot-sdk/go"
+)
+
+func main() {
+ client := copilot.NewClient(nil)
+ if err := client.Start(); err != nil {
+ log.Fatal(err)
+ }
+ defer client.Stop()
+
+ session, err := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"})
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ response, err := session.SendAndWait(copilot.MessageOptions{Prompt: "What is 2 + 2?"}, 0)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(*response.Data.Content)
+ os.Exit(0)
+}
+```
+
+Run it:
+
+```bash
+go run main.go
+```
+
+
+
+
+.NET
+
+Create a new console project and add this to `Program.cs`:
+
+```csharp
+using GitHub.Copilot.SDK;
+
+await using var client = new CopilotClient();
+await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });
+
+var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
+Console.WriteLine(response?.Data.Content);
+```
+
+Run it:
+
+```bash
+dotnet run
+```
+
+
+
+**You should see:**
+
+```
+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.
+
+
+Node.js / TypeScript
+
+Update `index.ts`:
+
+```typescript
+import { CopilotClient, SessionEvent } from "@github/copilot-sdk";
+
+const client = new CopilotClient();
+const session = await client.createSession({
+ model: "gpt-4.1",
+ streaming: true,
+});
+
+// Listen for response chunks
+session.on((event: SessionEvent) => {
+ if (event.type === "assistant.message_delta") {
+ process.stdout.write(event.data.deltaContent);
+ }
+ if (event.type === "session.idle") {
+ console.log(); // New line when done
+ }
+});
+
+await session.sendAndWait({ prompt: "Tell me a short joke" });
+
+await client.stop();
+process.exit(0);
+```
+
+
+
+
+Python
+
+Update `main.py`:
+
+```python
+import asyncio
+import sys
+from copilot import CopilotClient
+from copilot.generated.session_events import SessionEventType
+
+async def main():
+ client = CopilotClient()
+ await client.start()
+
+ session = await client.create_session({
+ "model": "gpt-4.1",
+ "streaming": True,
+ })
+
+ # Listen for response chunks
+ def handle_event(event):
+ if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
+ sys.stdout.write(event.data.delta_content)
+ sys.stdout.flush()
+ if event.type == SessionEventType.SESSION_IDLE:
+ print() # New line when done
+
+ session.on(handle_event)
+
+ await session.send_and_wait({"prompt": "Tell me a short joke"})
+
+ await client.stop()
+
+asyncio.run(main())
+```
+
+
+
+
+Go
+
+Update `main.go`:
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+
+ copilot "github.com/github/copilot-sdk/go"
+)
+
+func main() {
+ client := copilot.NewClient(nil)
+ if err := client.Start(); err != nil {
+ log.Fatal(err)
+ }
+ defer client.Stop()
+
+ session, err := client.CreateSession(&copilot.SessionConfig{
+ Model: "gpt-4.1",
+ Streaming: true,
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Listen for response chunks
+ session.On(func(event copilot.SessionEvent) {
+ if event.Type == "assistant.message_delta" {
+ fmt.Print(*event.Data.DeltaContent)
+ }
+ if event.Type == "session.idle" {
+ fmt.Println()
+ }
+ })
+
+ _, err = session.SendAndWait(copilot.MessageOptions{Prompt: "Tell me a short joke"}, 0)
+ if err != nil {
+ log.Fatal(err)
+ }
+ os.Exit(0)
+}
+```
+
+
+
+
+.NET
+
+Update `Program.cs`:
+
+```csharp
+using GitHub.Copilot.SDK;
+
+await using var client = new CopilotClient();
+await using var session = await client.CreateSessionAsync(new SessionConfig
+{
+ Model = "gpt-4.1",
+ Streaming = true,
+});
+
+// Listen for response chunks
+session.On(ev =>
+{
+ if (ev is AssistantMessageDeltaEvent deltaEvent)
+ {
+ Console.Write(deltaEvent.Data.DeltaContent);
+ }
+ if (ev is SessionIdleEvent)
+ {
+ Console.WriteLine();
+ }
+});
+
+await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short joke" });
+```
+
+
+
+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.
+
+
+Node.js / TypeScript
+
+Update `index.ts`:
+
+```typescript
+import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk";
+
+// Define a tool that Copilot can call
+const getWeather = defineTool("get_weather", {
+ description: "Get the current weather for a city",
+ parameters: {
+ type: "object",
+ properties: {
+ city: { type: "string", description: "The city name" },
+ },
+ required: ["city"],
+ },
+ handler: async (args: { city: string }) => {
+ const { city } = args;
+ // In a real app, you'd call a weather API here
+ const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
+ const temp = Math.floor(Math.random() * 30) + 50;
+ const condition = conditions[Math.floor(Math.random() * conditions.length)];
+ return { city, temperature: `${temp}°F`, condition };
+ },
+});
+
+const client = new CopilotClient();
+const session = await client.createSession({
+ model: "gpt-4.1",
+ streaming: true,
+ tools: [getWeather],
+});
+
+session.on((event: SessionEvent) => {
+ if (event.type === "assistant.message_delta") {
+ process.stdout.write(event.data.deltaContent);
+ }
+});
+
+await session.sendAndWait({
+ prompt: "What's the weather like in Seattle and Tokyo?",
+});
+
+await client.stop();
+process.exit(0);
+```
+
+
+
+
+Python
+
+Update `main.py`:
+
+```python
+import asyncio
+import random
+import sys
+from copilot import CopilotClient
+from copilot.tools import define_tool
+from copilot.generated.session_events import SessionEventType
+
+# Define a tool that Copilot can call
+@define_tool(description="Get the current weather for a city")
+async def get_weather(params: dict) -> dict:
+ city = params["city"]
+ # In a real app, you'd call a weather API here
+ conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
+ temp = random.randint(50, 80)
+ condition = random.choice(conditions)
+ return {"city": city, "temperature": f"{temp}°F", "condition": condition}
+
+async def main():
+ client = CopilotClient()
+ await client.start()
+
+ session = await client.create_session({
+ "model": "gpt-4.1",
+ "streaming": True,
+ "tools": [get_weather],
+ })
+
+ def handle_event(event):
+ if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
+ sys.stdout.write(event.data.delta_content)
+ sys.stdout.flush()
+ if event.type == SessionEventType.SESSION_IDLE:
+ print()
+
+ session.on(handle_event)
+
+ await session.send_and_wait({
+ "prompt": "What's the weather like in Seattle and Tokyo?"
+ })
+
+ await client.stop()
+
+asyncio.run(main())
+```
+
+
+
+
+Go
+
+Update `main.go`:
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+ "math/rand"
+ "os"
+
+ copilot "github.com/github/copilot-sdk/go"
+)
+
+// Define the parameter type
+type WeatherParams struct {
+ City string `json:"city" jsonschema:"The city name"`
+}
+
+// Define the return type
+type WeatherResult struct {
+ City string `json:"city"`
+ Temperature string `json:"temperature"`
+ Condition string `json:"condition"`
+}
+
+func main() {
+ // Define a tool that Copilot can call
+ getWeather := copilot.DefineTool(
+ "get_weather",
+ "Get the current weather for a city",
+ func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
+ // In a real app, you'd call a weather API here
+ conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"}
+ temp := rand.Intn(30) + 50
+ condition := conditions[rand.Intn(len(conditions))]
+ return WeatherResult{
+ City: params.City,
+ Temperature: fmt.Sprintf("%d°F", temp),
+ Condition: condition,
+ }, nil
+ },
+ )
+
+ client := copilot.NewClient(nil)
+ if err := client.Start(); err != nil {
+ log.Fatal(err)
+ }
+ defer client.Stop()
+
+ session, err := client.CreateSession(&copilot.SessionConfig{
+ Model: "gpt-4.1",
+ Streaming: true,
+ Tools: []copilot.Tool{getWeather},
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ session.On(func(event copilot.SessionEvent) {
+ if event.Type == "assistant.message_delta" {
+ fmt.Print(*event.Data.DeltaContent)
+ }
+ if event.Type == "session.idle" {
+ fmt.Println()
+ }
+ })
+
+ _, err = session.SendAndWait(copilot.MessageOptions{
+ Prompt: "What's the weather like in Seattle and Tokyo?",
+ }, 0)
+ if err != nil {
+ log.Fatal(err)
+ }
+ os.Exit(0)
+}
+```
+
+
+
+
+.NET
+
+Update `Program.cs`:
+
+```csharp
+using GitHub.Copilot.SDK;
+using Microsoft.Extensions.AI;
+using System.ComponentModel;
+
+await using var client = new CopilotClient();
+
+// Define a tool that Copilot can call
+var getWeather = AIFunctionFactory.Create(
+ ([Description("The city name")] string city) =>
+ {
+ // In a real app, you'd call a weather API here
+ var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" };
+ var temp = Random.Shared.Next(50, 80);
+ var condition = conditions[Random.Shared.Next(conditions.Length)];
+ return new { city, temperature = $"{temp}°F", condition };
+ },
+ "get_weather",
+ "Get the current weather for a city"
+);
+
+await using var session = await client.CreateSessionAsync(new SessionConfig
+{
+ Model = "gpt-4.1",
+ Streaming = true,
+ Tools = [getWeather],
+});
+
+session.On(ev =>
+{
+ if (ev is AssistantMessageDeltaEvent deltaEvent)
+ {
+ Console.Write(deltaEvent.Data.DeltaContent);
+ }
+ if (ev is SessionIdleEvent)
+ {
+ Console.WriteLine();
+ }
+});
+
+await session.SendAndWaitAsync(new MessageOptions
+{
+ Prompt = "What's the weather like in Seattle and Tokyo?",
+});
+```
+
+
+
+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:
+
+
+Node.js / TypeScript
+
+```typescript
+import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk";
+import * as readline from "readline";
+
+const getWeather = defineTool("get_weather", {
+ description: "Get the current weather for a city",
+ parameters: {
+ type: "object",
+ properties: {
+ city: { type: "string", description: "The city name" },
+ },
+ required: ["city"],
+ },
+ handler: async ({ city }) => {
+ const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
+ const temp = Math.floor(Math.random() * 30) + 50;
+ const condition = conditions[Math.floor(Math.random() * conditions.length)];
+ return { city, temperature: `${temp}°F`, condition };
+ },
+});
+
+const client = new CopilotClient();
+const session = await client.createSession({
+ model: "gpt-4.1",
+ streaming: true,
+ tools: [getWeather],
+});
+
+session.on((event: SessionEvent) => {
+ if (event.type === "assistant.message_delta") {
+ process.stdout.write(event.data.deltaContent);
+ }
+});
+
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+});
+
+console.log("🌤️ Weather Assistant (type 'exit' to quit)");
+console.log(" Try: 'What's the weather in Paris?'\n");
+
+const prompt = () => {
+ rl.question("You: ", async (input) => {
+ if (input.toLowerCase() === "exit") {
+ await client.stop();
+ rl.close();
+ return;
+ }
+
+ process.stdout.write("Assistant: ");
+ await session.sendAndWait({ prompt: input });
+ console.log("\n");
+ prompt();
+ });
+};
+
+prompt();
+```
+
+Run with:
+
+```bash
+npx tsx weather-assistant.ts
+```
+
+
+
+
+Python
+
+Create `weather_assistant.py`:
+
+```python
+import asyncio
+import random
+import sys
+from copilot import CopilotClient
+from copilot.tools import define_tool
+from copilot.generated.session_events import SessionEventType
+
+@define_tool(description="Get the current weather for a city")
+async def get_weather(params: dict) -> dict:
+ city = params["city"]
+ conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
+ temp = random.randint(50, 80)
+ condition = random.choice(conditions)
+ return {"city": city, "temperature": f"{temp}°F", "condition": condition}
+
+async def main():
+ client = CopilotClient()
+ await client.start()
+
+ session = await client.create_session({
+ "model": "gpt-4.1",
+ "streaming": True,
+ "tools": [get_weather],
+ })
+
+ def handle_event(event):
+ if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
+ sys.stdout.write(event.data.delta_content)
+ sys.stdout.flush()
+
+ session.on(handle_event)
+
+ print("🌤️ Weather Assistant (type 'exit' to quit)")
+ print(" Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n")
+
+ while True:
+ try:
+ user_input = input("You: ")
+ except EOFError:
+ break
+
+ if user_input.lower() == "exit":
+ break
+
+ sys.stdout.write("Assistant: ")
+ await session.send_and_wait({"prompt": user_input})
+ print("\n")
+
+ await client.stop()
+
+asyncio.run(main())
+```
+
+Run with:
+
+```bash
+python weather_assistant.py
+```
+
+
+
+**Example session:**
+
+```
+🌤️ Weather Assistant (type 'exit' to quit)
+ Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'
+
+You: What's the weather in Seattle?
+Assistant: Let me check the weather for Seattle...
+It's currently 62°F and cloudy in Seattle.
+
+You: How about Tokyo and London?
+Assistant: I'll check both cities for you:
+- Tokyo: 75°F and sunny
+- London: 58°F and rainy
+
+You: exit
+```
+
+You've built an assistant with a custom tool that Copilot can call!
+
+---
+
+## How Tools Work
+
+When you define a tool, you're telling Copilot:
+1. **What the tool does** (description)
+2. **What parameters it needs** (schema)
+3. **What code to run** (handler)
+
+Copilot decides when to call your tool based on the user's question. When it does:
+1. Copilot sends a tool call request with the parameters
+2. The SDK runs your handler function
+3. The result is sent back to Copilot
+4. Copilot incorporates the result into its response
+
+---
+
+## What's Next?
+
+Now that you've got the basics, here are more powerful features to explore:
+
+### Connect to MCP Servers
+
+MCP (Model Context Protocol) servers provide pre-built tools. Connect to GitHub's MCP server to give Copilot access to repositories, issues, and pull requests:
+
+```typescript
+const session = await client.createSession({
+ mcpServers: {
+ github: {
+ type: "http",
+ url: "https://api.githubcopilot.com/mcp/",
+ },
+ },
+});
+```
+
+### Create Custom Agents
+
+Define specialized AI personas for specific tasks:
+
+```typescript
+const session = await client.createSession({
+ customAgents: [{
+ name: "pr-reviewer",
+ displayName: "PR Reviewer",
+ description: "Reviews pull requests for best practices",
+ prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",
+ }],
+});
+```
+
+### Customize the System Message
+
+Control the AI's behavior and personality:
+
+```typescript
+const session = await client.createSession({
+ systemMessage: {
+ content: "You are a helpful assistant for our engineering team. Always be concise.",
+ },
+});
+```
+
+---
+
+## Learn More
+
+- [Node.js SDK Reference](../nodejs/README.md)
+- [Python SDK Reference](../python/README.md)
+- [Go SDK Reference](../go/README.md)
+- [.NET SDK Reference](../dotnet/README.md)
+- [GitHub MCP Server Documentation](https://github.com/github/github-mcp-server)
+- [MCP Servers Directory](https://github.com/modelcontextprotocol/servers) - Explore more MCP servers
+
+---
+
+**You did it!** You've learned the core concepts of the GitHub Copilot SDK:
+- ✅ Creating a client and session
+- ✅ Sending messages and receiving responses
+- ✅ Streaming for real-time output
+- ✅ Defining custom tools that Copilot can call
+
+Now go build something amazing! 🚀