Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ _Changes on `main` since the latest tagged release that have not yet been includ
- **Build-time overlay for custom VSIXes** — A `--customizations-dir` CLI flag (or `CODEQL_MCP_CUSTOMIZATIONS_DIR` env var) on `bundle:customizations` enables building custom VSIXes with overlay agents and skills. ([#281](https://github.com/advanced-security/codeql-development-mcp-server/pull/281))
- **`codeql-mcp.showAgentsStatus` command** — New Command Palette entry (**CodeQL MCP: Show Built-in Custom Agents Status**) that reports the bundled directory and the agents contributed via `contributes.chatAgents`. ([#281](https://github.com/advanced-security/codeql-development-mcp-server/pull/281))
- **Bundled skills** — Two skills (`ql-mcp-ext-create-workshop`, `ql-mcp-ext-validate-tools-queries`) are copied into the VSIX as static `contributes.chatSkills` contributions so they are available to Copilot Chat alongside the bundled agents. Source dirs in `.github/skills/` retain their original names; the bundler renames on copy and rewrites the `name:` frontmatter so the VS Code skill registry resolves them under the bundled name. ([#281](https://github.com/advanced-security/codeql-development-mcp-server/pull/281))
- **`codeql-mcp.queryPackIncludeDirs` / `codeql-mcp.queryPackExcludeDirs` settings** — Two new array settings give explicit, workspace-folder-ordering-independent control over which directories the prompt-driven workflows resolve CodeQL query and pack paths against. `queryPackIncludeDirs` adds extra roots (e.g. a query repository that is not opened as the first folder, or not opened at all); `queryPackExcludeDirs` drops roots (matching directories and anything nested inside them). Absolute entries are used as-is; relative entries are resolved against every workspace folder. Both are folded into the `CODEQL_MCP_WORKSPACE_FOLDERS` and `CODEQL_ADDITIONAL_PACKS` environment variables. ([#307](https://github.com/advanced-security/codeql-development-mcp-server/pull/307))
- **`codeql-mcp.requireCodeqlWorkspace` setting (default `true`)** — Makes the extension aware of [CodeQL workspaces](https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-workspaces): by default only workspace folders that contain a **top-level `codeql-workspace.yml`** are used as CodeQL query/pack resolution roots, so unrelated repositories opened in the same window are not scanned. `queryPackIncludeDirs` entries are always honored as the explicit opt-in for resolving CodeQL files outside this default pattern. When the setting is `true` but no open folder has a `codeql-workspace.yml` and no `queryPackIncludeDirs` are configured, the extension falls back to using every folder and logs a warning, so existing setups keep working. Set it to `false` to always use every open folder (legacy behavior). ([#307](https://github.com/advanced-security/codeql-development-mcp-server/pull/307))
Comment on lines +44 to +45

### Changed

Expand All @@ -59,6 +61,7 @@ _Changes on `main` since the latest tagged release that have not yet been includ

#### VS Code Extension

- **Multi-root resolution is now CodeQL-workspace-aware by default** — The environment builder no longer treats _every_ open workspace folder as a CodeQL query/pack resolution root. By default (`codeql-mcp.requireCodeqlWorkspace = true`) only folders containing a top-level `codeql-workspace.yml` are auto-selected, matching the CodeQL CLI's own workspace model. The previous all-folders behavior remains available via `requireCodeqlWorkspace: false`, via `queryPackIncludeDirs` for targeted opt-in, and via an automatic fallback (with a logged warning) when no folder qualifies and no include dirs are set. To exclude specific sub-paths or globs within a workspace, use the `ignore:` block of that folder's `codeql-workspace.yml`. ([#307](https://github.com/advanced-security/codeql-development-mcp-server/pull/307))
- **Workflow prompts now come exclusively from the `ql-mcp` MCP server** — Previously the extension also bundled four `.prompt.md` files (`ql-mcp-ext-tdd-basic`, `ql-mcp-ext-tdd-advanced`, `ql-mcp-ext-tools-query-workflow`, `ql-mcp-ext-workshop-creation-workflow`) as `contributes.chatPromptFiles`. Those were byte-for-byte renamed copies of prompts the MCP server already serves via `prompts/list`, which Copilot Chat surfaces as slash commands (`/ql_tdd_basic`, etc.). The duplicate `chatPromptFiles` contributions have been removed; the two shipped agents now reference an expanded set of canonical MCP slash IDs (`/ql_tdd_basic`, `/ql_tdd_advanced`, `/ql_lsp_iterative_development`, `/tools_query_workflow`, `/explain_codeql_query`, `/document_codeql_query`, `/data_extension_development`, `/workshop_creation_workflow`) so users get a richer workflow palette without the duplicate-slash-command UX. ([#281](https://github.com/advanced-security/codeql-development-mcp-server/pull/281))

#### Infrastructure & CI/CD
Expand All @@ -71,6 +74,7 @@ _Changes on `main` since the latest tagged release that have not yet been includ

### Fixed

- **VS Code extension: MCP workflow prompts could not target queries outside the first workspace folder.** In a multi-root workspace, the prompt-driven workflows only surfaced and resolved CodeQL queries, packs, databases, and SARIF files in the first root folder. The MCP server's prompt-argument completion providers now scan **every** workspace root (`CODEQL_MCP_WORKSPACE_FOLDERS`) with an **independent per-root scan budget** so a populous first root cannot starve the later roots out of the completion dropdown, and the extension's environment builder folds the new `queryPackIncludeDirs`/`queryPackExcludeDirs` settings into the resolution roots, so a query that lives in a non-first root (or an out-of-workspace query repository) is found and usable regardless of folder order. ([#307](https://github.com/advanced-security/codeql-development-mcp-server/pull/307))
- **Rust `PrintAST` and `PrintCFG` unit tests failed on CI.** Two distinct root causes: (1) CI had no Rust toolchain installed, so the extractor could not expand `format!`/`println!`/`vec!` and the entire `getMacroCallExpansion()` subtrees were missing from `PrintAST` output; (2) the legacy rust test extractor produces non-deterministic CFG entity ordering under parallel evaluation, which made the `PrintCFG` snapshot test flaky (5 distinct outputs across 5 runs with `--threads=-1`, identical output across every run with `--threads=1`). Fixes: install Rust in CI via the composite action; regenerate the rust `PrintAST.expected` baseline; and force `--threads=1` for the rust language entry in `run-query-unit-tests.sh` so `PrintCFG` produces deterministic output. ([#279](https://github.com/advanced-security/codeql-development-mcp-server/pull/279))
- **`run-query-unit-tests.sh` broke the Swift macOS workflow with `unbound variable`.** Bash 3.2 (the default `/bin/bash` on macOS GitHub Actions runners) errors when expanding an empty array under `set -u`. Replaced the `local _threads_arg=()` array with a plain scalar string and unquoted expansion so the script is portable across Bash 3.2 and 4+. ([#279](https://github.com/advanced-security/codeql-development-mcp-server/pull/279))

Expand Down
60 changes: 60 additions & 0 deletions extensions/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,66 @@ All settings are under the `codeql-mcp` namespace in VS Code settings:
| `codeql-mcp.additionalDatabaseDirs` | `[]` | Additional directories to search for CodeQL databases. |
| `codeql-mcp.additionalMrvaRunResultsDirs` | `[]` | Additional directories containing MRVA run results. |
| `codeql-mcp.additionalQueryRunResultsDirs` | `[]` | Additional directories containing query run results. |
| `codeql-mcp.queryPackIncludeDirs` | `[]` | Extra directories to resolve query/pack paths against (see below). |
| `codeql-mcp.queryPackExcludeDirs` | `[]` | Directories to exclude as query/pack resolution roots (see below). |
| `codeql-mcp.requireCodeqlWorkspace` | `true` | Use only folders with a top-level `codeql-workspace.yml` (below). |

### Multi-root workspaces and query/pack resolution

The prompt-driven workflows (slash commands) resolve query, pack, database, and
SARIF paths against the folders of a [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces),
not just the first one. So a query that lives in the second/third root folder —
for example when the query-development repository and the analysis-target
repository are opened as separate roots — is found and usable regardless of
folder order.

#### `codeql-workspace.yml` is the default selector (recommended)

By **default** (`codeql-mcp.requireCodeqlWorkspace = true`) only the workspace
folders that contain a **top-level `codeql-workspace.yml`** file are used as
CodeQL query/pack **resolution roots**. This matches the CodeQL CLI's own
[CodeQL workspaces](https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-workspaces)
model: a `codeql-workspace.yml` marks a folder as a set of related query/library
packs that resolve against each other from source. A folder you happen to have
open that does **not** contain a top-level `codeql-workspace.yml` is ignored for
CodeQL resolution, so unrelated repositories in the same window are not scanned.

> **Requirement:** to have a folder auto-discovered for CodeQL development and
> testing, add a top-level `codeql-workspace.yml` to it. A minimal example:
>
> ```yaml
> provide:
> - '**/qlpack.yml'
> - '**/codeql-pack.yml'
> ```

If `requireCodeqlWorkspace` is `true` but **no** open folder has a
`codeql-workspace.yml` and no `queryPackIncludeDirs` are configured, the
extension falls back to using **every** open folder (and logs a warning) so
existing setups keep working. Set `requireCodeqlWorkspace` to `false` to always
use every open folder regardless of `codeql-workspace.yml` (the legacy behavior).

#### Opting in and out, and excluding paths

- **`codeql-mcp.queryPackIncludeDirs`** — the explicit opt-in for resolving
CodeQL files **outside** the default `codeql-workspace.yml` pattern. Entries
here are **always** used as resolution roots, even without a
`codeql-workspace.yml`. Use it to target a query repository that is **not**
the first workspace folder, or that is not opened as a folder at all.
**Absolute** paths are used as-is; **relative** paths are resolved against
every workspace folder (so `queries` expands to one candidate per root).
- **`codeql-mcp.queryPackExcludeDirs`** — directories to exclude as resolution
**roots**. Any workspace folder or `queryPackIncludeDirs` entry that matches
(or is nested inside) one of these directories is dropped. Absolute paths are
used as-is; relative paths are resolved against every workspace folder.
- To exclude specific **sub-paths or globs within** a CodeQL workspace, prefer
the [`ignore:` block](https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-workspaces#example-of-a-codeql-workspaceyml-file)
of that folder's `codeql-workspace.yml` — the CodeQL-native mechanism, honored
by every CodeQL command. Use `codeql-mcp.scanExcludeDirs` to skip _nested_
directory names (e.g. `node_modules`, vendor trees) during workspace scans.

These settings are folded into the `CODEQL_MCP_WORKSPACE_FOLDERS` and
`CODEQL_ADDITIONAL_PACKS` environment variables passed to the MCP server.

## Commands

Expand Down
2 changes: 2 additions & 0 deletions extensions/vscode/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ const testSuiteConfig = {
'test/suite/agents.integration.test.ts',
'test/suite/bridge.integration.test.ts',
'test/suite/bundled-markdown-links.integration.test.ts',
'test/suite/codeql-workspace-resolution.integration.test.ts',
'test/suite/copydb-e2e.integration.test.ts',
'test/suite/extension.integration.test.ts',
'test/suite/file-watcher-stability.integration.test.ts',
'test/suite/mcp-completion-e2e.integration.test.ts',
'test/suite/mcp-completion-multiroot.integration.test.ts',
'test/suite/mcp-prompt-e2e.integration.test.ts',
'test/suite/mcp-resource-e2e.integration.test.ts',
'test/suite/mcp-server.integration.test.ts',
Expand Down
21 changes: 21 additions & 0 deletions extensions/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,27 @@
"default": true,
"markdownDescription": "Copy CodeQL databases from the `GitHub.vscode-codeql` extension storage into a managed directory, removing query-server lock files so the MCP server CLI can operate without contention. Disable to use databases in-place (may fail when the CodeQL query server is running)."
},
"codeql-mcp.queryPackIncludeDirs": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"markdownDescription": "Extra directories to resolve CodeQL query and pack paths against, **in addition** to the folders selected by `codeql-mcp.requireCodeqlWorkspace`. This is the explicit opt-in for CodeQL development outside the default `codeql-workspace.yml` pattern: entries here are **always** included as resolution roots, even when they do not contain a top-level `codeql-workspace.yml`. Use it to target a query repository that is **not** opened as the first workspace folder (or is not opened as a folder at all). Absolute paths are used as-is; relative paths are resolved against **every** workspace folder (so `queries` expands to one candidate per root). Folded into `CODEQL_MCP_WORKSPACE_FOLDERS` and `CODEQL_ADDITIONAL_PACKS`."
},
"codeql-mcp.queryPackExcludeDirs": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"markdownDescription": "Directories to exclude when resolving CodeQL query and pack paths. Any workspace folder or `queryPackIncludeDirs` entry that matches (or is nested inside) one of these directories is dropped from `CODEQL_MCP_WORKSPACE_FOLDERS` and `CODEQL_ADDITIONAL_PACKS`. Absolute paths are used as-is; relative paths are resolved against every workspace folder. This excludes whole resolution **roots**; to exclude specific sub-paths or globs *within* a CodeQL workspace, prefer the `ignore:` block of that folder's `codeql-workspace.yml` (the CodeQL-native mechanism), or use `scanExcludeDirs` to skip nested directory names (e.g. `node_modules`) during scans."
},
"codeql-mcp.requireCodeqlWorkspace": {
"type": "boolean",
"default": true,
"markdownDescription": "By default, only workspace folders that contain a top-level `codeql-workspace.yml` file are used as CodeQL query/pack **resolution roots**. This matches the CodeQL CLI's own [CodeQL workspaces](https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-workspaces) model and avoids scanning unrelated repositories opened as workspace folders. Folders listed in `codeql-mcp.queryPackIncludeDirs` are **always** included regardless of this setting. Set this to `false` to fall back to the legacy behavior of treating **every** open workspace folder as a resolution root. When this is `true` but no open folder has a `codeql-workspace.yml` and no `queryPackIncludeDirs` are configured, the extension falls back to using every folder and logs a warning, so existing setups keep working."
},
"codeql-mcp.serverArgs": {
"type": "array",
"items": {
Expand Down
Loading
Loading