<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Antonio GM</title>
    <description>The latest articles on DEV Community by Antonio GM (@antoniogm82).</description>
    <link>https://dev.to/antoniogm82</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4197801%2F5defdfcc-904d-448d-9d5e-28dfe409b1f5.jpg</url>
      <title>DEV Community: Antonio GM</title>
      <link>https://dev.to/antoniogm82</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antoniogm82"/>
    <language>en</language>
    <item>
      <title>Five read-only settings shrank an MCP tool list. Two did nothing.</title>
      <dc:creator>Antonio GM</dc:creator>
      <pubDate>Thu, 12 Nov 2026 13:04:40 +0000</pubDate>
      <link>https://dev.to/antoniogm82/five-read-only-settings-shrank-an-mcp-tool-list-two-did-nothing-2agm</link>
      <guid>https://dev.to/antoniogm82/five-read-only-settings-shrank-an-mcp-tool-list-two-did-nothing-2agm</guid>
      <description>&lt;p&gt;A read-only or safe-mode setting is a promise about what a server will do. The tool list is what the server tells a client about itself. Those are not the same thing, and sometimes the setting does not show up in the list at all.&lt;/p&gt;

&lt;p&gt;We started seven servers in Docker with and without such a setting and compared what each returned for &lt;code&gt;tools/list&lt;/code&gt;. Five lists got shorter. Two did not change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbems4ffjbig45zd5l7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbems4ffjbig45zd5l7o.png" alt="Tools listed by default and with a setting applied: Atlassian 98 and 58, Grafana 79 and 62, GitHub 46 and 27, Supabase 31 and 19, MongoDB 27 and 18, Blender 9 and 9, ClickHouse 3 and 3." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we ran
&lt;/h2&gt;

&lt;p&gt;Between 25 October and 5 November 2026 we started each server in Docker with no real credentials. Where a server needs a value to start, we passed an obviously fake one and no service was running behind it. We called no tools. The records are on each card under "Tested by us", with the exact start command.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;With the setting&lt;/th&gt;
&lt;th&gt;What left the list&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/mcp-atlassian#verified" rel="noopener noreferrer"&gt;Atlassian&lt;/a&gt; 0.23.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;READ_ONLY_MODE=true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;40 names: 25 Jira tools (such as &lt;code&gt;jira_create_issue&lt;/code&gt;, &lt;code&gt;jira_delete_issue&lt;/code&gt;, &lt;code&gt;jira_transition_issue&lt;/code&gt;) and 15 Confluence tools (such as &lt;code&gt;confluence_create_page&lt;/code&gt;, &lt;code&gt;confluence_delete_page&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/grafana-mcp-server#verified" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt; 2.1.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--disable-write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;79&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;17 names that create, update or delete (for example &lt;code&gt;create_datasource&lt;/code&gt;, &lt;code&gt;update_dashboard&lt;/code&gt;, &lt;code&gt;delete_annotation&lt;/code&gt;, &lt;code&gt;install_plugin&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/github-mcp-server#verified" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; 2.1.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--read-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;19 names (for example &lt;code&gt;create_pull_request&lt;/code&gt;, &lt;code&gt;merge_pull_request&lt;/code&gt;, &lt;code&gt;push_files&lt;/code&gt;, &lt;code&gt;delete_file&lt;/code&gt;, &lt;code&gt;issue_write&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/supabase-mcp#verified" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; 0.15.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--read-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;12 names (for example &lt;code&gt;apply_migration&lt;/code&gt;, &lt;code&gt;create_project&lt;/code&gt;, &lt;code&gt;deploy_edge_function&lt;/code&gt;, &lt;code&gt;delete_branch&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/mongodb-mcp-server#verified" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; 3.1.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--readOnly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;9 names: &lt;code&gt;insert-many&lt;/code&gt;, &lt;code&gt;update-many&lt;/code&gt;, &lt;code&gt;delete-many&lt;/code&gt;, and the create, rename and drop tools for collections, indexes and databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/blender-mcp#verified" rel="noopener noreferrer"&gt;Blender&lt;/a&gt; 2.2.4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BLENDER_MCP_SAFE_MODE=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Nothing: identical hashes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://agentshortlist.dev/agents/clickhouse-mcp-server#verified" rel="noopener noreferrer"&gt;ClickHouse&lt;/a&gt; 0.7.0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CLICKHOUSE_ALLOW_WRITE_ACCESS&lt;/code&gt; false or true&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Nothing: identical hashes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In every one of the five that shrank, tools only left: none were added. For Supabase, GitHub, Atlassian, Blender and ClickHouse we ran each configuration twice. Supabase, GitHub, Blender and ClickHouse gave identical hashes both times. Atlassian's descriptions matched, but its schema hash changed between starts: only the order of 11 comma-separated field names in four tools moved, the same set each time, and the tool count was the same. MongoDB and Grafana have one recorded run per configuration, and the MongoDB pair was run on two different days.&lt;/p&gt;

