Skip to main content
Glama
sh-aidev

MCP Server Template

by sh-aidev

Autoplot AI MCP

python mcp uv license

An MCP (Model Context Protocol) server, managed with uv, that lets an MCP client discover public datasets (currently World Bank Open Data) by keyword — the first step of an automated data-fetching and visualization pipeline.

šŸ“Œ Features

  • uv for dependency management

  • TOML + Pydantic based config, with API sources defined declaratively in configs/api_config.toml

  • get_datasets_list tool — keyword search over a configured data source's datasets

  • Multi-source ready: add new APIs by editing config, no code changes

  • Centralized logging (loguru)

  • Custom exception handling

  • Standalone stdio client for manual testing

Related MCP server: DDG MCP1234

šŸ“ Project Structure

The directory structure of the project looks like this:

ā”œā”€ā”€ LICENSE
ā”œā”€ā”€ Makefile
ā”œā”€ā”€ README.md
ā”œā”€ā”€ client.py
ā”œā”€ā”€ main.py
ā”œā”€ā”€ configs
│   ā”œā”€ā”€ config.toml
│   └── api_config.toml
ā”œā”€ā”€ outputs
ā”œā”€ā”€ pyproject.toml
└── src
    ā”œā”€ā”€ __init__.py
    ā”œā”€ā”€ app.py
    ā”œā”€ā”€ server
    │   ā”œā”€ā”€ __init__.py
    │   └── server.py
    ā”œā”€ā”€ tools
    │   ā”œā”€ā”€ __init__.py
    │   ā”œā”€ā”€ api_sources.py
    │   └── dataset_discovery.py
    └── utils
        ā”œā”€ā”€ __init__.py
        ā”œā”€ā”€ config.py
        ā”œā”€ā”€ exceptions.py
        ā”œā”€ā”€ logger.py
        └── models.py

šŸ—ļø Architecture

main.py boots an App, which loads config and hands it to a Server that wraps FastMCP. Tool implementations live under src/tools/ (one module per tool, or tool family), each exposing a register(mcp, config) function; src/tools/__init__.py calls all of them so Server stays a thin wrapper. MCP clients (like client.py or the MCP Inspector) talk to the server over stdio; the tools in turn call out to whichever external data API is configured (e.g. the World Bank REST API).

flowchart LR
    subgraph Client
        C["client.py<br/>(MCP client)"]
    end

    subgraph "Autoplot AI MCP Server"
        M["main.py"] --> A["App"]
        A --> CFG["Config"]
        A --> S["Server<br/>(FastMCP)"]
        S --> R["tools.register_all"]
        R -->|registers| T["dataset_discovery.get_datasets_list"]
        T -->|resolves source| API["tools.api_sources.get_api_source"]
    end

    subgraph "Config Files"
        CT["config.toml<br/>(logger, server)"]
        AT["api_config.toml<br/>(API sources)"]
    end

    subgraph "External Data Sources"
        WB["World Bank Open Data API"]
    end

    CFG --> CT
    CFG --> AT
    C <-->|stdio / MCP protocol| S
    T -->|HTTP GET| WB

šŸ” Sequence: get_datasets_list

sequenceDiagram
    participant U as User
    participant Cl as client.py
    participant Sv as Server (FastMCP)
    participant WB as World Bank API

    U->>Cl: Enter search text
    Cl->>Cl: Split input into keywords
    Cl->>Sv: call_tool("get_datasets_list", {keywords, source, limit})
    loop each result page
        Sv->>WB: GET discovery_endpoint (page, per_page)
        WB-->>Sv: indicators (name, sourceNote, id)
        Sv->>Sv: match keywords against name / description
    end
    Sv->>Sv: rank name-matches above description-matches,<br/>shorter names first
    Sv-->>Cl: top `limit` matching datasets
    Cl-->>U: print dataset id / name / description

šŸš€ Getting Started

Step 1: Install dependencies

uv sync

Step 2: Run the server

uv run python main.py
# or
make run

The server communicates over stdio and is meant to be launched by an MCP client (see Step 3), not run standalone in a terminal.

Step 3: Try it with the bundled client

uv run python client.py
# or
make client

This spawns main.py as a subprocess over stdio, lists the available tools, then prompts you for search text (e.g. population growth), splits it into keywords, and calls get_datasets_list to print matching datasets.

Step 4 (optional): Inspect it with the MCP Inspector

uv run mcp dev main.py:mcp

Opens a browser UI to browse and call the registered tools interactively. main.py exposes a lazily-built mcp attribute for this purpose (see __getattr__ at the bottom of the file) — normal runs via make run / make client don't trigger it.

āš™ļø Configuration

  • configs/config.toml — logger environment (dev / prod) and the MCP server's advertised name.

  • configs/api_config.toml — a list of [[apis]], each describing an external data source: its name, description, discovery_endpoint (lists datasets), data_endpoint (downloads one dataset), response format, and per_page page size. Add a new source by appending another [[apis]] block — no code changes required.

šŸ“œ References

Available Tools

5 tools
addB

Add two integers

ParametersJSON Schema
NameRequiredDescriptionDefault
aYes
bYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden. It only states the basic operation without addressing edge cases (e.g., overflow), return value, or any side effects. The output schema exists but the description adds no behavioral context.

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 extremely concise at 4 words, with no wasted language. It is front-loaded and efficient for its purpose.

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

Completeness5/5

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

For a simple addition tool with an output schema, the description is sufficient. It clearly conveys the core functionality without needing additional context. The tool is low complexity.

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

Parameters2/5

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

