Skip to main content
Glama
xcollantes

MCP Template

by xcollantes

MCP Template

MY_MCP_DESCRIPTION

Template Setup

Remove the Template Setup section after you have replaced all the variables.

Find All and Replace these variables throughout the project:

Variable

Description

Example

TODO

General placeholders

MY_MCP_NAME

Human-readable name

Weather MCP

MY_MCP_DESCRIPTION

One-liner description

MCP server for interacting with the Weather API.

MY_MCP_REPO_URL

Full GitHub repo URL

https://github.com/xcollantes/weather-mcp

MY_MCP_PACKAGE_NAME

Package name for CLI/binaries

weather-mcp

MY_MCP_SERVER_KEY

Key in mcpServers JSON config

weather

MY_MCP_ENV_VAR_PREFIX

Prefix for environment variables

WEATHER

MY_MCP_AUTHOR

Author name for LICENSE

Xavier Collantes

See more under Development section for CI/CD, formatting, tests, logging, and setup for pre-commit hooks.

Related MCP server: My MCP Server

Installation

Install MY_MCP_NAME

MY_MCP_NAME requires no additional dependencies to be installed.

TODO: Add any additional installation instructions for your MCP server. For example, many MCPs may use the CLI tool.

Download the latest release for your operating system from the Releases page.

Operating System

Binary

Linux

MY_MCP_PACKAGE_NAME-linux

Windows

MY_MCP_PACKAGE_NAME-windows.exe

macOS (Apple Silicon)

MY_MCP_PACKAGE_NAME-macos-apple-silicon-arm64

macOS (Intel)

MY_MCP_PACKAGE_NAME-macos-x64

Linux

# Download the binary.
curl -L -o MY_MCP_PACKAGE_NAME-linux MY_MCP_REPO_URL/releases/latest/download/MY_MCP_PACKAGE_NAME-linux

# Make it executable.
chmod +x MY_MCP_PACKAGE_NAME-linux

# Move to a directory in your PATH (optional).
sudo mv MY_MCP_PACKAGE_NAME-linux /usr/local/bin/

Add to your LLM client configuration:

NOTE: Make sure to replace /usr/local/bin/MY_MCP_PACKAGE_NAME-linux with the path to the binary on your machine if you moved it to a different location.

{
  "mcpServers": {
    "MY_MCP_SERVER_KEY": {
      "command": "/usr/local/bin/MY_MCP_PACKAGE_NAME-linux"
    }
  }
}

macOS

# For Apple Silicon (M1/M2/M3).
curl -L -o MY_MCP_PACKAGE_NAME MY_MCP_REPO_URL/releases/latest/download/MY_MCP_PACKAGE_NAME-macos-apple-silicon-arm64

# For Intel Macs.
curl -L -o MY_MCP_PACKAGE_NAME MY_MCP_REPO_URL/releases/latest/download/MY_MCP_PACKAGE_NAME-macos-x64

# Make it executable.
chmod +x MY_MCP_PACKAGE_NAME

# Move to a directory in your PATH (optional).
sudo mv MY_MCP_PACKAGE_NAME /usr/local/bin/

Note: macOS may block the binary on first run. If you see a security warning, go to System Settings > Privacy & Security and click Allow Anyway, or run:

xattr -d com.apple.quarantine /usr/local/bin/MY_MCP_PACKAGE_NAME

Add to your LLM client configuration:

NOTE: Make sure to replace /usr/local/bin/MY_MCP_PACKAGE_NAME with the path to the binary on your machine if you moved it to a different location.

{
  "mcpServers": {
    "MY_MCP_SERVER_KEY": {
      "command": "/usr/local/bin/MY_MCP_PACKAGE_NAME"
    }
  }
}

Windows

  1. Download MY_MCP_PACKAGE_NAME-windows.exe from the Releases page.

  2. Move the executable to a convenient location (e.g., C:\Program Files\MY_MCP_PACKAGE_NAME\).

Add to your LLM client configuration:

{
  "mcpServers": {
    "MY_MCP_SERVER_KEY": {
      "command": "C:\\Program Files\\MY_MCP_PACKAGE_NAME\\MY_MCP_PACKAGE_NAME-windows.exe"
    }
  }
}

NOTE: Make sure to replace C:\\Program Files\\MY_MCP_PACKAGE_NAME\\MY_MCP_PACKAGE_NAME-windows.exe with the path to the binary on your machine if you moved it to a different location.

MCP Server: Option 2: Development setup with uv

Get repo:

git clone MY_MCP_REPO_URL.git
cd MY_MCP_PACKAGE_NAME

Add MCP server to your choice of LLM client:

NOTE: You will need to look up for your specific client on how to add MCPs.

Usually the JSON file for the LLM client will look like this:

{
  "mcpServers": {
    "MY_MCP_SERVER_KEY": {
      "command": "uv",
      "args": ["--directory", "/ABSOLUTE/PATH/TO/REPO/ROOT", "run", "python", "-m", "src.main"]
    }
  }
}

This will tell your LLM client application that there's a tool that can be called by calling uv --directory /ABSOLUTE/PATH/TO/REPO run python -m src.main.

Install UV: https://docs.astral.sh/uv/getting-started/installation/

MCP Server: Option 3: Install globally with pipx

# Install pipx if you haven't already.
brew install pipx
pipx ensurepath

# Clone and install the MCP server.
git clone MY_MCP_REPO_URL.git
cd MY_MCP_PACKAGE_NAME
pipx install -e .

How it works

  1. You enter some questions or prompt to a LLM Client such as the Claude Desktop, Cursor, Windsurf, or ChatGPT.

  2. The client sends your question to the LLM model (Sonnet, Grok, ChatGPT)

  3. LLM analyzes the available tools and decides which one(s) to use

    • The LLM you're using will have a context of the tools and what each tool is meant for in human language.

    • Alternatively without MCPs, you could include in the prompt the endpoints and a description on each endpoint for the LLM to "call on". Then you could copy and paste the text commands into the terminal on your machine.

    • MCPs provide a more deterministic and standardized method on LLM-to-server interactions.

  4. The client executes the chosen tool(s) through the MCP server.

    • The MCP server is either running local on your machine or an endpoint hosting the MCP server remotely.

  5. The results are sent back to LLM.

  6. LLM formulates a natural language response and one or both of the following happen:

    • The response is displayed to you with data from the MCP server

    • Some action is performed using the MCP server

Development

Testing In Cursor/Windsurf

To test the MCP server in Cursor/Windsurf, you can use the MCP client to test the MCP server.

Add this to the MCP client configuration in Cursor/Windsurf:

{
  "mcpServers": {
    "MY_MCP_SERVER_KEY": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/REPO/ROOT",
        "run",
        "python",
        "-m",
        "src.main",
        "--debug"
      ]
    }
  }
}

This will start the MCP server and you can then use the MCP server in Cursor/Windsurf. You may need to restart in the MCP settings to see the changes.

CI/CD

Setup for CI/CD to build and release the MCP server on multiple operating systems and architectures.

  • The .github/workflows/ci.yml file is used to run the tests and linting checks.

  • The .github/workflows/release.yml file is used to build and release the MCP server on multiple operating systems and architectures.

    • Tag the release with the format vX.X.X.

    • The release will be built and released to the Releases page on your GitHub repository.

Formatting

This project uses ruff for linting and formatting. The .pre-commit-config.yaml file is used to run the linting and formatting checks before each commit.

To set up pre-commit hooks:

uv sync
uv run pre-commit install

Once installed, ruff will automatically run when you commit. To run checks manually on all files:

uv run pre-commit run --all-files

NOTE: A developer can skip installing pre-commit hook and formatting checks but the CI/CD workflow will fail if the checks are not passed.

Tests

This project uses pytest for testing. The tests directory is used to store the test files.

To run the tests:

uv run pytest

To run the tests with coverage:

uv run pytest --cov=src

Logging