&lt;p&gt;GitHub's server is distributed as a container image, so we took its binary from the official image (pinned by digest on the card) and ran it in our standard container. Its &lt;code&gt;--read-only&lt;/code&gt; flag removed 19 of 46 tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the list shrinks, a client can see it
&lt;/h2&gt;

&lt;p&gt;Atlassian, Grafana, GitHub, Supabase and MongoDB take tools away when you set the flag. A client, or a scanner reading tool definitions, can tell the two configurations apart from names and schemas alone. That is the useful case, and the size differs a lot: 9 tools for MongoDB, 40 for Atlassian.&lt;/p&gt;

&lt;p&gt;Two caveats. First, we only listed the tools; we did not check that the remaining ones respect the setting. Second, Grafana still lists &lt;code&gt;grafana_api_request&lt;/code&gt; with &lt;code&gt;--disable-write&lt;/code&gt;. The name says it makes API requests, and we did not test what it allows in that mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  When it does not, the setting is invisible
&lt;/h2&gt;

&lt;p&gt;Blender's safe mode and ClickHouse's write setting changed nothing in what the server announces. ClickHouse has a single query tool, &lt;code&gt;run_query&lt;/code&gt;, so a write setting can only act inside it. A client connected to either server sees the same list whichever way the setting is turned.&lt;/p&gt;

&lt;p&gt;That does not mean the settings do nothing. It means the tool list cannot tell you. It is the same situation as the two DBHub releases that announced a byte-identical tool list while one of them had a read-only mode that did not hold: &lt;a href="https://agentshortlist.dev/blog/dbhub-same-tool-list-different-security-status" rel="noopener noreferrer"&gt;DBHub 0.22.5 and 0.22.6: same tool list, different security status&lt;/a&gt;. To know whether a setting is enforced you need something other than the tool list: the advisories for that version, the project's tests, or a database user that cannot write.&lt;/p&gt;

&lt;h2&gt;
  
  
  A shorter list may also cost less
&lt;/h2&gt;

&lt;p&gt;Two readers raised the cost side. One pointed out that a shorter, stable list could help prefix caching. Another noted that Claude Code loads tool definitions on demand, so a long list may weigh less there than it would in a client that sends everything every turn. We have measured neither, so we are not putting a number on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A paired test for normalizing hashes
&lt;/h2&gt;

