ZYVOPMulti-Platform Sync
SeriesAI NewsWhy ZyVOPJoin Discord
LoginGet Started
ZYVOPMulti-Platform Sync

The Developer Publishing Hub. Write once, publish everywhere, and make your work citation-ready with built-in SEO, AEO, and GEO discovery support. Zero reader paywalls.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Why ZyVOP
  • Changelog
  • Compare Platforms
  • Hashnode vs ZyVOP
  • DEV vs ZyVOP
  • Developer API & CLI
  • Author Handbook
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

ยฉ 2026 ZyVOP. Developer Publishing Hub.

Zero paywalls ยท Full content ownership
All systems operational
HomeTutorialWhy Cosine Similarity Fails to Catch Confusable MCP Tools
Tutorial

Why Cosine Similarity Fails to Catch Confusable MCP Tools

Author
Author
Senior Developer
July 31, 2026Updated August 28, 2026
3 min read
Why Cosine Similarity Fails to Catch Confusable MCP Tools
#MCP#Schema Design#Python#open-source#developer tools#AI agents#LLM Tools#Agent Safety
๐Ÿ‘3

An MCP agent decides what to do based entirely on text it's handed at runtime โ€” a tool's name, its description, and its input schema. When a server exposes multiple tools with overlapping schemas or vague boundaries, an agent can easily invoke the wrong one, or take a destructive action it wasn't meant to.

I wanted a way to catch this before it happens: flag pairs of tools that are similar enough to confuse an agent, before that server ever gets used. The obvious first approach was cosine similarity on the tool descriptions. It completely failed.

The experiment

I ran TF-IDF + cosine similarity against the 14 tools exposed by the official MCP filesystem server โ€” 91 possible pairs. At the standard 0.85 similarity threshold, it flagged zero pairs.

Lowering the threshold didn't help โ€” it made things worse. Genuinely confusable pairs like read_file / read_text_file and completely unrelated pairs like read_file / write_file ended up scoring in the same range. There was no threshold, anywhere, that cleanly separated "these will confuse an agent" from "these obviously won't."

Why it breaks down

Two things were going on:

  1. Shared domain vocabulary swamps the signal. Tools on the same server all talk about path, file, directory โ€” regardless of whether they're actually confusable. That overlap dominates the similarity score.

  2. Opposing verbs barely move the needle. read_file and write_file share the vast majority of their tokens. The one word that actually matters โ€” read vs. write โ€” is a tiny fraction of the text, so it has almost no effect on a similarity score built from shared nouns.

In short: cosine similarity on tool descriptions measures topical overlap, not functional confusability. Those are different things, and the difference is exactly what matters here.

What actually worked

Instead of scoring text first, I flipped the question: can one tool's arguments satisfy the other tool's schema? If they can't, an agent can never actually confuse the two calls, no matter how similar the descriptions read. So that pair gets thrown out before any text comparison happens at all.

This structural gate โ€” checking schema substitutability first โ€” eliminated 63 of the 91 pairs immediately, before any similarity scoring touched them.

For the remaining 28 pairs, I scored on:

  • name affinity

  • non-domain token overlap (ignoring the shared path/file/directory noise)

  • a hard veto on opposing verbs (read/write, create/delete)

This surfaced exactly 4 genuinely confusable pairs โ€” the read_file / read_text_file / read_media_file cluster, and list_directory / list_directory_with_sizes โ€” cleanly separated from everything else by a real 0.33โ€“0.50 gap. That's the separation cosine similarity alone could never produce.

A note on scope

This is about accidental confusability between two legitimate, honestly-described tools โ€” not malicious or poisoned tool descriptions (e.g. prompt injection hidden in metadata). That's a different, already-covered problem. This is about well-intentioned tools that are just similar enough to trip an agent up.

Try it

I packaged this as mcplock, an open-source lint check for MCP servers:

bash

pip install mcplock
mcplock lint "npx -y @modelcontextprotocol/server-filesystem ./data"

mcplock also does drift detection โ€” it hashes tool definitions into a baseline so any runtime change to a tool's description, schema, or behavioral annotations becomes a reviewable diff, the same way a lockfile works for dependencies.

  • Repo: https://github.com/yash161004/mcplock

  • PyPI: https://pypi.org/project/mcplock/

If you're building or shipping MCP servers, I'd genuinely value you running it against yours and telling me what breaks.


The core takeaway: functional confusability is a structural property of tool schemas, not a text-similarity score โ€” checking substitutability first is what actually separates risky tool pairs from safe ones.

What's your MCP server's tool count? Curious how common this problem actually is at scale.

Comments (1)

Login to post a comment.

ZyVOP

ZyVOP

Word WarriorEarly Bird
1 month ago

Hey Welcome to ZyVOP, happy blogging

Author
Author

Passionate developer sharing knowledge about modern web technologies and best practices.

Subscribe to Author's Newsletter

Direct email dispatches when new stories are published. Zero algorithms.

Trending on ZyVOP

The Harness is the Moat: Building a Deterministic Agent Runtime with Context Pruning

Learn how a deterministic harness prunes context, uses a ledger and transactional tool calls to keep LLM agents reliable over many turns.

Lรช ฤแปฉc Minh
Lรช ฤแปฉc Minhยท
6 minSep 16

Building a Synthetic Data Generator

Building a synthetic data generator based on Red Hat's "sdg hub" Introduction For a...

Alain Airom (Ayrom)
Alain Airom (Ayrom)ยท
10 minSep 16

The Reference Image Looks Rightโ€”So Why Does My AI Video Ignore the Prompt?

The mug looks exactly right. It has the blue rim from your reference photo, the same curved handle, and the same morning light on the kitchen counter. But you...

john smith
john smithยท
3 minSep 16

Introducing Gemini 3.8 Live and 3.8 Live Extended Thinking

Google launched Gemini 3.8 Live and 3.8 Live Extended Thinking on September 15, 2026, its most advanced voice AI yet. The models reason and speak simultaneously, ground responses in live video, switch between 97 languages, and top several speech benchmarks.

Arpan Singh
Arpan Singhยท
3 minSep 16

Gemini 3.8 Live Extended Thinking vs GPT-Live-1 vs Grok Voice Think Fast 2.0: A Developer's Buying Guide

Google, OpenAI, and xAI each released a flagship voice-agent model between late July and mid-September 2026. The headline benchmarks look close, but the three models use very different architectures, and that difference changes the real cost of running one.

Anshu Pathak
Anshu Pathakยท
10 minSep 16