Skip to content

Commit feccbeb

Browse files
CopilotjamesadevineCopilot
authored
rename agency_paramscopilot_params, remove built-in MCP spawning, and update docs (#135)
* Initial plan * feat: rename agency_params to copilot_params and replace agency CLI references with copilot Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/6de925b5-b695-4ace-ace7-292d6f1896a2 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * feat: remove built-in MCP spawning via copilot mcp subcommand Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/d23028c8-f3ae-424f-a2cc-6adb95730353 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * feat: add COPILOT_CLI_VERSION to dependency version updater workflow Expand the update-awf-version workflow to also check for new releases of github/copilot-cli and open PRs to update the COPILOT_CLI_VERSION constant. Bumps max PRs from 1 to 2 to allow both dependencies to be updated in a single run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: remove agency-style built-in MCP references from AGENTS.md Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/b1199267-7b57-4f8e-b88f-9241078a80c7 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * fix: remove --mcp flag generation from generate_copilot_params; Copilot CLI has no mcp subcommand Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/5780d9cc-3b6e-4640-bd7b-df37f2acb416 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> * fix: restore builtin MCP --mcp flag generation in copilot params The MCP server iteration that adds --mcp flags for enabled built-in MCPs was accidentally removed during the agency rename refactor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove --mcp flag generation for builtin MCPs Copilot CLI has no built-in MCPs — all MCPs are handled via the MCP firewall. Update the test to assert --mcp flags are not generated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: update docs to reflect removal of --mcp flag generation All MCPs are now handled via the MCP firewall, not --mcp CLI flags. Renamed 'Agency parameters' to 'Copilot parameters' in test docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> Co-authored-by: James Devine <james_a_devine@outlook.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9887c97 commit feccbeb

13 files changed

Lines changed: 83 additions & 213 deletions

File tree

AGENTS.md

Lines changed: 32 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ The compiler transforms the input into valid Azure DevOps pipeline YAML based on
398398
- **Standalone**: Uses `templates/base.yml`
399399
- **1ES**: Uses `templates/1es-base.yml`
400400

401-
Explicit markings are embedded in these templates that the compiler is allowed to replace e.g. `{{ agency_params }}` denotes parameters which are passed to the agency command line tool. The compiler should not replace sections denoted by `${{ some content }}`. What follows is a mapping of markings to responsibilities (primarily for the standalone template).
401+
Explicit markings are embedded in these templates that the compiler is allowed to replace e.g. `{{ copilot_params }}` denotes parameters which are passed to the copilot command line tool. The compiler should not replace sections denoted by `${{ some content }}`. What follows is a mapping of markings to responsibilities (primarily for the standalone template).
402402

403403
## {{ repositories }}
404404
For each additional repository specified in the front matter append:
@@ -467,17 +467,16 @@ This distinction allows resources (like templates) to be available as pipeline r
467467

468468
Should be replaced with the human-readable name from the front matter (e.g., "Daily Code Review"). This is used for display purposes like stage names.
469469

470-
## {{ agency_params }}
470+
## {{ copilot_params }}
471471

472-
Additional params provided to agency CLI. The compiler generates:
472+
Additional params provided to copilot CLI. The compiler generates:
473473
- `--model <model>` - AI model from `engine` front matter field (default: claude-opus-4.5)
474474
- `--disable-builtin-mcps` - Disables all built-in MCPs initially
475475
- `--no-ask-user` - Prevents interactive prompts
476476
- `--allow-tool <tool>` - Explicitly allows specific tools (github, safeoutputs, write, shell commands like cat, date, echo, grep, head, ls, pwd, sort, tail, uniq, wc, yq)
477-
- `--disable-mcp-server <name>` - Disables specific MCPs (all built-in MCPs are disabled by default and must be explicitly enabled via mcp-servers config)
478-
- `--mcp <name>` - Enables MCPs specified in front matter
477+
- `--disable-mcp-server <name>` - Disables specific Copilot CLI MCPs
479478

480-
Only built-in MCPs are passed via params. Custom MCPs (with command field) are handled separately.
479+
All MCPs (both built-in and custom) are handled via the MCP firewall config, not via `--mcp` flags.
481480

482481
## {{ pool }}
483482

@@ -552,7 +551,7 @@ Should be replaced with the appropriate working directory based on the effective
552551
- `root`: `$(Build.SourcesDirectory)` - the checkout root directory
553552
- `repo`: `$(Build.SourcesDirectory)/$(Build.Repository.Name)` - the repository's subfolder
554553

555-
This is used for the `workingDirectory` property of the agency copilot task.
554+
This is used for the `workingDirectory` property of the copilot task.
556555

557556
## {{ source_path }}
558557

@@ -726,16 +725,16 @@ Should be replaced with the agent context root for 1ES Agency jobs. This determi
726725

727726
## {{ mcp_configuration }}
728727

729-
Should be replaced with the MCP server configuration for 1ES templates. For each enabled built-in MCP, generates service connection references:
728+
Should be replaced with the MCP server configuration for 1ES templates. For each `mcp-servers:` entry without a `command:` field, generates a service connection reference using the entry name:
730729

731730
```yaml
732-
ado:
733-
serviceConnection: mcp-ado-service-connection
734-
kusto:
735-
serviceConnection: mcp-kusto-service-connection
731+
my-mcp:
732+
serviceConnection: mcp-my-mcp-service-connection
733+
other-mcp:
734+
serviceConnection: mcp-other-mcp-service-connection
736735
```
737736

738-
Custom MCP servers (with `command:` field) are not supported in 1ES target. Only built-in MCPs with corresponding service connections are supported.
737+
Custom MCP servers (with `command:` field) are not supported in 1ES target. Only entries without a `command:` (which have a corresponding service connection) are supported.
739738

740739
## {{ global_options }}
741740

@@ -1119,30 +1118,7 @@ cargo add <crate-name>
11191118

11201119
## MCP Configuration
11211120

1122-
The `mcp-servers:` field provides a unified way to configure both built-in and custom MCP (Model Context Protocol) servers. The compiler distinguishes between them by checking for the `command:` field—if present, it's a custom server; otherwise, it's a built-in.
1123-
1124-
### Built-in MCP Servers
1125-
1126-
Enable built-in servers with `true` or configure them with options:
1127-
1128-
```yaml
1129-
mcp-servers:
1130-
ado: true # enabled with all default functions
1131-
ado-ext: true # Extended ADO functionality
1132-
asa: true # Azure Stream Analytics MCP
1133-
bluebird: true # Bluebird MCP
1134-
calculator: true # Calculator MCP
1135-
es-chat: true
1136-
icm: # enabled with restricted functions
1137-
allowed:
1138-
- create_incident
1139-
- get_incident
1140-
kusto:
1141-
allowed:
1142-
- query
1143-
msft-learn: true
1144-
stack: true # Stack MCP
1145-
```
1121+
The `mcp-servers:` field configures custom MCP (Model Context Protocol) servers that the agent can use. Each entry must include a `command:` field specifying the executable to spawn.
11461122

11471123
### Custom MCP Servers
11481124

@@ -1160,28 +1136,16 @@ mcp-servers:
11601136

11611137
### Configuration Properties
11621138

1163-
**For built-in MCPs:**
1164-
- `true` - Enable with all default functions
1165-
- `allowed:` - Array of function names to restrict available tools
1166-
- `service-connection:` - (1ES target only) Override the service connection name used for this MCP. If not specified, defaults to `mcp-<name>-service-connection` (e.g., `mcp-ado-service-connection` for the `ado` MCP)
1167-
1168-
**For custom MCPs (requires `command:`):**
11691139
- `command:` - The executable to run (e.g., `"node"`, `"python"`, `"dotnet"`)
11701140
- `args:` - Array of command-line arguments passed to the command
11711141
- `allowed:` - Array of function names agents are permitted to call (required for security)
11721142
- `env:` - Optional environment variables for the MCP server process
1143+
- `service-connection:` - (1ES target only) Override the service connection name used for this MCP. If not specified, defaults to `mcp-<name>-service-connection`
11731144

1174-
### Example: Mixed Configuration
1145+
### Example: Multiple Custom MCP Servers
11751146

11761147
```yaml
11771148
mcp-servers:
1178-
# Built-in servers
1179-
ado: true
1180-
ado-ext: true
1181-
es-chat: true
1182-
icm:
1183-
allowed: [create_incident, get_incident]
1184-
11851149
# Custom Python MCP server
11861150
data-processor:
11871151
command: "python"
@@ -1207,7 +1171,6 @@ mcp-servers:
12071171
2. **Command Validation**: The compiler validates that commands are from a trusted set
12081172
3. **Argument Sanitization**: Arguments are validated to prevent injection attacks
12091173
4. **Environment Isolation**: MCP servers run in the same isolated sandbox as the pipeline
1210-
5. **Built-in Trust**: Built-in MCPs are pre-vetted; custom MCPs require explicit `allowed:` list
12111174

12121175
## Network Isolation (AWF)
12131176

@@ -1323,17 +1286,13 @@ When agents are configured with multiple MCPs (e.g., `ado`, `kusto`, `icm`), the
13231286

13241287
```
13251288
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
1326-
│ │ │ │ │ ado MCP
1327-
│ Agent │────▶│ MCP Firewall │────▶│ (agency mcp ado)│
1328-
│ (Agency) │ │ │ └─────────────────┘
1289+
│ │ │ │ │ custom MCP │
1290+
│ Agent │────▶│ MCP Firewall │────▶│ (node server.js)│
1291+
│ (Copilot) │ │ │ └─────────────────┘
13291292
│ │ │ - Policy check │ ┌─────────────────┐
1330-
└─────────────┘ │ - Tool routing │────▶│ icm MCP
1331-
│ - Audit logging │ │ (agency mcp icm)
1293+
└─────────────┘ │ - Tool routing │────▶│ custom MCP │
1294+
│ - Audit logging │ │ (python -m ...)
13321295
└──────────────────┘ └─────────────────┘
1333-
┌─────────────────┐
1334-
────▶│ custom MCP │
1335-
│ (node server.js)│
1336-
└─────────────────┘
13371296
```
13381297
13391298
### Configuration File Format
@@ -1343,23 +1302,11 @@ The firewall reads a JSON configuration file at runtime:
13431302
```json
13441303
{
13451304
"upstreams": {
1346-
"ado": {
1347-
"command": "agency",
1348-
"args": ["mcp", "ado"],
1349-
"env": {},
1350-
"allowed": ["*"]
1351-
},
1352-
"icm": {
1353-
"command": "agency",
1354-
"args": ["mcp", "icm"],
1355-
"env": {},
1356-
"allowed": ["create_incident", "get_incident"]
1357-
},
1358-
"kusto": {
1359-
"command": "agency",
1360-
"args": ["mcp", "kusto"],
1361-
"env": {},
1362-
"allowed": ["query"]
1305+
"data-processor": {
1306+
"command": "python",
1307+
"args": ["-m", "my_mcp_server"],
1308+
"env": { "DATA_DIR": "/data" },
1309+
"allowed": ["process_data", "query_database"]
13631310
},
13641311
"custom-tool": {
13651312
"command": "node",
@@ -1398,9 +1345,8 @@ The `allowed` field supports several patterns:
13981345

13991346
All tools exposed by the firewall are namespaced with their upstream name:
14001347

1401-
- `ado:create-work-item` - from the `ado` upstream
1402-
- `icm:create_incident` - from the `icm` upstream
1403-
- `kusto:query` - from the `kusto` upstream
1348+
- `data-processor:process_data` - from the `data-processor` upstream
1349+
- `custom-tool:get_status` - from the `custom-tool` upstream
14041350

14051351
This prevents tool name collisions and makes it clear which upstream handles each call.
14061352

@@ -1416,8 +1362,8 @@ ado-aw mcp-firewall --config /path/to/config.json
14161362
The firewall is automatically configured in generated pipelines:
14171363

14181364
1. **Config Generation**: The compiler generates `mcp-firewall-config.json` from the agent's `mcp-servers:` front matter
1419-
2. **MCP Registration**: The firewall is registered in the agency MCP config as `mcp-firewall`
1420-
3. **Runtime Launch**: When agency starts, it launches the firewall which spawns upstream MCPs
1365+
2. **MCP Registration**: The firewall is registered in the copilot MCP config as `mcp-firewall`
1366+
3. **Runtime Launch**: When copilot starts, it launches the firewall which spawns upstream MCPs
14211367

14221368
The firewall config is written to `$(Agent.TempDirectory)/staging/mcp-firewall-config.json` in its own pipeline step, making it easy to inspect and debug.
14231369

@@ -1426,9 +1372,9 @@ The firewall config is written to `$(Agent.TempDirectory)/staging/mcp-firewall-c
14261372
All tool call attempts are logged to the centralized log file at `$HOME/.ado-aw/logs/YYYY-MM-DD.log`:
14271373

14281374
```
1429-
[2026-01-29T10:15:32Z] [INFO] [firewall] ALLOWED icm:create_incident (args: {"title": "...", "severity": 3})
1430-
[2026-01-29T10:15:45Z] [INFO] [firewall] BLOCKED icm:delete_incident (not in allowlist)
1431-
[2026-01-29T10:16:01Z] [INFO] [firewall] ALLOWED kusto:query (args: {"cluster": "...", "query": "..."})
1375+
[2026-01-29T10:15:32Z] [INFO] [firewall] ALLOWED custom-tool:process_data (args: {"input": "..."})
1376+
[2026-01-29T10:15:45Z] [INFO] [firewall] BLOCKED custom-tool:delete_all (not in allowlist)
1377+
[2026-01-29T10:16:01Z] [INFO] [firewall] ALLOWED data-processor:query_database (args: {"query": "..."})
14321378
```
14331379

14341380
This provides a complete audit trail of agent actions for security review.

src/compile/common.rs

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
33
use anyhow::{Context, Result};
44

5-
use super::types::{FrontMatter, McpConfig, Repository, TriggerConfig};
5+
use super::types::{FrontMatter, Repository, TriggerConfig};
66
use crate::fuzzy_schedule;
77
use crate::mcp_metadata::McpMetadataFile;
88

9-
/// Check if an MCP name is a built-in (launched via agency mcp)
9+
/// Check if an MCP name is a built-in (known to the Copilot CLI via mcp-metadata.json)
1010
pub fn is_builtin_mcp(name: &str) -> bool {
1111
let metadata = McpMetadataFile::bundled();
1212
metadata.get(name).map(|m| m.builtin).unwrap_or(false)
@@ -332,7 +332,7 @@ pub fn generate_copilot_params(front_matter: &FrontMatter) -> String {
332332

333333
for tool in allowed_tools {
334334
if tool.contains('(') || tool.contains(')') || tool.contains(' ') {
335-
// Use double quotes - the agency_params are embedded inside a single-quoted
335+
// Use double quotes - the copilot_params are embedded inside a single-quoted
336336
// bash string in the AWF command, so single quotes would break quoting.
337337
params.push(format!("--allow-tool \"{}\"", tool));
338338
} else {
@@ -344,22 +344,6 @@ pub fn generate_copilot_params(front_matter: &FrontMatter) -> String {
344344
params.push(format!("--disable-mcp-server {}", mcp));
345345
}
346346

347-
for (name, config) in &front_matter.mcp_servers {
348-
let is_custom = matches!(config, McpConfig::WithOptions(opts) if opts.command.is_some());
349-
if is_custom {
350-
continue;
351-
}
352-
353-
let is_enabled = match config {
354-
McpConfig::Enabled(enabled) => *enabled,
355-
McpConfig::WithOptions(_) => true,
356-
};
357-
358-
if is_enabled {
359-
params.push(format!("--mcp {}", name));
360-
}
361-
}
362-
363347
params.join(" ")
364348
}
365349

@@ -616,11 +600,7 @@ fn normalize_relative_path(path: &std::path::Path) -> Option<String> {
616600
/// traversal reaches the filesystem root without finding one.
617601
fn find_git_root(path: &std::path::Path) -> Option<std::path::PathBuf> {
618602
// Start from the file's parent directory (or the path itself if it is a dir).
619-
let start: &std::path::Path = if path.is_dir() {
620-
path
621-
} else {
622-
path.parent()?
623-
};
603+
let start: &std::path::Path = if path.is_dir() { path } else { path.parent()? };
624604

625605
let mut current = start.to_path_buf();
626606
loop {
@@ -897,7 +877,7 @@ mod tests {
897877
}
898878

899879
#[test]
900-
fn test_copilot_params_custom_mcp_not_added_with_mcp_flag() {
880+
fn test_copilot_params_custom_mcp_no_mcp_flag() {
901881
let mut fm = minimal_front_matter();
902882
fm.mcp_servers.insert(
903883
"my-tool".to_string(),
@@ -907,17 +887,17 @@ mod tests {
907887
}),
908888
);
909889
let params = generate_copilot_params(&fm);
910-
// Custom MCPs (with command) should NOT appear as --mcp flags
911890
assert!(!params.contains("--mcp my-tool"));
912891
}
913892

914893
#[test]
915-
fn test_copilot_params_builtin_mcp_added_with_mcp_flag() {
894+
fn test_copilot_params_builtin_mcp_no_mcp_flag() {
916895
let mut fm = minimal_front_matter();
917896
fm.mcp_servers
918897
.insert("ado".to_string(), McpConfig::Enabled(true));
919898
let params = generate_copilot_params(&fm);
920-
assert!(params.contains("--mcp ado"));
899+
// Copilot CLI has no built-in MCPs — all MCPs are handled via the MCP firewall
900+
assert!(!params.contains("--mcp ado"));
921901
}
922902

923903
#[test]

src/compile/onees.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl Compiler for OneESCompiler {
5959
let repositories = generate_repositories(&front_matter.repositories);
6060
let checkout_steps = generate_checkout_steps(&front_matter.checkout);
6161
let checkout_self = generate_checkout_self();
62-
let agency_params = generate_copilot_params(front_matter);
62+
let copilot_params = generate_copilot_params(front_matter);
6363

6464
let effective_workspace = compute_effective_workspace(
6565
&front_matter.workspace,
@@ -172,7 +172,7 @@ displayName: "Finalize""#,
172172
("{{ pipeline_path }}", &pipeline_path),
173173
("{{ working_directory }}", &working_directory),
174174
("{{ workspace }}", &working_directory),
175-
("{{ agency_params }}", &agency_params),
175+
("{{ copilot_params }}", &copilot_params),
176176
("{{ acquire_ado_token }}", &acquire_read_token),
177177
("{{ copilot_ado_env }}", &copilot_ado_env),
178178
("{{ acquire_write_token }}", &acquire_write_token),

0 commit comments

Comments
 (0)