&lt;p&gt;After our &lt;a href="https://agentshortlist.dev/blog/10-mcp-servers-in-docker-what-their-tool-lists-tell-you" rel="noopener noreferrer"&gt;last post&lt;/a&gt; a reader asked whether stripping what looks incidental could hide a real change. So we ran a paired test with a synthetic server of our own, with one tool and two settings: an ID written into the description (like the container ID), and an allowed target written into the input schema.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Only the ID changes.&lt;/strong&gt; The description hash and the combined hash change. The schema hash does not. After replacing 12-character hexadecimal strings with a placeholder, all three hashes are identical again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only the allowed target changes.&lt;/strong&gt; The description hash is the same. The schema hash changes, with or without normalizing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same configuration twice.&lt;/strong&gt; Identical, as a control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in this case normalizing removed the incidental difference and left the real one visible. The limits are plain: it is a toy server with one tool, and our normalization replaces only 12-character hex strings, nothing else. One more detail from a real server: on Desktop Commander the changing text was the container hostname, which Docker sets by default to the container's 12-character ID. With a fixed hostname the text becomes &lt;code&gt;probe-host&lt;/code&gt;, which that normalization does not touch. The script, &lt;code&gt;fake-mcp-server.mjs&lt;/code&gt;, and the comparison output are in the public repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not show
&lt;/h2&gt;

&lt;p&gt;One machine per run, one or two runs of each configuration. A description that includes the date would look identical in two runs on the same day, so we repeat passes on other days and say what we find. We did not call any tool, so none of this tells you whether a setting works, only what the server announces.&lt;/p&gt;




</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
      <category>testing</category>
    </item>
    <item>
      <title>DBHub 0.22.5 and 0.22.6 announce the same tool list. One has a published security advisory</title>
      <dc:creator>Antonio GM</dc:creator>
      <pubDate>Wed, 04 Nov 2026 09:19:45 +0000</pubDate>
      <link>https://dev.to/antoniogm82/dbhub-0225-and-0226-announce-the-same-tool-list-one-has-a-published-security-advisory-627</link>
      <guid>https://dev.to/antoniogm82/dbhub-0225-and-0226-announce-the-same-tool-list-one-has-a-published-security-advisory-627</guid>
      <description>&lt;p&gt;&lt;em&gt;I run &lt;a href="https://agentshortlist.dev" rel="noopener noreferrer"&gt;AgentShortlist&lt;/a&gt;, a directory of MCP servers where every line has a source. This is our own data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A check that reads only what an MCP server tells the model cannot tell these two releases apart. &lt;a href="https://agentshortlist.dev/agents/dbhub#verified" rel="noopener noreferrer"&gt;DBHub&lt;/a&gt; 0.22.5 and 0.22.6 announce exactly the same two tools, with the same descriptions and the same input schemas. One of them is affected by a published advisory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we compared
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@bytebase/dbhub&lt;/code&gt; 0.22.5 and 0.22.6, published on 24 June 2026, about three hours apart (04:22 and 07:34 UTC, from the npm registry).&lt;/li&gt;
&lt;li&gt;Advisory &lt;a href="https://github.com/bytebase/dbhub/security/advisories/GHSA-mwwr-p57h-56pf" rel="noopener noreferrer"&gt;GHSA-mwwr-p57h-56pf&lt;/a&gt;, from OSV.dev, rated high: DBHub's read-only mode did not prevent database writes. It affects every release before 0.22.6, including 0.22.5, and 0.22.6 is the fixed one. The advisory was published on 24 September 2026, three months after the fix.&lt;/li&gt;
&lt;li&gt;Both releases in Docker (&lt;code&gt;node:22-slim&lt;/code&gt;), no credentials, DBHub's &lt;code&gt;--demo&lt;/code&gt; mode (an in-memory SQLite database with sample data), a fixed hostname, in the order 0.22.5, 0.22.6, 0.22.5, 0.22.6. Each version ran twice so we could see whether the environment alone changes the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What we measured
&lt;/h2&gt;

