Skip to main content
Glama
Nishant-IIT

small-mcp

by Nishant-IIT

small-mcp

A minimal FastMCP server in Python that demonstrates all four MCP primitives: tools, resources, resource templates, and prompts — including how to use the context object for logging and progress reporting.

Requirements

  • uv (package manager)

  • Python 3.14+

Related MCP server: MCPServer (FastMCP)

Setup

uv sync

Run

uv run python main.py

The server starts in stdio mode, ready to be connected to any MCP client.

Primitives

Tools

Functions the LLM can call to perform actions.

Tool

Description

add(a, b)

Add two numbers

word_count(text)

Count words, characters, and lines

current_time(timezone)

Return the current UTC time

log_message(message)

Log a message via MCP context (demonstrates progress + logging)

Resources

Static data the LLM can read.

URI

Description

resource://server/info

Basic info about this server

resource://snippets/hello-world

A Python Hello World snippet

Resource Templates

Dynamic resources resolved from a URI pattern.

Template

Description

resource://snippets/{language}/hello

Hello World snippet for python, javascript, go, or rust

Prompts

Reusable prompt templates the LLM can request by name.

Prompt

Args

Description

summarize

text, style

Ask for a summary in a given style

code_review

code, language

Request a code review

explain_concept

concept, audience

Explain a concept to a target audience

Context

The log_message tool shows how to inject ctx: Context into a tool to:

  • Send log messages back to the client via ctx.info()

  • Report progress via ctx.report_progress(progress, total)

Inspect with MCP Inspector

uv run fastmcp dev inspector main.py

Then open the URL printed in the terminal to browse and call tools, read resources, and render prompts interactively.

Connect to Claude Desktop

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "small-mcp": {
      "command": "uv",
      "args": ["run", "--directory", "/Users/nishantbhagat/Study/Projects/small mcp", "python", "main.py"]
    }
  }
}

Project Structure

small mcp/
├── main.py          # MCP server (all primitives in one file)
├── pyproject.toml   # uv project config
└── uv.lock

Available Tools

6 tools
call_toolA

Call a tool by name with the given arguments.

Use this to execute tools discovered via search_tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe name of the tool to call
argumentsNoArguments to pass to the tool

TDQS

A3.5/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 for behavioral disclosure. It merely restates the schema without describing side effects, return values, error conditions, or the fact that calling arbitrary tools may have destructive consequences. This is a significant transparency gap.

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 exactly two sentences, front-loaded with the primary action and followed by a usage hint. Every word earns its place, with no redundancy or fluff.

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?

The tool is simple, but with no output schema and no annotations, the description could have mentioned that the tool returns the called tool's output or that invalid names will error. The core functionality is clear, but some behavioral expectations are missing, so it is minimally viable rather than complete.

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 100%, with both parameters described. The description adds little beyond the schema, repeating 'by name with the given arguments' without explaining how arguments map to the called tool's parameters. Baseline 3 is appropriate.

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 action: 'Call a tool by name with the given arguments,' which specifies the verb and resource. It also differentiates from search_tools by noting the tool is for executing discovered tools, but it does not explicitly distinguish from the sibling executar_lote, so it falls short of a 5.

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

Usage Guidelines4/5

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

The description provides clear usage context: 'Use this to execute tools discovered via search_tools.' This tells the agent when the tool is appropriate, but it does not mention exclusions or alternatives, so it is not a full 5.

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

get_promptA

Get a prompt by name with optional arguments.

