
> **TL;DR** > - Your MCP Server ID should be **kebab case** (**hyphen separated** & **lower case**) and > contain **mcp**, e.g. `epic-stuff-mcp` or `mcp-epic-stuff` > - Your MCP tools should be **snake case**, e.g. `get_epic_stuff` > - Your MCP prompts should be **snake case** or **kebab case**, e.g. `epic_prompt` or `epic-prompt` > - Your MCP resources should be **URIs**, e.g. `file:///epic/file.txt` As the MCP (Model Context Protocol) gold rush takes hold, you'll quickly realize that you need a name for your little gold-nugget of a project. That was the impasse that I found myself at. Therefore, I did my research and I wrote down guidelines for **naming MCP servers**, along with **tools**, **prompts** and **resources**. ## About this Guide This guide is **opinionated, but grounded with facts** from the [official MCP specification](https://modelcontextprotocol.io/introduction) and data on hundreds of MCP servers. This should be a reliable and helpful source of information for developers. If you find any problems then please **email me at alex@zazencodes.com** or **[ping me on Discord](https://discord.gg/e4zVza46CQ)**. ## MCP Server ID This is the **name of your package on `npm` and/or `PyPI`**, and it should also be the **name of your GitHub repo**. ### Core guidelines These are my personal recommendations: - **Include "mcp" somewhere in the package name** - **Keep it ASCII-lowercase, hyphen separated, ≤ 64 chars** - **Stay consistent across GitHub and npm/PyPI** \* \* *In npm you can use scoped packages, e.g. `@your-org/epic-stuff-mcp`, which can help with name conflicts, however you can't do this on PyPI.* ### What people actually do (sample of 500+ public servers) I analyzed an "awesome list" of MCP servers[^1] in June 2025 and here's what I found: | Naming pattern (example) | Count (approx %) | Popularity verdict | | ----------------------------------------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------- | | Does not include the word "server" (**`epic-mcp`** not **`epic-mcp-server`**) | 339 (**63%**) | Most people **don't include "server"** in the name. | | `<name>-mcp` (**`epic-mcp`**) | 222 (**40%**) | The most common convention is to **end the name with "mcp"**. | `mcp-<name>` (**`mcp-epic`**) | 195 (**35%**) | But a near-equally common convention is to **start the name with "mcp"**. | | `<name>-mcp-server` (**`epic-mcp-server`**) | 116 (**20%**) | A less common but still significant pattern is to **end the name with "mcp-server"**. | | `mcp-server-<name>` (**`mcp-server-epic`**) | 62 (**10%**) | And the least frequent pattern is to **start the name with "mcp-server"**. | | "mcp" or "mcp-server" in the middle (**`epic-mcp-server-thing`**) | 1 (**0%**) | Dancing on your own. | ### Practical naming checklist 1. **Use kebab-case** (`lowercase-with-hyphens`) for the published package. 2. **Include "mcp" in the name**. - If in doubt, **go with `<name>-mcp`**. It's the most common pattern and instantly readable. 3. **Ensure it's available on your registry of choice.** Before publishing: - Check: `https://www.npmjs.com/package/<your-mcp-id>` (or run `npm view <your-mcp-id>`) - Check: `https://pypi.org/project/<your-mcp-id>/` - For PyPI, verify the **normalized** form[^2] (dots, dashes, underscores collapse) is still unique. 4. **Do not use trademarks** (unless you own them) and **do not use misleading look-alikes.**[^3] 5. **Consider vendor prefixes** for your own enterprise packages, e.g. `atlassian-jira-mcp`. > Bonus points for publishing on both npm and PyPI. But in practice you only need to publish it in one place, since both Node and Python have very strong MCP ecosystems and MCP servers are equally interoperable with both. > > (Or maybe I'm wrong, and there is a good reason to publish your package in both places. In that case, [please correct me!](https://x.com/ZazenCodes)) ## MCP Tools, Prompts and Resources This section is about naming the things inside your MCP server. In particular: - **Tools** (**`get_lunch`**) - **Prompts** (**`make_vegan_sandwich`**) - **Resources** (**`file:///recipe/sandwich/vegan.json`**) ### Tools #### What people actually do (sample of 100 public servers) For starters, I analyzed the first 100 MCP servers on that "awesome list" referenced above[^1], and I found that: - **Over 90% of tools use snake case**. - Also, about **95% are multi-word** (e.g. `fetch_forecast`, as opposed to `forecast`) - Surprisingly, **less than 1% of the names were camel case**. > #### How to name your tools --- FastMCP example > > I thought that more tool names would be camel cased, since the underlying functions in JavaScript and TypeScript (dominant languages for writing MCP servers[^4]) are themselves defined with camel case variables. > > But then I looked at this example from the **FastMCP TypeScript framework** docs: > > ```javascript > import { FastMCP } from "fastmcp"; > import { z } from "zod"; > > const server = new FastMCP({ > name: "My Server", > version: "1.0.0", > }); > > server.addTool({ > name: "add-numbers", > description: "Add two numbers", > parameters: z.object({ > a: z.number(), > b: z.number(), > }), > execute: async (args) => { > return String(args.a + args.b); > }, > }); > ``` > > Notice how the tool name `add-numbers` is defined independently of the local function name (which in this case is anonymous anyway). > > Also notice how the tool name itself is kebab case! It's totally valid to do this, although not what I'd recommend. > > It's also useful to see how tools work with the **FastMCP Python framework**, where decorators are used to automatically infer tool names: > > ```python > mcp = FastMCP("Demo 🚀") > > @mcp.tool > def add_numbers(a: int, b: int) -> int: > """Add two numbers""" > return a + b > ``` > > > The point here is that popular MCP development frameworks are guiding users away from camel case and --- in the case of Python --- towards snake case. ### Official Guidelines In the MCP specification[^5], **tools and prompts must have a `name`** and **resources must have a `uri`**. The requirements are that: * **Names be unique identifiers** * **Resource identifiers be valid URIs** The MCP specification **does not provide a fixed naming schema** for the tool and prompt `name`. The recommendations below are therefore based on the implicit patterns from the documentation. *MCP is less than a year old and best practices are still evolving. I expect to see a convergence on some common standards which are not necessarily the same as what I've presented here.* > Most of the information in this section is straight from the MCP official 2025-06-18 spec for [tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools), [prompts](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) and [resources](https://modelcontextprotocol.io/specification/2025-06-18/server/resources) ### Tools | Convention | Why | Example | | ------------------------------------------------------------------------- | --------------------------------------------------------------------- | ----------------------- | | **Snake case** | Mirrors every tool in the spec. | `get_stock_price` | | **Begin with an imperative verb** (`get_*`, `list_*`, `create_*`) | Signals action and aligns with CRUD semantics. | `create_support_ticket` | | **≤ 32 chars recommended** | Keeps payloads lean and UI columns readable. | `summarize_contract` | ### Prompts | Convention | Why | Example | | --------------------------- | ----------------------------------------------------- | ------------------- | | **Snake case** | Consistent with tools and mirrors examples in the spec. | `draft_email` | | **Kebab case** | Frequently seen "in the wild" and one example in the spec. May be easier for users to type. | `draft-email` | | **Domain-first naming** | Groups related prompts (`summarize_*`, `generate_*`). | `summarize_meeting` | ### Resources | Field | Convention | Example | | ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- | | **`uri`** | Valid RFC 3986; pick scheme that reflects access path (`file://`, `https://`, `git://`, custom). | `file:///docs/design/architecture.md` | ### Final considerations for naming things 1. MCP servers are not much use if the client isn't able to see them. Good names **help LLMs and users identify which features to access** at the right time. 2. It's important to **choose a convention and stick with it**. Inconsistency signals poor quality. 3. A good name will **maximize interoperability** (the degree to which an LLM can make use of the feature) and **improve discoverability** (how easily an LLM or human can find it). ## Conclusion Are you ready to build your MCP server? I've got you covered with my FastMCP Python tutorial, where I walk through how to build an MCP server in 10 minutes using Claude Code. <iframe width="800" height="450" src="https://www.youtube.com/embed/rnljvmHorQw" frameborder="0" allowfullscreen></iframe> ### 🎥 Watch the Video https://youtu.be/rnljvmHorQw > ### 🚀 Level-up in 2025 > > If you're serious about AI-powered development, then you'll enjoy my **AI Engineering course** which is live on [ZazenCodes.com](https://zazencodes.com/courses). > > It covers: > - **Fundamental skills for AI Engineers** > - Programming > - Calculus > - ML/DL > - Data Engineering > - **AI Engineering in practice** > - Embeddings > - RAG > - Agents > - MCP > > And much more. 99 lessons. Roughly the same word count as Dune, but even more dry. Haha 🥁 > > It's good stuff. Check out the [open-source Jupyter Notebooks](https://github.com/zazencodes/ai-engineer-roadmap-notebooks) as well. Thanks for reading and happy coding! ## Footnotes [^1]: [Awesome MCP Servers on GitHub](https://github.com/punkpeye/awesome-mcp-servers) [^2]: [PyPI normalized form docs and reference helper function](https://packaging.python.org/en/latest/specifications/name-normalization/) [^3]: [Package name guidelines from npm (trademark, lookalikes)](https://docs.npmjs.com/package-name-guidelines) [^4]: Node (JavaScript + TypeScript) MCP servers are slightly more prevalent then Python ones, based on my [Awesome MCP Server dataset analysis (Juputer Notebook)](https://github.com/zazencodes/zazencodes-season-2/blob/main/src/mcp-server-analysis/workbook.ipynb) [^5]: [The official MCP spec](https://modelcontextprotocol.io/introduction).
TL;DR
- Your MCP Server ID should be kebab case (hyphen separated & lower case) and
contain mcp, e.g.epic-stuff-mcp
ormcp-epic-stuff
- Your MCP tools should be snake case, e.g.
get_epic_stuff
- Your MCP prompts should be snake case or kebab case, e.g.
epic_prompt
orepic-prompt
- Your MCP resources should be URIs, e.g.
file:///epic/file.txt
As the MCP (Model Context Protocol) gold rush takes hold, you’ll quickly realize that you need a name for your little gold-nugget of a project.
That was the impasse that I found myself at.
Therefore, I did my research and I wrote down guidelines for naming MCP servers, along with tools, prompts and resources.
About this Guide
This guide is opinionated, but grounded with facts from the official MCP specification and data on hundreds of MCP servers.
This should be a reliable and helpful source of information for developers. If you find any problems then please email me at alex@zazencodes.com or ping me on Discord.
MCP Server ID
This is the name of your package on npm
and/or PyPI
, and it should also be the name of your GitHub repo.
Core guidelines
These are my personal recommendations:
- Include “mcp” somewhere in the package name
- Keep it ASCII-lowercase, hyphen separated, ≤ 64 chars
- Stay consistent across GitHub and npm/PyPI *
* In npm you can use scoped packages, e.g. @your-org/epic-stuff-mcp
, which can help with name conflicts, however you can’t do this on PyPI.
What people actually do (sample of 500+ public servers)
I analyzed an “awesome list” of MCP servers[1] in June 2025 and here’s what I found:
Naming pattern (example) | Count (approx %) | Popularity verdict |
---|---|---|
Does not include the word “server” (epic-mcp not epic-mcp-server ) |
339 (63%) | Most people don’t include “server” in the name. |
<name>-mcp (epic-mcp ) |
222 (40%) | The most common convention is to end the name with “mcp”. |
mcp-<name> (mcp-epic ) |
195 (35%) | But a near-equally common convention is to start the name with “mcp”. |
<name>-mcp-server (epic-mcp-server ) |
116 (20%) | A less common but still significant pattern is to end the name with “mcp-server”. |
mcp-server-<name> (mcp-server-epic ) |
62 (10%) | And the least frequent pattern is to start the name with “mcp-server”. |
“mcp” or “mcp-server” in the middle (epic-mcp-server-thing ) |
1 (0%) | Dancing on your own. |
Practical naming checklist
-
Use kebab-case (
lowercase-with-hyphens
) for the published package. -
Include “mcp” in the name.
- If in doubt, go with
<name>-mcp
. It’s the most common pattern and instantly readable.
- If in doubt, go with
-
Ensure it’s available on your registry of choice. Before publishing:
- Check:
https://www.npmjs.com/package/<your-mcp-id>
(or runnpm view <your-mcp-id>
) - Check:
https://pypi.org/project/<your-mcp-id>/
- For PyPI, verify the normalized form[2] (dots, dashes, underscores collapse) is still unique.
- Check:
-
Do not use trademarks (unless you own them) and do not use misleading
look-alikes.[3] -
Consider vendor prefixes for your own enterprise packages, e.g.
atlassian-jira-mcp
.
Bonus points for publishing on both npm and PyPI. But in practice you only need to publish it in one place, since both Node and Python have very strong MCP ecosystems and MCP servers are equally interoperable with both.
(Or maybe I’m wrong, and there is a good reason to publish your package in both places. In that case, please correct me!)
MCP Tools, Prompts and Resources
This section is about naming the things inside your MCP server.
In particular:
- Tools (
get_lunch
) - Prompts (
make_vegan_sandwich
) - Resources (
file:///recipe/sandwich/vegan.json
)
Tools
What people actually do (sample of 100 public servers)
For starters, I analyzed the first 100 MCP servers on that “awesome list” referenced above[1:1], and I found that:
- Over 90% of tools use snake case.
- Also, about 95% are multi-word (e.g.
fetch_forecast
, as opposed toforecast
) - Surprisingly, less than 1% of the names were camel case.
How to name your tools — FastMCP example
I thought that more tool names would be camel cased, since the underlying functions in JavaScript and TypeScript (dominant languages for writing MCP servers[4]) are themselves defined with camel case variables.
But then I looked at this example from the FastMCP TypeScript framework docs:
import { FastMCP } from "fastmcp"; import { z } from "zod"; const server = new FastMCP({ name: "My Server", version: "1.0.0", }); server.addTool({ name: "add-numbers", description: "Add two numbers", parameters: z.object({ a: z.number(), b: z.number(), }), execute: async (args) => { return String(args.a + args.b); }, });
Notice how the tool name
add-numbers
is defined independently of the local function name (which in this case is anonymous anyway).Also notice how the tool name itself is kebab case! It’s totally valid to do this, although not what I’d recommend.
It’s also useful to see how tools work with the FastMCP Python framework, where decorators are used to automatically infer tool names:
mcp = FastMCP("Demo 🚀") @mcp.tool def add_numbers(a: int, b: int) -> int: """Add two numbers""" return a + b
The point here is that popular MCP development frameworks are guiding users away from camel case and — in the case of Python — towards snake case.
Official Guidelines
In the MCP specification[5], tools and prompts must have a name
and resources must have a uri
.
The requirements are that:
- Names be unique identifiers
- Resource identifiers be valid URIs
The MCP specification does not provide a fixed naming schema for the tool and prompt name
.
The recommendations below are therefore based on the implicit patterns from the documentation.
MCP is less than a year old and best practices are still evolving. I expect to see a convergence on some common standards which are not necessarily the same as what I’ve presented here.
Most of the information in this section is straight from the MCP official 2025-06-18 spec for tools, prompts and resources
Tools
Convention | Why | Example |
---|---|---|
Snake case | Mirrors every tool in the spec. | get_stock_price |
Begin with an imperative verb (get_* , list_* , create_* ) |
Signals action and aligns with CRUD semantics. | create_support_ticket |
≤ 32 chars recommended | Keeps payloads lean and UI columns readable. | summarize_contract |
Prompts
Convention | Why | Example |
---|---|---|
Snake case | Consistent with tools and mirrors examples in the spec. | draft_email |
Kebab case | Frequently seen “in the wild” and one example in the spec. May be easier for users to type. | draft-email |
Domain-first naming | Groups related prompts (summarize_* , generate_* ). |
summarize_meeting |
Resources
Field | Convention | Example |
---|---|---|
uri |
Valid RFC 3986; pick scheme that reflects access path (file:// , https:// , git:// , custom). |
file:///docs/design/architecture.md |
Final considerations for naming things
-
MCP servers are not much use if the client isn’t able to see them. Good names help LLMs and users identify which features to access at the right time.
-
It’s important to choose a convention and stick with it. Inconsistency signals poor quality.
-
A good name will maximize interoperability (the degree to which an LLM can make use of the feature) and improve discoverability (how easily an LLM or human can find it).
Conclusion
Are you ready to build your MCP server?
I’ve got you covered with my FastMCP Python tutorial, where I walk through how
to build an MCP server in 10 minutes using Claude Code.
🎥 Watch the Video
🚀 Level-up in 2025
If you’re serious about AI-powered development, then you’ll enjoy my AI Engineering course which is live on ZazenCodes.com.
It covers:
- Fundamental skills for AI Engineers
- Programming
- Calculus
- ML/DL
- Data Engineering
- AI Engineering in practice
- Embeddings
- RAG
- Agents
- MCP
And much more. 99 lessons. Roughly the same word count as Dune, but even more dry. Haha 🥁
It’s good stuff. Check out the open-source Jupyter Notebooks as well.
Thanks for reading and happy coding!
Footnotes
Node (JavaScript + TypeScript) MCP servers are slightly more prevalent then Python ones, based on my Awesome MCP Server dataset analysis (Juputer Notebook) ↩︎