Skip to content

[safeoutputs] Strengthen anti-probing guidance for add_comment and create_issue#33433

Merged
pelikhan merged 4 commits into
mainfrom
copilot/strengthen-anti-probing-guidance
May 20, 2026
Merged

[safeoutputs] Strengthen anti-probing guidance for add_comment and create_issue#33433
pelikhan merged 4 commits into
mainfrom
copilot/strengthen-anti-probing-guidance

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 20, 2026

Gemini was calling add_comment and create_issue with empty {} arguments as schema discovery probes before making real calls — wasting turns and violating the explicit write-once contract. The anti-probing warning existed but was buried mid-description.

Tool description changes (safe_outputs_tools.json, both copies)

  • Hoisted WRITE-ONCE: warning to first sentence of create_issue and add_comment descriptions so agents encounter it before the purpose blurb
  • Added "Must be the final intended value — not a placeholder or test value" to title and body field descriptions

Before:

Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for
actionable work items... This is a write-once declaration for a real intended issue,
not a sandbox or probe: do not call it with placeholder titles/bodies...

After:

WRITE-ONCE: do NOT call this tool with empty or placeholder arguments to probe or
discover its schema — required fields (title, body) are listed in this schema; if you
are not ready to open the real issue, call `noop` instead. Creates a new GitHub issue...

Probe detection in MCP server (mcp_server_core.cjs)

Added a distinct error path in both handleRequest and handleMessage when a tool with required fields receives a completely empty {} argument object:

Empty arguments are not allowed — this tool is write-once, not a discovery probe.
To inspect the schema, use the tools/list MCP method.
To signal that no action is needed, call `noop` with a `message`.

Previously, an empty call fell through to the generic field-level "missing or empty title, body" error, which gave no signal that probing was the problem. Partial args (some fields present but invalid) still follow the existing enhanced-error path.