Do not use print statements for logging. Use the logging module instead. Writing to stdout will corrupt the JSON-RPC messages and break your server.

Pre-commit

This project uses pre-commit to run ruff linting and formatting checks, and pytest tests before each commit.

To set up pre-commit hooks:

uv sync
uv run pre-commit install

Once installed, ruff and pytest will automatically run when you commit. To run checks manually on all files:

uv run pre-commit run --all-files

Docstrings / Tool decorator parameters

MCP.tools decorator parameters are especially important as this is the human readable text that the LLM has context of. This will be treated as part of the prompt when fed to the LLM and this will decide when to use each tool.

Architecture

MCP follows a client-server architecture where an MCP host (an AI application like Cursor or ChatGPT desktop) establishes connections to one or more MCP servers. The MCP host accomplishes this by creating one MCP client for each MCP server. Each MCP client maintains a dedicated connection with its corresponding MCP server.

https://modelcontextprotocol.io/docs/learn/architecture

Pitfalls / Troubleshooting

Edit the jira-cli config file

On MacOS:

/Users/<your-username>/.config/.jira/.config.yml

404 error when using jira init

If you get a 404 error when using jira init, you may need to edit the jira-cli config file to point to the correct Jira instance. There are only 3 possible values for the auth type so try each one. basic, password, or bearer.

Environment Variables

Make sure to set any required environment variables. Copy env.example to .env and fill in the values:

cp env.example .env

Server Not Starting

If the MCP server is not starting, check:

  1. You have Python 3.12+ installed

  2. All dependencies are installed (uv sync)

  3. Environment variables are set correctly

Available Tools

3 tools
get_alertsGet active weather alerts for a U.S. state.A

Retrieves all currently active weather alerts, warnings, and advisories issued by the National Weather Service for the specified state. This includes severe weather warnings, flood advisories, winter weather alerts, and more.

ParametersJSON Schema
NameRequiredDescriptionDefault
stateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the source (National Weather Service) and types of alerts included, but does not cover important aspects such as rate limits, authentication needs, data freshness, or error handling, leaving significant gaps for a tool that fetches real-time data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose in the first sentence, followed by additional context in the second sentence. Both sentences are efficient and contribute meaning, with no redundant or unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (1 parameter) and the presence of an output schema, the description is reasonably complete. It covers the purpose and scope adequately, though it lacks behavioral details like rate limits or error handling, which are somewhat mitigated by the output schema handling return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the schema provides no parameter details. The description adds value by specifying that the 'state' parameter refers to a U.S. state, but it does not elaborate on format (e.g., abbreviations vs. full names) or constraints, only partially compensating for the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('retrieves'), resource ('active weather alerts, warnings, and advisories'), and scope ('for the specified state'), distinguishing it from sibling tools like get_forecast and get_weather by focusing on alerts rather than forecasts or general weather data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving active weather alerts in a U.S. state, but it does not explicitly state when to use this tool versus alternatives like get_forecast or get_weather, nor does it provide exclusions or prerequisites for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_forecastGet detailed weather forecast for a specific location.A

Retrieves a multi-period weather forecast from the National Weather Service for the specified coordinates. The forecast includes temperature, wind conditions, and detailed descriptions for the next 5 forecast periods (typically covering the next 2-3 days).

ParametersJSON Schema
NameRequiredDescriptionDefault
latitudeYes
longitudeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the data source (National Weather Service), forecast duration (next 5 periods covering 2-3 days), and included elements (temperature, wind conditions, descriptions). However, it doesn't mention rate limits, authentication needs, error conditions, or response format details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences that are front-loaded with the core purpose and efficiently detail scope and content. Every phrase adds value without redundancy or unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 required parameters, no annotations, but with output schema), the description provides good coverage of purpose, data source, and forecast content. The existence of an output schema reduces the need to explain return values, but more behavioral context (like rate limits) would enhance completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It specifies that parameters are 'coordinates' and implies they're used for location-based forecasting, adding meaning beyond the bare schema. However, it doesn't clarify coordinate format (e.g., decimal degrees) or range constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('retrieves'), resource ('multi-period weather forecast from the National Weather Service'), and scope ('for the specified coordinates'). It distinguishes from potential siblings by specifying it provides a detailed forecast rather than alerts or current weather.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by specifying 'for the specified coordinates' and mentioning 'detailed forecast,' but doesn't explicitly state when to use this tool versus the 'get_alerts' or 'get_weather' siblings. No explicit alternatives or exclusions are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_weatherGet weather forecast data for a location.B