&lt;p&gt;Each server reported &lt;code&gt;execute_sql&lt;/code&gt; and &lt;code&gt;search_objects&lt;/code&gt;. The SHA-256 of the descriptions, of the schemas and of both together was the same in the four runs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hash&lt;/th&gt;
&lt;th&gt;Value (first 16 characters)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Descriptions&lt;/td&gt;
&lt;td&gt;a629bd6a8da832f3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schemas&lt;/td&gt;
&lt;td&gt;910f0162e3129022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;5fc028095d373457&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two runs of the same version were identical, so the environment is not what makes them match. The tool list of 0.22.5 and of 0.22.6 is byte-identical. Both releases answered with protocol revision 2025-03-26: neither answered &lt;code&gt;server/discover&lt;/code&gt; within 20 seconds, so these hashes come from &lt;code&gt;initialize&lt;/code&gt;. A hash is only comparable if it says how the list was asked.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did change
&lt;/h2&gt;

&lt;p&gt;Not the tool definitions. We compared the two published packages as text, without running either. In 0.22.6 the PostgreSQL, MySQL, MariaDB and SQLite connectors contain read-only statements (&lt;code&gt;BEGIN READ ONLY&lt;/code&gt;, &lt;code&gt;START TRANSACTION READ ONLY&lt;/code&gt; and &lt;code&gt;PRAGMA query_only&lt;/code&gt;); in 0.22.5 none of those strings appear. The lines that define each tool's description, input schema and registration are the same in both.&lt;/p&gt;

&lt;p&gt;That fits what the advisory describes: the database-level read-only setting was written but gated on a config value that was never set, so only a check of each statement's first keyword remained, and a &lt;code&gt;SELECT&lt;/code&gt; that calls a function with side effects passed it. It is the part the advisory is about, and it is not visible in &lt;code&gt;tools/list&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A scanner that compares tool descriptions and schemas, which is where tool-poisoning checks look, would give these two releases the same result. The advisory database gives them different ones. They answer different questions.&lt;/li&gt;
&lt;li&gt;Read-only mode is enforced in the server's code, not announced in its tool list. To know whether it holds you need the advisory data and the exact version.&lt;/li&gt;
&lt;li&gt;If you pin MCP servers, pin the version and check that version against the advisories, not just its tool list.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A second case, and what it does not show
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mysql-mcp-server&lt;/code&gt; 0.4.1 and 0.4.2 also span an advisory (GHSA-rqfv-2mw9-78g2, a missing Origin and Host check in the SSE transport). We could not compare their tool lists: in a clean Docker environment neither started, first because of a missing &lt;code&gt;dotenv&lt;/code&gt; module and then, with that added, on an &lt;code&gt;AttributeError&lt;/code&gt; about &lt;code&gt;list_resources&lt;/code&gt;. We did not investigate the cause. Version 0.4.4 started and listed three tools.&lt;/p&gt;

&lt;p&gt;What we did not test: whether read-only mode holds in 0.22.5 or 0.22.6 (we did not run a write), other DBHub versions, or any other transport. Read-only mode on the database also says nothing about data leaving through another tool in the same client, which a reader pointed out; that is outside this test. A matching hash is not a security result. It tells you the announced tools did not change.&lt;/p&gt;