Returns the rendered prompt as JSON with a messages array. Arguments should be provided as a dict mapping argument names to values.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe name of the prompt to get
argumentsNoOptional arguments for the prompt

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral transparency burden. It explains the return format (JSON with a messages array) and clarifies how arguments should be structured (dict mapping names to values). It does not cover error cases or side effects, but for a simple get operation this is adequate.

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 two sentences, front-loaded with the primary action ('Get a prompt by name'), followed by concise return-format and argument-format details. Every sentence adds value with no redundancy or filler.

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 has only two parameters, an output schema, and no annotations, the description covers the essential behavioral aspects: what it retrieves, how to pass arguments, and what the return shape looks like. It is sufficiently complete for an agent to invoke the tool correctly without further context.

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 already provides descriptions for both parameters (name and arguments), giving 100% coverage. The description adds extra meaning by specifying that arguments must be a dict mapping argument names to values, which is not fully detailed in the schema. This elevates the score above the baseline.

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 tool fetches a prompt by name, with optional arguments. This distinguishes it from sibling tools like list_prompts (which would enumerate prompts) and call_tool (which invokes tools). The verb-resource pair is specific and unambiguous.

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

Usage Guidelines4/5

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

The description implies when to use this tool: when you know the prompt's name and want its rendered output. It does not explicitly mention alternatives or provide 'when not to use' guidance, but the context is clear enough for an agent to decide appropriately.

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

list_promptsA

List all available prompts.

Returns JSON with prompt metadata including name, description, and optional arguments.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

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

With no annotations provided, the description must carry the full burden of behavioral disclosure. It states that the tool returns JSON metadata, which is useful, but it does not explicitly state that this is a read-only operation with no side effects, nor does it mention any limitations like pagination. For a simple list operation, this is adequate but not rich.

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 two terse sentences: the first delivers the primary action, the second clarifies the return format. Every word earns its place, with no redundancy or irrelevant detail.

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?

For a zero-parameter tool with an existing output schema, the description covers the essential purpose and return type. It is complete, but could be slightly more helpful by explicitly connecting to get_prompt for retrieving specific prompts, which would aid discoverability.

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 tool has zero parameters, so the description does not need to explain parameter meaning. The description adds a small amount of value by mentioning that the output includes 'optional arguments', but per the guideline, 0 params warrants a baseline score of 4.

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 action ('List') and the resource ('all available prompts'), making the purpose unambiguous. It also distinguishes from siblings like list_resources by specifying prompts, and from get_prompt by listing rather than retrieving a specific prompt.

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

Usage Guidelines4/5

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

The description implies when to use the tool: to enumerate all available prompts. It does not explicitly mention alternatives or exclusions, but the context is clear for a list operation with no parameters. A brief note on using it before get_prompt would elevate this to a 5.

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

list_resourcesA
Read-only

List all available resources and resource templates.

Returns JSON with resource metadata. Static resources have a 'uri' field, while templates have a 'uri_template' field with placeholders like {name}.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

The readOnlyHint annotation already indicates the tool is non-destructive. The description adds valuable context beyond this by explaining the output structure (JSON with resource metadata) and the key distinction between static 'uri' fields and templates with 'uri_template' placeholders. This extra detail about the return format and resource types exceeds what the annotation provides, though the read-only behavior itself is not elaborated further.

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 highly concise, consisting of two short sentences. It front-loads the primary action and object ('List all available resources and resource templates') and then provides necessary detail on return format and resource types without any redundant or vague phrasing. Every sentence adds meaningful content.

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 (no parameters, clear output schema present), the description is sufficiently complete. It explains what the tool returns (JSON metadata) and the critical distinction between static and template resources, which is essential for understanding the tool's behavior. The presence of an output schema means the description does not need to enumerate all return fields, and it covers the key context an agent would need to use the tool correctly.

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

Parameters5/5

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

The tool has zero parameters, and the schema coverage is 100% (vacuously). There are no parameter semantics to explain, so the description does not need to add any meaning. The description fully aligns with the input schema, and there is no ambiguity or missing parameter information.

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 action ('List') and the target ('all available resources and resource templates'). It distinguishes between static resources and templates, making the purpose unambiguous even without opening the schema. This is a precise, specific statement of what the tool does.

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 does not explicitly state when to use this tool over siblings like read_resource or legal_list_laws. It implies that this is for discovery (listing all resources), but it does not provide direct guidance on selection criteria. The information about static vs. template resources is helpful but does not constitute explicit usage direction.

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

