Skip to content

Early access Governed MCP calls open to beta partners in March 2027. The MCP tracker and scanner are free to use today.

Use cases / Teams building MCP servers

Catch a new delete tool in code review, before your users’ agents get it.

One pull request can add a tool, or quietly change what an argument means. The free pre-deploy check fails the build when your MCP server’s tools change, so a person looks at the change first.

A pull request stopped by the MCP check before it mergesA pipeline of three plates: a pull request, the MCP check and the merge. The check compares the server's tools with the approved lockfile. It flags a new delete_customer tool and a changed create_refund tool, so the check fails and the merge waits until a person reviews the change.PULL REQUESTTWO TOOL CHANGESMCP CHECKFAILEDMERGENEEDS A REVIEWSTACKDUKE.LOCK.JSONAPPROVED TOOLSCREATE_REFUNDSCHEMA CHANGEDDELETE_CUSTOMERADDED
Illustrative pull request. The check runs in your CI and sends nothing to Stackduke.

The risk to your users

Every connected agent gets the change when you deploy.

When you ship an MCP server, every agent connected to it picks up your new tools on the next deploy. A change that looks small in code review can be big for those agents.

A new tool is new power

Add a delete tool, and every connected agent can now delete.

Same name, new meaning

Switch amount from cents to dollars, and a refund of 50000, meant as USD 500, becomes USD 50,000.

Agents follow the description

Agents read a tool’s description as instructions. Change the description, and agents can use the tool differently while the code stays the same.

An example

One pull request, two quiet changes.

A pull request adds a delete_customer tool, and changes create_refund so the amount is in dollars instead of cents. Reviewers read the code. Nobody reads the list of tools.

stackduke.lock.json+8 -1Illustrative
@@ -41,7 +41,7 @@ create_refund
"amount": {
"description": "amount, in cents",
"description": "amount, in dollars",
"type": "integer"
}
@@ -58,6 +58,13 @@ delete_customer
},
{
"name": "delete_customer",
"description": "Deletes a customer.",
"annotations": {
"destructiveHint": true
},
},

The pre-deploy check

The check fails the build and names both changes.

The check starts your server in CI, asks for its list of tools and compares it with your approved list, a file called stackduke.lock.json. Both changes differ from that list, so the check fails, names them, and a person looks at them before the pull request merges.

stackduke checkFailedIllustrative check result
stackduke check  ✗ failed + delete_customer   added~ create_refund     input schema changed    was  "amount, in cents"    now  "amount, in dollars"
  1. 01

    Once, you ran the check with --update and committed stackduke.lock.json: your approved list of tools.

  2. 02

    On the pull request, the check starts your server in CI, lists its tools and compares them with that file.

  3. 03

    It fails and names both changes: a new tool, and a tool whose inputs changed.

  4. 04

    A person looks at both, then runs the check with --update. The new approved list goes in the same pull request, so reviewers see each change in the diff.

The check runs in your CI, sends nothing to Stackduke and needs no account.

What it covers

What Stackduke covers.

Stackduke

Each MCP call is checked against your rules before it runs.

  • When your users connect your server through Stackduke, a change to its tools is flagged for them, and they can hold changed tools until someone accepts them.
  • Their rules decide each call to your server: let it through, hold it for a person, or block it.

Free tools

Open source or public, and free to use.

  • The pre-deploy check fails a pull request when a tool is added, removed or changed: its name, title, description, inputs, outputs or annotations.
  • Text checks flag tool text that looks aimed at the agent, such as instructions, hidden characters or requests to send data elsewhere.
  • The GitHub Action can post the result on the pull request. GitLab CI runs the same check.

Not covered

Stackduke does not do these. Plan for them another way.

  • What your code does. The check reads what your server says about its tools. If a tool’s behaviour changes but its description does not, the check passes.
  • Someone who means harm. The author of a pull request can change both the code and the approved list, though both show in the diff.
  • Text checks look for patterns, so some findings are false alarms and some problems are missed.
  • Comments on GitLab merge requests. The check fails the job in GitLab CI, but does not comment.

What you can do now

Set it up today.

Write the first approved list, then run the check on every pull request and make it required.

  1. Write the first approved list

    Run it once, read the list it writes, and commit stackduke.lock.json.

    Terminal
    npx @stackduke/mcp-scanner check --update -- node dist/server.js
  2. Check pull requests on GitHub

    The check starts your server in CI and compares its tools with the approved list. GitLab CI runs the same check.

    Workflow step
    - uses: Stackduke/mcp-scanner@v0
      with:
        command: node dist/server.js
  3. Make it a required status check

    With the check required, the pull request cannot merge until someone accepts the change.

Go deeper

Further reading

  • Guide

    Check MCP tools in CI

    The full set-up for GitHub and GitLab, what fails the check, and its limits.

  • Open source

    The pre-deploy check

    Part of the free MCP scanner, alongside the scan and tool-change alerts.

Ship tools on purpose.

The check is free. Join the waitlist for the part that covers what happens after the deploy.

Join the waitlist

Stackduke is not affiliated with or endorsed by GitHub or GitLab. Their names are used here only to describe their products and public reports.