&lt;p&gt;We then ran the same kind of check across database servers: &lt;a href="https://agentshortlist.dev/blog/database-mcp-servers-who-can-write?utm_source=devto" rel="noopener noreferrer"&gt;13 database MCP servers: who can write?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full post, with the test records on the card: &lt;a href="https://agentshortlist.dev/blog/dbhub-same-tool-list-different-security-status?utm_source=devto" rel="noopener noreferrer"&gt;https://agentshortlist.dev/blog/dbhub-same-tool-list-different-security-status?utm_source=devto&lt;/a&gt; . We also publish a short note on MCP advisories, the MCP Risk Radar: &lt;a href="https://agentshortlist.dev/radar?utm_source=devto" rel="noopener noreferrer"&gt;https://agentshortlist.dev/radar?utm_source=devto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>testing</category>
      <category>database</category>
    </item>
    <item>
      <title>I started 10 MCP servers in Docker. One tool description changed between two runs of the same version</title>
      <dc:creator>Antonio GM</dc:creator>
      <pubDate>Wed, 28 Oct 2026 08:58:34 +0000</pubDate>
      <link>https://dev.to/antoniogm82/i-started-10-mcp-servers-in-docker-one-tool-description-changed-between-two-runs-of-the-same-5eam</link>
      <guid>https://dev.to/antoniogm82/i-started-10-mcp-servers-in-docker-one-tool-description-changed-between-two-runs-of-the-same-5eam</guid>
      <description>&lt;p&gt;&lt;em&gt;I run &lt;a href="https://agentshortlist.dev" rel="noopener noreferrer"&gt;AgentShortlist&lt;/a&gt;, a directory of MCP servers where every line has a source. This is our own data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A hash of a server's tool descriptions can change between two runs without anyone touching the code. We saw it with Desktop Commander 0.3.1. Across two runs only the description of &lt;code&gt;start_process&lt;/code&gt; differed, and the only difference in that text was a Docker container ID: &lt;code&gt;fd1cb95d1f61&lt;/code&gt; in one run, &lt;code&gt;6f6d4f1f57de&lt;/code&gt; in the other. It sits at character 1348 of a description 4180 characters long. The schemas and the other 24 descriptions were identical.&lt;/p&gt;

&lt;p&gt;Our first reading was that something had changed in the tool. It had not. The server writes its container hostname into the description, so the text depends on where it runs. This is an effect of the environment, not a vulnerability and not a sign of risk. We corrected our own notes the same day.&lt;/p&gt;

&lt;p&gt;The practical lesson is for anyone who watches MCP servers for changes by hashing &lt;code&gt;tools/list&lt;/code&gt;: compare hashes taken in the same environment, or strip hostnames and paths before hashing. Otherwise a harmless container ID looks like a changed tool.&lt;/p&gt;

&lt;p&gt;The rest of this post is what else those runs recorded.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we ran
&lt;/h2&gt;

&lt;p&gt;On 25 October 2026 we installed 10 servers from our &lt;a href="https://agentshortlist.dev/verified" rel="noopener noreferrer"&gt;verified cards&lt;/a&gt; in Docker on a Windows machine with WSL2, with no credentials and only synthetic data. Seven ran in &lt;code&gt;node:22-slim&lt;/code&gt;. Three (excel, fetch, git) ran in an image with &lt;code&gt;uv&lt;/code&gt; and Python 3.12; the git one also needed git installed, and a first attempt without it did not start.&lt;/p&gt;

&lt;p&gt;For each we sent &lt;code&gt;initialize&lt;/code&gt; and &lt;code&gt;tools/list&lt;/code&gt; with our probe script and stored the tool names and a sha256 of the canonical list (sorted by name and by key), with separate hashes for descriptions, schemas and both together. The records are on each card under "Tested by us".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All 10 passed.&lt;/strong&gt; Here "pass" means three things: the package installed and started, it answered the handshake with a valid protocol version, and it returned a tool list. It does not mean the tools work, that they do what their descriptions say, or that any limit the project documents holds. In this first run we called no tools. A second run later the same day added one harmless call, with synthetic data, to four of the servers (memory, everything, git and fetch); the result is on their cards.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Tools listed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;excel-mcp-server&lt;/td&gt;
&lt;td&gt;2.2.2&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chrome-devtools-mcp&lt;/td&gt;
&lt;td&gt;1.12.0&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@playwright/mcp&lt;/td&gt;
&lt;td&gt;0.0.83&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desktop Commander&lt;/td&gt;
&lt;td&gt;0.3.1&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;codebase-memory-mcp&lt;/td&gt;
&lt;td&gt;0.12.1&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;server-everything&lt;/td&gt;
&lt;td&gt;2.0.0&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mcp-server-git&lt;/td&gt;
&lt;td&gt;2026.10.19&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;server-memory&lt;/td&gt;
&lt;td&gt;2.0.0&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context7&lt;/td&gt;
&lt;td&gt;4.4.4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mcp-server-fetch&lt;/td&gt;
&lt;td&gt;2026.10.19&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Playwright's count is its default tool set. Its README lists more behind optional &lt;code&gt;--caps&lt;/code&gt; groups, which we did not enable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same hash twice, or only once
&lt;/h2&gt;