Schema description coverage is 0% (no descriptions in the schema) and the description adds no meaning beyond the schema. It says 'two integers' but does not explain the roles of parameters 'a' and 'b' or their order, though addition is commutative.

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 'Add two integers' clearly states the verb (add) and the resource (two integers). It distinguishes from sibling tools like divide, multiply, subtract, and reverse_string by specifying the addition operation.

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?

No guidance on when to use this tool versus alternatives like subtract or multiply. The description provides no context about when addition is appropriate or when to avoid it.

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

divideB

Divide the first integer by the second

ParametersJSON Schema
NameRequiredDescriptionDefault
aYes
bYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations provided, so the description must disclose behavior. It does not specify integer division semantics (floor, truncation, etc.) or error handling for division by zero.

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

Conciseness4/5

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

The description is a single sentence that is front-loaded with the core action. It is appropriately sized for a simple arithmetic tool.

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 simplicity and the presence of an output schema, the description is minimally adequate but lacks behavioral details like integer division specification and error handling.

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

Parameters2/5

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

Schema description coverage is 0%, and the description only says 'first integer' and 'second integer', adding no extra meaning beyond the parameter names. No constraints like non-zero for b are mentioned.

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 specifies the verb 'divide' and the resource 'the first integer by the second'. It is concise and distinguishes the tool from siblings like add, multiply, and subtract.

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?

No guidance on when to use this tool vs alternatives. For example, it does not mention that division by zero is invalid or that integer division may truncate.

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

multiplyB

Multiply two integers

ParametersJSON Schema
NameRequiredDescriptionDefault
aYes
bYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

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

Without annotations, the description provides no details beyond the basic operation, omitting edge cases or error handling.

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

Conciseness4/5

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

The description is remarkably concise and front-loaded, though it could include a brief behavioral note without losing efficiency.

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 simplicity and presence of an output schema, the description is adequate but not exhaustive.

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

Parameters2/5

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

The description adds no meaning beyond the schema; parameter names 'a' and 'b' are clear but no additional context is given.

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 'Multiply two integers' clearly states the action and resource, distinguishing it from sibling tools like 'add' and 'divide'.

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?

No explicit guidance on when to use this tool instead of siblings, but the purpose is implied for multiplication scenarios.

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

reverse_stringA

Reverse a given string

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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

No annotations provided, and the description only says 'Reverse a given string.' It does not disclose any edge cases, performance characteristics, or side effects. For a simple transformation, this is adequate but minimal.

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 a single, clear sentence with no unnecessary words. It is front-loaded and efficient.

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

Completeness5/5

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

Given the tool's simplicity, the description provides enough information. An output schema exists to clarify return values, so the description does not need to cover that.

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 coverage is 0%, and the description adds no parameter details beyond the schema. However, the single parameter 'text' is self-explanatory given the tool's purpose.

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 states the exact operation: reversing a string. It is a specific verb and resource. Sibling tools are all math operations, so it clearly distinguishes itself.

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?

No explicit guidance on when to use this tool versus alternatives. However, the sibling tools are all arithmetic, making the usage context implicitly clear for string reversal.

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

subtractA

Subtract the second integer from the first

ParametersJSON Schema
NameRequiredDescriptionDefault
aYes
bYes

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?

No annotations are provided, so the description carries the full burden. It correctly specifies the order of subtraction (second from first) but does not mention any behavioral traits like error handling, integer overflow, or return type, though the output schema likely covers the return type. The description is adequate for a simple pure function.

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 one sentence with no superfluous words. It is front-loaded and directly conveys the necessary information without waste.

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 simplicity and the presence of an output schema (as indicated by context signals), the description provides sufficient context for an agent to understand the operation. It could optionally mention that it returns an integer, but that is already covered by the output schema.

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, leaving parameters 'a' and 'b' without textual context. The description compensates by clarifying that 'a' is the first integer and 'b' is the second, establishing the order of subtraction. This adds meaningful semantic context beyond the schema.

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 operation: subtract the second integer from the first. The verb 'subtract' and the resource (two integers) are explicit, and it naturally distinguishes the tool from siblings like 'add', 'multiply', and 'divide'.

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?

No explicit when-to-use or when-not-to-use guidance is provided. However, the tool is a basic arithmetic operation, so its usage context is implied. It does not mention alternatives or scenarios where other tools would be better, but the simplicity reduces the need for extensive guidelines.

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. 5 tool updatesv0.1.0
    • First observedadd
    • First observeddivide
    • First observedmultiply
    • First observedreverse_string
    • First observedsubtract

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clear and distinct purpose. The arithmetic tools (add, subtract, multiply, divide) are well-differentiated, and reverse_string operates on an entirely different domain.

Naming Consistency5/5

All tool names follow a consistent pattern: simple, lowercase, with underscores for multi-word names (reverse_string). No mixed styles or confusing abbreviations.

Tool Count5/5

Five tools is a reasonable count for a small utility server. It's neither too few to be useful nor too many to manage.

Completeness3/5

The arithmetic set covers basic operations but misses common ones like modulus or exponentiation. The string domain has only one operation, leaving gaps for typical string manipulations.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A basic MCP server template with example tools for echoing messages and retrieving server information. Built with FastMCP framework and supports both stdio and HTTP transports.
    -
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A basic MCP server template with example tools for echoing messages and retrieving server information. Built with FastMCP framework and supports both stdio and HTTP transports.
    -
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A basic MCP server template with example tools for echoing messages and retrieving server information. Built with FastMCP framework and supports both stdio and HTTP transports.
    -