Skip to main content
Glama

MCP Sentiment Analysis Server

MCP Testbed

This project demonstrates sentiment analysis using the Model Context Protocol (MCP) and is based on the Hugging Face MCP Course. Instead of using the gradio library in the HuggingFace course, this project utilizes the fastmcp library to implement an MCP server and client.

Main Components

Architecture Diagram

+-------------------+ +-------------------+ | | | | | mcp_client_stdio |<----------------->| | | | stdio | | +-------------------+ | | | | +-------------------+ | | | |<----------------->| | | mcp_client_sse |-----/sse--------->| MCP Server | | | | (app_fastmcp.py) | +-------------------+ | | | | +-------------------+ | | | |<----------------->| | | mcp_client_stream-|----/mcp---------->| | | able.py | | | +-------------------+ +-------------------+

Each client module communicates with the MCP server using a different transport protocol:

  • mcp_client_stdio.py uses stdio
  • mcp_client_sse.py uses SSE (Server-Sent Events) at /sse
  • mcp_client_streamable.py uses streamable-http at /mcp

Server

  • mcp-sentiment/app_fastmcp.py
    Implements the MCP server using FastMCP. Exposes a sentiment_analysis tool that uses TextBlob to analyze the sentiment of input text and returns polarity, subjectivity, and an overall assessment as JSON.

Clients

  • mcp-sentiment/mcp_client_stdio.py
    MCP client using stdio transport. Connects to the server via subprocess, lists available tools, and sends text for sentiment analysis. Uses argparse for CLI.
  • mcp-sentiment/mcp_client_sse.py
    MCP client using Server-Sent Events (SSE) transport. Connects to the server via HTTP SSE endpoint, lists tools, and sends text for analysis. Uses argparse for CLI.
  • mcp-sentiment/mcp_client_streamable.py
    MCP client using streamable-http transport. Connects to the server via HTTP with bidirectional streaming, lists tools, and sends text for analysis. Uses argparse for CLI.

Tests

  • tests/test_sentiment_analysis.py
    Unit tests for the sentiment analysis tool, checking various input cases and error handling.
  • tests/test_client_stdio.py
    Tests for the stdio client, including unit tests for request handling and integration tests for end-to-end sentiment analysis.
  • tests/test_client_sse.py
    Integration tests for the SSE client, including server process management and sentiment analysis checks.
  • tests/test_client_streamable.py
    Integration tests for the streamable-http client, including server process management and sentiment analysis checks.

Directory Structure

mcp_testlab/ ├── mcp-sentiment/ │ ├── app_fastmcp.py # MCP server exposing sentiment_analysis tool │ ├── mcp_client_stdio.py # MCP client (stdio transport) │ ├── mcp_client_sse.py # MCP client (SSE transport) │ └── mcp_client_streamable.py # MCP client (streamable-http transport) ├── tests/ │ ├── test_sentiment_analysis.py # Unit tests for sentiment_analysis tool │ ├── test_client_stdio.py # Tests for stdio client │ ├── test_client_sse.py # Tests for SSE client │ └── test_client_streamable.py # Tests for streamable-http client ├── requirements.txt # Python dependencies ├── README.md # Project documentation and usage ├── LICENSE # License file ├── .gitignore # Git ignore rules └── .gitattributes # Git LFS attributes

How It Works

The application uses Model Context Protocol (MCP) to facilitate communication between a client and a sentiment analysis server. When you run the client with a text string, it:

  1. Connects to the server script (app_fastmcp.py) or sse/streamable-http endpoint
  2. Sends your text for sentiment analysis
  3. Returns the sentiment result (positive, negative, or neutral)

Server (app_fastmcp.py)

The app_fastmcp.py file implements an MCP server using FastMCP that:

  • Exposes a sentiment analysis tool via the Model Context Protocol
  • Uses TextBlob library to analyze sentiment of provided text
  • Returns JSON results with:
    • Polarity score (-1 to 1, negative to positive)
    • Subjectivity score (0 to 1, objective to subjective)
    • Overall assessment (positive, negative, or neutral)
  • Supports stdio or sse or streamable-http transport for communication with clients

