Skip to content
Open
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
12 changes: 12 additions & 0 deletions server/src/prompts/data-extension-development.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ Validate the model against a real database:
- If the `.model.yml` lives under `.github/codeql/extensions/` of the consuming repo, you are **done** — Code Scanning will load it on the next analysis.
- If you authored a reusable model pack and want it to apply across an organization, publish it to GHCR with `codeql pack publish` and configure it under org Code security → Global settings → CodeQL analysis → Model packs.

> **When data extensions aren't enough**: If `subtypes: True` fails to match subclasses (common when the base type is a library stub not present in the database), or the detection logic cannot be expressed as a source/sink/summary tuple, a QL library change (`.qll`) is needed instead. Use the `codeql://prompts/ql-tdd-basic` workflow to develop and test the fix, then contribute it upstream to `github/codeql`.

## Validation Checklist

- [ ] Correct tuple format for the language (API Graph vs MaD)
Expand All @@ -147,3 +149,13 @@ Validate the model against a real database:
- `codeql://languages/{{language}}/library-modeling` — Language-specific library modeling guide
- `codeql://templates/security` — Security query templates
- `codeql://learning/test-driven-development` — TDD workflow for CodeQL queries

## Troubleshooting

| Issue | Likely Cause | Resolution |
| ----- | ------------ | ---------- |
| Extension not found by `codeql query run` | `.github/codeql/extensions/` is only auto-loaded by Code Scanning (GitHub Actions), not the CLI | Move `.model.yml` into the pack's `ext/` directory (e.g., `csharp/ql/lib/ext/`) or pass the directory via `--additional-packs` |
| Stale results after adding/changing `.model.yml` | Compilation cache is returning previously cached results | Use `--no-default-compilation-cache` with a fresh `--compilation-cache=<empty-dir>` to force recompilation |
| `subtypes: True` not matching subclass methods | The base type only exists as a library stub in the database, not as extracted source | `subtypes` resolution requires the declaring type to be in the database. For framework base types (e.g., `PageModel`, `ControllerBase`) that are only stubs, use a QL-based source/sink class instead of a data extension |
| Extension loads but produces no findings | Missing link in the source → summary → sink chain | Verify all hops are modeled — a single missing `summaryModel` between source and sink will break the chain |
| YAML parse error or silent failure | Wrong column count for the extensible predicate | Double-check the exact column count for your language's format (MaD vs API Graph) — extra or missing columns fail silently |
1 change: 1 addition & 0 deletions server/src/prompts/ql-tdd-basic.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ codeql_test_accept: {
- ❌ Not using #codeql_lsp_completion to discover available types
- ❌ Not setting `workspace_uri` when using LSP tools (completions will be empty)
- ❌ Creating tests that are too complex
- ❌ Not clearing compilation cache after adding data extensions (stale cached results hide new models)
- ❌ Ignoring false positives in results
- ❌ Not refactoring after tests pass

Expand Down
7 changes: 7 additions & 0 deletions server/src/resources/languages/csharp_library_modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ C# uses a **MaD (Models as Data)** format with **9–10 column tuples** that ide
| `kind` | Source/sink/summary kind | `"sql-injection"`, `"taint"` |
| `provenance` | Origin of the model | `"manual"` |

### Important: `subtypes` Flag

- `True` — the model applies to the method **and all overrides** in subclasses and implementing classes
- `False` — only applies to the exact class specified

> **Caveat**: `subtypes: True` requires the base type to be **present in the CodeQL database** as extracted source or a resolved reference. For framework base types that exist only as library stubs (e.g., `Microsoft.AspNetCore.Mvc.RazorPages.PageModel`), subtypes resolution may silently fail to match subclass methods. In these cases, model each concrete class explicitly or implement a QL-based source/sink class instead.

### Important: C#-Specific Signature Rules

- Type names must be **fully qualified**: `System.String`, not `string`
Expand Down
2 changes: 1 addition & 1 deletion server/src/tools/codeql/bqrs-decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const codeqlBqrsDecodeTool: CLIToolDefinition = {
command: 'codeql',
subcommand: 'bqrs decode',
inputSchema: {
files: z.array(z.string()).describe('BQRS file(s) to decode'),
files: z.array(z.string()).describe('Array of BQRS file paths to decode. Pass an array even for a single file, e.g. ["/path/to/results.bqrs"]'),
output: createCodeQLSchemas.output(),
format: z.enum(['csv', 'json', 'text', 'bqrs']).optional()
.describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'),
Expand Down
5 changes: 4 additions & 1 deletion server/src/tools/codeql/quick-evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ export async function quickEvaluate({
export function registerQuickEvaluateTool(server: McpServer): void {
server.tool(
'quick_evaluate',
'Quick evaluate either a class or a predicate in a CodeQL query for debugging',
'Resolve a class or predicate symbol in a CodeQL query file for quick evaluation. ' +
'Locates the symbol position and returns an output path for results. ' +
'Note: this tool validates the symbol exists but does not yet execute the evaluation — ' +
'use codeql_query_run for full evaluation.',
{
file: z.string().describe('Path to the .ql file containing the symbol'),
db: z.string().describe('Path to the CodeQL database'),
Expand Down
4 changes: 3 additions & 1 deletion server/src/tools/codeql/register-database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ export async function registerDatabase(dbPath: string): Promise<string> {
export function registerRegisterDatabaseTool(server: McpServer): void {
server.tool(
'register_database',
'Register a CodeQL database given a local path to the database directory',
'Register a CodeQL database for use by other MCP tools. ' +
'Validates that the database directory exists, contains codeql-database.yml, and has source files (src.zip or src/). ' +
'Does not persist any session state — acts as a preflight check before using other database tools.',
{
db_path: z.string().describe('Path to the CodeQL database directory'),
},
Expand Down
Loading