Full automated deployment to Azure via GitHub Actions
Deploy Planetary Explorer to your Azure subscription with full automation. This workflow deploys all infrastructure, backend, and frontend in < 1 hour.
Prefer a one-command local deploy? After
az login, run./deploy-infrastructure.ps1from the repo root. It auto-picks a region (preflight verifies AOAIgpt-4o, Container Apps, ACR availability), defaults all opt-ins OFF, and accepts the same toggles via env vars:MPC_PRO,PRIVATE,FABRIC,WEATHER_MODELS,LOCATION. The GitHub Actions flow below is the recommended path for shared / repeatable environments.
Planetary Explorer is a multi-agent geospatial AI system powered by Azure AI Foundry, Microsoft Agent Framework (MAF), Semantic Kernel, Azure AI Agent Service, and Model Context Protocol (MCP).
Core stack (always deployed):
- Azure AI Foundry - Model deployment for AI agents (GPT-5 or model of choice)
- Azure AI Agent Service - Multi-turn tool orchestration for GEOINT agents (Hub + Project)
- Azure Container Apps - Backend API hosting the full agent surface (STAC, Clarifier, Load, Raster Sampling, Contextual, Vision, Terrain, Mobility, Comparison, Building Damage, Extreme Weather, Site Intel, Resilience, Forecast)
- Azure App Service (Web App) - React frontend hosting
- Azure Maps - Geocoding and map visualization
- Azure AI Search - Vector search for private data catalogs (RAG) and BCP / permitting precedent docs
- Azure Storage - Blob storage for raster intermediate results and ingest
- Azure Key Vault - Secrets and connection strings
- Azure Container Registry - Docker image storage
- Log Analytics + Application Insights - Monitoring, traces, container logs
Opt-in (off by default):
- VNet + Private Endpoints + Private DNS -
-EnablePrivateEndpoints - MPC Pro MCP Sidecar (Container App) -
-EnableMpcPro - Weather Stub Server (Container App, CPU-only Aurora + Earth-2 FCN stub) -
-EnableWeatherModels - Microsoft Fabric F2 Capacity -
-EnableFabric - MCP Server (Container App, for VS Code / Claude clients) - workflow input
deploy_mcp_server
Data sources (external, no setup required):
- Microsoft Planetary Computer STAC API - 130+ global satellite collections
- NASA VEDA STAC API - Earth science datasets from NASA missions
These instructions work for any Azure subscription:
| Aspect | Value | Who Provides It |
|---|---|---|
| Source repo to fork | microsoft/Planetary-Explorer |
OSS |
| Azure subscription | User's own | User |
| Deployment identity (OIDC) | App registration + federated credential | User |
| GitHub secrets | AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID |
User |
| Resource group | rg-planetaryexplorer (default) |
Workflow (vars.RESOURCE_GROUP) |
| Location | eastus2 (default; local script auto-picks via preflight if not set) |
Workflow (vars.LOCATION) |
| Project name prefix | planetaryexplorer (default) |
Workflow (vars.PROJECT_NAME) |
| Resource names | Auto-generated unique | Workflow (dynamic) |
| Private endpoints | OFF by default | Workflow (opt-in: enable_private_endpoints) |
| MPC Pro | OFF by default | Workflow input enable_mpc_pro + mpc_pro_stac_url (overrides main.parameters.json) |
| Fabric capacity | OFF by default | Workflow inputs enable_fabric + deploy_fabric_capacity (BYO via fabric_capacity_resource_id) |
| Forecast Agent weather models | OFF by default | Workflow input deploy_weather_stub (CPU mock) or aurora_endpoint_url / earth2_fcn_endpoint_url / mai_weather_endpoint_url overrides |
| MCP server Container App | OFF by default | Workflow input deploy_mcp_server + mcp_image_name |
| Authentication | ON if AUTH_CLIENT_ID secret is set |
User creates app registration + sets secret. Override per-run with disable_auth=true. |
| Auto-deploy on push | OFF by default | Set repo variable ENABLE_AUTO_DEPLOY=true (Settings → Variables → Actions) to let pushes to main/dev trigger the workflow. Without it, only workflow_dispatch runs the deploy — so a fork can review code freely without burning Azure cost on every commit. |
- Azure Account: Active Azure subscription
- GitHub Account: To fork this repository
- Azure CLI 2.51+: Required for Azure authentication, the federated-credential setup in Step 7, and resource provider registration. Run
az upgradeif you're on an older version. (Install in Step 3) - GitHub CLI: Optional but recommended for easier secret configuration (Install in Step 3)
You need these permissions (all configured manually before deploying):
| Permission Type | Required Role | Purpose | Required? |
|---|---|---|---|
| Azure AD / Entra ID | "Users can register applications" = Yes (default) OR Application Developer role | Create deployment app registration + federated credential (Step 7) + auth app registration (Step 8.3) | Yes |
| Azure Subscription | Contributor + User Access Administrator (or Owner) | Deploy resources + assign roles | Yes |
Heads up
User Access Administratoris not granted to a default Contributor. Step 7.2's secondaz role assignment createwill fail unless you're a subscription Owner. If you're not, ask your subscription Owner to run that single command for you.- "Users can register applications" is disabled in many enterprise tenants. If so, both Step 7 (
az ad app create) and Step 8.3 (creating the auth app registration) will fail with Insufficient privileges. Check with your tenant admin before starting.- GPT-5 quota is not granted by default — most subscriptions need to either request
GlobalStandardquota in advance, or deploy with-f deploy_gpt5=false(the app then uses GPT-4o, which every Azure OpenAI region has).- Region quota — the GitHub Actions path defaults to
eastus2. If your subscription has no AOAI / Container Apps quota in eastus2, setvars.LOCATIONin Settings → Environments → dev to a region where you do (e.g.eastus,swedencentral,westus3). The localdeploy-infrastructure.ps1path auto-picks a region for you via preflight.
- Go to: https://github.com/microsoft/Planetary-Explorer
- Click the "Fork" button at the top right
- Choose your GitHub account as the destination
- Wait for the fork to complete (~10 seconds)
You now have your own copy of Planetary Explorer!
# Clone your fork
git clone https://github.com/YOUR-USERNAME/Planetary-Explorer.git
cd Planetary-Explorer
# Open in VS Code
code .Replace YOUR-USERNAME with your GitHub username.
Windows:
winget install Microsoft.AzureCLImacOS:
brew install azure-cliLinux:
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bashRestart your terminal and verify:
az --versionThe GitHub CLI makes it easier to configure secrets, trigger deployments, and monitor workflows.
Windows:
winget install GitHub.climacOS:
brew install ghLinux:
# Debian/Ubuntu
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update && sudo apt install ghRestart your terminal and authenticate:
gh --version
gh auth loginFollow the prompts to authenticate with your GitHub account.
# Authenticate with Azure CLI (opens browser)
az login
# Verify you're using the correct subscription
az account show --query "{Name:name, SubscriptionId:id, TenantId:tenantId}" -o table
# If you have multiple subscriptions, set the correct one:
az account set --subscription "YOUR-SUBSCRIPTION-ID"
# If you have multiple tenants and need a specific one:
az login --tenant YOUR-TENANT-IDFor an AI-assisted deployment experience, use GitHub Copilot Agent Mode in VS Code:
- Press
Ctrl+Shift+I(Windows/Linux) orCmd+Shift+I(macOS) to open Copilot Chat - Click the Agent Mode toggle (or type
@workspaceto start) - Ask Copilot to help with deployment:
Help me deploy Planetary Explorer to Azure following QUICK_DEPLOY.md
Required for Container Apps, AI services, and Agent Service.
# Register required resource providers
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.ContainerService
az provider register --namespace Microsoft.CognitiveServices
az provider register --namespace Microsoft.Maps
az provider register --namespace Microsoft.MachineLearningServices # Required for AI Foundry Hub/Project (Agent Service)
# Verify registration (should show "Registered")
az provider show --namespace Microsoft.App --query "registrationState"
az provider show --namespace Microsoft.MachineLearningServices --query "registrationState"This takes 2-3 minutes. Wait for all to show "Registered" before proceeding.
This gives GitHub Actions passwordless permission to deploy to your Azure subscription. The workflow authenticates via OpenID Connect (OIDC) — GitHub exchanges a short-lived token with Entra ID at deploy time, so no client secret is ever stored in your repo.
Run all of Step 7 in the same shell session. First set your fork's coordinates:
$githubOrg = "YOUR-USERNAME" # your GitHub user or org that owns the fork $githubRepo = "Planetary-Explorer" # your fork's repository name
$subscriptionId = az account show --query id -o tsv
$tenantId = az account show --query tenantId -o tsv
# Create the app registration (the deployment identity)
$appId = az ad app create --display-name "sp-planetaryexplorer-dev" --query appId -o tsv
# Create a service principal for the app
az ad sp create --id $appId | Out-Nullaz role assignment create --assignee $appId --role "Contributor" --scope /subscriptions/$subscriptionId
az role assignment create --assignee $appId --role "User Access Administrator" --scope /subscriptions/$subscriptionIdWhy two roles?
- Contributor: Deploys Azure resources (Container Apps, Key Vault, etc.)
- User Access Administrator: Creates role assignments (ACR pull permissions, Key Vault access)
This tells Entra ID to trust GitHub Actions runs from your fork's dev environment — which is what makes the passwordless login work.
@{
name = "github-planetaryexplorer-dev"
issuer = "https://token.actions.githubusercontent.com"
subject = "repo:$($githubOrg)/$($githubRepo):environment:dev"
audiences = @("api://AzureADTokenExchange")
} | ConvertTo-Json | Out-File -FilePath fic.json -Encoding ascii
az ad app federated-credential create --id $appId --parameters fic.json
Remove-Item fic.json
Write-Host "AZURE_CLIENT_ID = $appId"
Write-Host "AZURE_TENANT_ID = $tenantId"
Write-Host "AZURE_SUBSCRIPTION_ID = $subscriptionId"Copy the three values printed above — you'll set them as GitHub secrets in Step 8.
macOS / Linux (bash) equivalent for the federated credential:
az ad app federated-credential create --id "$appId" --parameters "{ \"name\": \"github-planetaryexplorer-dev\", \"issuer\": \"https://token.actions.githubusercontent.com\", \"subject\": \"repo:${githubOrg}/${githubRepo}:environment:dev\", \"audiences\": [\"api://AzureADTokenExchange\"] }"
Heads up: the federated credential
subjectmust match exactlyrepo:<owner>/<repo>:environment:dev. If you rename your fork or deploy from a different environment, update the credential or login will fail withAADSTS700213.
The workflow uses three secrets (no password) plus the GitHub dev environment that the federated credential from Step 7.3 trusts.
# From your cloned fork (same shell session as Step 7, so $appId etc. are still set)
cd Planetary-Explorer
# Create the dev environment (the federated credential subject references it)
gh api repos/$githubOrg/$githubRepo/environments/dev -X PUT
# Set the three OIDC secrets — passwordless, no JSON blob
gh secret set AZURE_CLIENT_ID --env dev --body $appId
gh secret set AZURE_TENANT_ID --env dev --body $tenantId
gh secret set AZURE_SUBSCRIPTION_ID --env dev --body $subscriptionId8.1 Create Environment
- Go to your forked repo on GitHub
- Click Settings tab → Environments (left sidebar)
- Click New environment
- Name:
dev(must match the federated credential subject from Step 7.3) - Click Configure environment
8.2 Add the three OIDC secrets
Under Environment secrets, click Add secret and create each of these (values were printed at the end of Step 7.3):
| Secret name | Value |
|---|---|
AZURE_CLIENT_ID |
App (client) ID |
AZURE_TENANT_ID |
Tenant ID |
AZURE_SUBSCRIPTION_ID |
Subscription ID |
No client secret is stored. GitHub presents a short-lived OIDC token that Entra ID validates against the federated credential — the modern, recommended, secretless pattern.
Note: The workflow automatically discovers resource names at runtime. To customize defaults, set GitHub Environment variables (
vars.RESOURCE_GROUP,vars.LOCATION,vars.PROJECT_NAME) in Settings → Environments → dev. No workflow file edits needed.
The pipeline automatically configures Entra ID authentication (EasyAuth) on both the frontend and backend — but it needs an app registration that you create once manually.
- Frontend (App Service): Redirects unauthenticated users to the Microsoft login page
- Backend (Container App): Returns
401 Unauthorizedfor API requests without a valid token (health and docs endpoints are excluded) - The frontend automatically forwards the user's identity token on every API call
- Go to Azure Portal → Microsoft Entra ID → App registrations → New registration
- Name:
PlanetaryExplorer-Auth(or any name you prefer) - Supported account types: Single tenant (this organization only)
- Redirect URI: Leave blank (the pipeline sets this automatically)
- Click Register
- Copy the Application (client) ID from the overview page
Then set it as a GitHub secret:
# Set the app registration client ID
gh secret set AUTH_CLIENT_ID --env dev
# Paste the Application (client) ID and press Enter, then on a NEW empty line
# press Ctrl+Z then Enter (Windows PowerShell) or Ctrl+D (macOS/Linux).Why manual? Creating app registrations requires Microsoft Graph API permissions (
Application.ReadWrite.All) — these are directory-level permissions separate from Azure RBAC. A standard deployment service principal (Contributor + User Access Administrator) doesn't have them.
Skip this step if you want to deploy without authentication first and add it later.
AADSTS50011 after deploy? If sign-in fails with "The redirect URI ... does not match", the workflow tried to patch your app registration but the deployment SP lacked
Application.ReadWrite.OwnedBy. Fix manually with:az ad app update --id <AUTH_CLIENT_ID> --web-redirect-uris "https://<your-webapp>.azurewebsites.net/.auth/login/aad/callback"Then refresh the sign-in page (Entra propagation < 1 min).
Now the automated part begins! The default deployment is public with Entra ID authentication (if AUTH_CLIENT_ID is set in Step 8.3).
# Trigger deployment — public by default; auth enabled if AUTH_CLIENT_ID is set (Step 8.3).
# deploy_gpt5=false uses GPT-4o instead (available in every AOAI region, no special quota).
gh workflow run deploy.yml -f force_all=true -f deploy_gpt5=false
# Watch the workflow run
gh run watchIf you've already requested and been granted GlobalStandard quota for GPT-5, drop the flag (it defaults to true):
gh workflow run deploy.yml -f force_all=trueWant a fully private deployment? For production lockdown with VNet, private endpoints, and ACR agent pool:
gh workflow run deploy.yml -f force_all=true -f enable_private_endpoints=trueThis adds VNet integration, private DNS zones, and a VNet-integrated ACR build agent. First deploy takes ~30-45 min.
Flags can be combined:
-f enable_private_endpoints=true -f deploy_gpt5=false
- Go to your forked repository on GitHub
- Click the Actions tab
- Select "Deploy Planetary Explorer" workflow
- Click "Run workflow" button
- Check "Force deploy all components" to deploy everything
- Check "Enable private endpoints" for a fully private/VNet deployment (optional)
- Uncheck "Deploy GPT-5 model" if your subscription lacks
GlobalStandardquota - Click "Run workflow"
The default deployment enables only the public Microsoft Planetary Computer STAC API — no extra Azure cost, no extra setup. The following integrations are wired up but disabled by default because they require resources you may not have:
| Toggle | Default | What it adds | When to enable |
|---|---|---|---|
enable_mpc_pro + mpc_pro_stac_url |
false |
Routes STAC searches through a private GeoCatalog (MPC Pro) you own. UI exposes an "MPC Pro" toggle that is locked when disabled. | You have a Microsoft.Orbital/geoCatalogs instance with private collections. |
enable_fabric + deploy_fabric_capacity (or fabric_capacity_resource_id for BYO) |
false |
Provisions (or attaches BYO) a Microsoft Fabric F-SKU capacity + wires the API to a Fabric lakehouse. Powers Site Intel and Resilience agents. | You want Site Intel / Resilience to read live Delta tables (power, water, candidate sites, facilities, supply edges). |
deploy_weather_stub + weather_stub_image_name |
false |
Provisions a CPU-only Container App that mocks Aurora + Earth-2 FCN scoring endpoints so the Forecast Agent works end-to-end without GPU quota. Image must be built and pushed to ACR first (see planetary-explorer/weather-stub-server/). |
You want a demo-quality Forecast Agent without requesting Standard_NC24ads_A100_v4 quota. |
aurora_endpoint_url / earth2_fcn_endpoint_url / mai_weather_endpoint_url |
empty | Production overrides for the Forecast Agent. When set, the backend points at your real Foundry endpoints instead of the stub. MAI Weather has no stub equivalent. | You have GPU quota + a deployed Foundry managed online endpoint (Aurora / Earth-2) or are allow-listed for MAI Weather. |
deploy_mcp_server + mcp_image_name |
false |
Deploys a separate MCP server Container App exposing every Planetary Explorer agent as MCP tools for VS Code Copilot / Claude Desktop / other MCP clients. | You want to call Planetary Explorer from an MCP-compatible AI assistant. |
disable_auth |
false |
Skips the EasyAuth configuration step — app deploys publicly. Dev/test only. | You want a quick public demo and accept that anyone with the URL can use it. |
Flip them on directly from the workflow_dispatch inputs — no file edits needed:
# Enable MPC Pro and point at your GeoCatalog
gh workflow run deploy.yml -f force_all=true `
-f enable_mpc_pro=true `
-f mpc_pro_stac_url="https://<gc>.<region>.geocatalog.spatio.azure.com/stac"
# Provision a new Fabric F2 capacity (powers Site Intel + Resilience)
gh workflow run deploy.yml -f force_all=true `
-f enable_fabric=true `
-f deploy_fabric_capacity=true
# BYO existing Fabric capacity instead
gh workflow run deploy.yml -f force_all=true `
-f enable_fabric=true `
-f fabric_capacity_resource_id="/subscriptions/.../resourceGroups/.../providers/Microsoft.Fabric/capacities/myCapacity"
# Stand up the CPU weather stub so the Forecast Agent works without GPU quota
gh workflow run deploy.yml -f force_all=true `
-f deploy_weather_stub=true `
-f weather_stub_image_name="planetary-explorer-weather-stub:latest"
# Point Forecast Agent at real Foundry endpoints (any subset; missing ones fall back to stub or skip)
gh workflow run deploy.yml -f force_all=true `
-f aurora_endpoint_url="https://aurora-endpoint.region.inference.ml.azure.com/score" `
-f earth2_fcn_endpoint_url="https://earth2-fcn.region.inference.ml.azure.com/score" `
-f mai_weather_endpoint_url="https://mai-weather.region.inference.ml.azure.com/score"
# Deploy the MCP server Container App
gh workflow run deploy.yml -f force_all=true `
-f deploy_mcp_server=true `
-f mcp_image_name="planetary-explorer-mcp:latest"For values that don't have a workflow input (e.g. fabricAdministrators, fabricWorkspaceId, fabricLakehouseId), edit planetary-explorer/infra/main.parameters.json before re-running:
The container exposes the effective config at GET /api/config → features: { mpcPublic, mpcPro, fabric } so the UI hides/locks controls accordingly. No code changes needed — set the toggles, redeploy, the UI adapts.
Expected deployment time: ~20-30 minutes on the first run (cold ACR build + AI Foundry Hub/Project + Agent Service capability host wiring), ~10-15 minutes on subsequent runs. ~30-45 minutes on the first deploy with enable_private_endpoints=true (adds ACR VNet-integrated agent pool provisioning).
If the workflow fails on
Microsoft.CognitiveServices/accounts/deploymentswith a quota or capacity error, your chosen region doesn't have the model SKU available. Either re-run with-f deploy_gpt5=false, or changevars.LOCATION(Settings → Environments → dev) to a region with quota and re-run.
# Watch the workflow run (if using GitHub CLI)
gh run watch
# Or view in browser
gh run list --workflow=deploy.ymlThe workflow runs these jobs:
- Detect Changes — Determines which components need deployment (or deploys all if
force_all=true) - Deploy Infrastructure — All Azure resources including AI Foundry (model of your choice + Agent Service Hub/Project), Container Apps Environment, ACR, Azure Maps, AI Search, Key Vault, Storage, Log Analytics, and optional VNet + Private Endpoints / Fabric capacity / Weather stub / MCP server
- Deploy Backend — Container App with FastAPI + the full agent surface: Clarifier (L1+L2), Action Router, Query Splitter, Load Agent, Raster Sampling, Contextual, Vision, Terrain, Mobility, Comparison, Building Damage, Extreme Weather, Site Intel (MAF), Resilience (MAF), Forecast (MAF; Aurora + Earth-2 FCN + MAI Weather). Credentials wired via managed identity.
- Deploy Frontend — App Service with React UI (Public/Pro STAC toggle, GEOINT module selectors, Site Intel + Resilience + Forecast panels)
- Enable Agent Service — Enables Agent Service capability hosts on AI Foundry so GEOINT agents can use multi-turn tool orchestration (fallback:
scripts\enable-agent-service.ps1) - Configure Auth — Configures Entra ID EasyAuth on both frontend (login redirect) and backend Container App (Return401) using the app registration from Step 8.3 (skipped if
AUTH_CLIENT_IDsecret is not set ordisable_auth=true) - Summary — Prints deployment status, endpoints, auth configuration, and Agent Service status
Example Azure AI Foundry Deployment:
After deployment completes, you can find your application URLs in multiple ways:
- Go to your repository → Actions tab
- Click on the completed "Deploy Planetary Explorer" workflow run
- Scroll down to the "Deployment Summary" at the bottom
- The summary lists your Frontend URL, Backend API URL, and API Docs URL
All resource names are auto-generated with a unique suffix based on your subscription. The exact URLs are known after deployment.
- Go to Azure Portal
- Navigate to your resource group:
rg-planetaryexplorer - Find the App Service (name starts with
app-) - Click on it → the URL is shown at the top right
# Get frontend URL
az webapp show --name (az webapp list --resource-group rg-planetaryexplorer --query "[0].name" -o tsv) --resource-group rg-planetaryexplorer --query "defaultHostName" -o tsv
# Get backend URL
az containerapp show --name (az containerapp list --resource-group rg-planetaryexplorer --query "[0].name" -o tsv) --resource-group rg-planetaryexplorer --query "properties.configuration.ingress.fqdn" -o tsvYour Planetary Explorer is now live! Open the frontend URL and click Get Started to try sample searches. The rest of the steps in this guide are optional.
If you completed Step 8.3, authentication is enabled and all users in your tenant can sign in. To restrict access to only specific users:
- Go to Azure Portal → Microsoft Entra ID → Enterprise applications
- Search for your app registration name (e.g.,
PlanetaryExplorer-Auth) - Properties → Set Assignment required? to Yes → Save
- Users and groups → Add user/group → Add the users who should have access
Example — Adding 3 authorized users:
| Step | Action |
|---|---|
| 1 | In Enterprise applications, click your app (PlanetaryExplorer-Auth) |
| 2 | Left menu → Properties → toggle Assignment required? to Yes → click Save |
| 3 | Left menu → Users and groups → click + Add user/group |
| 4 | Click Users → None Selected → search for and select each user by email: |
[email protected] |
|
[email protected] |
|
[email protected] |
|
| 5 | Click Select → click Assign |
Once Assignment required is set to Yes, only users you explicitly add in step 4 can sign in. Everyone else in the tenant gets an AADSTS50105 error. This applies to both the frontend login and backend API calls since they share the same app registration.
Set the AUTH_AUTHORIZED_USERS variable before running the workflow. The pipeline will attempt to configure user restrictions (requires the service principal to have Microsoft Graph AppRoleAssignment.ReadWrite.All permission, which most SPs don't have by default).
# Comma-separated list of user principal names (UPNs)
gh variable set AUTH_AUTHORIZED_USERS --env dev --body "[email protected],[email protected]"You can enable auth at any time by completing Step 8.3 and re-running the workflow:
# Set the secret, then redeploy
gh secret set AUTH_CLIENT_ID --env dev
gh workflow run deploy.yml -f force_all=trueWhy? Your analysts already live in Microsoft Teams and M365 Copilot. Instead of switching to a separate web app, Copilot Studio lets them search satellite imagery and analyze terrain directly from their chat window — no context switching. It's the fastest path to adoption for organizations already on Microsoft 365.
Copilot Studio acts as a distribution channel — all AI intelligence stays in your deployed backend. No code changes needed. The backend already supports the M365 Copilot audience in its auth layer.
| What You Get | How It Works |
|---|---|
| Chat with Planetary Explorer in Microsoft Teams | Copilot Studio agent calls your Container App API through a custom connector |
| Use Planetary Explorer as a declarative agent inside M365 Copilot | M365 Copilot routes natural-language queries to the same backend |
| Multi-turn conversations with session memory | Backend preserves chat session state across turns |
Getting started: Create a Copilot Studio agent with a custom connector pointing to your deployed backend API. See Microsoft Copilot Studio documentation for setup instructions.
Requirements: Copilot Studio license (included in M365 E3/E5 or standalone) + deployed Planetary Explorer backend.
Why? If your developers use GitHub Copilot, Claude, or other AI coding assistants, the MCP (Model Context Protocol) server lets them query satellite data and analyze terrain directly from their IDE — no browser, no API docs, no curl commands. The AI assistant discovers Planetary Explorer's capabilities automatically and calls them in context.
| What You Get | How It Works |
|---|---|
| Query satellite imagery from VS Code Copilot Chat | MCP tools with dynamic capability discovery |
| Multi-turn conversations with context memory | MCP preserves session state across turns |
| Works with any MCP-compatible client | GitHub Copilot, Claude Desktop, custom agents |
| Domain-specific expert prompts | Built-in geospatial analyst personas |
Follow the full guide: planetary-explorer/mcp-server/README.md
Requirements: Deployed Planetary Explorer backend + an MCP-compatible client (GitHub Copilot in VS Code, Claude Desktop, etc.).
For developers who don't want to set up GitHub Actions, deploy-infrastructure.ps1
delivers the same stack from a local shell. Defaults: public, all opt-ins off,
auto-picked region (preflight verifies AOAI gpt-4o, Container Apps, ACR, and
any enabled opt-ins are available in the chosen region).
# Public, minimal stack, region auto-selected
.\deploy-infrastructure.ps1
# Override via env vars (CI / one-click deploy friendly)
$env:MPC_PRO = 'true'; $env:FABRIC = 'true'; $env:PRIVATE = 'true'
.\deploy-infrastructure.ps1
# Or via flags
.\deploy-infrastructure.ps1 -EnableMpcPro -EnableFabric -EnablePrivateEndpoints
# Pin a region (skips preflight)
.\deploy-infrastructure.ps1 -Location eastus2| Flag (switch / env) | Default | Effect |
|---|---|---|
-EnableMpcPro / MPC_PRO |
off | UI surfaces the MPC Pro toggle (requires your GeoCatalog URL in mpcProStacUrl). |
-EnablePrivateEndpoints / PRIVATE |
off | VNet + private endpoints + private DNS. |
-EnableFabric / FABRIC |
off | Provisions a Fabric F2 capacity (~$262/mo). |
-EnableWeatherModels / WEATHER_MODELS |
off | Deploys the CPU-only weather stub (planetary-explorer/weather-stub-server/) and wires the Forecast Agent's Aurora + Earth-2 FCN providers to it — no GPU quota needed. Override with real Foundry endpoints via auroraEndpointUrl / earth2FcnEndpointUrl / maiWeatherEndpointUrl Bicep params when you have GPU quota. |
Planetary Explorer supports any number of side-by-side environments. Each environment
lives in its own resource group (rg-<envName>) with its own resource names
(derived from uniqueString(subscription, envName, location)), so prod and dev
never collide. Tear down one environment without touching the others.
# Deploy prod (default — creates rg-planetaryexplorer)
.\deploy-infrastructure.ps1 `
-EnvironmentName planetaryexplorer `
-EnableAuthentication `
-MicrosoftEntraClientId "<prod-app-reg-client-id>" `
-MicrosoftEntraTenantId "<tenant-id>"
# Deploy dev from a feature branch (creates rg-planetaryexplorer-dev, separate Entra app reg)
git checkout experimental/v2-pipeline
.\deploy-infrastructure.ps1 `
-EnvironmentName planetaryexplorer-dev `
-EnableAuthentication `
-MicrosoftEntraClientId "<dev-app-reg-client-id>" `
-MicrosoftEntraTenantId "<tenant-id>"
# Tear down only the dev environment when you're done
az group delete --name rg-planetaryexplorer-dev --yes --no-waitAfter infra is provisioned, push the matching container image into each
environment's ACR and run the per-env backend / frontend deploy scripts. The
existing deploy-backend.ps1 / deploy-frontend.ps1 scripts auto-discover the
resource group from rg-<envName> — just pass -EnvironmentName to point them
at the right one.
OSS contributors: the same script works for any environment name. A new user running
.\deploy-infrastructure.ps1(no args) gets a singlerg-planetaryexplorerenvironment — no surprise resources. They can opt into a second environment any time by re-running with-EnvironmentName <name>.
After deploying the core application, you can extend Planetary Explorer with these optional integrations:
| Integration | What It Does | Enable | Guide |
|---|---|---|---|
| MPC Pro / GeoCatalog | Same chat, your tenant's STAC. Mirror MPC collections + ingest private items; agents see both Public and Pro with one toggle. Provenance reported per response. | -EnableMpcPro + mpcProStacUrl=<url> |
Planetary Computer Pro |
| Microsoft Fabric | Powers Site Intel + Resilience over your Lakehouse Delta tables (sites, facilities, supply edges, infrastructure). Falls back to bundled seed data if not configured. | -EnableFabric + workspace env vars |
Microsoft Fabric |
| Weather Models (Forecast Agent) | Wires Aurora + Earth-2 FCN + MAI Weather into the Forecast ensemble. CPU-only stub is included; swap in Foundry endpoints when you have GPU quota. | -EnableWeatherModels or set auroraEndpointUrl / earth2FcnEndpointUrl / maiWeatherEndpointUrl |
planetary-explorer/weather-stub-server/ |
| Copilot Studio + M365 | Chat in Microsoft Teams (bot) or M365 Copilot (declarative agent / connector). Backend already supports the M365 audience in the auth layer. | Register Teams bot / declarative agent | Microsoft Copilot Studio |
| MCP Server | Expose every Planetary Explorer agent as MCP tools for VS Code GitHub Copilot, Claude Desktop, and other MCP-compatible clients. | Deploy mcp-server/ |
Setup Guide |
| ArcGIS | Connect Esri ArcGIS for enterprise GIS workflows and map services. | Configure custom connector | Esri ArcGIS |





{ "fabricSkuName": { "value": "F2" }, "fabricAdministrators": { "value": ["[email protected]"] }, "fabricWorkspaceId": { "value": "<workspace-guid>" }, "fabricLakehouseId": { "value": "<lakehouse-guid>" } }