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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ release cadence.

_Changes on `main` since the latest tagged release that have not yet been included in a stable release._

### Added

#### MCP Server Prompts

| Prompt | Description |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data_extension_development` | End-to-end workflow for authoring CodeQL data extensions (Models-as-Data) for third-party libraries; restricts `language` to MaD-supported languages. ([#266](https://github.com/advanced-security/codeql-development-mcp-server/pull/266)) |

#### MCP Server Resources

| URI | Description |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `codeql://learning/data-extensions` | Models-as-Data (MaD) overview: YAML model formats, extensible predicates, and model-pack layout. ([#266](https://github.com/advanced-security/codeql-development-mcp-server/pull/266)) |
| `codeql://languages/rust/library-modeling` | Rust-specific library-modeling guide (crate-path-based MaD format) for the `data_extension_development` workflow. ([#266](https://github.com/advanced-security/codeql-development-mcp-server/pull/266)) |
| `codeql://languages/swift/library-modeling` | Swift-specific library-modeling guide (MaD tuple format) for the `data_extension_development` workflow. ([#266](https://github.com/advanced-security/codeql-development-mcp-server/pull/266)) |

Every CodeQL language that supports Models-as-Data upstream (`cpp`, `csharp`, `go`, `java`, `javascript`, `python`, `ruby`, `rust`, `swift`) now has a registered `codeql://languages/<language>/library-modeling` resource. `actions` is intentionally excluded because it does not support data extensions.
Comment thread
data-douser marked this conversation as resolved.

### Fixed

- **`query_results_cache_retrieve` rejected by GitHub Copilot Chat (HTTP 400 invalid schema)** — The `lineRange` and `resultIndices` parameters were defined with `z.tuple([...])`, which the MCP SDK serialized to a bare-array JSON Schema value (e.g. `[{"type":"integer"}, {"type":"integer"}]`). GitHub Copilot Chat enforces strict JSON Schema validation and rejected the entire `ql-mcp` server with `"... is not of type 'object', 'boolean'"`. Both parameters now use `z.object({ start, end })` so they serialize to a valid `type: "object"` JSON Schema. Tool callers must now pass `{ "lineRange": { "start": 1, "end": 10 } }` instead of `{ "lineRange": [1, 10] }`. ([#263](https://github.com/advanced-security/codeql-development-mcp-server/pull/263))
Expand Down
2 changes: 1 addition & 1 deletion client/cmd/code_scanning_download_analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ func runDownloadAnalysis(cmd *cobra.Command, _ []string) error {
}
}

fmt.Fprintf(cmd.OutOrStdout(), "Downloaded SARIF to %s (%d bytes)\n", outPath, len(sarif))
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Downloaded SARIF to %s (%d bytes)\n", outPath, len(sarif))
return nil
}
4 changes: 2 additions & 2 deletions client/cmd/code_scanning_list_alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ func runListAlerts(cmd *cobra.Command, _ []string) error {
}

w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 4, 2, ' ', 0)
fmt.Fprintln(w, "NUM\tSTATE\tRULE\tSEVERITY\tFILE:LINE\tCREATED")
_, _ = fmt.Fprintln(w, "NUM\tSTATE\tRULE\tSEVERITY\tFILE:LINE\tCREATED")
for _, a := range alerts {
loc := a.MostRecentInstance.Location
locStr := fmt.Sprintf("%s:%d", loc.Path, loc.StartLine)
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\n",
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\n",
a.Number, a.State, a.Rule.ID, a.Rule.Severity, locStr, a.CreatedAt)
}
return w.Flush()
Expand Down
4 changes: 2 additions & 2 deletions client/cmd/code_scanning_list_analyses.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ func runListAnalyses(cmd *cobra.Command, _ []string) error {
}

w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 4, 2, ' ', 0)
fmt.Fprintln(w, "ID\tTOOL\tREF\tCATEGORY\tRESULTS\tRULES\tCREATED")
_, _ = fmt.Fprintln(w, "ID\tTOOL\tREF\tCATEGORY\tRESULTS\tRULES\tCREATED")
for _, a := range analyses {
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%d\t%d\t%s\n",
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%d\t%d\t%s\n",
a.ID, a.Tool.Name, a.Ref, a.Category, a.ResultsCount, a.RulesCount, a.CreatedAt)
}
return w.Flush()
Expand Down
2 changes: 1 addition & 1 deletion client/cmd/integration_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func runIntegrationTests(cmd *cobra.Command, _ []string) error {
// server/.tmp/) which causes log directory validation failures.
tmpBase := filepath.Join(repoRoot, ".tmp")
if os.Getenv("CODEQL_MCP_TMP_DIR") == "" {
os.Setenv("CODEQL_MCP_TMP_DIR", tmpBase)
_ = os.Setenv("CODEQL_MCP_TMP_DIR", tmpBase)
}

// Connect to MCP server
Expand Down
24 changes: 12 additions & 12 deletions client/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func runListTools(_ *cobra.Command, _ []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

tools, err := client.ListTools(ctx)
if err != nil {
Expand All @@ -87,15 +87,15 @@ func runListTools(_ *cobra.Command, _ []string) error {
}

w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0)
fmt.Fprintf(w, "NAME\tDESCRIPTION\n")
_, _ = fmt.Fprintf(w, "NAME\tDESCRIPTION\n")
for _, t := range tools {
desc := t.Description
if len(desc) > 80 {
desc = desc[:77] + "..."
}
fmt.Fprintf(w, "%s\t%s\n", t.Name, desc)
_, _ = fmt.Fprintf(w, "%s\t%s\n", t.Name, desc)
}
w.Flush()
_ = w.Flush()
fmt.Printf("\n%d tools registered\n", len(tools))
return nil
}
Expand All @@ -106,7 +106,7 @@ func runListPrompts(_ *cobra.Command, _ []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

prompts, err := client.ListPrompts(ctx)
if err != nil {
Expand All @@ -132,15 +132,15 @@ func runListPrompts(_ *cobra.Command, _ []string) error {
}

w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0)
fmt.Fprintf(w, "NAME\tDESCRIPTION\n")
_, _ = fmt.Fprintf(w, "NAME\tDESCRIPTION\n")
for _, p := range prompts {
desc := p.Description
if len(desc) > 80 {
desc = desc[:77] + "..."
}
fmt.Fprintf(w, "%s\t%s\n", p.Name, desc)
_, _ = fmt.Fprintf(w, "%s\t%s\n", p.Name, desc)
}
w.Flush()
_ = w.Flush()
fmt.Printf("\n%d prompts registered\n", len(prompts))
return nil
}
Expand All @@ -151,7 +151,7 @@ func runListResources(_ *cobra.Command, _ []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

resources, err := client.ListResources(ctx)
if err != nil {
Expand All @@ -178,15 +178,15 @@ func runListResources(_ *cobra.Command, _ []string) error {
}

w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0)
fmt.Fprintf(w, "NAME\tURI\tDESCRIPTION\n")
_, _ = fmt.Fprintf(w, "NAME\tURI\tDESCRIPTION\n")
for _, r := range resources {
desc := r.Description
if len(desc) > 60 {
desc = desc[:57] + "..."
}
fmt.Fprintf(w, "%s\t%s\t%s\n", r.Name, r.URI, desc)
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", r.Name, r.URI, desc)
}
w.Flush()
_ = w.Flush()
fmt.Printf("\n%d resources registered\n", len(resources))
return nil
}
8 changes: 4 additions & 4 deletions client/cmd/use_prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func runUsePrompt(_ *cobra.Command, args []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

result, err := mcpclient.GetPrompt(ctx, client, promptName, params)
if err != nil {
Expand All @@ -58,11 +58,11 @@ func outputPromptMessages(result *mcpclient.PromptMessages) error {
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, s)
_, _ = fmt.Fprintln(os.Stdout, s)
case "markdown":
fmt.Fprint(os.Stdout, mcpclient.FormatPromptMessagesMarkdown(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatPromptMessagesMarkdown(result))
default:
fmt.Fprint(os.Stdout, mcpclient.FormatPromptMessagesText(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatPromptMessagesText(result))
}
return nil
}
8 changes: 4 additions & 4 deletions client/cmd/use_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func runUseResource(_ *cobra.Command, args []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

result, err := mcpclient.ReadResource(ctx, client, uri)
if err != nil {
Expand All @@ -50,11 +50,11 @@ func outputResourceContent(result *mcpclient.ResourceContent) error {
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, s)
_, _ = fmt.Fprintln(os.Stdout, s)
case "markdown":
fmt.Fprint(os.Stdout, mcpclient.FormatResourceContentMarkdown(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatResourceContentMarkdown(result))
default:
fmt.Fprint(os.Stdout, mcpclient.FormatResourceContentText(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatResourceContentText(result))
}
return nil
}
8 changes: 4 additions & 4 deletions client/cmd/use_tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func runUseTool(_ *cobra.Command, args []string) error {
if err != nil {
return err
}
defer client.Close()
defer func() { _ = client.Close() }()

result, err := mcpclient.CallTool(ctx, client, toolName, params)
if err != nil {
Expand All @@ -59,11 +59,11 @@ func outputToolResult(result *mcpclient.ToolResult) error {
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, s)
_, _ = fmt.Fprintln(os.Stdout, s)
case "markdown":
fmt.Fprint(os.Stdout, mcpclient.FormatToolResultMarkdown(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatToolResultMarkdown(result))
default:
fmt.Fprint(os.Stdout, mcpclient.FormatToolResultText(result))
_, _ = fmt.Fprint(os.Stdout, mcpclient.FormatToolResultText(result))
}
if result.IsError {
return fmt.Errorf("tool returned error")
Expand Down
12 changes: 6 additions & 6 deletions client/internal/mcp/primitives.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ func FormatResourceContentText(rc *ResourceContent) string {
sb.WriteString("\n---\n")
}
if item.URI != "" {
sb.WriteString(fmt.Sprintf("URI: %s\n", item.URI))
fmt.Fprintf(&sb, "URI: %s\n", item.URI)
}
if item.MIMEType != "" {
sb.WriteString(fmt.Sprintf("Type: %s\n", item.MIMEType))
fmt.Fprintf(&sb, "Type: %s\n", item.MIMEType)
}
sb.WriteString("\n")
sb.WriteString(item.Text)
Expand All @@ -211,13 +211,13 @@ func FormatResourceContentText(rc *ResourceContent) string {
func FormatPromptMessagesText(pm *PromptMessages) string {
var sb strings.Builder
if pm.Description != "" {
sb.WriteString(fmt.Sprintf("Description: %s\n\n", pm.Description))
fmt.Fprintf(&sb, "Description: %s\n\n", pm.Description)
}
for i, msg := range pm.Messages {
if i > 0 {
sb.WriteString("\n---\n")
}
sb.WriteString(fmt.Sprintf("[%s]\n", msg.Role))
fmt.Fprintf(&sb, "[%s]\n", msg.Role)
sb.WriteString(msg.Content)
sb.WriteString("\n")
}
Expand Down Expand Up @@ -254,13 +254,13 @@ func FormatResourceContentMarkdown(rc *ResourceContent) string {
func FormatPromptMessagesMarkdown(pm *PromptMessages) string {
var sb strings.Builder
if pm.Description != "" {
sb.WriteString(fmt.Sprintf("*%s*\n\n", pm.Description))
fmt.Fprintf(&sb, "*%s*\n\n", pm.Description)
}
for i, msg := range pm.Messages {
if i > 0 {
sb.WriteString("\n---\n\n")
}
sb.WriteString(fmt.Sprintf("### %s\n\n", msg.Role))
fmt.Fprintf(&sb, "### %s\n\n", msg.Role)
sb.WriteString(msg.Content)
sb.WriteString("\n")
}
Expand Down
Loading
Loading