&lt;p&gt;Eight servers (chrome-devtools, codebase-memory, Context7, excel, memory, everything, git and fetch) gave identical hashes in two runs. Desktop Commander was run twice and differed, as above. For Playwright our record does not show a second run, so a repeat could still differ. One matching pair is weak evidence of stability, not proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the names say
&lt;/h2&gt;

&lt;p&gt;From the tool names alone we group tools by what they appear to do. The rules are in the open and deliberately simple: a name such as &lt;code&gt;start_process&lt;/code&gt; counts as running commands, &lt;code&gt;write_file&lt;/code&gt; as writing files. &lt;strong&gt;These groups come from names, not from what the tools do inside, and not from any limit the server enforces.&lt;/strong&gt; A tool called &lt;code&gt;read_file&lt;/code&gt; might refuse most paths; we did not test that.&lt;/p&gt;

&lt;p&gt;With that caveat, some names are worth knowing before you connect a server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desktop Commander:&lt;/strong&gt; 7 tool names that start, talk to or stop processes (&lt;code&gt;start_process&lt;/code&gt;, &lt;code&gt;interact_with_process&lt;/code&gt;, &lt;code&gt;kill_process&lt;/code&gt;, &lt;code&gt;force_terminate&lt;/code&gt;, &lt;code&gt;list_processes&lt;/code&gt;, &lt;code&gt;read_process_output&lt;/code&gt;, &lt;code&gt;list_sessions&lt;/code&gt;), 5 that write files or folders, and 2 that read or set its own config.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright:&lt;/strong&gt; &lt;code&gt;browser_evaluate&lt;/code&gt; and &lt;code&gt;browser_run_code_unsafe&lt;/code&gt;, two tools that run code. The second one has "unsafe" in its name; we only know what the name says.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chrome DevTools MCP:&lt;/strong&gt; &lt;code&gt;evaluate_script&lt;/code&gt; is the one name our rules treat as running code, among 32.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mcp-server-git:&lt;/strong&gt; 5 names that change repository state (&lt;code&gt;git_add&lt;/code&gt;, &lt;code&gt;git_commit&lt;/code&gt;, &lt;code&gt;git_checkout&lt;/code&gt;, &lt;code&gt;git_create_branch&lt;/code&gt;, &lt;code&gt;git_reset&lt;/code&gt;) and 7 that only read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;server-memory:&lt;/strong&gt; 6 of 9 names create, add or delete stored data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;server-everything:&lt;/strong&gt; one name, &lt;code&gt;get-env&lt;/code&gt;, says it returns environment variables. We did not call it. The project is a reference server for testing clients, so this is not a statement about what it exposes in normal use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mcp-server-fetch:&lt;/strong&gt; one tool, &lt;code&gt;fetch&lt;/code&gt;, which reaches the network by its name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The grouping has gaps. For codebase-memory, 16 of 17 names match no group, and for Context7 neither of its two does. That does not mean those tools are harmless; it means our name rules say nothing about them. Cards for those servers show how many tools fall outside any group.&lt;/p&gt;

&lt;h2&gt;
  
  
  One count that was off
&lt;/h2&gt;

&lt;p&gt;The Desktop Commander card said 24 tools, counted from the source when we wrote it. The running server listed 25 for our test client. We checked the project's &lt;code&gt;src/server.ts&lt;/code&gt; on its main branch, where &lt;code&gt;package.json&lt;/code&gt; says 0.3.1: it defines 25 distinct tool names, the same 25 the server returned. One of them, &lt;code&gt;give_feedback_to_desktop_commander&lt;/code&gt;, is left out when the connecting client is named &lt;code&gt;desktop-commander-app&lt;/code&gt;, so for that client the list has 24. The card will say 25, with a note that the count depends on the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not show
&lt;/h2&gt;