Client (mcp_client_stdio.py)

The mcp_client_stdio.py file implements an MCP client that:

  • Uses the argparse library for command-line argument handling
  • Accepts text input as a required positional argument
  • Accepts an optional --server parameter to specify the server script path
  • Accepts an optional --verbose flag to display detailed tool information
  • Establishes a connection to the MCP server using stdio transport
  • Lists available tools on the connected server
  • Sends the input text to the sentiment_analysis tool
  • Displays formatted sentiment results showing polarity, subjectivity, and assessment
  • Properly manages resources with async context managers and AsyncExitStack

Client (mcp_client_sse.py)

The mcp_client_sse.py file implements an MCP client that:

  • Uses the argparse library for command-line argument handling
  • Accepts text input as a required positional argument
  • Accepts an optional --url parameter to specify the server endpoint (default: http://localhost:8000/sse)
  • Accepts an optional --verbose flag to display detailed tool information
  • Establishes a connection to the MCP server using SSE transport
  • Lists available tools on the connected server
  • Sends the input text to the sentiment_analysis tool
  • Displays formatted sentiment results showing polarity, subjectivity, and assessment
  • Properly manages resources with async context managers and AsyncExitStack

Client (mcp_client_streamable.py)

The mcp_client_streamable.py file implements an MCP client that:

  • Uses the argparse library for command-line argument handling
  • Accepts text input as a required positional argument
  • Accepts an optional --url parameter to specify the server endpoint (default: http://localhost:8000/mcp)
  • Accepts an optional --verbose flag to display detailed tool information
  • Establishes a connection to the MCP server using streamable-http transport
  • Displays the session ID when available
  • Lists available tools on the connected server
  • Sends the input text to the sentiment_analysis tool
  • Displays formatted sentiment results showing polarity, subjectivity, and assessment
  • Properly manages resources with async context managers and AsyncExitStack

Example Usage with stdio Transport

Command-line Arguments

((venv) ) Mac:jim mcp_testlab[529]$ python mcp-sentiment/mcp_client_stdio.py --help usage: mcp_client_stdio.py [-h] [--server SERVER] [--verbose] text MCP Client for sentiment analysis using stdio transport positional arguments: text Text to analyze for sentiment options: -h, --help show this help message and exit --server SERVER Path to the MCP server script (default: mcp-sentiment/app_fastmcp.py) --verbose, -v Display detailed information about available tools **Client** ```bash ((venv) ) Mac:jim mcp_testlab[512]$ python mcp-sentiment/mcp_client_stdio.py "i love mcp" Connected to MCP server at mcp-sentiment/app_fastmcp.py Listing available tools... [07/29/25 13:45:16] INFO Processing request of type ListToolsRequest server.py:619 Connected to MCP server. Listing available tools... INFO Processing request of type ListToolsRequest server.py:619 Available tools: ['sentiment_analysis'] Analyzing sentiment for: 'i love mcp' INFO Processing request of type CallToolRequest server.py:619 {'polarity': 0.5, 'subjectivity': 0.6, 'assessment': 'positive'} Sentiment Analysis Result: Polarity: 0.5 (-1=negative, 1=positive) Subjectivity: 0.6 (0=objective, 1=subjective) Assessment: positive Sentiment Analysis Result: (0.5, 0.6, 'positive') ((venv) ) Mac:jim mcp_testlab[513]$ python mcp-sentiment/mcp_client_stdio.py "i hate java" Connected to MCP server at mcp-sentiment/app_fastmcp.py Listing available tools... [07/29/25 13:45:38] INFO Processing request of type ListToolsRequest server.py:619 Connected to MCP server. Listing available tools... INFO Processing request of type ListToolsRequest server.py:619 Available tools: ['sentiment_analysis'] Analyzing sentiment for: 'i hate java' INFO Processing request of type CallToolRequest server.py:619 {'polarity': -0.8, 'subjectivity': 0.9, 'assessment': 'negative'} Sentiment Analysis Result: Polarity: -0.8 (-1=negative, 1=positive) Subjectivity: 0.9 (0=objective, 1=subjective) Assessment: negative Sentiment Analysis Result: (-0.8, 0.9, 'negative') ((venv) ) Mac:jim mcp_testlab[514]$ python mcp-sentiment/mcp_client_stdio.py "i really like python" -v Connected to MCP server at mcp-sentiment/app_fastmcp.py Listing available tools... [07/29/25 13:46:35] INFO Processing request of type ListToolsRequest server.py:619 Connected to MCP server. Listing available tools... INFO Processing request of type ListToolsRequest server.py:619 sentiment_analysis: Description: Analyze the sentiment of the given text. Args: text (str): The text to analyze Returns: str: A JSON string containing polarity, subjectivity, and assessment Annotations: None Inputschema: {'properties': {'text': {'title': 'Text', 'type': 'string'}}, 'required': ['text'], 'title': 'sentiment_analysisArguments', 'type': 'object'} Meta: None /Users/jim/Desktop/modelcontextprotocol/mcp_testlab/mcp-sentiment/mcp_client_stdio.py:154: PydanticDeprecatedSince211: Accessing the 'model_computed_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0. value = getattr(tool, attr) Model_computed_fields: {} Model_config: {'extra': 'allow'} Model_extra: {} /Users/jim/Desktop/modelcontextprotocol/mcp_testlab/mcp-sentiment/mcp_client_stdio.py:154: PydanticDeprecatedSince211: Accessing the 'model_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0. value = getattr(tool, attr) Model_fields: {'name': FieldInfo(annotation=str, required=True), 'title': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'description': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'inputSchema': FieldInfo(annotation=dict[str, Any], required=True), 'outputSchema': FieldInfo(annotation=Union[dict[str, Any], NoneType], required=False, default=None), 'annotations': FieldInfo(annotation=Union[ToolAnnotations, NoneType], required=False, default=None), 'meta': FieldInfo(annotation=Union[dict[str, Any], NoneType], required=False, default=None, alias='_meta', alias_priority=2)} Model_fields_set: {'description', 'inputSchema', 'outputSchema', 'name'} Outputschema: {'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': 'sentiment_analysisOutput', 'type': 'object'} Title: None Analyzing sentiment for: 'i really like python' INFO Processing request of type CallToolRequest server.py:619 {'polarity': 0.2, 'subjectivity': 0.2, 'assessment': 'positive'} Sentiment Analysis Result: Polarity: 0.2 (-1=negative, 1=positive) Subjectivity: 0.2 (0=objective, 1=subjective) Assessment: positive Sentiment Analysis Result: (0.2, 0.2, 'positive')

Example Usage with sse Transport

Command-line Arguments

((venv) ) Mac:jim mcp_testlab[532]$ python mcp-sentiment/mcp_client_sse.py --help usage: mcp_client_sse.py [-h] [--url URL] [--verbose] text_to_test MCP SSE Client for Sentiment Analysis positional arguments: text_to_test Text to analyze for sentiment options: -h, --help show this help message and exit --url URL URL of the SSE server endpoint (default: http://localhost:8000/sse) --verbose, -v Display detailed information about available tools

Client

python mcp-sentiment/mcp_client_sse.py "i really like python" Connecting to MCP server at http://localhost:8000/sse... Connected to MCP server. Listing available tools... Available tools: ['sentiment_analysis'] Analyzing sentiment for: 'i really like python' Sentiment Analysis Result: Polarity: 0.2 (-1=negative, 1=positive) Subjectivity: 0.2 (0=objective, 1=subjective) Assessment: positive

SSE Server

((venv) ) Mac:jim mcp_testlab[506]$ python mcp-sentiment/app_fastmcp.py --transport sse INFO: Started server process [8908] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: 127.0.0.1:49538 - "GET /sse HTTP/1.1" 200 OK INFO: 127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted [07/29/25 06:13:08] INFO Processing request of type ListToolsRequest server.py:619 INFO: 127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted INFO Processing request of type CallToolRequest server.py:619 INFO: 127.0.0.1:49543 - "GET /sse HTTP/1.1" 200 OK INFO: 127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted [07/29/25 06:13:46] INFO Processing request of type ListToolsRequest server.py:619 INFO: 127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted INFO Processing request of type CallToolRequest server.py:619 INFO: 127.0.0.1:49547 - "GET /sse HTTP/1.1" 200 OK INFO: 127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted INFO: 127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted [07/29/25 06:14:17] INFO Processing request of type ListToolsRequest server.py:619 INFO: 127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted INFO Processing request of type CallToolRequest server.py:619 INFO: Shutting down INFO: Waiting for application shutdown. INFO: Application shutdown complete. INFO: Finished server process [8908] Terminated: 15 python mcp-sentiment/app_fastmcp.py --transport sse

Example Usage with streamable-http Transport

Command-line Arguments

((venv) ) Mac:jim mcp_testlab[533]$ python mcp-sentiment/mcp_client_streamable.py --help usage: mcp_client_streamable.py [-h] [--url URL] [--verbose] text_to_test MCP Streamable Client for Sentiment Analysis positional arguments: text_to_test Text to analyze for sentiment options: -h, --help show this help message and exit --url URL URL of the streamable-http server endpoint (default: http://localhost:8000/mcp) --verbose, -v Display detailed information about available tools

Client

# Using the default URL ((venv) ) Mac:jim mcp_testlab[517]$ python mcp-sentiment/mcp_client_streamable.py "MCP is the best" Connecting to MCP server at http://localhost:8000/mcp... Session ID: fdc3c721f04441a1ae4c22cadebc9226 Connected to MCP server. Listing available tools... Available tools: ['sentiment_analysis'] Analyzing sentiment for: 'MCP is the best' Sentiment Analysis Result: Polarity: 1.0 (-1=negative, 1=positive) Subjectivity: 0.3 (0=objective, 1=subjective) Assessment: positive

Streamable-HTTP Server

((venv) ) Mac:jim mcp_testlab[507]$ python mcp-sentiment/app_fastmcp.py --transport streamable-http INFO: Started server process [2701] INFO: Waiting for application startup. [07/28/25 22:48:20] INFO StreamableHTTP session manager started streamable_http_manager.py:112 INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: 127.0.0.1:54049 - "POST /mcp HTTP/1.1" 307 Temporary Redirect [07/28/25 22:48:29] INFO Created new transport with session ID: 6a17c2206e6e478b830bd0da73771b8b streamable_http_manager.py:229 INFO: 127.0.0.1:54049 - "POST /mcp/ HTTP/1.1" 200 OK INFO: 127.0.0.1:54052 - "POST /mcp HTTP/1.1" 307 Temporary Redirect INFO: 127.0.0.1:54053 - "GET /mcp HTTP/1.1" 307 Temporary Redirect INFO: 127.0.0.1:54052 - "POST /mcp/ HTTP/1.1" 202 Accepted INFO: 127.0.0.1:54053 - "GET /mcp/ HTTP/1.1" 200 OK INFO: 127.0.0.1:54055 - "POST /mcp HTTP/1.1" 307 Temporary Redirect INFO: 127.0.0.1:54055 - "POST /mcp/ HTTP/1.1" 200 OK INFO Processing request of type ListToolsRequest server.py:619 INFO: 127.0.0.1:54057 - "POST /mcp HTTP/1.1" 307 Temporary Redirect INFO: 127.0.0.1:54057 - "POST /mcp/ HTTP/1.1" 200 OK INFO Processing request of type CallToolRequest server.py:619 INFO: 127.0.0.1:54059 - "DELETE /mcp HTTP/1.1" 307 Temporary Redirect INFO Terminating session: 6a17c2206e6e478b830bd0da73771b8b streamable_http.py:633 INFO: 127.0.0.1:54059 - "DELETE /mcp/ HTTP/1.1" 200 OK INFO: Shutting down INFO: Waiting for application shutdown. [07/28/25 22:48:42] INFO StreamableHTTP session manager shutting down streamable_http_manager.py:116 INFO: Application shutdown complete. INFO: Finished server process [2701] Terminated: 15 python mcp-sentiment/app_fastmcp.py --transport streamable-http

Unit Tests

Unit tests are provided to ensure the functionality of the MCP server and client. To run the tests, use the following command:

$ pytest -v tests

Sample output:

MCP Inspector

The MCP Inspector is a tool for exploring and interacting with Model Context Protocol (MCP) servers. It provides a user-friendly interface for:

  • Discovering available tools and their capabilities
  • Sending requests to tools and viewing responses
  • Debugging and testing MCP interactions

Running MCP Inspector with stdio Transport

To run the MCP Inspector for server using stdio transport, use the following command:

mcp dev mcp-sentiment/app_fastmcp.py

Sample output will show the available tools and their descriptions, allowing you to interact with the sentiment analysis tool.

MCP Inspector Listing Tools

MCP Inspector Testing Sentiment Analysis

Running MCP Inspector with sse Transport

Starting the sse Server for testing

python mcp-sentiment/app_fastmcp.py --transport sse

To run the MCP Inspector for server using sse or streamable-http transport, use the following command:

npx @modelcontextprotocol/inspector

Connecting to the MCP Inspector

Open the browser to access the MCP Inspector interface, change from http to https if necessary. Once the MCP Inspector is running, configure "Transport Type" for sse or streamable-http and set the server URL to point to your running MCP server (e.g., http://localhost:8000/sse or http://localhost:8000/mcp) and click "Connect" button.

sse Server URL: http://localhost:8000/sse

Starting the streamable-http Server for testing

python mcp-sentiment/app_fastmcp.py --transport streamable-http

streamable-http Server URL: http://localhost:8000/mcp

Requirements

  • Python 3.12+
  • Dependencies: pip install -r requirements.txt
  • Required NLP libraries for sentiment analysis
  • Required version of node > v20.x to run MCP Inspector (see GH Issue on unexpected token)
-
security - not tested
A
license - permissive license
-
quality - not tested

This server implements the Model Context Protocol to provide sentiment analysis of text, returning polarity, subjectivity, and overall assessment (positive, negative, or neutral).

  1. Main Components
    1. Architecture Diagram
    2. Server
    3. Clients
    4. Tests
    5. Directory Structure
  2. How It Works
    1. Server (app_fastmcp.py)
    2. Client (mcp_client_stdio.py)
    3. Client (mcp_client_sse.py)
    4. Client (mcp_client_streamable.py)
    5. Example Usage with stdio Transport
  3. Using the default URL
    1. Requirements

Related MCP Servers

  • A
    security
    A
    license
    A
    quality
    A Model Context Protocol server that provides tools for analyzing text documents, including counting words and characters. This server helps LLMs perform text analysis tasks by exposing simple document statistics functionality.
    Last updated -
    1
    441
    10
    JavaScript
    Apache 2.0
  • A
    security
    A
    license
    A
    quality
    This server implements the Model Context Protocol to facilitate meaningful interaction and understanding development between humans and AI through structured tools and progressive interaction patterns.
    Last updated -
    13
    51
    TypeScript
    MIT License
  • -
    security
    A
    license
    -
    quality
    Provides advanced analytical, research, and natural language processing capabilities through a Model Context Protocol server, enabling dataset analysis, decision analysis, and enhanced NLP features like entity recognition and fact extraction.
    Last updated -
    2
    TypeScript
    MIT License
    • Linux
    • Apple
  • -
    security
    A
    license
    -
    quality
    A Model Context Protocol server that enables users to query, retrieve details, and manage reviews/ratings for NetMind AI servers through simple endpoints.
    Last updated -
    Python
    MIT License

View all related MCP servers

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/jimthompson5802/mcp_testlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server