Retrieves weather forecast information from the National annotations Weather Service API for the specified location. The location should be in the format of latitude,longitude (e.g., '47.7623,-122.2054').

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the data source ('National Weather Service API') but doesn't describe other behavioral traits such as rate limits, authentication requirements, error handling, or what specific forecast data is returned. The description is insufficient for a tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured in two sentences: one stating the tool's purpose and source, and another specifying the parameter format with an example. Every sentence adds value with no wasted words, making it appropriately concise and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (1 parameter, no annotations, but with an output schema), the description is partially complete. It explains the parameter format but lacks behavioral context and usage guidelines. The presence of an output schema reduces the need to describe return values, but other gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, but the description compensates by explaining the 'location' parameter's format: 'latitude,longitude (e.g., '47.7623,-122.2054')'. This adds meaningful semantics beyond the bare schema, though it doesn't cover all potential parameter nuances (e.g., coordinate ranges).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Retrieves weather forecast information from the National Weather Service API for the specified location.' It specifies the verb ('retrieves'), resource ('weather forecast information'), and source ('National Weather Service API'), but doesn't explicitly differentiate it from sibling tools like 'get_alerts' or 'get_forecast'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'get_alerts' or 'get_forecast'. It only states what the tool does without indicating appropriate contexts, exclusions, or comparisons to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedget_alerts
    • First observedget_forecast
    • First observedget_weather

TDQS

B3.4/5.0

Scored across 3 tools

Disambiguation2/5

The tools 'get_forecast' and 'get_weather' have significant overlap in purpose, as both retrieve weather forecast data from the National Weather Service for a location. The descriptions are similar, with 'get_forecast' specifying multi-period details and 'get_weather' being more general, which could cause confusion for an agent trying to select the appropriate tool. 'get_alerts' is distinct, focusing on active warnings rather than forecasts.

Naming Consistency5/5

All tool names follow a consistent 'verb_noun' pattern using snake_case: 'get_alerts', 'get_forecast', and 'get_weather'. There are no deviations in naming conventions, making the set predictable and easy to parse for an agent.

Tool Count3/5

With 3 tools, the count is borderline for a weather service server. It feels thin, as it lacks operations like updating or managing alerts, or providing historical data, which might be expected for a more comprehensive weather API. However, it covers basic retrieval needs, so it's not severely mismatched.

Completeness2/5

Inferring the domain as weather data access, there are significant gaps in the tool surface. The server only provides retrieval operations (get_alerts, get_forecast, get_weather) with no create, update, or delete capabilities, and it lacks tools for other common weather functions like radar data, historical trends, or location-based searches beyond coordinates. This incompleteness could lead to agent failures when more advanced operations are needed.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A template repository for building Model Context Protocol (MCP) servers that enables developers to create interactive AI agents with real-time bidirectional communication capabilities through WebSocket and SSE endpoints.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Python template for building Model Context Protocol (MCP) servers that expose tools via JSON-RPC, enabling secure and scalable context and tool invocation for language models.
    MIT
  • F
    license
    B
    quality
    D
    maintenance
    A basic starter project for building Model Context Protocol (MCP) servers that enables standardized interactions between AI systems and various data sources through secure, controlled tool implementations.
    2
    -
  • F
    license
    C
    quality
    D
    maintenance
    A starter template for building custom MCP (Model Context Protocol) servers that can integrate with Claude, Cursor, or other MCP-compatible AI assistants. Provides a clean foundation with TypeScript support, example implementations, and installation scripts for quickly creating custom tools, resources, and prompts.
    2
    5 npm
    -