&lt;p&gt;Apart from one harmless call on four of the servers, we did not test whether any tool works, what it does with real data, or whether it is safe to run. Ten passes on one machine on one day say these packages can be installed and answer a basic request in that environment. For any one server, check the card's other lines (source per line, &lt;a href="https://agentshortlist.dev/blog/mcp-risk-radar-1-66-advisories-none-on-the-latest-versions" rel="noopener noreferrer"&gt;advisories&lt;/a&gt;, access type) before you connect it, and use the report link on the card if something here is wrong.&lt;/p&gt;




&lt;p&gt;Full post with the per-server cards: &lt;a href="https://agentshortlist.dev/blog/10-mcp-servers-in-docker-what-their-tool-lists-tell-you?utm_source=devto" rel="noopener noreferrer"&gt;https://agentshortlist.dev/blog/10-mcp-servers-in-docker-what-their-tool-lists-tell-you?utm_source=devto&lt;/a&gt;. We also publish a short note on MCP advisories, the MCP Risk Radar: &lt;a href="https://agentshortlist.dev/radar?utm_source=devto" rel="noopener noreferrer"&gt;https://agentshortlist.dev/radar?utm_source=devto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>testing</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>We read 25 MCP servers. Here is what we found</title>
      <dc:creator>Antonio GM</dc:creator>
      <pubDate>Sat, 24 Oct 2026 13:30:00 +0000</pubDate>
      <link>https://dev.to/antoniogm82/we-read-25-mcp-servers-here-is-what-we-found-2ngn</link>
      <guid>https://dev.to/antoniogm82/we-read-25-mcp-servers-here-is-what-we-found-2ngn</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a copy of an article first published on &lt;a href="https://agentshortlist.dev/blog/we-read-25-mcp-servers" rel="noopener noreferrer"&gt;AgentShortlist&lt;/a&gt;, where the tables and cards live.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On 18 and 19 October 2026 we read the documentation and source of 25 MCP servers and wrote down, line by line, what each one says and does. Every line on a &lt;a href="https://agentshortlist.dev/verified" rel="noopener noreferrer"&gt;verified card&lt;/a&gt; carries a source and a review date. This article adds the 25 cards up.&lt;/p&gt;

&lt;p&gt;It isn't a ranking or a security audit. It records what the projects document and what their code shows. Where we couldn't check something, the card says "not verified", and that turned out to be a big part of the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read-only modes: documented in 5 of 25
&lt;/h2&gt;

&lt;p&gt;Plenty of these servers can change data. Whether you can run them read-only is the question that moves the risk the most.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Documented read-only mode or recipe&lt;/th&gt;
&lt;th&gt;None found in the docs and source we read&lt;/th&gt;
&lt;th&gt;Not verified&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub MCP server, n8n-mcp, MongoDB MCP server, DBHub, pREST&lt;/td&gt;
&lt;td&gt;Playwright MCP, Desktop Commander, MySQL MCP server, Chrome DevTools MCP, Blender MCP, IDA Pro MCP, Talk to Figma MCP&lt;/td&gt;
&lt;td&gt;The other 13&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"None found" means we didn't find one in what we read, not that none exists. For browser and design tools a read-only mode isn't really the right idea anyway. For the MySQL server it is, and there isn't one, so the limit has to live in the database user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telemetry: three on by default, and mostly silence
&lt;/h2&gt;

&lt;p&gt;Chrome DevTools MCP collects usage statistics by default, and its performance tools can send trace URLs to Google's CrUX API. The Apify MCP server collects telemetry about tool calls by default, with Sentry error tracking. Blender MCP collects a minimal anonymous usage record by default; prompts, generated code and scene data are collected only if you opt in.&lt;/p&gt;