read_resourceA
Read-only

Read a resource by its URI.

For static resources, provide the exact URI. For templated resources, provide the URI with template parameters filled in.

Returns the resource content as a string. Binary content is base64-encoded.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYesThe URI of the resource to read

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

The readOnlyHint annotation is consistent with the described read-only behavior. The description adds useful details about return content and base64 encoding, going beyond the annotation without contradicting it.

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 compact and well-structured, with no unnecessary words or repetition. It delivers all essential information in two sentences.

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 read operation, the description is complete: it covers input format, output type, and encoding. No further details are needed for correct usage.

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 single parameter 'uri' is described in the schema, but the tool description adds important nuance about static vs. templated URIs, which is not present in the schema. This additional guidance improves parameter understanding.

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?

Clearly states the verb 'Read' and the object 'resource by its URI.' It distinguishes from sibling tools such as list_resources (listing) and legal_* tools (specific legal actions) by focusing on reading a single resource.

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

Usage Guidelines4/5

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

Provides guidance on static vs. templated URIs and explains output encoding. Does not explicitly contrast with alternatives, but the purpose is straightforward and the instructions are sufficient for correct invocation.

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

search_toolsA

Search for tools using natural language.

Returns matching tool definitions ranked by relevance, in the same format as list_tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesNatural language query to search for tools

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/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 burden. It states that it returns matching tool definitions ranked by relevance, which is a behavioral trait. It also mentions the format is same as list_tools, which is useful. However, it doesn't disclose any side effects, rate limits, or other behavioral details. Given the tool is a search operation, this is adequate but not rich.

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 concise, two sentences, and front-loaded with the purpose. Every sentence adds value: the first states what it does, the second clarifies the return format. No 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?

The tool is simple with one parameter and an output schema. The description explains the return format (same as list_tools) and ranking by relevance. Given the simplicity and the presence of an output schema, the description is complete enough. It could mention that it's a read-only operation, but that's not critical.

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 100%, so the schema already documents the single parameter 'query' as a natural language query. The description adds no additional meaning beyond that. Baseline 3 is appropriate since the schema does the heavy lifting.

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: searching for tools using natural language. It specifies the action (search) and the resource (tools), and distinguishes it from siblings like list_tools by mentioning the return format. However, it doesn't explicitly differentiate from other sibling tools like call_tool, but the purpose is clear.

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: when you need to find tools by natural language query. It mentions the return format is same as list_tools, which gives some context. However, it doesn't explicitly state when to use this vs alternatives, nor does it provide exclusions or alternative tool references. The guidance is minimal but not misleading.

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. 6 tool updatesv0.1.0
    • First observedcall_tool
    • First observedget_prompt
    • First observedlist_prompts
    • First observedlist_resources
    • First observedread_resource
    • First observedsearch_tools

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clear, distinct role: search vs call, list vs read, list vs get. There is no overlap in purpose.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (search_tools, call_tool, list_resources, read_resource, list_prompts, get_prompt).

Tool Count5/5

With 6 tools covering three resource types (tools, resources, prompts), the count is well-scoped and appropriate for a small MCP utility server.

Completeness3/5

The server covers tools, resources, and prompts, but misses a list_tools tool, which is a notable gap since search_tools cannot enumerate all tools. This could cause agent failures when trying to discover the full tool surface.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An educational MCP server example built with FastMCP that demonstrates how to expose tools, resources, and prompts to AI clients. Provides a learning foundation for building MCP servers with Python and integrating them with AI applications like IDEs and chatbots.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    A minimal Model Context Protocol server built with FastMCP that provides basic utility tools including user greetings, number addition, and file listing operations. Includes examples of exposing tools, resources, and prompts for MCP-aware clients.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    A basic MCP server implementation using the FastMCP framework that provides utility tools for greetings and mathematical calculations. It is designed to demonstrate tool integration for AI-assisted development workflows like Cline.
    -