Tests

  • Updated existing mcp_server_core test for empty-args case to assert the new probe-detection message
  • Added a separate test for the partial-args path to preserve coverage of the missing or empty enhanced error

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go /vit�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go env -json GO111MODULE _modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv rror GO111MODULE de GOINSECURE GOMOD GOMODCACHE go /vit�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv .js' --ignore-paname GO111MODULE ache/node/24.14.1/x64/bin/node GOINSECURE GOMOD GOMODCACHE ache/node/24.14.-f ndle�� -json GO111MODULE n-advisor.lock.y-f GOINSECURE GOMOD GOMODCACHE node (http block)
  • https://api.github.com/repos/actions/download-artifact/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/download-artifact/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv quest tions/setup/js/mcp_server_core.cjs tions/setup/node_modules/.bin/node GOINSECURE GOMOD GOMODCACHE go tion�� -json GO111MODULE l GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv rror GO111MODULE /vitest GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv rror GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go /vit�� -json GO111MODULE node GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/-
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/- --jq [.object.sha, .object.type] | @tsv -json GO111MODULE bin/bash GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE repository(owner: $owner, name:-f GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv rror GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go /vit�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv k && vitest run name GO111MODULE ache/node/24.14.1/x64/bin/node GOINSECURE GOMOD GOMODCACHE ache/node/24.14.config ndle�� --noprofile GOPROXY k/gh-aw/gh-aw/node_modules/.bin/node GOSUMDB GOWORK 64/bin/go node (http block)
  • https://api.github.com/repos/docker/metadata-action/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE go env '**/*.ts' '**/*.json' --ignore-premote.upstream.url GO111MODULE ndlers-ChiiVk/env_handler.sh GOINSECURE GOMOD GOMODCACHE ndlers-ChiiVk/enshow (http block)
  • https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/node GOINSECURE GOMOD GOMODCACHE go 1/x6�� k && vitest run remote.upstream.url GO111MODULE n-dir/node GOINSECURE GOMOD GOMODCACHE ndlers-ExvlRq/muconfig (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .default_branch json GO111MODULE rgo/bin/bash GOINSECURE GOMOD GOMODCACHE head -20 ithub/workflows GOPROXY mance.lock.yml GOSUMDB GOWORK 64/bin/go sh (http block)

If you need me to access, download, or install something from one of these locations, you can either:

…nd create_issue

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/d13e7327-53d9-468b-98e0-5befd6f65c9e

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI changed the title [WIP] Strengthen anti-probing guidance for add_comment and create_issue [safeoutputs] Strengthen anti-probing guidance for add_comment and create_issue May 20, 2026
Copilot AI requested a review from gh-aw-bot May 20, 2026 02:53
@pelikhan pelikhan marked this pull request as ready for review May 20, 2026 02:59
Copilot AI review requested due to automatic review settings May 20, 2026 02:59
@pelikhan
Copy link
Copy Markdown
Collaborator

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens “write-once / no schema-probing” guidance for safe-outputs tools and adds an explicit MCP-server error path for completely empty {} tool calls (to discourage schema discovery probes).

Changes:

  • Hoists “WRITE-ONCE: don’t probe with empty/placeholder args” to the first sentence of create_issue / add_comment tool descriptions (both tool JSON copies), and clarifies that title/body must be final intended values.
  • Adds a distinct -32602 error response for tool calls that provide a completely empty {} arguments object when required fields exist, plus updates/extends unit tests for this behavior.
  • Modifies the Datadog MCP headers interpolation in .github/workflows/smoke-otel-backends.lock.yml (appears unrelated to the PR goal).
Show a summary per file
File Description
pkg/workflow/js/safe_outputs_tools.json Strengthens write-once / anti-probing messaging and field guidance for create_issue and add_comment.
actions/setup/js/safe_outputs_tools.json Same safe-outputs tool description updates in the setup copy.
actions/setup/js/mcp_server_core.cjs Adds special-case error messaging for empty {} arguments when required fields exist.
actions/setup/js/mcp_server_core.test.cjs Updates/adds tests for the new empty-args probe-detection error path and the partial-args enhanced-error path.
.github/workflows/smoke-otel-backends.lock.yml Changes Datadog header value interpolation (scope mismatch with PR description).

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (1)

actions/setup/js/mcp_server_core.cjs:769

  • Same issue as the HTTP path: probe-detection currently applies to every tool with required fields and emits a write-once/noop-specific message. Since handleMessage is shared by servers beyond safe-outputs, please gate this behavior to explicitly write-once tools (or detect presence of a noop tool) to avoid misleading errors for other MCP servers.
      const missing = validateRequiredFields(args, tool.inputSchema);
      if (missing.length) {
        const hasRequiredFields = tool.inputSchema && Array.isArray(tool.inputSchema.required) && tool.inputSchema.required.length > 0;
        if (hasRequiredFields && Object.keys(args).length === 0) {
          server.replyError(
            id,
            -32602,
            `Empty arguments are not allowed — this tool is write-once, not a discovery probe. To inspect the schema, use the tools/list MCP method. To signal that no action is needed, call \`noop\` with a \`message\`.`
          );
          return;
        }
  • Files reviewed: 5/5 changed files
  • Comments generated: 2

Comment on lines 773 to 777
"url": "https://mcp.datadoghq.com/api/unstable/mcp-server/mcp?toolsets=core",
"headers": {
"DD_API_KEY": "\${DD_API_KEY}",
"DD_APPLICATION_KEY": "\${DD_APPLICATION_KEY}",
"DD_APPLICATION_KEY": "\${DD_APP_KEY}",
"DD_SITE": "\${DD_SITE}"
Comment on lines 624 to +632
const missing = validateRequiredFields(args, tool.inputSchema);
if (missing.length) {
const hasRequiredFields = tool.inputSchema && Array.isArray(tool.inputSchema.required) && tool.inputSchema.required.length > 0;
if (hasRequiredFields && Object.keys(args).length === 0) {
throw {
code: -32602,
message: `Empty arguments are not allowed — this tool is write-once, not a discovery probe. To inspect the schema, use the tools/list MCP method. To signal that no action is needed, call \`noop\` with a \`message\`.`,
};
}
…tection

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 20, 2026

@copilot fix https://github.com/github/gh-aw/actions/runs/26138523106/job/76878793215?pr=33433

Fixed in the latest commit. safe_outputs_mcp_error_messages.test.cjs had 5 tests that passed empty {} arguments expecting the old field-level "missing or empty" error, but the new probe detection now intercepts that path first. Updated those tests to pass empty-string values (e.g. { title: "", body: "" }) instead of {} — empty strings still trigger validateRequiredFields and produce the expected field-level errors, while {} correctly triggers the new probe-detection message.

Copilot AI requested a review from pelikhan May 20, 2026 03:09
@github-actions github-actions Bot mentioned this pull request May 20, 2026
@pelikhan pelikhan merged commit f5e24d0 into main May 20, 2026
72 of 76 checks passed
@pelikhan pelikhan deleted the copilot/strengthen-anti-probing-guidance branch May 20, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[safeoutputs] Strengthen anti-probing guidance for add_comment and create_issue tool descriptions

4 participants