&lt;p&gt;All three document how to turn it off. Two more projects, codebase-memory-mcp and context-mode, say they send nothing; we didn't verify that claim. For the other 20 we found no statement either way in the docs we read. What stood out to us is how few projects say anything about what leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advisories: 40 published, none on the latest versions we checked
&lt;/h2&gt;

&lt;p&gt;We matched the cards to packages on npm, PyPI and Go, but only when we could confirm the package belongs to the same repository. That gave 24 packages across 20 of the 25 cards, with 40 published advisories on OSV.dev in total. Half of those 20 cards have none.&lt;/p&gt;

&lt;p&gt;We could check the latest version for 23 of the 24 packages, the npm and PyPI ones, and none of them is affected by a published advisory as of 19 October. We didn't check the latest version of the one Go module, the GitHub MCP server.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Card&lt;/th&gt;
&lt;th&gt;Published advisories&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;n8n-mcp&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP reference servers (filesystem and git packages)&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub MCP server&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MySQL MCP server&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chrome DevTools MCP, DBHub, Apify, Desktop Commander and Serena&lt;/td&gt;
&lt;td&gt;2 each&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the table with care. More advisories often just means a project is more used and more closely examined, not that it's worse. A package with none isn't proven safe. The practical takeaway is smaller: older versions are affected, so pin a version you've actually checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upkeep: the issue backlogs differ a lot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm45fgnynb79lyqd04oe5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm45fgnynb79lyqd04oe5.png" alt="Playwright MCP, Chrome DevTools MCP and Browser Tools MCP side by side: telemetry, read-only option, advisories, last push and open issues, checked on 19 October 2026" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open issues created before 20 July 2026, counted on 19 October:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Open issues&lt;/th&gt;
&lt;th&gt;Of which older than that date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Playwright MCP&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n-mcp&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chrome DevTools MCP&lt;/td&gt;
&lt;td&gt;173&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub MCP server&lt;/td&gt;
&lt;td&gt;380&lt;/td&gt;
&lt;td&gt;112&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desktop Commander&lt;/td&gt;
&lt;td&gt;311&lt;/td&gt;
&lt;td&gt;126&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MySQL MCP server&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A busy project collects more issues. The number tells you where to look, not what to conclude.&lt;/p&gt;

&lt;h2&gt;
  
  
  Projects that point somewhere else
&lt;/h2&gt;

&lt;p&gt;A few READMEs say another option fits better, which is useful to read before you install:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Playwright MCP README recommends Playwright CLI with Skills for coding agents, because it avoids loading large tool schemas and page snapshots into the model's context.&lt;/li&gt;
&lt;li&gt;The awslabs/mcp README recommends the Agent Toolkit for AWS for production software built with coding agents, and calls it the successor to the servers in that repository.&lt;/li&gt;
&lt;li&gt;The IDA Pro MCP README opens by recommending the official Hex-Rays server instead.&lt;/li&gt;
&lt;li&gt;The MCP reference servers README says they are reference implementations, not production-ready solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to do with this
&lt;/h2&gt;

&lt;p&gt;If a server can change data, look for its read-only option before anything else. Search the README for telemetry and set the opt-out if you want it. Pin versions and check them against advisories; the &lt;a href="https://agentshortlist.dev/check" rel="noopener noreferrer"&gt;config checker&lt;/a&gt; does that in your browser. And treat "not stated" as a question to ask the maintainers, not as a yes.&lt;/p&gt;

&lt;p&gt;Every card, with its sources, is on the &lt;a href="https://agentshortlist.dev/verified" rel="noopener noreferrer"&gt;verified cards page&lt;/a&gt;. You can compare servers in the &lt;a href="https://agentshortlist.dev/compare/live" rel="noopener noreferrer"&gt;live comparator&lt;/a&gt; or filter by what you need in the &lt;a href="https://agentshortlist.dev/pick" rel="noopener noreferrer"&gt;picker&lt;/a&gt;. If a card has a mistake, send us the primary source and we'll correct it.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
