Vellum
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@VellumCount the words and characters in this text: 'The quick brown fox jumps over the lazy dog.'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Vellum
An MCP server that gives exact answers about text · By Shuja Jamal
A language model reads tokens, not characters. Ask one how many letters are in a paragraph and it estimates, often badly. The same is true of diffing two files by eye, or predicting what a regular expression will match without running it.
These are not hard problems. They are simply not the kind of problem a model is built to solve. So it should ask instead.
Live | |
Smithery | |
Write-up | EXPERIENCE.md, on using existing MCPs before building this |
The five tools
Tool | What it answers | Instead of |
| Characters, words, lines, sentences, bytes | an estimate from token count |
| Flesch reading ease, grade level, longest sentence | an impression |
| Unified diff, lines added and removed, similarity | reading both and describing |
| Every match, its position and capture groups | reasoning about the pattern |
| md5, sha1, sha256, sha512 | nothing, it cannot |
count_text reports visible characters separately from code points, because café is four characters to a person, five to len(), and six bytes. Which of those you want depends on why you asked, so it returns all three.
Related MCP server: text-stats-ai-mcp
Using it
Claude Code
claude mcp add --transport http vellum https://vellum-mcp.vercel.app/mcpOr locally, over stdio:
claude mcp add vellum -- python -m vellum.serverOne thing that cost me time when installing somebody else's server: a server added mid-session shows as connected but its tools are not callable until the session restarts. A working install and a usable install are different states.
Claude Desktop
In claude_desktop_config.json:
{
"mcpServers": {
"vellum": {
"command": "python",
"args": ["-m", "vellum.server"],
"cwd": "/path/to/vellum-mcp"
}
}
}Running it
pip install -r requirements.txtpython -m vellum.serverThat is stdio, which is what a local client speaks. For the HTTP transport and the landing page:
python -m vellum.server --http --port 8000Then http://localhost:8000 for the page and http://localhost:8000/mcp for the endpoint.
Testing
python tests/test_vellum.py46 checks. The first half calls the analysis functions directly. The second half is the part that matters: it launches the server as a subprocess and speaks MCP to it, doing the real handshake, listing the tools, calling them and reading the results back. A server whose functions are correct can still fail to speak the protocol, and only the second half would catch that.
python tests/test_deploy.pyChecks the deployed shape before deploying it: that a rewritten request reaches the MCP app at the path it expects, that ?action=demo reaches the demo instead, that the static server card describes tools that actually exist, and that there is exactly one function because that is what the runtime builds.
Deploying
Vercel, for the hosting
vercelNo environment variables and no secrets: every tool is a pure function of its arguments.
The routing is deliberate and worth explaining, because the obvious version does not work.
A Vercel rewrite does not hand the function the path the browser asked for. Rewriting /(.*) to a single function means every request arrives as /api/index, so an app that routes on path answers every URL with its own 404 while looking, from outside, completely dead. I lost an afternoon to exactly that on an earlier project.
And the Python runtime builds one function for the whole project, not one per file. I had api/demo.py sitting next to api/index.py, declared in vercel.json and bundled into the deployment, and /api/demo still returned Vercel's own 404. vercel inspect showed the reason plainly: a single python lambda. Filesystem routing across several Python entrypoints does not happen.
So the deployment is one function plus static files:
/ static public/index.html
/.well-known/mcp/server-card.json static generated by build_card.py
/mcp -> /api/index function
/api/demo -> /api/index function, told apart by ?action=demoapi/index.py dispatches on the query string, because that is the part a rewrite preserves while it replaces the path, and it puts the path back before the MCP app routes on it. There are tests for both, because neither is something you want to discover from a live URL.
The two things that worked first time were the landing page and the server card, and they are exactly the two that never touch a function.
Smithery, for the listing
Smithery's current model is bring your own hosting: you give it a public HTTPS URL to a streamable HTTP server and its gateway proxies to it. There is no container to build.
Deploy to Vercel first and note the URL
Go to smithery.ai/new
Enter
https://your-deployment.vercel.app/mcpComplete the publishing flow
Smithery then reads the server's tools for the listing page. The documented path is a live scan, with a static card at /.well-known/mcp/server-card.json as the fallback when a scan cannot complete.
In practice the fallback was the primary path. The publish log reads:
Server metadata discovered (server card: 5 tools).
Using .well-known/mcp/server-card.json: (5 tools)So the card was not insurance against a failure, it was the mechanism. build_card.py generates it from the server's own tool definitions, which is why it could not have listed tools that do not exist.
The log also warns that no config schema was provided. That is correct and intended here: every tool is a pure function of its arguments, so there is nothing to prompt a user for. The warning matters for a server that wraps an API and needs a key.
smithery.yaml records the details the publishing flow asks for. Note that it does not drive a build: the older container-based deployment path is no longer how this works.
Both tiers are free. Vercel's hobby tier hosts the function and the static files; Smithery's registry listing costs nothing.
How it is put together
vellum/
analysis.py the actual work, with no MCP anywhere in it
server.py the five tools, their descriptions, and the transports
api/
index.py the one Vercel function: MCP, and the demo behind a query flag
public/
index.html the landing page
.well-known/mcp/server-card.json generated
tests/
test_vellum.py analysis, then a real MCP handshake over stdio
test_deploy.py the routing and the cardanalysis.py imports nothing from MCP. That is what lets the tests call it directly, and it is why the landing page's demo can call the same functions the tools call rather than being a second implementation that drifts.
Notes on writing tools for a model
The description is the interface. It is not documentation for a developer; it is the only thing the model reads when deciding whether a tool is relevant. A vague one means the tool is never chosen, a wrong one means it is chosen at the wrong moment. So count_text does not say "returns a dictionary of counts". It says to use this when the answer needs to be a precise number, because reading tokens is not the same as counting characters.
Failure should be readable. A broken regex comes back as {"valid": false, "error": ...} rather than an exception, and an unknown hash algorithm names the ones that exist. A model can act on that; it cannot act on a stack trace.
Pick something the model genuinely cannot do. The temptation is to wrap an API and call it a tool, but a "summarise this text" tool adds a network round trip to something the model already does better itself. Counting, hashing and running a regex are real gaps. Filling a real gap is what makes a tool get used rather than politely ignored.
By Shuja Jamal, August 2026.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides basic text manipulation and analysis tools including word reversal and character counting. Designed for integration with Le Chat and other MCP-compatible clients.3
- AlicenseNot gradedqualityAmaintenanceProvides text analysis tools including word counting, reading time estimation, keyword density analysis, and sentiment scoring.8MIT
- AlicenseNot gradedqualityCmaintenanceProvides a tool to calculate basic text metrics including character count, characters without spaces, and word count.MIT
- AlicenseNot gradedqualityCmaintenanceProvides text statistics and readability scores (Flesch Reading Ease, Flesch-Kincaid Grade Level) via offline, keyless tools.10MIT
Related MCP Connectors
Text statistics & readability MCP.
Count occurrences of any character in your text instantly. Specify the character and get precise c…
Generate IDs, QR codes, and hashes, encode values, geolocate IPs, plus gated host diagnostics.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/slider79/vellum-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server