I’m currently working on building my own Copilot agent(more about this in another post). As part of the process, I needed to create an API and expose it publicly so it is accessible publicly through a GitHub app. During local development and debugging I don't want to have to publish my API, so let's look at how we can use the VS Code Port Forwarding feature to expose a local API publicly.
Port forwarding
Port forwarding is a networking technique that redirects communication requests from one address and port combination to another. In the context of web development and VS Code, here's what it means:
When you run a web application or API locally, it's typically only accessible from your own machine at addresses like localhost:3000
or 127.0.0.1:8080
. Port forwarding creates a tunnel that takes requests coming to a publicly accessible address and forwards them to your local port.
For example, if you have an API running locally on port 3000:
- Without port forwarding: Only your computer can access http://localhost:3000
- With port forwarding: The service creates a public URL (like https://your-random-id.devtunnels.ms) that forwards all incoming traffic to your local port 3000
This is useful for:
- Sharing your in-development work with clients or teammates
- Testing webhook integrations that need to reach your local environment
- Debugging mobile apps that need to communicate with your local backend
- Accessing your local development environment from another device
Using port forwarding in VS Code
I started by opening VS Code and creating a new .NET Core Web API project:
dotnet new webapi
This creates a new example Web API project using the Minimal API feature exposing a single ‘weatherforecast’ endpoint:
var summaries = new[] | |
{ | |
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" | |
}; | |
app.MapGet("/weatherforecast", () => | |
{ | |
var forecast = Enumerable.Range(1, 5).Select(index => | |
new WeatherForecast | |
( | |
DateOnly.FromDateTime(DateTime.Now.AddDays(index)), | |
Random.Shared.Next(-20, 55), | |
summaries[Random.Shared.Next(summaries.Length)] | |
)) | |
.ToArray(); | |
return forecast; | |
}) | |
.WithName("GetWeatherForecast"); |
Once the project is created, check the launchsettings.json
for the default port used:
{ | |
"$schema": "https://json.schemastore.org/launchsettings.json", | |
"profiles": { | |
"http": { | |
"commandName": "Project", | |
"dotnetRunMessages": true, | |
"launchBrowser": false, | |
"applicationUrl": "http://localhost:5068", | |
"environmentVariables": { | |
"ASPNETCORE_ENVIRONMENT": "Development" | |
} | |
}, | |
"https": { | |
"commandName": "Project", | |
"dotnetRunMessages": true, | |
"launchBrowser": false, | |
"applicationUrl": "https://localhost:7082;http://localhost:5068", | |
"environmentVariables": { | |
"ASPNETCORE_ENVIRONMENT": "Development" | |
} | |
} | |
} | |
} |
Now debug or run your application. Once it is running, go to the Ports tab:
Hit the Forward a Port button and enter the port number you want to forward. The first time you do this; you are requested to sign in on GitHub. Click on Allow and go through the authentication flow.
Now you get a publicly accessible endpoint.
By default this endpoint is set to private. This means that you need to authenticate when you try to open the URL in your browser:
If you don’t want this, you can change the endpoint to Public. Right click on the Endpoint and use the Port Visibility menu item from the context menu:
This removes the requirement to sign-in. Be careful when you do this as everyone is able to access your endpoint now.
Remark: A similar feature exists in Visual Studio where it is called Dev Tunnels.