Spaces:
Sleeping
Sleeping
Peter Yang
commited on
Commit
·
d884bf1
1
Parent(s):
1e6a195
Move docker-mcp-server contents to root
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +11 -1
- Dockerfile +41 -0
- Makefile +152 -0
- README.md +192 -34
- app.py +275 -0
- demo.py +180 -0
- deploy_to_hf.py +283 -0
- quiz/README.md +0 -1
- quiz/data/unit_1.json +0 -10
- quiz/push_questions.py +0 -31
- quiz/pyproject.toml +0 -12
- quiz/uv.lock +0 -0
- requirements.txt +10 -3
- scripts/translation.py +0 -85
- scripts/vi.py +0 -125
- test_mcp_server.py +194 -0
- units/en/_toctree.yml +0 -54
- units/en/unit0/introduction.mdx +0 -137
- units/en/unit1/architectural-components.mdx +0 -85
- units/en/unit1/capabilities.mdx +0 -243
- units/en/unit1/certificate.mdx +0 -19
- units/en/unit1/communication-protocol.mdx +0 -223
- units/en/unit1/gradio-mcp.mdx +0 -154
- units/en/unit1/introduction.mdx +0 -33
- units/en/unit1/key-concepts.mdx +0 -92
- units/en/unit1/mcp-clients.mdx +0 -357
- units/en/unit1/quiz1.mdx +0 -125
- units/en/unit1/quiz2.mdx +0 -125
- units/en/unit1/sdk.mdx +0 -169
- units/en/unit1/unit1-recap.mdx +0 -45
- units/en/unit2/clients.mdx +0 -136
- units/en/unit2/gradio-client.mdx +0 -179
- units/en/unit2/gradio-server.mdx +0 -190
- units/en/unit2/introduction.mdx +0 -64
- units/en/unit2/tiny-agents.mdx +0 -274
- units/en/unit3/introduction.mdx +0 -3
- units/en/unit4/introduction.mdx +0 -5
- units/vi/_toctree.yml +0 -46
- units/vi/unit0/introduction.mdx +0 -135
- units/vi/unit1/architectural-components.mdx +0 -85
- units/vi/unit1/capabilities.mdx +0 -377
- units/vi/unit1/communication-protocol.mdx +0 -223
- units/vi/unit1/gradio-mcp.mdx +0 -188
- units/vi/unit1/introduction.mdx +0 -33
- units/vi/unit1/key-concepts.mdx +0 -88
- units/vi/unit1/mcp-clients.mdx +0 -422
- units/vi/unit1/sdk.mdx +0 -279
- units/vi/unit2/clients.mdx +0 -79
- units/vi/unit2/gradio-client.mdx +0 -144
- units/vi/unit2/gradio-server.mdx +0 -228
.gitignore
CHANGED
|
@@ -173,4 +173,14 @@ cython_debug/
|
|
| 173 |
# PyPI configuration file
|
| 174 |
.pypirc
|
| 175 |
|
| 176 |
-
.DS_Store
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
# PyPI configuration file
|
| 174 |
.pypirc
|
| 175 |
|
| 176 |
+
.DS_Store
|
| 177 |
+
|
| 178 |
+
# Docker
|
| 179 |
+
.dockerignore
|
| 180 |
+
docker-compose.yml
|
| 181 |
+
docker-compose.override.yml
|
| 182 |
+
.docker/
|
| 183 |
+
|
| 184 |
+
# Hugging Face Spaces
|
| 185 |
+
.space/
|
| 186 |
+
mcpserver/
|
Dockerfile
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use Python 3.11 slim image as base
|
| 2 |
+
FROM python:3.11-slim
|
| 3 |
+
|
| 4 |
+
# Set environment variables
|
| 5 |
+
ENV PYTHONUNBUFFERED=1 \
|
| 6 |
+
PYTHONDONTWRITEBYTECODE=1 \
|
| 7 |
+
PIP_NO_CACHE_DIR=1 \
|
| 8 |
+
PIP_DISABLE_PIP_VERSION_CHECK=1
|
| 9 |
+
|
| 10 |
+
# Set working directory
|
| 11 |
+
WORKDIR /app
|
| 12 |
+
|
| 13 |
+
# Install system dependencies
|
| 14 |
+
RUN apt-get update && apt-get install -y \
|
| 15 |
+
build-essential \
|
| 16 |
+
curl \
|
| 17 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 18 |
+
|
| 19 |
+
# Copy requirements first for better caching
|
| 20 |
+
COPY requirements.txt .
|
| 21 |
+
|
| 22 |
+
# Install Python dependencies
|
| 23 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 24 |
+
|
| 25 |
+
# Copy application code
|
| 26 |
+
COPY app.py .
|
| 27 |
+
|
| 28 |
+
# Create a non-root user for security
|
| 29 |
+
RUN useradd --create-home --shell /bin/bash app && \
|
| 30 |
+
chown -R app:app /app
|
| 31 |
+
USER app
|
| 32 |
+
|
| 33 |
+
# Expose the port that Gradio will run on
|
| 34 |
+
EXPOSE 7860
|
| 35 |
+
|
| 36 |
+
# Health check
|
| 37 |
+
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
| 38 |
+
CMD curl -f http://localhost:7860/ || exit 1
|
| 39 |
+
|
| 40 |
+
# Run the application
|
| 41 |
+
CMD ["python", "app.py"]
|
Makefile
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Makefile for MCP Sentiment Analysis Server
|
| 2 |
+
|
| 3 |
+
# Variables
|
| 4 |
+
IMAGE_NAME = mcp-sentiment
|
| 5 |
+
CONTAINER_NAME = mcp-sentiment-container
|
| 6 |
+
PORT = 7860
|
| 7 |
+
DOCKER_REGISTRY =
|
| 8 |
+
VERSION = latest
|
| 9 |
+
|
| 10 |
+
# Default target
|
| 11 |
+
.PHONY: help
|
| 12 |
+
help:
|
| 13 |
+
@echo "MCP Sentiment Analysis Server - Development Commands"
|
| 14 |
+
@echo "=================================================="
|
| 15 |
+
@echo ""
|
| 16 |
+
@echo "Development:"
|
| 17 |
+
@echo " install Install Python dependencies locally"
|
| 18 |
+
@echo " run Run the server locally (without Docker)"
|
| 19 |
+
@echo " test Run tests locally"
|
| 20 |
+
@echo ""
|
| 21 |
+
@echo "Docker:"
|
| 22 |
+
@echo " build Build Docker image"
|
| 23 |
+
@echo " run-docker Run Docker container"
|
| 24 |
+
@echo " stop Stop Docker container"
|
| 25 |
+
@echo " logs Show Docker container logs"
|
| 26 |
+
@echo " shell Open shell in running container"
|
| 27 |
+
@echo ""
|
| 28 |
+
@echo "Testing:"
|
| 29 |
+
@echo " test-docker Test Docker container"
|
| 30 |
+
@echo " test-all Run all tests (local + Docker)"
|
| 31 |
+
@echo ""
|
| 32 |
+
@echo "Deployment:"
|
| 33 |
+
@echo " deploy-hf Deploy to Hugging Face Spaces (interactive)"
|
| 34 |
+
@echo ""
|
| 35 |
+
@echo "Cleanup:"
|
| 36 |
+
@echo " clean Remove Docker containers and images"
|
| 37 |
+
@echo " clean-all Remove everything including volumes"
|
| 38 |
+
|
| 39 |
+
# Development targets
|
| 40 |
+
.PHONY: install
|
| 41 |
+
install:
|
| 42 |
+
pip install -r requirements.txt
|
| 43 |
+
|
| 44 |
+
.PHONY: run
|
| 45 |
+
run:
|
| 46 |
+
python app.py
|
| 47 |
+
|
| 48 |
+
.PHONY: test
|
| 49 |
+
test:
|
| 50 |
+
python test_mcp_server.py
|
| 51 |
+
|
| 52 |
+
# Docker targets
|
| 53 |
+
.PHONY: build
|
| 54 |
+
build:
|
| 55 |
+
docker build -t $(IMAGE_NAME):$(VERSION) .
|
| 56 |
+
|
| 57 |
+
.PHONY: run-docker
|
| 58 |
+
run-docker: build
|
| 59 |
+
docker run -d \
|
| 60 |
+
--name $(CONTAINER_NAME) \
|
| 61 |
+
-p $(PORT):7860 \
|
| 62 |
+
$(IMAGE_NAME):$(VERSION)
|
| 63 |
+
@echo "Container started. Access at http://localhost:$(PORT)"
|
| 64 |
+
@echo "MCP endpoint: http://localhost:$(PORT)/gradio_api/mcp/sse"
|
| 65 |
+
|
| 66 |
+
.PHONY: stop
|
| 67 |
+
stop:
|
| 68 |
+
-docker stop $(CONTAINER_NAME)
|
| 69 |
+
-docker rm $(CONTAINER_NAME)
|
| 70 |
+
|
| 71 |
+
.PHONY: logs
|
| 72 |
+
logs:
|
| 73 |
+
docker logs -f $(CONTAINER_NAME)
|
| 74 |
+
|
| 75 |
+
.PHONY: shell
|
| 76 |
+
shell:
|
| 77 |
+
docker exec -it $(CONTAINER_NAME) /bin/bash
|
| 78 |
+
|
| 79 |
+
# Testing targets
|
| 80 |
+
.PHONY: test-docker
|
| 81 |
+
test-docker:
|
| 82 |
+
python test_mcp_server.py --server --wait
|
| 83 |
+
|
| 84 |
+
.PHONY: test-all
|
| 85 |
+
test-all: test test-docker
|
| 86 |
+
|
| 87 |
+
# Deployment targets
|
| 88 |
+
.PHONY: deploy-hf
|
| 89 |
+
deploy-hf:
|
| 90 |
+
@echo "Deploying to Hugging Face Spaces..."
|
| 91 |
+
@read -p "Enter your HF username: " username; \
|
| 92 |
+
read -p "Enter space name: " space_name; \
|
| 93 |
+
python deploy_to_hf.py $$space_name $$username
|
| 94 |
+
|
| 95 |
+
# Docker Compose targets
|
| 96 |
+
.PHONY: up
|
| 97 |
+
up:
|
| 98 |
+
docker-compose up -d
|
| 99 |
+
|
| 100 |
+
.PHONY: down
|
| 101 |
+
down:
|
| 102 |
+
docker-compose down
|
| 103 |
+
|
| 104 |
+
.PHONY: restart
|
| 105 |
+
restart: down up
|
| 106 |
+
|
| 107 |
+
# Cleanup targets
|
| 108 |
+
.PHONY: clean
|
| 109 |
+
clean: stop
|
| 110 |
+
-docker rmi $(IMAGE_NAME):$(VERSION)
|
| 111 |
+
-docker system prune -f
|
| 112 |
+
|
| 113 |
+
.PHONY: clean-all
|
| 114 |
+
clean-all: clean
|
| 115 |
+
-docker volume prune -f
|
| 116 |
+
-docker network prune -f
|
| 117 |
+
|
| 118 |
+
# Development workflow
|
| 119 |
+
.PHONY: dev
|
| 120 |
+
dev: install test build test-docker
|
| 121 |
+
@echo "Development setup complete!"
|
| 122 |
+
|
| 123 |
+
# Production workflow
|
| 124 |
+
.PHONY: prod
|
| 125 |
+
prod: clean build test-docker
|
| 126 |
+
@echo "Production build complete!"
|
| 127 |
+
|
| 128 |
+
# Quick start
|
| 129 |
+
.PHONY: quick-start
|
| 130 |
+
quick-start: build run-docker
|
| 131 |
+
@echo "Quick start complete!"
|
| 132 |
+
@echo "Waiting for server to be ready..."
|
| 133 |
+
@sleep 5
|
| 134 |
+
@python test_mcp_server.py --server --url=http://localhost:$(PORT)
|
| 135 |
+
|
| 136 |
+
# Health check
|
| 137 |
+
.PHONY: health
|
| 138 |
+
health:
|
| 139 |
+
@curl -f http://localhost:$(PORT)/ || echo "Server not responding"
|
| 140 |
+
|
| 141 |
+
# Show running containers
|
| 142 |
+
.PHONY: ps
|
| 143 |
+
ps:
|
| 144 |
+
docker ps --filter "name=$(CONTAINER_NAME)"
|
| 145 |
+
|
| 146 |
+
# Show image info
|
| 147 |
+
.PHONY: info
|
| 148 |
+
info:
|
| 149 |
+
@echo "Image: $(IMAGE_NAME):$(VERSION)"
|
| 150 |
+
@echo "Container: $(CONTAINER_NAME)"
|
| 151 |
+
@echo "Port: $(PORT)"
|
| 152 |
+
@docker images $(IMAGE_NAME) || echo "Image not built yet"
|
README.md
CHANGED
|
@@ -1,57 +1,215 @@
|
|
| 1 |
-
#
|
| 2 |
|
| 3 |
-
|
| 4 |
|
| 5 |
-
|
| 6 |
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
-
|
| 10 |
|
| 11 |
-
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
|
| 16 |
|
| 17 |
-
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
| 3 | MCP Protocol Deep Dive | Explore advanced MCP features, architecture, and real-world integration patterns|
|
| 25 |
-
| 4 | Bonus Units & Collaborations | Special topics, partner libraries, and community-driven projects.|
|
| 26 |
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
|
| 33 |
-
|
| 34 |
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
-
|
| 38 |
|
| 39 |
-
|
| 40 |
|
| 41 |
-
###
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
```
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
}
|
| 57 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Docker MCP Sentiment Analysis Server
|
| 2 |
|
| 3 |
+
This is a containerized Model Context Protocol (MCP) server that provides sentiment analysis capabilities using TextBlob. It's designed to run in Docker containers and can be easily deployed to Hugging Face Spaces or any Docker-compatible hosting platform.
|
| 4 |
|
| 5 |
+
## Features
|
| 6 |
|
| 7 |
+
- **Sentiment Analysis**: Comprehensive sentiment analysis with polarity and subjectivity scores
|
| 8 |
+
- **Sentiment Scoring**: Numerical sentiment scoring from -1 (negative) to 1 (positive)
|
| 9 |
+
- **Emotion Classification**: Basic emotion classification (Joy, Sadness, Anger, etc.)
|
| 10 |
+
- **Batch Processing**: Analyze multiple texts at once
|
| 11 |
+
- **Web Interface**: User-friendly Gradio interface for testing
|
| 12 |
+
- **MCP Protocol**: Full MCP server support for AI applications
|
| 13 |
+
- **Docker Ready**: Containerized for consistent deployment
|
| 14 |
|
| 15 |
+
## Quick Start
|
| 16 |
|
| 17 |
+
### Local Development with Docker
|
| 18 |
|
| 19 |
+
1. **Build the Docker image:**
|
| 20 |
+
```bash
|
| 21 |
+
cd docker-mcp-server
|
| 22 |
+
docker build -t mcp-sentiment .
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
2. **Run the container:**
|
| 26 |
+
```bash
|
| 27 |
+
docker run -p 7860:7860 mcp-sentiment
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
3. **Access the server:**
|
| 31 |
+
- Web interface: http://localhost:7860
|
| 32 |
+
- MCP endpoint: http://localhost:7860/gradio_api/mcp/sse
|
| 33 |
+
|
| 34 |
+
### Local Development without Docker
|
| 35 |
+
|
| 36 |
+
1. **Install dependencies:**
|
| 37 |
+
```bash
|
| 38 |
+
cd docker-mcp-server
|
| 39 |
+
pip install -r requirements.txt
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
2. **Run the server:**
|
| 43 |
+
```bash
|
| 44 |
+
python app.py
|
| 45 |
+
```
|
| 46 |
|
| 47 |
+
## Deployment to Hugging Face Spaces
|
| 48 |
|
| 49 |
+
### Method 1: Direct Upload
|
| 50 |
|
| 51 |
+
1. **Create a new Space on Hugging Face:**
|
| 52 |
+
- Go to [huggingface.co/spaces](https://huggingface.co/spaces)
|
| 53 |
+
- Click "Create new Space"
|
| 54 |
+
- Choose "Docker" as the SDK
|
| 55 |
+
- Name your space (e.g., "mcp-sentiment-analysis")
|
|
|
|
|
|
|
| 56 |
|
| 57 |
+
2. **Upload files:**
|
| 58 |
+
- Copy `app.py` and `requirements.txt` to your Space repository
|
| 59 |
+
- Ensure `app.py` is in the root directory of your Space
|
| 60 |
|
| 61 |
+
3. **Your server will be available at:**
|
| 62 |
+
- Web interface: `https://YOUR_USERNAME-mcp-sentiment-analysis.hf.space`
|
| 63 |
+
- MCP endpoint: `https://YOUR_USERNAME-mcp-sentiment-analysis.hf.space/gradio_api/mcp/sse`
|
| 64 |
|
| 65 |
+
### Method 2: Git Push
|
| 66 |
|
| 67 |
+
1. **Clone your Space repository:**
|
| 68 |
+
```bash
|
| 69 |
+
git clone https://huggingface.co/spaces/YOUR_USERNAME/mcp-sentiment-analysis
|
| 70 |
+
cd mcp-sentiment-analysis
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
2. **Copy files and push:**
|
| 74 |
+
```bash
|
| 75 |
+
cp ../docker-mcp-server/app.py .
|
| 76 |
+
cp ../docker-mcp-server/requirements.txt .
|
| 77 |
+
git add app.py requirements.txt
|
| 78 |
+
git commit -m "Add MCP sentiment analysis server"
|
| 79 |
+
git push
|
| 80 |
+
```
|
| 81 |
|
| 82 |
+
## Available MCP Tools
|
| 83 |
|
| 84 |
+
The server provides the following tools that can be used by MCP clients:
|
| 85 |
|
| 86 |
+
### 1. analyze_sentiment
|
| 87 |
+
- **Description**: Comprehensive sentiment analysis
|
| 88 |
+
- **Input**: Text string
|
| 89 |
+
- **Output**: JSON with sentiment, polarity, subjectivity, and interpretation
|
| 90 |
|
| 91 |
+
### 2. get_sentiment_score
|
| 92 |
+
- **Description**: Numerical sentiment scoring
|
| 93 |
+
- **Input**: Text string
|
| 94 |
+
- **Output**: JSON with sentiment score (-1 to 1)
|
| 95 |
|
| 96 |
+
### 3. classify_emotion
|
| 97 |
+
- **Description**: Basic emotion classification
|
| 98 |
+
- **Input**: Text string
|
| 99 |
+
- **Output**: JSON with emotion category and confidence
|
| 100 |
|
| 101 |
+
### 4. batch_analyze
|
| 102 |
+
- **Description**: Analyze multiple texts at once
|
| 103 |
+
- **Input**: Multiple texts (one per line)
|
| 104 |
+
- **Output**: JSON with summary statistics and individual results
|
| 105 |
|
| 106 |
+
## Using the MCP Server
|
| 107 |
+
|
| 108 |
+
### With MCP Clients
|
| 109 |
+
|
| 110 |
+
Once deployed, you can connect to your MCP server using various MCP clients:
|
| 111 |
+
|
| 112 |
+
#### Python (smolagents)
|
| 113 |
+
```python
|
| 114 |
+
from smolagents.mcp_client import MCPClient
|
| 115 |
+
|
| 116 |
+
with MCPClient(
|
| 117 |
+
{"url": "https://YOUR_USERNAME-mcp-sentiment-analysis.hf.space/gradio_api/mcp/sse"}
|
| 118 |
+
) as tools:
|
| 119 |
+
# Use the sentiment analysis tools
|
| 120 |
+
for tool in tools:
|
| 121 |
+
print(f"{tool.name}: {tool.description}")
|
| 122 |
```
|
| 123 |
+
|
| 124 |
+
#### Cursor IDE
|
| 125 |
+
Add to your MCP configuration:
|
| 126 |
+
```json
|
| 127 |
+
{
|
| 128 |
+
"mcpServers": {
|
| 129 |
+
"sentiment-analysis": {
|
| 130 |
+
"command": "npx",
|
| 131 |
+
"args": [
|
| 132 |
+
"-y",
|
| 133 |
+
"mcp-remote",
|
| 134 |
+
"https://YOUR_USERNAME-mcp-sentiment-analysis.hf.space/gradio_api/mcp/sse",
|
| 135 |
+
"--transport",
|
| 136 |
+
"sse-only"
|
| 137 |
+
]
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
}
|
| 141 |
```
|
| 142 |
+
|
| 143 |
+
### Direct HTTP Requests
|
| 144 |
+
|
| 145 |
+
You can also make direct HTTP requests to the MCP endpoint:
|
| 146 |
+
|
| 147 |
+
```bash
|
| 148 |
+
curl -X POST "https://YOUR_USERNAME-mcp-sentiment-analysis.hf.space/gradio_api/mcp/sse" \
|
| 149 |
+
-H "Content-Type: application/json" \
|
| 150 |
+
-d '{"method": "tools/call", "params": {"name": "analyze_sentiment", "arguments": {"text": "I love this!"}}}'
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
## Configuration
|
| 154 |
+
|
| 155 |
+
### Environment Variables
|
| 156 |
+
|
| 157 |
+
- `GRADIO_SERVER_NAME`: Server host (default: "0.0.0.0")
|
| 158 |
+
- `GRADIO_SERVER_PORT`: Server port (default: 7860)
|
| 159 |
+
|
| 160 |
+
### Docker Configuration
|
| 161 |
+
|
| 162 |
+
The Dockerfile includes:
|
| 163 |
+
- Python 3.11 slim base image
|
| 164 |
+
- Non-root user for security
|
| 165 |
+
- Health checks
|
| 166 |
+
- Optimized layer caching
|
| 167 |
+
|
| 168 |
+
## Development
|
| 169 |
+
|
| 170 |
+
### Adding New Tools
|
| 171 |
+
|
| 172 |
+
To add new sentiment analysis tools:
|
| 173 |
+
|
| 174 |
+
1. Create a new function in `app.py`
|
| 175 |
+
2. Add it to the Gradio interface
|
| 176 |
+
3. The function will automatically be available as an MCP tool
|
| 177 |
+
|
| 178 |
+
### Testing
|
| 179 |
+
|
| 180 |
+
Test your server locally before deployment:
|
| 181 |
+
|
| 182 |
+
```bash
|
| 183 |
+
# Build and run
|
| 184 |
+
docker build -t mcp-sentiment .
|
| 185 |
+
docker run -p 7860:7860 mcp-sentiment
|
| 186 |
+
|
| 187 |
+
# Test the web interface
|
| 188 |
+
open http://localhost:7860
|
| 189 |
+
|
| 190 |
+
# Test MCP endpoint
|
| 191 |
+
curl http://localhost:7860/gradio_api/mcp/sse
|
| 192 |
+
```
|
| 193 |
+
|
| 194 |
+
## Troubleshooting
|
| 195 |
+
|
| 196 |
+
### Common Issues
|
| 197 |
+
|
| 198 |
+
1. **Port conflicts**: Change the port mapping if 7860 is in use
|
| 199 |
+
2. **Memory issues**: Increase Docker memory limits for large batch processing
|
| 200 |
+
3. **Network issues**: Ensure proper firewall configuration for deployment
|
| 201 |
+
|
| 202 |
+
### Logs
|
| 203 |
+
|
| 204 |
+
View container logs:
|
| 205 |
+
```bash
|
| 206 |
+
docker logs <container_id>
|
| 207 |
+
```
|
| 208 |
+
|
| 209 |
+
## License
|
| 210 |
+
|
| 211 |
+
This project follows the same license as the MCP Course repository.
|
| 212 |
+
|
| 213 |
+
## Contributing
|
| 214 |
+
|
| 215 |
+
Contributions are welcome! Please follow the course contribution guidelines.
|
app.py
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
MCP Sentiment Analysis Server with Docker Support
|
| 4 |
+
|
| 5 |
+
This is a Model Context Protocol (MCP) server that provides sentiment analysis
|
| 6 |
+
capabilities using TextBlob. It's designed to run in Docker containers and
|
| 7 |
+
can be deployed to Hugging Face Spaces.
|
| 8 |
+
|
| 9 |
+
The server provides the following tools:
|
| 10 |
+
- analyze_sentiment: Analyze the sentiment of text
|
| 11 |
+
- get_sentiment_score: Get numerical sentiment score
|
| 12 |
+
- classify_emotion: Classify text into emotion categories
|
| 13 |
+
"""
|
| 14 |
+
|
| 15 |
+
import gradio as gr
|
| 16 |
+
from textblob import TextBlob
|
| 17 |
+
import json
|
| 18 |
+
import re
|
| 19 |
+
from typing import Dict, Any, List
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def improved_sentiment_analysis(text: str) -> tuple[float, float]:
|
| 23 |
+
"""
|
| 24 |
+
Improved sentiment analysis that handles negations better than TextBlob alone.
|
| 25 |
+
|
| 26 |
+
Returns:
|
| 27 |
+
tuple: (polarity, subjectivity)
|
| 28 |
+
"""
|
| 29 |
+
# Get TextBlob's analysis
|
| 30 |
+
blob = TextBlob(text)
|
| 31 |
+
original_polarity = blob.sentiment.polarity
|
| 32 |
+
subjectivity = blob.sentiment.subjectivity
|
| 33 |
+
|
| 34 |
+
# Define negation patterns
|
| 35 |
+
negation_patterns = [
|
| 36 |
+
r"\b(don't|dont|do not|doesn't|doesnt|does not|didn't|didnt|did not)\b",
|
| 37 |
+
r"\b(won't|wont|will not|wouldn't|wouldnt|would not|can't|cant|cannot)\b",
|
| 38 |
+
r"\b(shouldn't|shouldnt|should not|isn't|isnt|is not|aren't|arent|are not)\b",
|
| 39 |
+
r"\b(wasn't|wasnt|was not|weren't|werent|were not|haven't|havent|have not)\b",
|
| 40 |
+
r"\b(hasn't|hasnt|has not|hadn't|hadnt|had not|never|no|not)\b",
|
| 41 |
+
r"\b(hate|dislike|terrible|awful|horrible|bad|worst|disgusting)\b"
|
| 42 |
+
]
|
| 43 |
+
|
| 44 |
+
# Check for negations
|
| 45 |
+
text_lower = text.lower()
|
| 46 |
+
negation_found = any(re.search(pattern, text_lower) for pattern in negation_patterns)
|
| 47 |
+
|
| 48 |
+
# Adjust polarity if negation is found and TextBlob gave a positive result
|
| 49 |
+
if negation_found and original_polarity > 0:
|
| 50 |
+
# Flip the polarity for negated positive statements
|
| 51 |
+
adjusted_polarity = -abs(original_polarity) * 0.8 # Make it negative but slightly less extreme
|
| 52 |
+
else:
|
| 53 |
+
adjusted_polarity = original_polarity
|
| 54 |
+
|
| 55 |
+
return adjusted_polarity, subjectivity
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def analyze_sentiment(text: str) -> str:
|
| 59 |
+
"""
|
| 60 |
+
Analyze the sentiment of the given text.
|
| 61 |
+
|
| 62 |
+
Args:
|
| 63 |
+
text: The text to analyze
|
| 64 |
+
|
| 65 |
+
Returns:
|
| 66 |
+
A detailed sentiment analysis including polarity and subjectivity
|
| 67 |
+
"""
|
| 68 |
+
if not text or not text.strip():
|
| 69 |
+
return "Error: Please provide text to analyze"
|
| 70 |
+
|
| 71 |
+
# Use improved sentiment analysis
|
| 72 |
+
polarity, subjectivity = improved_sentiment_analysis(text)
|
| 73 |
+
|
| 74 |
+
# Also get TextBlob's original analysis for comparison
|
| 75 |
+
blob = TextBlob(text)
|
| 76 |
+
original_polarity = blob.sentiment.polarity
|
| 77 |
+
|
| 78 |
+
# Determine sentiment category with more conservative thresholds
|
| 79 |
+
if polarity > 0.05:
|
| 80 |
+
sentiment = "Positive"
|
| 81 |
+
elif polarity < -0.05:
|
| 82 |
+
sentiment = "Negative"
|
| 83 |
+
else:
|
| 84 |
+
sentiment = "Neutral"
|
| 85 |
+
|
| 86 |
+
# Determine subjectivity level
|
| 87 |
+
if subjectivity > 0.6:
|
| 88 |
+
subjectivity_level = "Highly subjective"
|
| 89 |
+
elif subjectivity > 0.3:
|
| 90 |
+
subjectivity_level = "Moderately subjective"
|
| 91 |
+
else:
|
| 92 |
+
subjectivity_level = "Objective"
|
| 93 |
+
|
| 94 |
+
# Add debug information to help understand the analysis
|
| 95 |
+
debug_info = f"Original TextBlob: {original_polarity:.3f} -> Improved: {polarity:.3f}, subjectivity={subjectivity:.3f}"
|
| 96 |
+
|
| 97 |
+
result = {
|
| 98 |
+
"text": text,
|
| 99 |
+
"sentiment": sentiment,
|
| 100 |
+
"polarity": round(polarity, 3),
|
| 101 |
+
"subjectivity": round(subjectivity, 3),
|
| 102 |
+
"subjectivity_level": subjectivity_level,
|
| 103 |
+
"interpretation": f"The text is {sentiment.lower()} with a polarity of {polarity:.3f} and is {subjectivity_level.lower()}.",
|
| 104 |
+
"debug": debug_info
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
return json.dumps(result, indent=2)
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def get_sentiment_score(text: str) -> str:
|
| 111 |
+
"""
|
| 112 |
+
Get a numerical sentiment score for the text.
|
| 113 |
+
|
| 114 |
+
Args:
|
| 115 |
+
text: The text to score
|
| 116 |
+
|
| 117 |
+
Returns:
|
| 118 |
+
A numerical score between -1 (very negative) and 1 (very positive)
|
| 119 |
+
"""
|
| 120 |
+
if not text or not text.strip():
|
| 121 |
+
return "Error: Please provide text to analyze"
|
| 122 |
+
|
| 123 |
+
# Use improved sentiment analysis
|
| 124 |
+
score, _ = improved_sentiment_analysis(text)
|
| 125 |
+
|
| 126 |
+
result = {
|
| 127 |
+
"text": text,
|
| 128 |
+
"sentiment_score": round(score, 3),
|
| 129 |
+
"scale": "Score ranges from -1 (very negative) to 1 (very positive)"
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
return json.dumps(result, indent=2)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def classify_emotion(text: str) -> str:
|
| 136 |
+
"""
|
| 137 |
+
Classify the text into basic emotion categories.
|
| 138 |
+
|
| 139 |
+
Args:
|
| 140 |
+
text: The text to classify
|
| 141 |
+
|
| 142 |
+
Returns:
|
| 143 |
+
Emotion classification based on sentiment analysis
|
| 144 |
+
"""
|
| 145 |
+
if not text or not text.strip():
|
| 146 |
+
return "Error: Please provide text to analyze"
|
| 147 |
+
|
| 148 |
+
blob = TextBlob(text)
|
| 149 |
+
polarity = blob.sentiment.polarity
|
| 150 |
+
subjectivity = blob.sentiment.subjectivity
|
| 151 |
+
|
| 152 |
+
# Simple emotion classification based on polarity and subjectivity
|
| 153 |
+
if polarity > 0.5:
|
| 154 |
+
emotion = "Joy"
|
| 155 |
+
elif polarity > 0.1:
|
| 156 |
+
emotion = "Contentment"
|
| 157 |
+
elif polarity < -0.5:
|
| 158 |
+
emotion = "Anger" if subjectivity > 0.5 else "Sadness"
|
| 159 |
+
elif polarity < -0.1:
|
| 160 |
+
emotion = "Disappointment"
|
| 161 |
+
else:
|
| 162 |
+
if subjectivity > 0.7:
|
| 163 |
+
emotion = "Confusion"
|
| 164 |
+
else:
|
| 165 |
+
emotion = "Neutral"
|
| 166 |
+
|
| 167 |
+
confidence = abs(polarity) if abs(polarity) > 0.1 else 0.1
|
| 168 |
+
|
| 169 |
+
result = {
|
| 170 |
+
"text": text,
|
| 171 |
+
"emotion": emotion,
|
| 172 |
+
"confidence": round(confidence, 3),
|
| 173 |
+
"polarity": round(polarity, 3),
|
| 174 |
+
"subjectivity": round(subjectivity, 3)
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
return json.dumps(result, indent=2)
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def batch_analyze(texts: str) -> str:
|
| 181 |
+
"""
|
| 182 |
+
Analyze multiple texts at once (one per line).
|
| 183 |
+
|
| 184 |
+
Args:
|
| 185 |
+
texts: Multiple texts separated by newlines
|
| 186 |
+
|
| 187 |
+
Returns:
|
| 188 |
+
Batch analysis results
|
| 189 |
+
"""
|
| 190 |
+
if not texts or not texts.strip():
|
| 191 |
+
return "Error: Please provide texts to analyze (one per line)"
|
| 192 |
+
|
| 193 |
+
lines = [line.strip() for line in texts.split('\n') if line.strip()]
|
| 194 |
+
if not lines:
|
| 195 |
+
return "Error: No valid text lines found"
|
| 196 |
+
|
| 197 |
+
results = []
|
| 198 |
+
for i, text in enumerate(lines, 1):
|
| 199 |
+
# Use improved sentiment analysis
|
| 200 |
+
polarity, _ = improved_sentiment_analysis(text)
|
| 201 |
+
|
| 202 |
+
# Use the same conservative thresholds as analyze_sentiment
|
| 203 |
+
if polarity > 0.05:
|
| 204 |
+
sentiment = "Positive"
|
| 205 |
+
elif polarity < -0.05:
|
| 206 |
+
sentiment = "Negative"
|
| 207 |
+
else:
|
| 208 |
+
sentiment = "Neutral"
|
| 209 |
+
|
| 210 |
+
results.append({
|
| 211 |
+
"line": i,
|
| 212 |
+
"text": text,
|
| 213 |
+
"sentiment": sentiment,
|
| 214 |
+
"polarity": round(polarity, 3)
|
| 215 |
+
})
|
| 216 |
+
|
| 217 |
+
summary = {
|
| 218 |
+
"total_texts": len(results),
|
| 219 |
+
"positive": len([r for r in results if r["sentiment"] == "Positive"]),
|
| 220 |
+
"negative": len([r for r in results if r["sentiment"] == "Negative"]),
|
| 221 |
+
"neutral": len([r for r in results if r["sentiment"] == "Neutral"]),
|
| 222 |
+
"average_polarity": round(sum(r["polarity"] for r in results) / len(results), 3)
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
return json.dumps({
|
| 226 |
+
"summary": summary,
|
| 227 |
+
"results": results
|
| 228 |
+
}, indent=2)
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
# Create the main MCP interface - using TabbedInterface to expose all functions as MCP tools
|
| 232 |
+
demo = gr.TabbedInterface(
|
| 233 |
+
[
|
| 234 |
+
gr.Interface(
|
| 235 |
+
fn=analyze_sentiment,
|
| 236 |
+
inputs=gr.Textbox(placeholder="Enter text to analyze...", label="Text"),
|
| 237 |
+
outputs=gr.JSON(label="Analysis Result"),
|
| 238 |
+
title="Sentiment Analysis",
|
| 239 |
+
description="Analyze the sentiment of text using TextBlob"
|
| 240 |
+
),
|
| 241 |
+
gr.Interface(
|
| 242 |
+
fn=get_sentiment_score,
|
| 243 |
+
inputs=gr.Textbox(placeholder="Enter text to score...", label="Text"),
|
| 244 |
+
outputs=gr.JSON(label="Score Result"),
|
| 245 |
+
title="Sentiment Score",
|
| 246 |
+
description="Get numerical sentiment score (-1 to 1)"
|
| 247 |
+
),
|
| 248 |
+
gr.Interface(
|
| 249 |
+
fn=classify_emotion,
|
| 250 |
+
inputs=gr.Textbox(placeholder="Enter text to classify...", label="Text"),
|
| 251 |
+
outputs=gr.JSON(label="Emotion Result"),
|
| 252 |
+
title="Emotion Classification",
|
| 253 |
+
description="Classify text into emotion categories"
|
| 254 |
+
),
|
| 255 |
+
gr.Interface(
|
| 256 |
+
fn=batch_analyze,
|
| 257 |
+
inputs=gr.Textbox(placeholder="Enter multiple texts, one per line...", label="Texts", lines=5),
|
| 258 |
+
outputs=gr.JSON(label="Batch Results"),
|
| 259 |
+
title="Batch Analysis",
|
| 260 |
+
description="Analyze multiple texts at once"
|
| 261 |
+
)
|
| 262 |
+
],
|
| 263 |
+
tab_names=["Sentiment Analysis", "Sentiment Score", "Emotion Classification", "Batch Analysis"],
|
| 264 |
+
title="MCP Sentiment Analysis Server"
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
if __name__ == "__main__":
|
| 269 |
+
# Launch the Gradio app with MCP server support
|
| 270 |
+
demo.launch(
|
| 271 |
+
server_name="0.0.0.0",
|
| 272 |
+
server_port=7860,
|
| 273 |
+
share=False,
|
| 274 |
+
mcp_server=True # This enables MCP protocol support
|
| 275 |
+
)
|
demo.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Demo script showing how to use the MCP Sentiment Analysis Server
|
| 4 |
+
|
| 5 |
+
This script demonstrates various ways to interact with the MCP server:
|
| 6 |
+
1. Direct function calls (local testing)
|
| 7 |
+
2. HTTP requests to the MCP endpoint
|
| 8 |
+
3. Using the smolagents MCP client (if available)
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
import json
|
| 12 |
+
import requests
|
| 13 |
+
import sys
|
| 14 |
+
from typing import Dict, Any
|
| 15 |
+
|
| 16 |
+
# Import local functions for testing
|
| 17 |
+
try:
|
| 18 |
+
from app import analyze_sentiment, get_sentiment_score, classify_emotion, batch_analyze
|
| 19 |
+
LOCAL_FUNCTIONS_AVAILABLE = True
|
| 20 |
+
except ImportError:
|
| 21 |
+
LOCAL_FUNCTIONS_AVAILABLE = False
|
| 22 |
+
print("⚠️ Local functions not available. Make sure you're in the docker-mcp-server directory.")
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def demo_local_functions():
|
| 26 |
+
"""Demonstrate the sentiment analysis functions directly."""
|
| 27 |
+
print("🔧 Testing Local Functions")
|
| 28 |
+
print("=" * 40)
|
| 29 |
+
|
| 30 |
+
if not LOCAL_FUNCTIONS_AVAILABLE:
|
| 31 |
+
print("❌ Local functions not available")
|
| 32 |
+
return
|
| 33 |
+
|
| 34 |
+
# Test texts
|
| 35 |
+
texts = [
|
| 36 |
+
"I absolutely love this product! It's amazing!",
|
| 37 |
+
"This is terrible and I hate it.",
|
| 38 |
+
"The weather is okay today.",
|
| 39 |
+
"I'm feeling confused about this situation."
|
| 40 |
+
]
|
| 41 |
+
|
| 42 |
+
for i, text in enumerate(texts, 1):
|
| 43 |
+
print(f"\n📝 Test {i}: '{text}'")
|
| 44 |
+
|
| 45 |
+
# Analyze sentiment
|
| 46 |
+
result = analyze_sentiment(text)
|
| 47 |
+
data = json.loads(result)
|
| 48 |
+
print(f" Sentiment: {data['sentiment']} (polarity: {data['polarity']})")
|
| 49 |
+
|
| 50 |
+
# Get emotion
|
| 51 |
+
emotion_result = classify_emotion(text)
|
| 52 |
+
emotion_data = json.loads(emotion_result)
|
| 53 |
+
print(f" Emotion: {emotion_data['emotion']} (confidence: {emotion_data['confidence']})")
|
| 54 |
+
|
| 55 |
+
# Test batch analysis
|
| 56 |
+
print(f"\n📊 Batch Analysis:")
|
| 57 |
+
batch_text = "\n".join(texts)
|
| 58 |
+
batch_result = batch_analyze(batch_text)
|
| 59 |
+
batch_data = json.loads(batch_result)
|
| 60 |
+
print(f" Total texts: {batch_data['summary']['total_texts']}")
|
| 61 |
+
print(f" Positive: {batch_data['summary']['positive']}")
|
| 62 |
+
print(f" Negative: {batch_data['summary']['negative']}")
|
| 63 |
+
print(f" Neutral: {batch_data['summary']['neutral']}")
|
| 64 |
+
print(f" Average polarity: {batch_data['summary']['average_polarity']}")
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def demo_http_requests(base_url: str = "http://localhost:7860"):
|
| 68 |
+
"""Demonstrate HTTP requests to the MCP server."""
|
| 69 |
+
print("\n🌐 Testing HTTP Requests")
|
| 70 |
+
print("=" * 40)
|
| 71 |
+
|
| 72 |
+
# Test if server is running
|
| 73 |
+
try:
|
| 74 |
+
response = requests.get(base_url, timeout=5)
|
| 75 |
+
if response.status_code != 200:
|
| 76 |
+
print(f"❌ Server not accessible at {base_url}")
|
| 77 |
+
return
|
| 78 |
+
except requests.exceptions.RequestException:
|
| 79 |
+
print(f"❌ Cannot connect to server at {base_url}")
|
| 80 |
+
print(" Make sure the server is running with: docker run -p 7860:7860 mcp-sentiment")
|
| 81 |
+
return
|
| 82 |
+
|
| 83 |
+
print(f"✅ Server accessible at {base_url}")
|
| 84 |
+
|
| 85 |
+
# Test MCP endpoint
|
| 86 |
+
mcp_url = f"{base_url}/gradio_api/mcp/sse"
|
| 87 |
+
try:
|
| 88 |
+
response = requests.get(mcp_url, timeout=5)
|
| 89 |
+
print(f"✅ MCP endpoint accessible at {mcp_url}")
|
| 90 |
+
except requests.exceptions.RequestException as e:
|
| 91 |
+
print(f"❌ MCP endpoint not accessible: {e}")
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def demo_mcp_client(server_url: str = "http://localhost:7860/gradio_api/mcp/sse"):
|
| 95 |
+
"""Demonstrate using the smolagents MCP client."""
|
| 96 |
+
print("\n🤖 Testing MCP Client")
|
| 97 |
+
print("=" * 40)
|
| 98 |
+
|
| 99 |
+
try:
|
| 100 |
+
from smolagents.mcp_client import MCPClient
|
| 101 |
+
|
| 102 |
+
print(f"Connecting to MCP server at {server_url}...")
|
| 103 |
+
|
| 104 |
+
with MCPClient({"url": server_url}) as tools:
|
| 105 |
+
print(f"✅ Connected! Available tools:")
|
| 106 |
+
for tool in tools:
|
| 107 |
+
print(f" - {tool.name}: {tool.description}")
|
| 108 |
+
|
| 109 |
+
# Test a tool
|
| 110 |
+
if tools:
|
| 111 |
+
print(f"\n🧪 Testing first tool...")
|
| 112 |
+
# This would require more specific implementation
|
| 113 |
+
# depending on how the MCP client works
|
| 114 |
+
|
| 115 |
+
except ImportError:
|
| 116 |
+
print("❌ smolagents not available")
|
| 117 |
+
print(" Install with: pip install smolagents")
|
| 118 |
+
except Exception as e:
|
| 119 |
+
print(f"❌ MCP client error: {e}")
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def demo_gradio_api(base_url: str = "http://localhost:7860"):
|
| 123 |
+
"""Demonstrate using the Gradio API directly."""
|
| 124 |
+
print("\n🎨 Testing Gradio API")
|
| 125 |
+
print("=" * 40)
|
| 126 |
+
|
| 127 |
+
# This is a simplified example - actual Gradio API usage
|
| 128 |
+
# would require knowing the specific endpoint structure
|
| 129 |
+
try:
|
| 130 |
+
# Test basic connectivity
|
| 131 |
+
response = requests.get(f"{base_url}/api/", timeout=5)
|
| 132 |
+
if response.status_code == 200:
|
| 133 |
+
print("✅ Gradio API accessible")
|
| 134 |
+
else:
|
| 135 |
+
print(f"⚠️ Gradio API returned status {response.status_code}")
|
| 136 |
+
except requests.exceptions.RequestException:
|
| 137 |
+
print("❌ Gradio API not accessible")
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def main():
|
| 141 |
+
"""Run all demos."""
|
| 142 |
+
print("🎭 MCP Sentiment Analysis Server Demo")
|
| 143 |
+
print("=" * 50)
|
| 144 |
+
|
| 145 |
+
# Parse command line arguments
|
| 146 |
+
server_url = "http://localhost:7860"
|
| 147 |
+
mcp_url = f"{server_url}/gradio_api/mcp/sse"
|
| 148 |
+
|
| 149 |
+
for arg in sys.argv[1:]:
|
| 150 |
+
if arg.startswith("--url="):
|
| 151 |
+
server_url = arg.split("=", 1)[1]
|
| 152 |
+
mcp_url = f"{server_url}/gradio_api/mcp/sse"
|
| 153 |
+
|
| 154 |
+
# Run demos
|
| 155 |
+
if LOCAL_FUNCTIONS_AVAILABLE:
|
| 156 |
+
demo_local_functions()
|
| 157 |
+
|
| 158 |
+
demo_http_requests(server_url)
|
| 159 |
+
demo_gradio_api(server_url)
|
| 160 |
+
demo_mcp_client(mcp_url)
|
| 161 |
+
|
| 162 |
+
print("\n🎉 Demo completed!")
|
| 163 |
+
print("\nNext steps:")
|
| 164 |
+
print("1. Deploy to Hugging Face Spaces using: python deploy_to_hf.py")
|
| 165 |
+
print("2. Connect your MCP clients to the deployed endpoint")
|
| 166 |
+
print("3. Use the sentiment analysis tools in your AI applications")
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
if __name__ == "__main__":
|
| 170 |
+
if "--help" in sys.argv or "-h" in sys.argv:
|
| 171 |
+
print("Usage: python demo.py [--url=SERVER_URL]")
|
| 172 |
+
print("\nOptions:")
|
| 173 |
+
print(" --url=URL Server URL (default: http://localhost:7860)")
|
| 174 |
+
print(" --help, -h Show this help message")
|
| 175 |
+
print("\nExamples:")
|
| 176 |
+
print(" python demo.py")
|
| 177 |
+
print(" python demo.py --url=https://myspace.hf.space")
|
| 178 |
+
sys.exit(0)
|
| 179 |
+
|
| 180 |
+
main()
|
deploy_to_hf.py
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Deployment script for Hugging Face Spaces
|
| 4 |
+
|
| 5 |
+
This script helps deploy the MCP server to Hugging Face Spaces.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import os
|
| 9 |
+
import shutil
|
| 10 |
+
import subprocess
|
| 11 |
+
import sys
|
| 12 |
+
import argparse
|
| 13 |
+
from pathlib import Path
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def check_git():
|
| 17 |
+
"""Check if git is available."""
|
| 18 |
+
try:
|
| 19 |
+
subprocess.run(["git", "--version"], capture_output=True, check=True)
|
| 20 |
+
return True
|
| 21 |
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
| 22 |
+
print("❌ Git is not installed or not available in PATH")
|
| 23 |
+
return False
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def check_huggingface_hub():
|
| 27 |
+
"""Check if huggingface_hub is available."""
|
| 28 |
+
try:
|
| 29 |
+
import huggingface_hub
|
| 30 |
+
return True
|
| 31 |
+
except ImportError:
|
| 32 |
+
print("❌ huggingface_hub is not installed")
|
| 33 |
+
print("Install it with: pip install huggingface_hub")
|
| 34 |
+
return False
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def create_space_files(space_dir: Path):
|
| 38 |
+
"""Create the necessary files for Hugging Face Spaces."""
|
| 39 |
+
# Copy main files
|
| 40 |
+
shutil.copy("app.py", space_dir / "app.py")
|
| 41 |
+
shutil.copy("requirements.txt", space_dir / "requirements.txt")
|
| 42 |
+
|
| 43 |
+
# Create README for the space
|
| 44 |
+
readme_content = """---
|
| 45 |
+
title: MCP Sentiment Analysis Server
|
| 46 |
+
emoji: 🎭
|
| 47 |
+
colorFrom: blue
|
| 48 |
+
colorTo: purple
|
| 49 |
+
sdk: gradio
|
| 50 |
+
sdk_version: "5.0.0"
|
| 51 |
+
app_file: app.py
|
| 52 |
+
pinned: false
|
| 53 |
+
license: mit
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
# MCP Sentiment Analysis Server
|
| 57 |
+
|
| 58 |
+
This is a Model Context Protocol (MCP) server that provides sentiment analysis capabilities.
|
| 59 |
+
|
| 60 |
+
## Features
|
| 61 |
+
|
| 62 |
+
- Comprehensive sentiment analysis
|
| 63 |
+
- Numerical sentiment scoring
|
| 64 |
+
- Emotion classification
|
| 65 |
+
- Batch text processing
|
| 66 |
+
- Full MCP protocol support
|
| 67 |
+
|
| 68 |
+
## Usage
|
| 69 |
+
|
| 70 |
+
### Web Interface
|
| 71 |
+
Use the interface above to test the sentiment analysis tools.
|
| 72 |
+
|
| 73 |
+
### MCP Endpoint
|
| 74 |
+
Connect your MCP clients to: `https://YOUR_USERNAME-SPACE_NAME.hf.space/gradio_api/mcp/sse`
|
| 75 |
+
|
| 76 |
+
### Available Tools
|
| 77 |
+
- `analyze_sentiment`: Comprehensive sentiment analysis
|
| 78 |
+
- `get_sentiment_score`: Numerical sentiment scoring (-1 to 1)
|
| 79 |
+
- `classify_emotion`: Basic emotion classification
|
| 80 |
+
- `batch_analyze`: Analyze multiple texts at once
|
| 81 |
+
|
| 82 |
+
## Example with smolagents
|
| 83 |
+
|
| 84 |
+
```python
|
| 85 |
+
from smolagents.mcp_client import MCPClient
|
| 86 |
+
|
| 87 |
+
with MCPClient(
|
| 88 |
+
{"url": "https://YOUR_USERNAME-SPACE_NAME.hf.space/gradio_api/mcp/sse"}
|
| 89 |
+
) as tools:
|
| 90 |
+
for tool in tools:
|
| 91 |
+
print(f"{tool.name}: {tool.description}")
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
## Example with Cursor IDE
|
| 95 |
+
|
| 96 |
+
Add to your MCP configuration:
|
| 97 |
+
|
| 98 |
+
```json
|
| 99 |
+
{
|
| 100 |
+
"mcpServers": {
|
| 101 |
+
"sentiment-analysis": {
|
| 102 |
+
"command": "npx",
|
| 103 |
+
"args": [
|
| 104 |
+
"-y",
|
| 105 |
+
"mcp-remote",
|
| 106 |
+
"https://YOUR_USERNAME-SPACE_NAME.hf.space/gradio_api/mcp/sse",
|
| 107 |
+
"--transport",
|
| 108 |
+
"sse-only"
|
| 109 |
+
]
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
```
|
| 114 |
+
"""
|
| 115 |
+
|
| 116 |
+
with open(space_dir / "README.md", "w") as f:
|
| 117 |
+
f.write(readme_content)
|
| 118 |
+
|
| 119 |
+
print(f"✅ Created space files in {space_dir}")
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def deploy_with_git(space_name: str, username: str):
|
| 123 |
+
"""Deploy using git commands."""
|
| 124 |
+
space_dir = Path(f"./hf_space_{space_name}")
|
| 125 |
+
|
| 126 |
+
if space_dir.exists():
|
| 127 |
+
print(f"Directory {space_dir} already exists. Remove it first or use a different name.")
|
| 128 |
+
return False
|
| 129 |
+
|
| 130 |
+
try:
|
| 131 |
+
# Clone the space repository
|
| 132 |
+
repo_url = f"https://huggingface.co/spaces/{username}/{space_name}"
|
| 133 |
+
print(f"Cloning {repo_url}...")
|
| 134 |
+
subprocess.run(["git", "clone", repo_url, str(space_dir)], check=True)
|
| 135 |
+
|
| 136 |
+
# Create space files
|
| 137 |
+
create_space_files(space_dir)
|
| 138 |
+
|
| 139 |
+
# Git operations
|
| 140 |
+
os.chdir(space_dir)
|
| 141 |
+
subprocess.run(["git", "add", "."], check=True)
|
| 142 |
+
subprocess.run(["git", "commit", "-m", "Deploy MCP sentiment analysis server"], check=True)
|
| 143 |
+
subprocess.run(["git", "push"], check=True)
|
| 144 |
+
|
| 145 |
+
print(f"✅ Successfully deployed to {repo_url}")
|
| 146 |
+
print(f"🌐 Your space will be available at: https://{username}-{space_name}.hf.space")
|
| 147 |
+
print(f"🔗 MCP endpoint: https://{username}-{space_name}.hf.space/gradio_api/mcp/sse")
|
| 148 |
+
|
| 149 |
+
return True
|
| 150 |
+
|
| 151 |
+
except subprocess.CalledProcessError as e:
|
| 152 |
+
print(f"❌ Git operation failed: {e}")
|
| 153 |
+
return False
|
| 154 |
+
except Exception as e:
|
| 155 |
+
print(f"❌ Deployment failed: {e}")
|
| 156 |
+
return False
|
| 157 |
+
finally:
|
| 158 |
+
# Go back to original directory
|
| 159 |
+
os.chdir("..")
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def deploy_with_hub_api(space_name: str, username: str):
|
| 163 |
+
"""Deploy using Hugging Face Hub API."""
|
| 164 |
+
try:
|
| 165 |
+
from huggingface_hub import HfApi, create_repo
|
| 166 |
+
|
| 167 |
+
api = HfApi()
|
| 168 |
+
|
| 169 |
+
# Create the space repository
|
| 170 |
+
repo_id = f"{username}/{space_name}"
|
| 171 |
+
print(f"Creating space {repo_id}...")
|
| 172 |
+
|
| 173 |
+
create_repo(
|
| 174 |
+
repo_id=repo_id,
|
| 175 |
+
repo_type="space",
|
| 176 |
+
space_sdk="gradio",
|
| 177 |
+
exist_ok=True
|
| 178 |
+
)
|
| 179 |
+
|
| 180 |
+
# Upload files
|
| 181 |
+
print("Uploading files...")
|
| 182 |
+
api.upload_file(
|
| 183 |
+
path_or_fileobj="app.py",
|
| 184 |
+
path_in_repo="app.py",
|
| 185 |
+
repo_id=repo_id,
|
| 186 |
+
repo_type="space"
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
api.upload_file(
|
| 190 |
+
path_or_fileobj="requirements.txt",
|
| 191 |
+
path_in_repo="requirements.txt",
|
| 192 |
+
repo_id=repo_id,
|
| 193 |
+
repo_type="space"
|
| 194 |
+
)
|
| 195 |
+
|
| 196 |
+
# Create and upload README
|
| 197 |
+
space_dir = Path("./temp_space")
|
| 198 |
+
space_dir.mkdir(exist_ok=True)
|
| 199 |
+
create_space_files(space_dir)
|
| 200 |
+
|
| 201 |
+
api.upload_file(
|
| 202 |
+
path_or_fileobj=str(space_dir / "README.md"),
|
| 203 |
+
path_in_repo="README.md",
|
| 204 |
+
repo_id=repo_id,
|
| 205 |
+
repo_type="space"
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
# Cleanup
|
| 209 |
+
shutil.rmtree(space_dir)
|
| 210 |
+
|
| 211 |
+
print(f"✅ Successfully deployed to https://huggingface.co/spaces/{repo_id}")
|
| 212 |
+
print(f"🌐 Your space will be available at: https://{username}-{space_name}.hf.space")
|
| 213 |
+
print(f"🔗 MCP endpoint: https://{username}-{space_name}.hf.space/gradio_api/mcp/sse")
|
| 214 |
+
|
| 215 |
+
return True
|
| 216 |
+
|
| 217 |
+
except Exception as e:
|
| 218 |
+
print(f"❌ Hub API deployment failed: {e}")
|
| 219 |
+
return False
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
def main():
|
| 223 |
+
parser = argparse.ArgumentParser(description="Deploy MCP server to Hugging Face Spaces")
|
| 224 |
+
parser.add_argument("space_name", help="Name of the Hugging Face Space")
|
| 225 |
+
parser.add_argument("username", help="Your Hugging Face username")
|
| 226 |
+
parser.add_argument("--method", choices=["git", "api"], default="git",
|
| 227 |
+
help="Deployment method (default: git)")
|
| 228 |
+
parser.add_argument("--check-only", action="store_true",
|
| 229 |
+
help="Only check prerequisites without deploying")
|
| 230 |
+
|
| 231 |
+
args = parser.parse_args()
|
| 232 |
+
|
| 233 |
+
print("🚀 MCP Server Deployment to Hugging Face Spaces")
|
| 234 |
+
print("=" * 50)
|
| 235 |
+
|
| 236 |
+
# Check prerequisites
|
| 237 |
+
print("Checking prerequisites...")
|
| 238 |
+
|
| 239 |
+
if not Path("app.py").exists():
|
| 240 |
+
print("❌ app.py not found in current directory")
|
| 241 |
+
return 1
|
| 242 |
+
|
| 243 |
+
if not Path("requirements.txt").exists():
|
| 244 |
+
print("❌ requirements.txt not found in current directory")
|
| 245 |
+
return 1
|
| 246 |
+
|
| 247 |
+
git_ok = check_git()
|
| 248 |
+
hub_ok = check_huggingface_hub()
|
| 249 |
+
|
| 250 |
+
if args.method == "git" and not git_ok:
|
| 251 |
+
print("❌ Git method selected but git is not available")
|
| 252 |
+
return 1
|
| 253 |
+
|
| 254 |
+
if args.method == "api" and not hub_ok:
|
| 255 |
+
print("❌ API method selected but huggingface_hub is not available")
|
| 256 |
+
return 1
|
| 257 |
+
|
| 258 |
+
if args.check_only:
|
| 259 |
+
print("✅ All prerequisites check passed")
|
| 260 |
+
return 0
|
| 261 |
+
|
| 262 |
+
# Deploy
|
| 263 |
+
print(f"\nDeploying '{args.space_name}' for user '{args.username}' using {args.method} method...")
|
| 264 |
+
|
| 265 |
+
if args.method == "git":
|
| 266 |
+
success = deploy_with_git(args.space_name, args.username)
|
| 267 |
+
else:
|
| 268 |
+
success = deploy_with_hub_api(args.space_name, args.username)
|
| 269 |
+
|
| 270 |
+
if success:
|
| 271 |
+
print("\n🎉 Deployment completed successfully!")
|
| 272 |
+
print("\nNext steps:")
|
| 273 |
+
print("1. Wait a few minutes for the space to build")
|
| 274 |
+
print("2. Test the web interface")
|
| 275 |
+
print("3. Test the MCP endpoint with your clients")
|
| 276 |
+
return 0
|
| 277 |
+
else:
|
| 278 |
+
print("\n💥 Deployment failed!")
|
| 279 |
+
return 1
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
if __name__ == "__main__":
|
| 283 |
+
sys.exit(main())
|
quiz/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
# MCP Course quiz scripts
|
|
|
|
|
|
quiz/data/unit_1.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
| 1 |
-
[
|
| 2 |
-
{
|
| 3 |
-
"question": "Which of the following best describes a Large Language Model (LLM)?",
|
| 4 |
-
"answer_a": "A model specializing in language recognition",
|
| 5 |
-
"answer_b": "A massive neural network that understands and generates human language",
|
| 6 |
-
"answer_c": "A model exclusively used for language data tasks like summarization or classification",
|
| 7 |
-
"answer_d": "A rule-based chatbot used for conversations",
|
| 8 |
-
"correct_answer": "B"
|
| 9 |
-
}
|
| 10 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
quiz/push_questions.py
DELETED
|
@@ -1,31 +0,0 @@
|
|
| 1 |
-
import json
|
| 2 |
-
from pathlib import Path
|
| 3 |
-
from datasets import Dataset
|
| 4 |
-
|
| 5 |
-
ORG_NAME = "mcp-course"
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
def main():
|
| 9 |
-
"""Push quiz questions to the Hugging Face Hub"""
|
| 10 |
-
|
| 11 |
-
for file in Path("data").glob("*.json"):
|
| 12 |
-
print(f"Processing {file}")
|
| 13 |
-
|
| 14 |
-
with open(file, "r") as f:
|
| 15 |
-
quiz_data = json.load(f)
|
| 16 |
-
|
| 17 |
-
repo_id = f"{ORG_NAME}/{file.stem}_quiz"
|
| 18 |
-
|
| 19 |
-
dataset = Dataset.from_list(quiz_data)
|
| 20 |
-
|
| 21 |
-
print(f"Pushing {repo_id} to the Hugging Face Hub")
|
| 22 |
-
|
| 23 |
-
dataset.push_to_hub(
|
| 24 |
-
repo_id,
|
| 25 |
-
private=True,
|
| 26 |
-
commit_message=f"Update quiz questions for {file.stem}",
|
| 27 |
-
)
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
if __name__ == "__main__":
|
| 31 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
quiz/pyproject.toml
DELETED
|
@@ -1,12 +0,0 @@
|
|
| 1 |
-
[project]
|
| 2 |
-
name = "agents-course"
|
| 3 |
-
version = "0.1.0"
|
| 4 |
-
description = "Add your description here"
|
| 5 |
-
readme = "README.md"
|
| 6 |
-
requires-python = ">=3.11"
|
| 7 |
-
dependencies = [
|
| 8 |
-
"datasets>=3.2.0",
|
| 9 |
-
"huggingface-hub>=0.27.1",
|
| 10 |
-
"ipykernel>=6.29.5",
|
| 11 |
-
"requests>=2.32.3",
|
| 12 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
quiz/uv.lock
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirements.txt
CHANGED
|
@@ -1,3 +1,10 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core dependencies for MCP server
|
| 2 |
+
gradio[mcp]>=5.0.0
|
| 3 |
+
textblob>=0.17.1
|
| 4 |
+
|
| 5 |
+
# Additional dependencies for better functionality
|
| 6 |
+
numpy>=1.24.0
|
| 7 |
+
requests>=2.31.0
|
| 8 |
+
|
| 9 |
+
# Development and debugging (optional)
|
| 10 |
+
uvicorn>=0.23.0
|
scripts/translation.py
DELETED
|
@@ -1,85 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import sys
|
| 3 |
-
from huggingface_hub import InferenceClient
|
| 4 |
-
from dotenv import load_dotenv
|
| 5 |
-
load_dotenv()
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
hf_token = os.environ.get("HF_TOKEN")
|
| 9 |
-
if not hf_token:
|
| 10 |
-
raise ValueError("HF_TOKEN not found in environment variables. Please set it in a .env file.")
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
# Get the directory containing the current script
|
| 14 |
-
script_dir = os.path.dirname(os.path.abspath(__file__))
|
| 15 |
-
default_inp_dir = os.path.join(script_dir, '..', 'units/en')
|
| 16 |
-
default_model = "deepseek-ai/DeepSeek-R1"
|
| 17 |
-
default_client = InferenceClient(
|
| 18 |
-
provider="together",
|
| 19 |
-
# api_key is read from the environment
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
def auto_translate(
|
| 23 |
-
output_lang: str,
|
| 24 |
-
prompt: callable,
|
| 25 |
-
inp_dir: str = default_inp_dir,
|
| 26 |
-
model: str = default_model,
|
| 27 |
-
client: InferenceClient = default_client
|
| 28 |
-
):
|
| 29 |
-
get_output_path = lambda x: x.replace('/en', f'/{output_lang}')
|
| 30 |
-
escape_special_tokens = lambda x: x.replace('<think>', '<%%think%%>').replace('</think>', '<%%/think%%>')
|
| 31 |
-
unescape_special_tokens = lambda x: x.replace('<%%think%%>', '<think>').replace('<%%/think%%>', '</think>')
|
| 32 |
-
|
| 33 |
-
# Get the list of all files in the directory, recursively
|
| 34 |
-
inp_files: list[str] = []
|
| 35 |
-
print('Collecting files...')
|
| 36 |
-
for root, dirs, files in os.walk(inp_dir):
|
| 37 |
-
for file in files:
|
| 38 |
-
if file.endswith('.mdx') or file == "_toctree.yml":
|
| 39 |
-
fname = os.path.join(root, file)
|
| 40 |
-
print(' +', fname)
|
| 41 |
-
inp_files.append(fname)
|
| 42 |
-
|
| 43 |
-
def write_out_file(fpath: str, content: str):
|
| 44 |
-
base_path = os.path.dirname(fpath)
|
| 45 |
-
os.makedirs(base_path, exist_ok=True)
|
| 46 |
-
with open(fpath, 'w', encoding='utf-8') as f:
|
| 47 |
-
f.write(content)
|
| 48 |
-
|
| 49 |
-
# Read the content of the file and process
|
| 50 |
-
for i, inp_file in enumerate(inp_files):
|
| 51 |
-
out_file = get_output_path(inp_file)
|
| 52 |
-
if os.path.exists(out_file):
|
| 53 |
-
print(f'[{i+1}/{len(inp_files)}] Skipping file: {inp_file}')
|
| 54 |
-
continue
|
| 55 |
-
with open(inp_file, 'r', encoding='utf-8') as f:
|
| 56 |
-
content: str = f.read()
|
| 57 |
-
content = escape_special_tokens(content)
|
| 58 |
-
if content.strip() == "":
|
| 59 |
-
print(f'[{i+1}/{len(inp_files)}] Skipping empty file: {inp_file}')
|
| 60 |
-
write_out_file(out_file, "")
|
| 61 |
-
continue
|
| 62 |
-
|
| 63 |
-
print(f'[{i+1}/{len(inp_files)}] Processing file: {inp_file}')
|
| 64 |
-
stream = client.chat.completions.create(
|
| 65 |
-
model=model,
|
| 66 |
-
temperature=0.0,
|
| 67 |
-
messages=[
|
| 68 |
-
{"role": "user", "content": prompt(content)},
|
| 69 |
-
],
|
| 70 |
-
stream=True,
|
| 71 |
-
)
|
| 72 |
-
final_text = ""
|
| 73 |
-
for chunk in stream:
|
| 74 |
-
content_chunk = chunk.choices[0].delta.content
|
| 75 |
-
print(content_chunk, end="", flush=True)
|
| 76 |
-
final_text += content_chunk
|
| 77 |
-
# Optionally filter <think>...</think> reasoning process
|
| 78 |
-
final_text = final_text.split('</think>').pop().strip()
|
| 79 |
-
# Write the output to the file
|
| 80 |
-
final_text = unescape_special_tokens(final_text)
|
| 81 |
-
write_out_file(out_file, final_text)
|
| 82 |
-
print()
|
| 83 |
-
print(f' -> Translated to: {out_file}')
|
| 84 |
-
print("--" * 20)
|
| 85 |
-
#break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scripts/vi.py
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
from translation import auto_translate
|
| 2 |
-
|
| 3 |
-
output_lang = "vi"
|
| 4 |
-
|
| 5 |
-
# Fix the prompt function to escape curly braces in the content
|
| 6 |
-
prompt = lambda content: f'''
|
| 7 |
-
You are a translator for the Vietnamese translation team. You are tasked with translating the following texts into Vietnamese. You must follow these instructions:
|
| 8 |
-
- Translate the texts into Vietnamese, while keeping the original formatting (either Markdown, MDX or HTML)
|
| 9 |
-
- Inside code blocks, translate the comments but leave the code as-is; If the code block contains quite plain texts, you MUST provide the translation in <details> tag
|
| 10 |
-
- Do not translate inline code, the URLs and file paths
|
| 11 |
-
- If the term is abbreviated, keep the original term and provide the translation in parentheses for the first time it appears in the text
|
| 12 |
-
- If there are any slag or funny joke in english, keep it (do not translate) and give an explanation so Vietnamese reader can understand
|
| 13 |
-
- Use "ta", "mình, "chúng ta", "chúng mình", "các bạn" as pronouns
|
| 14 |
-
|
| 15 |
-
KEEP THESE TERMS (DO NOT TRANSLATE, do NOT add translation in parentheses): MCP, API, SDK, CLI, HTML, GGUF, AI, Client, Server, Hugging Face, Space, CodeAgent, LangGraph, LangChain, Llama, Gemma, inference, notebook, python, transformers, token, pretrain, format, certificate.
|
| 16 |
-
|
| 17 |
-
For these terms, use the pre-defined translation:
|
| 18 |
-
- Quick Quiz: Kiểm tra nhanh
|
| 19 |
-
- Unit: Chương
|
| 20 |
-
- Bonus Unit: Chương bổ trợ
|
| 21 |
-
- Module: Mô-đun
|
| 22 |
-
- Lesson ...: Bài ...
|
| 23 |
-
- Model: Mô hình
|
| 24 |
-
- Dataset: Tập dữ liệu
|
| 25 |
-
- Course: Khóa học
|
| 26 |
-
- state-of-the-art: nổi tiếng
|
| 27 |
-
- Q&A: Hỏi và Đáp
|
| 28 |
-
- Dummy: ảo (or "giả", or "thử" depending on the context)
|
| 29 |
-
- onboarding: làm quen
|
| 30 |
-
- Hands-on: Thực hành
|
| 31 |
-
- Challenge: Bài tập lớn
|
| 32 |
-
- Training: Huấn luyện
|
| 33 |
-
- Model Context Protocol: Giao Thức Ngữ Cảnh Mô Hình
|
| 34 |
-
|
| 35 |
-
Here is an example:
|
| 36 |
-
- Original text: [Agents Course](https://huggingface.co/learn/agents-course/) will guide you through building AI agents with LLMs.
|
| 37 |
-
- Translation: [Agents Course](https://huggingface.co/learn/agents-course/) sẽ hướng dẫn các bạn cách xây dựng AI Agents với LLMs.
|
| 38 |
-
|
| 39 |
-
Here is another example:
|
| 40 |
-
- Original text: JSON-RPC defines the message format, but MCP also specifies how these messages are transported between Clients and Servers.
|
| 41 |
-
- Translation: JSON-RPC định nghĩa định dạng tin nhắn, nhưng MCP cũng chỉ định cách thức các tin nhắn này được truyền tải giữa Máy khách và Máy chủ.
|
| 42 |
-
|
| 43 |
-
If the code block contains many plain texts, prove translation in collapsible <details> tag. Example:
|
| 44 |
-
- Original text:
|
| 45 |
-
```python
|
| 46 |
-
def get_weather(location: str) -> dict:
|
| 47 |
-
"""Get the current weather for a specified location."""
|
| 48 |
-
# Connect to weather API and fetch data
|
| 49 |
-
return {{
|
| 50 |
-
"temperature": 72,
|
| 51 |
-
"conditions": "Sunny",
|
| 52 |
-
"humidity": 45
|
| 53 |
-
}}
|
| 54 |
-
```
|
| 55 |
-
- Translation (add the <details> collapsible ABOVE of the original code block):
|
| 56 |
-
<details>
|
| 57 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 58 |
-
```
|
| 59 |
-
def get_weather(location: str) -> dict:
|
| 60 |
-
"""Nhận thông tin thời tiết hiện tại ở một địa điểm cụ thể."""
|
| 61 |
-
# Connect to weather API and fetch data
|
| 62 |
-
return {{
|
| 63 |
-
"temperature": 72,
|
| 64 |
-
"conditions": "Sunny",
|
| 65 |
-
"humidity": 45
|
| 66 |
-
}}
|
| 67 |
-
```
|
| 68 |
-
</details>
|
| 69 |
-
```
|
| 70 |
-
def get_weather(location: str) -> dict:
|
| 71 |
-
"""Get the current weather for a specified location."""
|
| 72 |
-
# Connect to weather API and fetch data
|
| 73 |
-
return {{
|
| 74 |
-
"temperature": 72,
|
| 75 |
-
"conditions": "Sunny",
|
| 76 |
-
"humidity": 45
|
| 77 |
-
}}
|
| 78 |
-
```
|
| 79 |
-
|
| 80 |
-
If the code block does not contain any plain texts or comments, leave it as it is. Example:
|
| 81 |
-
- Original text:
|
| 82 |
-
```json
|
| 83 |
-
{{
|
| 84 |
-
"servers": [
|
| 85 |
-
{{
|
| 86 |
-
"name": "File Explorer",
|
| 87 |
-
"transport": {{
|
| 88 |
-
"type": "stdio",
|
| 89 |
-
"command": "python",
|
| 90 |
-
"args": ["/path/to/file_explorer_server.py"]
|
| 91 |
-
}}
|
| 92 |
-
}}
|
| 93 |
-
]
|
| 94 |
-
}}
|
| 95 |
-
```
|
| 96 |
-
|
| 97 |
-
- Translation:
|
| 98 |
-
```json
|
| 99 |
-
{{
|
| 100 |
-
"servers": [
|
| 101 |
-
{{
|
| 102 |
-
"name": "File Explorer",
|
| 103 |
-
"transport": {{
|
| 104 |
-
"type": "stdio",
|
| 105 |
-
"command": "python",
|
| 106 |
-
"args": ["/path/to/file_explorer_server.py"]
|
| 107 |
-
}}
|
| 108 |
-
}}
|
| 109 |
-
]
|
| 110 |
-
}}
|
| 111 |
-
```
|
| 112 |
-
|
| 113 |
-
IMPORTANT: Only output the translated texts and nothing else, no need explaination or instruction. The input text is between "=== BEGIN OF TEXT ===" and "=== END OF TEXT ===".
|
| 114 |
-
|
| 115 |
-
Please translate the following texts to Vietnamese:
|
| 116 |
-
|
| 117 |
-
=== BEGIN OF TEXT ===
|
| 118 |
-
{content}
|
| 119 |
-
=== END OF TEXT ===
|
| 120 |
-
'''.strip()
|
| 121 |
-
|
| 122 |
-
auto_translate(
|
| 123 |
-
prompt=prompt,
|
| 124 |
-
output_lang=output_lang,
|
| 125 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_mcp_server.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Test script for the MCP Sentiment Analysis Server
|
| 4 |
+
|
| 5 |
+
This script tests the MCP server functionality both locally and remotely.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import requests
|
| 9 |
+
import json
|
| 10 |
+
import time
|
| 11 |
+
import sys
|
| 12 |
+
from typing import Dict, Any
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def test_web_interface(base_url: str = "http://localhost:7860") -> bool:
|
| 16 |
+
"""Test if the web interface is accessible."""
|
| 17 |
+
try:
|
| 18 |
+
response = requests.get(base_url, timeout=10)
|
| 19 |
+
if response.status_code == 200:
|
| 20 |
+
print(f"✅ Web interface accessible at {base_url}")
|
| 21 |
+
return True
|
| 22 |
+
else:
|
| 23 |
+
print(f"❌ Web interface returned status {response.status_code}")
|
| 24 |
+
return False
|
| 25 |
+
except requests.exceptions.RequestException as e:
|
| 26 |
+
print(f"❌ Failed to connect to web interface: {e}")
|
| 27 |
+
return False
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def test_mcp_endpoint(base_url: str = "http://localhost:7860") -> bool:
|
| 31 |
+
"""Test if the MCP endpoint is accessible."""
|
| 32 |
+
mcp_url = f"{base_url}/gradio_api/mcp/sse"
|
| 33 |
+
try:
|
| 34 |
+
# Test basic connectivity
|
| 35 |
+
response = requests.get(mcp_url, timeout=10)
|
| 36 |
+
print(f"✅ MCP endpoint accessible at {mcp_url}")
|
| 37 |
+
return True
|
| 38 |
+
except requests.exceptions.RequestException as e:
|
| 39 |
+
print(f"❌ Failed to connect to MCP endpoint: {e}")
|
| 40 |
+
return False
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def test_sentiment_functions() -> bool:
|
| 44 |
+
"""Test the sentiment analysis functions directly."""
|
| 45 |
+
try:
|
| 46 |
+
# Import the functions from app.py
|
| 47 |
+
import sys
|
| 48 |
+
import os
|
| 49 |
+
sys.path.append(os.path.dirname(__file__))
|
| 50 |
+
|
| 51 |
+
from app import analyze_sentiment, get_sentiment_score, classify_emotion, batch_analyze
|
| 52 |
+
|
| 53 |
+
# Test analyze_sentiment
|
| 54 |
+
result = analyze_sentiment("I love this product!")
|
| 55 |
+
result_data = json.loads(result)
|
| 56 |
+
assert "sentiment" in result_data
|
| 57 |
+
assert result_data["sentiment"] == "Positive"
|
| 58 |
+
print("✅ analyze_sentiment function works")
|
| 59 |
+
|
| 60 |
+
# Test get_sentiment_score
|
| 61 |
+
result = get_sentiment_score("This is terrible!")
|
| 62 |
+
result_data = json.loads(result)
|
| 63 |
+
assert "sentiment_score" in result_data
|
| 64 |
+
assert result_data["sentiment_score"] < 0
|
| 65 |
+
print("✅ get_sentiment_score function works")
|
| 66 |
+
|
| 67 |
+
# Test classify_emotion
|
| 68 |
+
result = classify_emotion("I'm so happy today!")
|
| 69 |
+
result_data = json.loads(result)
|
| 70 |
+
assert "emotion" in result_data
|
| 71 |
+
print("✅ classify_emotion function works")
|
| 72 |
+
|
| 73 |
+
# Test batch_analyze
|
| 74 |
+
result = batch_analyze("I love this!\nThis is bad.\nNeutral statement.")
|
| 75 |
+
result_data = json.loads(result)
|
| 76 |
+
assert "summary" in result_data
|
| 77 |
+
assert result_data["summary"]["total_texts"] == 3
|
| 78 |
+
print("✅ batch_analyze function works")
|
| 79 |
+
|
| 80 |
+
return True
|
| 81 |
+
|
| 82 |
+
except Exception as e:
|
| 83 |
+
print(f"❌ Function tests failed: {e}")
|
| 84 |
+
return False
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def test_gradio_api(base_url: str = "http://localhost:7860") -> bool:
|
| 88 |
+
"""Test the Gradio API endpoints."""
|
| 89 |
+
try:
|
| 90 |
+
# Test the analyze_sentiment endpoint
|
| 91 |
+
api_url = f"{base_url}/api/predict"
|
| 92 |
+
|
| 93 |
+
# This is a basic test - actual Gradio API testing would require
|
| 94 |
+
# more specific endpoint knowledge
|
| 95 |
+
print("ℹ️ Gradio API testing requires running server")
|
| 96 |
+
return True
|
| 97 |
+
|
| 98 |
+
except Exception as e:
|
| 99 |
+
print(f"❌ Gradio API test failed: {e}")
|
| 100 |
+
return False
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def wait_for_server(base_url: str = "http://localhost:7860", max_wait: int = 60) -> bool:
|
| 104 |
+
"""Wait for the server to become available."""
|
| 105 |
+
print(f"Waiting for server at {base_url}...")
|
| 106 |
+
|
| 107 |
+
for i in range(max_wait):
|
| 108 |
+
try:
|
| 109 |
+
response = requests.get(base_url, timeout=5)
|
| 110 |
+
if response.status_code == 200:
|
| 111 |
+
print(f"✅ Server is ready after {i+1} seconds")
|
| 112 |
+
return True
|
| 113 |
+
except requests.exceptions.RequestException:
|
| 114 |
+
pass
|
| 115 |
+
|
| 116 |
+
time.sleep(1)
|
| 117 |
+
if (i + 1) % 10 == 0:
|
| 118 |
+
print(f"Still waiting... ({i+1}/{max_wait} seconds)")
|
| 119 |
+
|
| 120 |
+
print(f"❌ Server did not become available within {max_wait} seconds")
|
| 121 |
+
return False
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def main():
|
| 125 |
+
"""Run all tests."""
|
| 126 |
+
print("🧪 Testing MCP Sentiment Analysis Server")
|
| 127 |
+
print("=" * 50)
|
| 128 |
+
|
| 129 |
+
# Test functions directly (doesn't require server)
|
| 130 |
+
print("\n📋 Testing sentiment analysis functions...")
|
| 131 |
+
functions_ok = test_sentiment_functions()
|
| 132 |
+
|
| 133 |
+
# Check if we should test the server
|
| 134 |
+
test_server = "--server" in sys.argv or len(sys.argv) == 1
|
| 135 |
+
base_url = "http://localhost:7860"
|
| 136 |
+
|
| 137 |
+
# Allow custom URL
|
| 138 |
+
for arg in sys.argv:
|
| 139 |
+
if arg.startswith("--url="):
|
| 140 |
+
base_url = arg.split("=", 1)[1]
|
| 141 |
+
|
| 142 |
+
if test_server:
|
| 143 |
+
print(f"\n🌐 Testing server at {base_url}...")
|
| 144 |
+
|
| 145 |
+
# Wait for server if needed
|
| 146 |
+
if "--wait" in sys.argv:
|
| 147 |
+
server_ready = wait_for_server(base_url)
|
| 148 |
+
if not server_ready:
|
| 149 |
+
print("❌ Server tests skipped - server not available")
|
| 150 |
+
return 1 if not functions_ok else 0
|
| 151 |
+
|
| 152 |
+
# Test server endpoints
|
| 153 |
+
web_ok = test_web_interface(base_url)
|
| 154 |
+
mcp_ok = test_mcp_endpoint(base_url)
|
| 155 |
+
api_ok = test_gradio_api(base_url)
|
| 156 |
+
|
| 157 |
+
server_ok = web_ok and mcp_ok and api_ok
|
| 158 |
+
else:
|
| 159 |
+
print("\n⏭️ Server tests skipped (use --server to enable)")
|
| 160 |
+
server_ok = True
|
| 161 |
+
|
| 162 |
+
# Summary
|
| 163 |
+
print("\n📊 Test Summary")
|
| 164 |
+
print("=" * 50)
|
| 165 |
+
print(f"Functions: {'✅ PASS' if functions_ok else '❌ FAIL'}")
|
| 166 |
+
if test_server:
|
| 167 |
+
print(f"Server: {'✅ PASS' if server_ok else '❌ FAIL'}")
|
| 168 |
+
|
| 169 |
+
overall_success = functions_ok and (server_ok if test_server else True)
|
| 170 |
+
print(f"Overall: {'✅ PASS' if overall_success else '❌ FAIL'}")
|
| 171 |
+
|
| 172 |
+
if overall_success:
|
| 173 |
+
print("\n🎉 All tests passed!")
|
| 174 |
+
return 0
|
| 175 |
+
else:
|
| 176 |
+
print("\n💥 Some tests failed!")
|
| 177 |
+
return 1
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
if __name__ == "__main__":
|
| 181 |
+
if "--help" in sys.argv or "-h" in sys.argv:
|
| 182 |
+
print("Usage: python test_mcp_server.py [options]")
|
| 183 |
+
print("\nOptions:")
|
| 184 |
+
print(" --server Test server endpoints (default: enabled)")
|
| 185 |
+
print(" --wait Wait for server to become available")
|
| 186 |
+
print(" --url=URL Use custom server URL (default: http://localhost:7860)")
|
| 187 |
+
print(" --help, -h Show this help message")
|
| 188 |
+
print("\nExamples:")
|
| 189 |
+
print(" python test_mcp_server.py")
|
| 190 |
+
print(" python test_mcp_server.py --wait")
|
| 191 |
+
print(" python test_mcp_server.py --url=https://myspace.hf.space")
|
| 192 |
+
sys.exit(0)
|
| 193 |
+
|
| 194 |
+
sys.exit(main())
|
units/en/_toctree.yml
DELETED
|
@@ -1,54 +0,0 @@
|
|
| 1 |
-
- title: "0. Welcome to the MCP Course"
|
| 2 |
-
sections:
|
| 3 |
-
- local: unit0/introduction
|
| 4 |
-
title: Welcome to the MCP Course
|
| 5 |
-
|
| 6 |
-
- title: "1. Introduction to Model Context Protocol"
|
| 7 |
-
sections:
|
| 8 |
-
- local: unit1/introduction
|
| 9 |
-
title: Introduction to Model Context Protocol (MCP)
|
| 10 |
-
- local: unit1/key-concepts
|
| 11 |
-
title: Key Concepts and Terminology
|
| 12 |
-
- local: unit1/architectural-components
|
| 13 |
-
title: Architectural Components
|
| 14 |
-
- local: unit1/quiz1
|
| 15 |
-
title: Quiz 1 - MCP Fundamentals
|
| 16 |
-
- local: unit1/communication-protocol
|
| 17 |
-
title: The Communication Protocol
|
| 18 |
-
- local: unit1/capabilities
|
| 19 |
-
title: Understanding MCP Capabilities
|
| 20 |
-
- local: unit1/sdk
|
| 21 |
-
title: MCP SDK
|
| 22 |
-
- local: unit1/quiz2
|
| 23 |
-
title: Quiz 2 - MCP SDK
|
| 24 |
-
- local: unit1/mcp-clients
|
| 25 |
-
title: MCP Clients
|
| 26 |
-
- local: unit1/gradio-mcp
|
| 27 |
-
title: Gradio MCP Integration
|
| 28 |
-
- local: unit1/unit1-recap
|
| 29 |
-
title: Unit 1 Recap
|
| 30 |
-
- local: unit1/certificate
|
| 31 |
-
title: Get your certificate!
|
| 32 |
-
|
| 33 |
-
- title: "2. Use Case: End-to-End MCP Application"
|
| 34 |
-
sections:
|
| 35 |
-
- local: unit2/introduction
|
| 36 |
-
title: Introduction to Building an MCP Application
|
| 37 |
-
- local: unit2/gradio-server
|
| 38 |
-
title: Building the Gradio MCP Server
|
| 39 |
-
- local: unit2/clients
|
| 40 |
-
title: Using MCP Clients with your application
|
| 41 |
-
- local: unit2/gradio-client
|
| 42 |
-
title: Building an MCP Client with Gradio
|
| 43 |
-
- local: unit2/tiny-agents
|
| 44 |
-
title: Building Tiny Agents with MCP and the Hugging Face Hub
|
| 45 |
-
|
| 46 |
-
- title: "3. Use Case: Advanced MCP Development"
|
| 47 |
-
sections:
|
| 48 |
-
- local: unit3/introduction
|
| 49 |
-
title: Coming Soon
|
| 50 |
-
|
| 51 |
-
- title: "Bonus Units"
|
| 52 |
-
sections:
|
| 53 |
-
- local: unit4/introduction
|
| 54 |
-
title: Coming Soon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit0/introduction.mdx
DELETED
|
@@ -1,137 +0,0 @@
|
|
| 1 |
-
# Welcome to the 🤗 Model Context Protocol (MCP) Course
|
| 2 |
-
|
| 3 |
-

|
| 4 |
-
|
| 5 |
-
Welcome to the most exciting topic in AI today: **Model Context Protocol (MCP)**!
|
| 6 |
-
|
| 7 |
-
This free course will take you on a journey, **from beginner to informed**, in understanding, using, and building applications with MCP.
|
| 8 |
-
|
| 9 |
-
This first unit will help you onboard:
|
| 10 |
-
|
| 11 |
-
* Discover the **course's syllabus**.
|
| 12 |
-
* **Get more information about the certification process and the schedule**.
|
| 13 |
-
* Get to know the team behind the course.
|
| 14 |
-
* Create your **account**.
|
| 15 |
-
* **Sign-up to our Discord server**, and meet your classmates and us.
|
| 16 |
-
|
| 17 |
-
Let's get started!
|
| 18 |
-
|
| 19 |
-
## What to expect from this course?
|
| 20 |
-
|
| 21 |
-
In this course, you will:
|
| 22 |
-
|
| 23 |
-
* 📖 Study Model Context Protocol in **theory, design, and practice.**
|
| 24 |
-
* 🧑💻 Learn to **use established MCP SDKs and frameworks**.
|
| 25 |
-
* 💾 **Share your projects** and explore applications created by the community.
|
| 26 |
-
* 🏆 Participate in challenges where you will **evaluate your MCP implementations against other students'.**
|
| 27 |
-
* 🎓 **Earn a certificate of completion** by completing assignments.
|
| 28 |
-
|
| 29 |
-
And more!
|
| 30 |
-
|
| 31 |
-
At the end of this course, you'll understand **how MCP works and how to build your own AI applications that leverage external data and tools using the latest MCP standards**.
|
| 32 |
-
|
| 33 |
-
Don't forget to [**sign up to the course!**](https://huggingface.co/mcp-course)
|
| 34 |
-
|
| 35 |
-
## What does the course look like?
|
| 36 |
-
|
| 37 |
-
The course is composed of:
|
| 38 |
-
|
| 39 |
-
* _Foundational Units_: where you learn MCP **concepts in theory**.
|
| 40 |
-
* _Hands-on_: where you'll learn **to use established MCP SDKs** to build your applications. These hands-on sections will have pre-configured environments.
|
| 41 |
-
* _Use case assignments_: where you'll apply the concepts you've learned to solve a real-world problem that you'll choose.
|
| 42 |
-
* _Collaborations_: We're collaborating with Hugging Face's partners to give you the latest MCP implementations and tools.
|
| 43 |
-
|
| 44 |
-
This **course is a living project, evolving with your feedback and contributions!** Feel free to open issues and PRs in GitHub, and engage in discussions in our Discord server.
|
| 45 |
-
|
| 46 |
-
## What's the syllabus?
|
| 47 |
-
|
| 48 |
-
Here is the **general syllabus for the course**. A more detailed list of topics will be released with each unit.
|
| 49 |
-
|
| 50 |
-
| Chapter | Topic | Description |
|
| 51 |
-
| ------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
| 52 |
-
| 0 | Onboarding | Set you up with the tools and platforms that you will use. |
|
| 53 |
-
| 1 | MCP Fundamentals, Architecture and Core Concepts | Explain core concepts, architecture, and components of Model Context Protocol. Show a simple use case using MCP. |
|
| 54 |
-
| 2 | End-to-end Use case: MCP in Action | Build a simple end-to-end MCP application that you can share with the community. |
|
| 55 |
-
| 3 | Deployed Use case: MCP in Action | Build a deployed MCP application using the Hugging Face ecosystem and partners' services. |
|
| 56 |
-
| 4 | Bonus Units | Bonus units to help you get more out of the course, working with partners' libraries and services. |
|
| 57 |
-
|
| 58 |
-
## What are the prerequisites?
|
| 59 |
-
|
| 60 |
-
To be able to follow this course, you should have:
|
| 61 |
-
|
| 62 |
-
* Basic understanding of AI and LLM concepts
|
| 63 |
-
* Familiarity with software development principles and API concepts
|
| 64 |
-
* Experience with at least one programming language (Python or TypeScript examples will be shown)
|
| 65 |
-
|
| 66 |
-
If you don't have any of these, don't worry! Here are some resources that can help you:
|
| 67 |
-
|
| 68 |
-
* [LLM Course](https://huggingface.co/learn/llm-course/) will guide you through the basics of using and building with LLMs.
|
| 69 |
-
* [Agents Course](https://huggingface.co/learn/agents-course/) will guide you through building AI agents with LLMs.
|
| 70 |
-
|
| 71 |
-
<Tip>
|
| 72 |
-
|
| 73 |
-
The above courses are not prerequisites in themselves, so if you understand the concepts of LLMs and agents, you can start the course now!
|
| 74 |
-
|
| 75 |
-
</Tip>
|
| 76 |
-
|
| 77 |
-
## What tools do I need?
|
| 78 |
-
|
| 79 |
-
You only need 2 things:
|
| 80 |
-
|
| 81 |
-
* _A computer_ with an internet connection.
|
| 82 |
-
* An _account_: to access the course resources and create projects. If you don't have an account yet, you can create one [here](https://huggingface.co/join) (it's free).
|
| 83 |
-
|
| 84 |
-
## The Certification Process
|
| 85 |
-
|
| 86 |
-
You can choose to follow this course _in audit mode_, or do the activities and _get one of the two certificates we'll issue_. If you audit the course, you can participate in all the challenges and do assignments if you want, and **you don't need to notify us**.
|
| 87 |
-
|
| 88 |
-
The certification process is **completely free**:
|
| 89 |
-
|
| 90 |
-
* _To get a certification for fundamentals_: you need to complete Unit 1 of the course. This is intended for students that want to get up to date with the latest trends in MCP, without the need to build a full application.
|
| 91 |
-
* _To get a certificate of completion_: you need to complete the use case units (2 and 3). This is intended for students that want to build a full application and share it with the community.
|
| 92 |
-
|
| 93 |
-
## What is the recommended pace?
|
| 94 |
-
|
| 95 |
-
Each chapter in this course is designed **to be completed in 1 week, with approximately 3-4 hours of work per week**.
|
| 96 |
-
|
| 97 |
-
Since there's a deadline, we provide you a recommended pace:
|
| 98 |
-
|
| 99 |
-

|
| 100 |
-
|
| 101 |
-
## How to get the most out of the course?
|
| 102 |
-
|
| 103 |
-
To get the most out of the course, we have some advice:
|
| 104 |
-
|
| 105 |
-
1. [Join study groups in Discord](https://discord.gg/UrrTSsSyjb): Studying in groups is always easier. To do that, you need to join our discord server and verify your account.
|
| 106 |
-
2. **Do the quizzes and assignments**: The best way to learn is through hands-on practice and self-assessment.
|
| 107 |
-
3. **Define a schedule to stay in sync**: You can use our recommended pace schedule below or create yours.
|
| 108 |
-
|
| 109 |
-

|
| 110 |
-
|
| 111 |
-
## Who are we
|
| 112 |
-
|
| 113 |
-
About the authors:
|
| 114 |
-
|
| 115 |
-
### Ben Burtenshaw
|
| 116 |
-
|
| 117 |
-
Ben is a Machine Learning Engineer at Hugging Face who focuses on building LLM applications, with post training and agentic approaches. [Follow Ben on the Hub](https://huggingface.co/burtenshaw) to see his latest projects.
|
| 118 |
-
|
| 119 |
-
<!-- ## Acknowledgments -->
|
| 120 |
-
|
| 121 |
-
<!-- We would like to extend our gratitude to the following individuals and partners for their invaluable contributions and support: -->
|
| 122 |
-
|
| 123 |
-
<!-- TODO: @burtenshaw add contributors and partners -->
|
| 124 |
-
|
| 125 |
-
## I found a bug, or I want to improve the course
|
| 126 |
-
|
| 127 |
-
Contributions are **welcome** 🤗
|
| 128 |
-
|
| 129 |
-
* If you _found a bug 🐛 in a notebook_, please [open an issue](https://github.com/huggingface/mcp-course/issues/new) and **describe the problem**.
|
| 130 |
-
* If you _want to improve the course_, you can [open a Pull Request](https://github.com/huggingface/mcp-course/pulls).
|
| 131 |
-
* If you _want to add a full section or a new unit_, the best is to [open an issue](https://github.com/huggingface/mcp-course/issues/new) and **describe what content you want to add before starting to write it so that we can guide you**.
|
| 132 |
-
|
| 133 |
-
## I still have questions
|
| 134 |
-
|
| 135 |
-
Please ask your question in our discord server #mcp-course-questions.
|
| 136 |
-
|
| 137 |
-
Now that you have all the information, let's get on board ⛵
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/architectural-components.mdx
DELETED
|
@@ -1,85 +0,0 @@
|
|
| 1 |
-
# Architectural Components of MCP
|
| 2 |
-
|
| 3 |
-
In the previous section, we discussed the key concepts and terminology of MCP. Now, let's dive deeper into the architectural components that make up the MCP ecosystem.
|
| 4 |
-
|
| 5 |
-
## Host, Client, and Server
|
| 6 |
-
|
| 7 |
-
The Model Context Protocol (MCP) is built on a client-server architecture that enables structured communication between AI models and external systems.
|
| 8 |
-
|
| 9 |
-

|
| 10 |
-
|
| 11 |
-
The MCP architecture consists of three primary components, each with well-defined roles and responsibilities: Host, Client, and Server. We touched on these in the previous section, but let's dive deeper into each component and their responsibilities.
|
| 12 |
-
|
| 13 |
-
### Host
|
| 14 |
-
|
| 15 |
-
The **Host** is the user-facing AI application that end-users interact with directly.
|
| 16 |
-
|
| 17 |
-
Examples include:
|
| 18 |
-
- AI Chat apps like OpenAI ChatGPT or Anthropic's Claude Desktop
|
| 19 |
-
- AI-enhanced IDEs like Cursor, or integrations to tools like Continue.dev
|
| 20 |
-
- Custom AI agents and applications built in libraries like LangChain or smolagents
|
| 21 |
-
|
| 22 |
-
The Host's responsibilities include:
|
| 23 |
-
- Managing user interactions and permissions
|
| 24 |
-
- Initiating connections to MCP Servers via MCP Clients
|
| 25 |
-
- Orchestrating the overall flow between user requests, LLM processing, and external tools
|
| 26 |
-
- Rendering results back to users in a coherent format
|
| 27 |
-
|
| 28 |
-
In most cases, users will select their host application based on their needs and preferences. For example, a developer may choose Cursor for its powerful code editing capabilities, while domain experts may use custom applications built in smolagents.
|
| 29 |
-
|
| 30 |
-
### Client
|
| 31 |
-
|
| 32 |
-
The **Client** is a component within the Host application that manages communication with a specific MCP Server. Key characteristics include:
|
| 33 |
-
|
| 34 |
-
- Each Client maintains a 1:1 connection with a single Server
|
| 35 |
-
- Handles the protocol-level details of MCP communication
|
| 36 |
-
- Acts as the intermediary between the Host's logic and the external Server
|
| 37 |
-
|
| 38 |
-
### Server
|
| 39 |
-
|
| 40 |
-
The **Server** is an external program or service that exposes capabilities to AI models via the MCP protocol. Servers:
|
| 41 |
-
|
| 42 |
-
- Provide access to specific external tools, data sources, or services
|
| 43 |
-
- Act as lightweight wrappers around existing functionality
|
| 44 |
-
- Can run locally (on the same machine as the Host) or remotely (over a network)
|
| 45 |
-
- Expose their capabilities in a standardized format that Clients can discover and use
|
| 46 |
-
|
| 47 |
-
## Communication Flow
|
| 48 |
-
|
| 49 |
-
Let's examine how these components interact in a typical MCP workflow:
|
| 50 |
-
|
| 51 |
-
<Tip>
|
| 52 |
-
|
| 53 |
-
In the next section, we'll dive deeper into the communication protocol that enables these components with practical examples.
|
| 54 |
-
|
| 55 |
-
</Tip>
|
| 56 |
-
|
| 57 |
-
1. **User Interaction**: The user interacts with the **Host** application, expressing an intent or query.
|
| 58 |
-
|
| 59 |
-
2. **Host Processing**: The **Host** processes the user's input, potentially using an LLM to understand the request and determine which external capabilities might be needed.
|
| 60 |
-
|
| 61 |
-
3. **Client Connection**: The **Host** directs its **Client** component to connect to the appropriate Server(s).
|
| 62 |
-
|
| 63 |
-
4. **Capability Discovery**: The **Client** queries the **Server** to discover what capabilities (Tools, Resources, Prompts) it offers.
|
| 64 |
-
|
| 65 |
-
5. **Capability Invocation**: Based on the user's needs or the LLM's determination, the Host instructs the **Client** to invoke specific capabilities from the **Server**.
|
| 66 |
-
|
| 67 |
-
6. **Server Execution**: The **Server** executes the requested functionality and returns results to the **Client**.
|
| 68 |
-
|
| 69 |
-
7. **Result Integration**: The **Client** relays these results back to the **Host**, which incorporates them into the context for the LLM or presents them directly to the user.
|
| 70 |
-
|
| 71 |
-
A key advantage of this architecture is its modularity. A single **Host** can connect to multiple **Servers** simultaneously via different **Clients**. New **Servers** can be added to the ecosystem without requiring changes to existing **Hosts**. Capabilities can be easily composed across different **Servers**.
|
| 72 |
-
|
| 73 |
-
<Tip>
|
| 74 |
-
|
| 75 |
-
As we discussed in the previous section, this modularity transforms the traditional M×N integration problem (M AI applications connecting to N tools/services) into a more manageable M+N problem, where each Host and Server needs to implement the MCP standard only once.
|
| 76 |
-
|
| 77 |
-
</Tip>
|
| 78 |
-
|
| 79 |
-
The architecture might appear simple, but its power lies in the standardization of the communication protocol and the clear separation of responsibilities between components. This design allows for a cohesive ecosystem where AI models can seamlessly connect with an ever-growing array of external tools and data sources.
|
| 80 |
-
|
| 81 |
-
## Conclusion
|
| 82 |
-
|
| 83 |
-
These interaction patterns are guided by several key principles that shape the design and evolution of MCP. The protocol emphasizes **standardization** by providing a universal protocol for AI connectivity, while maintaining **simplicity** by keeping the core protocol straightforward yet enabling advanced features. **Safety** is prioritized by requiring explicit user approval for sensitive operations, and discoverability enables dynamic discovery of capabilities. The protocol is built with **extensibility** in mind, supporting evolution through versioning and capability negotiation, and ensures **interoperability** across different implementations and environments.
|
| 84 |
-
|
| 85 |
-
In the next section, we'll explore the communication protocol that enables these components to work together effectively.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/capabilities.mdx
DELETED
|
@@ -1,243 +0,0 @@
|
|
| 1 |
-
# Understanding MCP Capabilities
|
| 2 |
-
|
| 3 |
-
MCP Servers expose a variety of capabilities to Clients through the communication protocol. These capabilities fall into four main categories, each with distinct characteristics and use cases. Let's explore these core primitives that form the foundation of MCP's functionality.
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
In this section, we'll show examples as framework agnostic functions in each language. This is to focus on the concepts and how they work together, rather than the complexities of any framework.
|
| 8 |
-
|
| 9 |
-
In the coming units, we'll show how these concepts are implemented in MCP specific code.
|
| 10 |
-
|
| 11 |
-
</Tip>
|
| 12 |
-
|
| 13 |
-
## Tools
|
| 14 |
-
|
| 15 |
-
Tools are executable functions or actions that the AI model can invoke through the MCP protocol.
|
| 16 |
-
|
| 17 |
-
- **Control**: Tools are typically **model-controlled**, meaning that the AI model (LLM) decides when to call them based on the user's request and context.
|
| 18 |
-
- **Safety**: Due to their ability to perform actions with side effects, tool execution can be dangerous. Therefore, they typically require explicit user approval.
|
| 19 |
-
- **Use Cases**: Sending messages, creating tickets, querying APIs, performing calculations.
|
| 20 |
-
|
| 21 |
-
**Example**: A weather tool that fetches current weather data for a given location:
|
| 22 |
-
|
| 23 |
-
<hfoptions id="tool-example">
|
| 24 |
-
<hfoption id="python">
|
| 25 |
-
|
| 26 |
-
```python
|
| 27 |
-
def get_weather(location: str) -> dict:
|
| 28 |
-
"""Get the current weather for a specified location."""
|
| 29 |
-
# Connect to weather API and fetch data
|
| 30 |
-
return {
|
| 31 |
-
"temperature": 72,
|
| 32 |
-
"conditions": "Sunny",
|
| 33 |
-
"humidity": 45
|
| 34 |
-
}
|
| 35 |
-
```
|
| 36 |
-
|
| 37 |
-
</hfoption>
|
| 38 |
-
<hfoption id="javascript">
|
| 39 |
-
|
| 40 |
-
```javascript
|
| 41 |
-
function getWeather(location) {
|
| 42 |
-
// Connect to weather API and fetch data
|
| 43 |
-
return {
|
| 44 |
-
temperature: 72,
|
| 45 |
-
conditions: 'Sunny',
|
| 46 |
-
humidity: 45
|
| 47 |
-
};
|
| 48 |
-
}
|
| 49 |
-
```
|
| 50 |
-
|
| 51 |
-
</hfoption>
|
| 52 |
-
</hfoptions>
|
| 53 |
-
|
| 54 |
-
## Resources
|
| 55 |
-
|
| 56 |
-
Resources provide read-only access to data sources, allowing the AI model to retrieve context without executing complex logic.
|
| 57 |
-
|
| 58 |
-
- **Control**: Resources are **application-controlled**, meaning the Host application typically decides when to access them.
|
| 59 |
-
- **Nature**: They are designed for data retrieval with minimal computation, similar to GET endpoints in REST APIs.
|
| 60 |
-
- **Safety**: Since they are read-only, they typically present lower security risks than Tools.
|
| 61 |
-
- **Use Cases**: Accessing file contents, retrieving database records, reading configuration information.
|
| 62 |
-
|
| 63 |
-
**Example**: A resource that provides access to file contents:
|
| 64 |
-
|
| 65 |
-
<hfoptions id="resource-example">
|
| 66 |
-
<hfoption id="python">
|
| 67 |
-
|
| 68 |
-
```python
|
| 69 |
-
def read_file(file_path: str) -> str:
|
| 70 |
-
"""Read the contents of a file at the specified path."""
|
| 71 |
-
with open(file_path, 'r') as f:
|
| 72 |
-
return f.read()
|
| 73 |
-
```
|
| 74 |
-
|
| 75 |
-
</hfoption>
|
| 76 |
-
<hfoption id="javascript">
|
| 77 |
-
|
| 78 |
-
```javascript
|
| 79 |
-
function readFile(filePath) {
|
| 80 |
-
// Using fs.readFile to read file contents
|
| 81 |
-
const fs = require('fs');
|
| 82 |
-
return new Promise((resolve, reject) => {
|
| 83 |
-
fs.readFile(filePath, 'utf8', (err, data) => {
|
| 84 |
-
if (err) {
|
| 85 |
-
reject(err);
|
| 86 |
-
return;
|
| 87 |
-
}
|
| 88 |
-
resolve(data);
|
| 89 |
-
});
|
| 90 |
-
});
|
| 91 |
-
}
|
| 92 |
-
```
|
| 93 |
-
|
| 94 |
-
</hfoption>
|
| 95 |
-
</hfoptions>
|
| 96 |
-
|
| 97 |
-
## Prompts
|
| 98 |
-
|
| 99 |
-
Prompts are predefined templates or workflows that guide the interaction between the user, the AI model, and the Server's capabilities.
|
| 100 |
-
|
| 101 |
-
- **Control**: Prompts are **user-controlled**, often presented as options in the Host application's UI.
|
| 102 |
-
- **Purpose**: They structure interactions for optimal use of available Tools and Resources.
|
| 103 |
-
- **Selection**: Users typically select a prompt before the AI model begins processing, setting context for the interaction.
|
| 104 |
-
- **Use Cases**: Common workflows, specialized task templates, guided interactions.
|
| 105 |
-
|
| 106 |
-
**Example**: A prompt template for generating a code review:
|
| 107 |
-
|
| 108 |
-
<hfoptions id="prompt-example">
|
| 109 |
-
<hfoption id="python">
|
| 110 |
-
|
| 111 |
-
```python
|
| 112 |
-
def code_review(code: str, language: str) -> list:
|
| 113 |
-
"""Generate a code review for the provided code snippet."""
|
| 114 |
-
return [
|
| 115 |
-
{
|
| 116 |
-
"role": "system",
|
| 117 |
-
"content": f"You are a code reviewer examining {language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement."
|
| 118 |
-
},
|
| 119 |
-
{
|
| 120 |
-
"role": "user",
|
| 121 |
-
"content": f"Please review this {language} code:\n\n```{language}\n{code}\n```"
|
| 122 |
-
}
|
| 123 |
-
]
|
| 124 |
-
```
|
| 125 |
-
|
| 126 |
-
</hfoption>
|
| 127 |
-
<hfoption id="javascript">
|
| 128 |
-
|
| 129 |
-
```javascript
|
| 130 |
-
function codeReview(code, language) {
|
| 131 |
-
return [
|
| 132 |
-
{
|
| 133 |
-
role: 'system',
|
| 134 |
-
content: `You are a code reviewer examining ${language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement.`
|
| 135 |
-
},
|
| 136 |
-
{
|
| 137 |
-
role: 'user',
|
| 138 |
-
content: `Please review this ${language} code:\n\n\`\`\`${language}\n${code}\n\`\`\``
|
| 139 |
-
}
|
| 140 |
-
];
|
| 141 |
-
}
|
| 142 |
-
```
|
| 143 |
-
|
| 144 |
-
</hfoption>
|
| 145 |
-
</hfoptions>
|
| 146 |
-
|
| 147 |
-
## Sampling
|
| 148 |
-
|
| 149 |
-
Sampling allows Servers to request the Client (specifically, the Host application) to perform LLM interactions.
|
| 150 |
-
|
| 151 |
-
- **Control**: Sampling is **server-initiated** but requires Client/Host facilitation.
|
| 152 |
-
- **Purpose**: It enables server-driven agentic behaviors and potentially recursive or multi-step interactions.
|
| 153 |
-
- **Safety**: Like Tools, sampling operations typically require user approval.
|
| 154 |
-
- **Use Cases**: Complex multi-step tasks, autonomous agent workflows, interactive processes.
|
| 155 |
-
|
| 156 |
-
**Example**: A Server might request the Client to analyze data it has processed:
|
| 157 |
-
|
| 158 |
-
<hfoptions id="sampling-example">
|
| 159 |
-
<hfoption id="python">
|
| 160 |
-
|
| 161 |
-
```python
|
| 162 |
-
def request_sampling(messages, system_prompt=None, include_context="none"):
|
| 163 |
-
"""Request LLM sampling from the client."""
|
| 164 |
-
# In a real implementation, this would send a request to the client
|
| 165 |
-
return {
|
| 166 |
-
"role": "assistant",
|
| 167 |
-
"content": "Analysis of the provided data..."
|
| 168 |
-
}
|
| 169 |
-
```
|
| 170 |
-
|
| 171 |
-
</hfoption>
|
| 172 |
-
<hfoption id="javascript">
|
| 173 |
-
|
| 174 |
-
```javascript
|
| 175 |
-
function requestSampling(messages, systemPrompt = null, includeContext = 'none') {
|
| 176 |
-
// In a real implementation, this would send a request to the client
|
| 177 |
-
return {
|
| 178 |
-
role: 'assistant',
|
| 179 |
-
content: 'Analysis of the provided data...'
|
| 180 |
-
};
|
| 181 |
-
}
|
| 182 |
-
|
| 183 |
-
function handleSamplingRequest(request) {
|
| 184 |
-
const { messages, systemPrompt, includeContext } = request;
|
| 185 |
-
// In a real implementation, this would process the request and return a response
|
| 186 |
-
return {
|
| 187 |
-
role: 'assistant',
|
| 188 |
-
content: 'Response to the sampling request...'
|
| 189 |
-
};
|
| 190 |
-
}
|
| 191 |
-
```
|
| 192 |
-
|
| 193 |
-
</hfoption>
|
| 194 |
-
</hfoptions>
|
| 195 |
-
|
| 196 |
-
The sampling flow follows these steps:
|
| 197 |
-
1. Server sends a `sampling/createMessage` request to the client
|
| 198 |
-
2. Client reviews the request and can modify it
|
| 199 |
-
3. Client samples from an LLM
|
| 200 |
-
4. Client reviews the completion
|
| 201 |
-
5. Client returns the result to the server
|
| 202 |
-
|
| 203 |
-
<Tip>
|
| 204 |
-
|
| 205 |
-
This human-in-the-loop design ensures users maintain control over what the LLM sees and generates. When implementing sampling, it's important to provide clear, well-structured prompts and include relevant context.
|
| 206 |
-
|
| 207 |
-
</Tip>
|
| 208 |
-
|
| 209 |
-
## How Capabilities Work Together
|
| 210 |
-
|
| 211 |
-
Let's look at how these capabilities work together to enable complex interactions. In the table below, we've outlined the capabilities, who controls them, the direction of control, and some other details.
|
| 212 |
-
|
| 213 |
-
| Capability | Controlled By | Direction | Side Effects | Approval Needed | Typical Use Cases |
|
| 214 |
-
|------------|---------------|-----------|--------------|-----------------|-------------------|
|
| 215 |
-
| Tools | Model (LLM) | Client → Server | Yes (potentially) | Yes | Actions, API calls, data manipulation |
|
| 216 |
-
| Resources | Application | Client → Server | No (read-only) | Typically no | Data retrieval, context gathering |
|
| 217 |
-
| Prompts | User | Server → Client | No | No (selected by user) | Guided workflows, specialized templates |
|
| 218 |
-
| Sampling | Server | Server → Client → Server | Indirectly | Yes | Multi-step tasks, agentic behaviors |
|
| 219 |
-
|
| 220 |
-
These capabilities are designed to work together in complementary ways:
|
| 221 |
-
|
| 222 |
-
1. A user might select a **Prompt** to start a specialized workflow
|
| 223 |
-
2. The Prompt might include context from **Resources**
|
| 224 |
-
3. During processing, the AI model might call **Tools** to perform specific actions
|
| 225 |
-
4. For complex operations, the Server might use **Sampling** to request additional LLM processing
|
| 226 |
-
|
| 227 |
-
The distinction between these primitives provides a clear structure for MCP interactions, enabling AI models to access information, perform actions, and engage in complex workflows while maintaining appropriate control boundaries.
|
| 228 |
-
|
| 229 |
-
## Discovery Process
|
| 230 |
-
|
| 231 |
-
One of MCP's key features is dynamic capability discovery. When a Client connects to a Server, it can query the available Tools, Resources, and Prompts through specific list methods:
|
| 232 |
-
|
| 233 |
-
- `tools/list`: Discover available Tools
|
| 234 |
-
- `resources/list`: Discover available Resources
|
| 235 |
-
- `prompts/list`: Discover available Prompts
|
| 236 |
-
|
| 237 |
-
This dynamic discovery mechanism allows Clients to adapt to the specific capabilities each Server offers without requiring hardcoded knowledge of the Server's functionality.
|
| 238 |
-
|
| 239 |
-
## Conclusion
|
| 240 |
-
|
| 241 |
-
Understanding these core primitives is essential for working with MCP effectively. By providing distinct types of capabilities with clear control boundaries, MCP enables powerful interactions between AI models and external systems while maintaining appropriate safety and control mechanisms.
|
| 242 |
-
|
| 243 |
-
In the next section, we'll explore how Gradio integrates with MCP to provide easy-to-use interfaces for these capabilities.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/certificate.mdx
DELETED
|
@@ -1,19 +0,0 @@
|
|
| 1 |
-
# Get your certificate!
|
| 2 |
-
|
| 3 |
-
Well done! You've completed the first unit of the MCP course. Now it's time to take the exam to get your certificate.
|
| 4 |
-
|
| 5 |
-
Below is a quiz to check your understanding of the unit.
|
| 6 |
-
|
| 7 |
-
<iframe
|
| 8 |
-
src="https://mcp-course-unit-1-quiz.hf.space"
|
| 9 |
-
frameborder="0"
|
| 10 |
-
width="850"
|
| 11 |
-
height="450"
|
| 12 |
-
></iframe>
|
| 13 |
-
|
| 14 |
-
<Tip>
|
| 15 |
-
|
| 16 |
-
If you're struggling to use the quiz above, go to the space directly [on the Hugging Face Hub](https://huggingface.co/spaces/mcp-course/unit_1_quiz). If you find errors, you can report them in the space's [Community tab](https://huggingface.co/spaces/mcp-course/unit_1_quiz/discussions).
|
| 17 |
-
|
| 18 |
-
</Tip>
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/communication-protocol.mdx
DELETED
|
@@ -1,223 +0,0 @@
|
|
| 1 |
-
# The Communication Protocol
|
| 2 |
-
|
| 3 |
-
MCP defines a standardized communication protocol that enables Clients and Servers to exchange messages in a consistent, predictable way. This standardization is critical for interoperability across the community. In this section, we'll explore the protocol structure and transport mechanisms used in MCP.
|
| 4 |
-
|
| 5 |
-
<Tip warning={true}>
|
| 6 |
-
|
| 7 |
-
We're getting down to the nitty-gritty details of the MCP protocol. You won't need to know all of this to build with MCP, but it's good to know that it exists and how it works.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
## JSON-RPC: The Foundation
|
| 12 |
-
|
| 13 |
-
At its core, MCP uses **JSON-RPC 2.0** as the message format for all communication between Clients and Servers. JSON-RPC is a lightweight remote procedure call protocol encoded in JSON, which makes it:
|
| 14 |
-
|
| 15 |
-
- Human-readable and easy to debug
|
| 16 |
-
- Language-agnostic, supporting implementation in any programming environment
|
| 17 |
-
- Well-established, with clear specifications and widespread adoption
|
| 18 |
-
|
| 19 |
-

|
| 20 |
-
|
| 21 |
-
The protocol defines three types of messages:
|
| 22 |
-
|
| 23 |
-
### 1. Requests
|
| 24 |
-
|
| 25 |
-
Sent from Client to Server to initiate an operation. A Request message includes:
|
| 26 |
-
- A unique identifier (`id`)
|
| 27 |
-
- The method name to invoke (e.g., `tools/call`)
|
| 28 |
-
- Parameters for the method (if any)
|
| 29 |
-
|
| 30 |
-
Example Request:
|
| 31 |
-
|
| 32 |
-
```json
|
| 33 |
-
{
|
| 34 |
-
"jsonrpc": "2.0",
|
| 35 |
-
"id": 1,
|
| 36 |
-
"method": "tools/call",
|
| 37 |
-
"params": {
|
| 38 |
-
"name": "weather",
|
| 39 |
-
"arguments": {
|
| 40 |
-
"location": "San Francisco"
|
| 41 |
-
}
|
| 42 |
-
}
|
| 43 |
-
}
|
| 44 |
-
```
|
| 45 |
-
|
| 46 |
-
### 2. Responses
|
| 47 |
-
|
| 48 |
-
Sent from Server to Client in reply to a Request. A Response message includes:
|
| 49 |
-
- The same `id` as the corresponding Request
|
| 50 |
-
- Either a `result` (for success) or an `error` (for failure)
|
| 51 |
-
|
| 52 |
-
Example Success Response:
|
| 53 |
-
```json
|
| 54 |
-
{
|
| 55 |
-
"jsonrpc": "2.0",
|
| 56 |
-
"id": 1,
|
| 57 |
-
"result": {
|
| 58 |
-
"temperature": 62,
|
| 59 |
-
"conditions": "Partly cloudy"
|
| 60 |
-
}
|
| 61 |
-
}
|
| 62 |
-
```
|
| 63 |
-
|
| 64 |
-
Example Error Response:
|
| 65 |
-
```json
|
| 66 |
-
{
|
| 67 |
-
"jsonrpc": "2.0",
|
| 68 |
-
"id": 1,
|
| 69 |
-
"error": {
|
| 70 |
-
"code": -32602,
|
| 71 |
-
"message": "Invalid location parameter"
|
| 72 |
-
}
|
| 73 |
-
}
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
-
### 3. Notifications
|
| 77 |
-
|
| 78 |
-
One-way messages that don't require a response. Typically sent from Server to Client to provide updates or notifications about events.
|
| 79 |
-
|
| 80 |
-
Example Notification:
|
| 81 |
-
```json
|
| 82 |
-
{
|
| 83 |
-
"jsonrpc": "2.0",
|
| 84 |
-
"method": "progress",
|
| 85 |
-
"params": {
|
| 86 |
-
"message": "Processing data...",
|
| 87 |
-
"percent": 50
|
| 88 |
-
}
|
| 89 |
-
}
|
| 90 |
-
```
|
| 91 |
-
|
| 92 |
-
## Transport Mechanisms
|
| 93 |
-
|
| 94 |
-
JSON-RPC defines the message format, but MCP also specifies how these messages are transported between Clients and Servers. Two primary transport mechanisms are supported:
|
| 95 |
-
|
| 96 |
-
### stdio (Standard Input/Output)
|
| 97 |
-
|
| 98 |
-
The stdio transport is used for local communication, where the Client and Server run on the same machine:
|
| 99 |
-
|
| 100 |
-
The Host application launches the Server as a subprocess and communicates with it by writing to its standard input (stdin) and reading from its standard output (stdout).
|
| 101 |
-
|
| 102 |
-
<Tip>
|
| 103 |
-
|
| 104 |
-
**Use cases** for this transport are local tools like file system access or running local scripts.
|
| 105 |
-
|
| 106 |
-
</Tip>
|
| 107 |
-
|
| 108 |
-
The main **Advantages** of this transport are that it's simple, no network configuration required, and securely sandboxed by the operating system.
|
| 109 |
-
|
| 110 |
-
### HTTP + SSE (Server-Sent Events) / Streamable HTTP
|
| 111 |
-
|
| 112 |
-
The HTTP+SSE transport is used for remote communication, where the Client and Server might be on different machines:
|
| 113 |
-
|
| 114 |
-
Communication happens over HTTP, with the Server using Server-Sent Events (SSE) to push updates to the Client over a persistent connection.
|
| 115 |
-
|
| 116 |
-
<Tip>
|
| 117 |
-
|
| 118 |
-
**Use cases** for this transport are connecting to remote APIs, cloud services, or shared resources.
|
| 119 |
-
|
| 120 |
-
</Tip>
|
| 121 |
-
|
| 122 |
-
The main **Advantages** of this transport are that it works across networks, enables integration with web services, and is compatible with serverless environments.
|
| 123 |
-
|
| 124 |
-
Recent updates to the MCP standard have introduced or refined "Streamable HTTP," which offers more flexibility by allowing servers to dynamically upgrade to SSE for streaming when needed, while maintaining compatibility with serverless environments.
|
| 125 |
-
|
| 126 |
-
## The Interaction Lifecycle
|
| 127 |
-
|
| 128 |
-
In the previous section, we discussed the lifecycle of a single interaction between a Client (💻) and a Server (🌐). Let's now look at the lifecycle of a complete interaction between a Client and a Server in the context of the MCP protocol.
|
| 129 |
-
|
| 130 |
-
The MCP protocol defines a structured interaction lifecycle between Clients and Servers:
|
| 131 |
-
|
| 132 |
-
### Initialization
|
| 133 |
-
|
| 134 |
-
The Client connects to the Server and they exchange protocol versions and capabilities, and the Server responds with its supported protocol version and capabilities.
|
| 135 |
-
|
| 136 |
-
<table style="width: 100%;">
|
| 137 |
-
<tr>
|
| 138 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 139 |
-
<td style="text-align: center;">→<br>initialize</td>
|
| 140 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 141 |
-
</tr>
|
| 142 |
-
<tr>
|
| 143 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 144 |
-
<td style="text-align: center;">←<br>response</td>
|
| 145 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 146 |
-
</tr>
|
| 147 |
-
<tr>
|
| 148 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 149 |
-
<td style="text-align: center;">→<br>initialized</td>
|
| 150 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 151 |
-
</tr>
|
| 152 |
-
</table>
|
| 153 |
-
|
| 154 |
-
The Client confirms the initialization is complete via a notification message.
|
| 155 |
-
|
| 156 |
-
### Discovery
|
| 157 |
-
|
| 158 |
-
The Client requests information about available capabilities and the Server responds with a list of available tools.
|
| 159 |
-
|
| 160 |
-
<table style="width: 100%;">
|
| 161 |
-
<tr>
|
| 162 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 163 |
-
<td style="text-align: center;">→<br>tools/list</td>
|
| 164 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 165 |
-
</tr>
|
| 166 |
-
<tr>
|
| 167 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 168 |
-
<td style="text-align: center;">←<br>response</td>
|
| 169 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 170 |
-
</tr>
|
| 171 |
-
</table>
|
| 172 |
-
|
| 173 |
-
This process could be repeated for each tool, resource, or prompt type.
|
| 174 |
-
|
| 175 |
-
### Execution
|
| 176 |
-
|
| 177 |
-
The Client invokes capabilities based on the Host's needs.
|
| 178 |
-
|
| 179 |
-
<table style="width: 100%;">
|
| 180 |
-
<tr>
|
| 181 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 182 |
-
<td style="text-align: center;">→<br>tools/call</td>
|
| 183 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 184 |
-
</tr>
|
| 185 |
-
<tr>
|
| 186 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 187 |
-
<td style="text-align: center;">←<br>notification (optional progress)</td>
|
| 188 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 189 |
-
</tr>
|
| 190 |
-
<tr>
|
| 191 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 192 |
-
<td style="text-align: center;">←<br>response</td>
|
| 193 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 194 |
-
</tr>
|
| 195 |
-
</table>
|
| 196 |
-
|
| 197 |
-
### Termination
|
| 198 |
-
|
| 199 |
-
The connection is gracefully closed when no longer needed and the Server acknowledges the shutdown request.
|
| 200 |
-
|
| 201 |
-
<table style="width: 100%;">
|
| 202 |
-
<tr>
|
| 203 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 204 |
-
<td style="text-align: center;">→<br>shutdown</td>
|
| 205 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 206 |
-
</tr>
|
| 207 |
-
<tr>
|
| 208 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 209 |
-
<td style="text-align: center;">←<br>response</td>
|
| 210 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 211 |
-
</tr>
|
| 212 |
-
<tr>
|
| 213 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 214 |
-
<td style="text-align: center;">→<br>exit</td>
|
| 215 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 216 |
-
</tr>
|
| 217 |
-
</table>
|
| 218 |
-
|
| 219 |
-
The Client sends the final exit message to complete the termination.
|
| 220 |
-
|
| 221 |
-
## Protocol Evolution
|
| 222 |
-
|
| 223 |
-
The MCP protocol is designed to be extensible and adaptable. The initialization phase includes version negotiation, allowing for backward compatibility as the protocol evolves. Additionally, capability discovery enables Clients to adapt to the specific features each Server offers, enabling a mix of basic and advanced Servers in the same ecosystem.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/gradio-mcp.mdx
DELETED
|
@@ -1,154 +0,0 @@
|
|
| 1 |
-
# Gradio MCP Integration
|
| 2 |
-
|
| 3 |
-
We've now explored the core concepts of the MCP protocol and how to implement MCP Servers and Clients. In this section, we're going to make things slightly easier by using Gradio to create an MCP Server!
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
Gradio is a popular Python library for quickly creating customizable web interfaces for machine learning models.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
## Introduction to Gradio
|
| 12 |
-
|
| 13 |
-
Gradio allows developers to create UIs for their models with just a few lines of Python code. It's particularly useful for:
|
| 14 |
-
|
| 15 |
-
- Creating demos and prototypes
|
| 16 |
-
- Sharing models with non-technical users
|
| 17 |
-
- Testing and debugging model behavior
|
| 18 |
-
|
| 19 |
-
With the addition of MCP support, Gradio now offers a straightforward way to expose AI model capabilities through the standardized MCP protocol.
|
| 20 |
-
|
| 21 |
-
Combining Gradio with MCP allows you to create both human-friendly interfaces and AI-accessible tools with minimal code. But best of all, Gradio is already well-used by the AI community, so you can use it to share your MCP Servers with others.
|
| 22 |
-
|
| 23 |
-
## Prerequisites
|
| 24 |
-
|
| 25 |
-
To use Gradio with MCP support, you'll need to install Gradio with the MCP extra:
|
| 26 |
-
|
| 27 |
-
```bash
|
| 28 |
-
pip install "gradio[mcp]"
|
| 29 |
-
```
|
| 30 |
-
|
| 31 |
-
You'll also need an LLM application that supports tool calling using the MCP protocol, such as Cursor ( known as "MCP Hosts").
|
| 32 |
-
|
| 33 |
-
## Creating an MCP Server with Gradio
|
| 34 |
-
|
| 35 |
-
Let's walk through a basic example of creating an MCP Server using Gradio:
|
| 36 |
-
|
| 37 |
-
```python
|
| 38 |
-
import gradio as gr
|
| 39 |
-
|
| 40 |
-
def letter_counter(word: str, letter: str) -> int:
|
| 41 |
-
"""
|
| 42 |
-
Count the number of occurrences of a letter in a word or text.
|
| 43 |
-
|
| 44 |
-
Args:
|
| 45 |
-
word (str): The input text to search through
|
| 46 |
-
letter (str): The letter to search for
|
| 47 |
-
|
| 48 |
-
Returns:
|
| 49 |
-
int: The number of times the letter appears in the text
|
| 50 |
-
"""
|
| 51 |
-
word = word.lower()
|
| 52 |
-
letter = letter.lower()
|
| 53 |
-
count = word.count(letter)
|
| 54 |
-
return count
|
| 55 |
-
|
| 56 |
-
# Create a standard Gradio interface
|
| 57 |
-
demo = gr.Interface(
|
| 58 |
-
fn=letter_counter,
|
| 59 |
-
inputs=["textbox", "textbox"],
|
| 60 |
-
outputs="number",
|
| 61 |
-
title="Letter Counter",
|
| 62 |
-
description="Enter text and a letter to count how many times the letter appears in the text."
|
| 63 |
-
)
|
| 64 |
-
|
| 65 |
-
# Launch both the Gradio web interface and the MCP server
|
| 66 |
-
if __name__ == "__main__":
|
| 67 |
-
demo.launch(mcp_server=True)
|
| 68 |
-
```
|
| 69 |
-
|
| 70 |
-
With this setup, your letter counter function is now accessible through:
|
| 71 |
-
|
| 72 |
-
1. A traditional Gradio web interface for direct human interaction
|
| 73 |
-
2. An MCP Server that can be connected to compatible clients
|
| 74 |
-
|
| 75 |
-
The MCP server will be accessible at:
|
| 76 |
-
```
|
| 77 |
-
http://your-server:port/gradio_api/mcp/sse
|
| 78 |
-
```
|
| 79 |
-
|
| 80 |
-
The application itself will still be accessible and it looks like this:
|
| 81 |
-
|
| 82 |
-

|
| 83 |
-
|
| 84 |
-
## How It Works Behind the Scenes
|
| 85 |
-
|
| 86 |
-
When you set `mcp_server=True` in `launch()`, several things happen:
|
| 87 |
-
|
| 88 |
-
1. Gradio functions are automatically converted to MCP Tools
|
| 89 |
-
2. Input components map to tool argument schemas
|
| 90 |
-
3. Output components determine the response format
|
| 91 |
-
4. The Gradio server now also listens for MCP protocol messages
|
| 92 |
-
5. JSON-RPC over HTTP+SSE is set up for client-server communication
|
| 93 |
-
|
| 94 |
-
## Key Features of the Gradio <> MCP Integration
|
| 95 |
-
|
| 96 |
-
1. **Tool Conversion**: Each API endpoint in your Gradio app is automatically converted into an MCP tool with a corresponding name, description, and input schema. To view the tools and schemas, visit `http://your-server:port/gradio_api/mcp/schema` or go to the "View API" link in the footer of your Gradio app, and then click on "MCP".
|
| 97 |
-
|
| 98 |
-
2. **Environment Variable Support**: There are two ways to enable the MCP server functionality:
|
| 99 |
-
- Using the `mcp_server` parameter in `launch()`:
|
| 100 |
-
```python
|
| 101 |
-
demo.launch(mcp_server=True)
|
| 102 |
-
```
|
| 103 |
-
- Using environment variables:
|
| 104 |
-
```bash
|
| 105 |
-
export GRADIO_MCP_SERVER=True
|
| 106 |
-
```
|
| 107 |
-
|
| 108 |
-
3. **File Handling**: The server automatically handles file data conversions, including:
|
| 109 |
-
- Converting base64-encoded strings to file data
|
| 110 |
-
- Processing image files and returning them in the correct format
|
| 111 |
-
- Managing temporary file storage
|
| 112 |
-
|
| 113 |
-
It is **strongly** recommended that input images and files be passed as full URLs ("http://..." or "https://...") as MCP Clients do not always handle local files correctly.
|
| 114 |
-
|
| 115 |
-
4. **Hosted MCP Servers on 🤗 Spaces**: You can publish your Gradio application for free on Hugging Face Spaces, which will allow you to have a free hosted MCP server. Here's an example of such a Space: https://huggingface.co/spaces/abidlabs/mcp-tools
|
| 116 |
-
|
| 117 |
-
## Troubleshooting Tips
|
| 118 |
-
|
| 119 |
-
1. **Type Hints and Docstrings**: Ensure you provide type hints and valid docstrings for your functions. The docstring should include an "Args:" block with indented parameter names.
|
| 120 |
-
|
| 121 |
-
2. **String Inputs**: When in doubt, accept input arguments as `str` and convert them to the desired type inside the function.
|
| 122 |
-
|
| 123 |
-
3. **SSE Support**: Some MCP Hosts don't support SSE-based MCP Servers. In those cases, you can use `mcp-remote`:
|
| 124 |
-
```json
|
| 125 |
-
{
|
| 126 |
-
"mcpServers": {
|
| 127 |
-
"gradio": {
|
| 128 |
-
"command": "npx",
|
| 129 |
-
"args": [
|
| 130 |
-
"mcp-remote",
|
| 131 |
-
"http://your-server:port/gradio_api/mcp/sse"
|
| 132 |
-
]
|
| 133 |
-
}
|
| 134 |
-
}
|
| 135 |
-
}
|
| 136 |
-
```
|
| 137 |
-
|
| 138 |
-
4. **Restart**: If you encounter connection issues, try restarting both your MCP Client and MCP Server.
|
| 139 |
-
|
| 140 |
-
## Share your MCP Server
|
| 141 |
-
|
| 142 |
-
You can share your MCP Server by publishing your Gradio app to Hugging Face Spaces. The video below shows how to create a Hugging Face Space.
|
| 143 |
-
|
| 144 |
-
<Youtube id="3bSVKNKb_PY" />
|
| 145 |
-
|
| 146 |
-
Now, you can share your MCP Server with others by sharing your Hugging Face Space.
|
| 147 |
-
|
| 148 |
-
## Conclusion
|
| 149 |
-
|
| 150 |
-
Gradio's integration with MCP provides an accessible entry point to the MCP ecosystem. By leveraging Gradio's simplicity and adding MCP's standardization, developers can quickly create both human-friendly interfaces and AI-accessible tools with minimal code.
|
| 151 |
-
|
| 152 |
-
As we progress through this course, we'll explore more sophisticated MCP implementations, but Gradio offers an excellent starting point for understanding and experimenting with the protocol.
|
| 153 |
-
|
| 154 |
-
In the next unit, we'll dive deeper into building MCP applications, focusing on setting up development environments, exploring SDKs, and implementing more advanced MCP Servers and Clients.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/introduction.mdx
DELETED
|
@@ -1,33 +0,0 @@
|
|
| 1 |
-
# Introduction to Model Context Protocol (MCP)
|
| 2 |
-
|
| 3 |
-
Welcome to Unit 1 of the MCP Course! In this unit, we'll explore the fundamentals of Model Context Protocol.
|
| 4 |
-
|
| 5 |
-
## What You Will Learn
|
| 6 |
-
|
| 7 |
-
In this unit, you will:
|
| 8 |
-
|
| 9 |
-
* Understand what Model Context Protocol is and why it's important
|
| 10 |
-
* Learn the key concepts and terminology associated with MCP
|
| 11 |
-
* Explore the integration challenges that MCP solves
|
| 12 |
-
* Walk through the key benefits and goals of MCP
|
| 13 |
-
* See a simple example of MCP integration in action
|
| 14 |
-
|
| 15 |
-
By the end of this unit, you'll have a solid understanding of the foundational concepts of MCP and be ready to dive deeper into its architecture and implementation in the next unit.
|
| 16 |
-
|
| 17 |
-
## Importance of MCP
|
| 18 |
-
|
| 19 |
-
The AI ecosystem is evolving rapidly, with Large Language Models (LLMs) and other AI systems becoming increasingly capable. However, these models are often limited by their training data and lack access to real-time information or specialized tools. This limitation hinders the potential of AI systems to provide truly relevant, accurate, and helpful responses in many scenarios.
|
| 20 |
-
|
| 21 |
-
This is where Model Context Protocol (MCP) comes in. MCP enables AI models to connect with external data sources, tools, and environments, allowing for the seamless transfer of information and capabilities between AI systems and the broader digital world. This interoperability is crucial for the growth and adoption of truly useful AI applications.
|
| 22 |
-
|
| 23 |
-
## Overview of Unit 1
|
| 24 |
-
|
| 25 |
-
Here's a brief overview of what we'll cover in this unit:
|
| 26 |
-
|
| 27 |
-
1. **What is Model Context Protocol?** - We'll start by defining what MCP is and discussing its role in the AI ecosystem.
|
| 28 |
-
2. **Key Concepts** - We'll explore the fundamental concepts and terminology associated with MCP.
|
| 29 |
-
3. **Integration Challenges** - We'll examine the problems that MCP aims to solve, particularly the "M×N Integration Problem."
|
| 30 |
-
4. **Benefits and Goals** - We'll discuss the key benefits and goals of MCP, including standardization, enhanced AI capabilities, and interoperability.
|
| 31 |
-
5. **Simple Example** - Finally, we'll walk through a simple example of MCP integration to see how it works in practice.
|
| 32 |
-
|
| 33 |
-
Let's dive in and explore the exciting world of Model Context Protocol!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/key-concepts.mdx
DELETED
|
@@ -1,92 +0,0 @@
|
|
| 1 |
-
# Key Concepts and Terminology
|
| 2 |
-
|
| 3 |
-
Before diving deeper into the Model Context Protocol, it's important to understand the key concepts and terminology that form the foundation of MCP. This section will introduce the fundamental ideas that underpin the protocol and provide a common vocabulary for discussing MCP implementations throughout the course.
|
| 4 |
-
|
| 5 |
-
MCP is often described as the "USB-C for AI applications." Just as USB-C provides a standardized physical and logical interface for connecting various peripherals to computing devices, MCP offers a consistent protocol for linking AI models to external capabilities. This standardization benefits the entire ecosystem:
|
| 6 |
-
|
| 7 |
-
- **users** enjoy simpler and more consistent experiences across AI applications
|
| 8 |
-
- **AI application developers** gain easy integration with a growing ecosystem of tools and data sources
|
| 9 |
-
- **tool and data providers** need only create a single implementation that works with multiple AI applications
|
| 10 |
-
- the broader ecosystem benefits from increased interoperability, innovation, and reduced fragmentation
|
| 11 |
-
|
| 12 |
-
## The Integration Problem
|
| 13 |
-
|
| 14 |
-
The **M×N Integration Problem** refers to the challenge of connecting M different AI applications to N different external tools or data sources without a standardized approach.
|
| 15 |
-
|
| 16 |
-
### Without MCP (M×N Problem)
|
| 17 |
-
|
| 18 |
-
Without a protocol like MCP, developers would need to create M×N custom integrations—one for each possible pairing of an AI application with an external capability.
|
| 19 |
-
|
| 20 |
-

|
| 21 |
-
|
| 22 |
-
Each AI application would need to integrate with each tool/data source individually. This is a very complex and expensive process which introduces a lot of friction for developers, and high maintenance costs.
|
| 23 |
-
|
| 24 |
-
Once we have multiple models and multiple tools, the number of integrations becomes too large to manage, each with its own unique interface.
|
| 25 |
-
|
| 26 |
-

|
| 27 |
-
|
| 28 |
-
### With MCP (M+N Solution)
|
| 29 |
-
|
| 30 |
-
MCP transforms this into an M+N problem by providing a standard interface: each AI application implements the client side of MCP once, and each tool/data source implements the server side once. This dramatically reduces integration complexity and maintenance burden.
|
| 31 |
-
|
| 32 |
-

|
| 33 |
-
|
| 34 |
-
Each AI application implements the client side of MCP once, and each tool/data source implements the server side once.
|
| 35 |
-
|
| 36 |
-
## Core MCP Terminology
|
| 37 |
-
|
| 38 |
-
Now that we understand the problem that MCP solves, let's dive into the core terminology and concepts that make up the MCP protocol.
|
| 39 |
-
|
| 40 |
-
<Tip>
|
| 41 |
-
|
| 42 |
-
MCP is a standard like HTTP or USB-C, and is a protocol for connecting AI applications to external tools and data sources. Therefore, using standard terminology is crucial to making the MCP work effectively.
|
| 43 |
-
|
| 44 |
-
When documenting our applications and communicating with the community, we should use the following terminology.
|
| 45 |
-
|
| 46 |
-
</Tip>
|
| 47 |
-
|
| 48 |
-
### Components
|
| 49 |
-
|
| 50 |
-
Just like client server relationships in HTTP, MCP has a client and a server.
|
| 51 |
-
|
| 52 |
-

|
| 53 |
-
|
| 54 |
-
- **Host**: The user-facing AI application that end-users interact with directly. Examples include Anthropic's Claude Desktop, AI-enhanced IDEs like Cursor, inference libraries like Hugging Face Python SDK, or custom applications built in libraries like LangChain or smolagents. Hosts initiate connections to MCP Servers and orchestrate the overall flow between user requests, LLM processing, and external tools.
|
| 55 |
-
|
| 56 |
-
- **Client**: A component within the host application that manages communication with a specific MCP Server. Each Client maintains a 1:1 connection with a single Server, handling the protocol-level details of MCP communication and acting as an intermediary between the Host's logic and the external Server.
|
| 57 |
-
|
| 58 |
-
- **Server**: An external program or service that exposes capabilities (Tools, Resources, Prompts) via the MCP protocol.
|
| 59 |
-
|
| 60 |
-
<Tip warning={true}>
|
| 61 |
-
|
| 62 |
-
A lot of content uses 'Client' and 'Host' interchangeably. Technically speaking, the host is the user-facing application, and the client is the component within the host application that manages communication with a specific MCP Server.
|
| 63 |
-
|
| 64 |
-
</Tip>
|
| 65 |
-
|
| 66 |
-
### Capabilities
|
| 67 |
-
|
| 68 |
-
Of course, your application's value is the sum of the capabilities it offers. So the capabilities are the most important part of your application. MCP's can connect with any software service, but there are some common capabilities that are used for many AI applications.
|
| 69 |
-
|
| 70 |
-
| Capability | Description | Example |
|
| 71 |
-
| ---------- | ----------- | ------- |
|
| 72 |
-
| **Tools** | Executable functions that the AI model can invoke to perform actions or retrieve computed data. Typically relating to the use case of the application. | A tool for a weather application might be a function that returns the weather in a specific location. |
|
| 73 |
-
| **Resources** | Read-only data sources that provide context without significant computation. | A researcher assistant might have a resource for scientific papers. |
|
| 74 |
-
| **Prompts** | Pre-defined templates or workflows that guide interactions between users, AI models, and the available capabilities. | A summarization prompt. |
|
| 75 |
-
| **Sampling** | Server-initiated requests for the Client/Host to perform LLM interactions, enabling recursive actions where the LLM can review generated content and make further decisions. | A writing application reviewing its own output and decides to refine it further. |
|
| 76 |
-
|
| 77 |
-
In the following diagram, we can see the collective capabilities applied to a use case for a code agent.
|
| 78 |
-
|
| 79 |
-

|
| 80 |
-
|
| 81 |
-
This application might use their MCP entities in the following way:
|
| 82 |
-
|
| 83 |
-
| Entity | Name | Description |
|
| 84 |
-
| --- | --- | --- |
|
| 85 |
-
| Tool | Code Interpreter | A tool that can execute code that the LLM writes. |
|
| 86 |
-
| Resource | Documentation | A resource that contains the documentation of the application. |
|
| 87 |
-
| Prompt | Code Style | A prompt that guides the LLM to generate code. |
|
| 88 |
-
| Sampling | Code Review | A sampling that allows the LLM to review the code and make further decisions. |
|
| 89 |
-
|
| 90 |
-
### Conclusion
|
| 91 |
-
|
| 92 |
-
Understanding these key concepts and terminology provides the foundation for working with MCP effectively. In the following sections, we'll build on this foundation to explore the architectural components, communication protocol, and capabilities that make up the Model Context Protocol.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/mcp-clients.mdx
DELETED
|
@@ -1,357 +0,0 @@
|
|
| 1 |
-
# MCP Clients
|
| 2 |
-
|
| 3 |
-
Now that we have a basic understanding of the Model Context Protocol, we can explore the essential role of MCP Clients in the Model Context Protocol ecosystem.
|
| 4 |
-
|
| 5 |
-
In this part of Unit 1, we'll explore the essential role of MCP Clients in the Model Context Protocol ecosystem.
|
| 6 |
-
|
| 7 |
-
In this section, you will:
|
| 8 |
-
|
| 9 |
-
* Understand what MCP Clients are and their role in the MCP architecture
|
| 10 |
-
* Learn about the key responsibilities of MCP Clients
|
| 11 |
-
* Explore the major MCP Client implementations
|
| 12 |
-
* Discover how to use Hugging Face's MCP Client implementation
|
| 13 |
-
* See practical examples of MCP Client usage
|
| 14 |
-
|
| 15 |
-
<Tip>
|
| 16 |
-
|
| 17 |
-
In this page we're going to show examples of how to set up MCP Clients in a few different ways using the JSON notation. For now, we will use *examples* like `path/to/server.py` to represent the path to the MCP Server. In the next unit, we'll implement this with real MCP Servers.
|
| 18 |
-
|
| 19 |
-
For now, focus on understanding the MCP Client notation. We'll implement the MCP Servers in the next unit.
|
| 20 |
-
|
| 21 |
-
</Tip>
|
| 22 |
-
|
| 23 |
-
## Understanding MCP Clients
|
| 24 |
-
|
| 25 |
-
MCP Clients are crucial components that act as the bridge between AI applications (Hosts) and external capabilities provided by MCP Servers. Think of the Host as your main application (like an AI assistant or IDE) and the Client as a specialized module within that Host responsible for handling MCP communications.
|
| 26 |
-
|
| 27 |
-
## User Interface Client
|
| 28 |
-
|
| 29 |
-
Let's start by exploring the user interface clients that are available for the MCP.
|
| 30 |
-
|
| 31 |
-
### Chat Interface Clients
|
| 32 |
-
|
| 33 |
-
Anthropic's Claude Desktop stands as one of the most prominent MCP Clients, providing integration with various MCP Servers.
|
| 34 |
-
|
| 35 |
-
### Interactive Development Clients
|
| 36 |
-
|
| 37 |
-
Cursor's MCP Client implementation enables AI-powered coding assistance through direct integration with code editing capabilities. It supports multiple MCP Server connections and provides real-time tool invocation during coding, making it a powerful tool for developers.
|
| 38 |
-
|
| 39 |
-
Continue.dev is another example of an interactive development client that supports MCP and connects to an MCP server from VS Code.
|
| 40 |
-
|
| 41 |
-
## Configuring MCP Clients
|
| 42 |
-
|
| 43 |
-
Now that we've covered the core of the MCP protocol, let's look at how to configure your MCP servers and clients.
|
| 44 |
-
|
| 45 |
-
Effective deployment of MCP servers and clients requires proper configuration.
|
| 46 |
-
|
| 47 |
-
<Tip>
|
| 48 |
-
|
| 49 |
-
The MCP specification is still evolving, so the configuration methods are subject to evolution. We'll focus on the current best practices for configuration.
|
| 50 |
-
|
| 51 |
-
</Tip>
|
| 52 |
-
|
| 53 |
-
### MCP Configuration Files
|
| 54 |
-
|
| 55 |
-
MCP hosts use configuration files to manage server connections. These files define which servers are available and how to connect to them.
|
| 56 |
-
|
| 57 |
-
Fortunately, the configuration files are very simple, easy to understand, and consistent across major MCP hosts.
|
| 58 |
-
|
| 59 |
-
#### `mcp.json` Structure
|
| 60 |
-
|
| 61 |
-
The standard configuration file for MCP is named `mcp.json`. Here's the basic structure:
|
| 62 |
-
|
| 63 |
-
This is the basic structure of the `mcp.json` can be passed to applications like Claude Desktop, Cursor, or VS Code.
|
| 64 |
-
|
| 65 |
-
```json
|
| 66 |
-
{
|
| 67 |
-
"servers": [
|
| 68 |
-
{
|
| 69 |
-
"name": "Server Name",
|
| 70 |
-
"transport": {
|
| 71 |
-
"type": "stdio|sse",
|
| 72 |
-
// Transport-specific configuration
|
| 73 |
-
}
|
| 74 |
-
}
|
| 75 |
-
]
|
| 76 |
-
}
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
-
In this example, we have a single server with a name and a transport type. The transport type is either `stdio` or `sse`.
|
| 80 |
-
|
| 81 |
-
#### Configuration for stdio Transport
|
| 82 |
-
|
| 83 |
-
For local servers using stdio transport, the configuration includes the command and arguments to launch the server process:
|
| 84 |
-
|
| 85 |
-
```json
|
| 86 |
-
{
|
| 87 |
-
"servers": [
|
| 88 |
-
{
|
| 89 |
-
"name": "File Explorer",
|
| 90 |
-
"transport": {
|
| 91 |
-
"type": "stdio",
|
| 92 |
-
"command": "python",
|
| 93 |
-
"args": ["/path/to/file_explorer_server.py"] // This is an example, we'll use a real server in the next unit
|
| 94 |
-
}
|
| 95 |
-
}
|
| 96 |
-
]
|
| 97 |
-
}
|
| 98 |
-
```
|
| 99 |
-
|
| 100 |
-
Here, we have a server called "File Explorer" that is a local script.
|
| 101 |
-
|
| 102 |
-
#### Configuration for HTTP+SSE Transport
|
| 103 |
-
|
| 104 |
-
For remote servers using HTTP+SSE transport, the configuration includes the server URL:
|
| 105 |
-
|
| 106 |
-
```json
|
| 107 |
-
{
|
| 108 |
-
"servers": [
|
| 109 |
-
{
|
| 110 |
-
"name": "Remote API Server",
|
| 111 |
-
"transport": {
|
| 112 |
-
"type": "sse",
|
| 113 |
-
"url": "https://example.com/mcp-server"
|
| 114 |
-
}
|
| 115 |
-
}
|
| 116 |
-
]
|
| 117 |
-
}
|
| 118 |
-
```
|
| 119 |
-
|
| 120 |
-
#### Environment Variables in Configuration
|
| 121 |
-
|
| 122 |
-
Environment variables can be passed to server processes using the `env` field. Here's how to access them in your server code:
|
| 123 |
-
|
| 124 |
-
<hfoptions id="env-variables">
|
| 125 |
-
<hfoption id="python">
|
| 126 |
-
|
| 127 |
-
In Python, we use the `os` module to access environment variables:
|
| 128 |
-
|
| 129 |
-
```python
|
| 130 |
-
import os
|
| 131 |
-
|
| 132 |
-
# Access environment variables
|
| 133 |
-
github_token = os.environ.get("GITHUB_TOKEN")
|
| 134 |
-
if not github_token:
|
| 135 |
-
raise ValueError("GITHUB_TOKEN environment variable is required")
|
| 136 |
-
|
| 137 |
-
# Use the token in your server code
|
| 138 |
-
def make_github_request():
|
| 139 |
-
headers = {"Authorization": f"Bearer {github_token}"}
|
| 140 |
-
# ... rest of your code
|
| 141 |
-
```
|
| 142 |
-
|
| 143 |
-
</hfoption>
|
| 144 |
-
<hfoption id="javascript">
|
| 145 |
-
|
| 146 |
-
In JavaScript, we use the `process.env` object to access environment variables:
|
| 147 |
-
|
| 148 |
-
```javascript
|
| 149 |
-
// Access environment variables
|
| 150 |
-
const githubToken = process.env.GITHUB_TOKEN;
|
| 151 |
-
if (!githubToken) {
|
| 152 |
-
throw new Error("GITHUB_TOKEN environment variable is required");
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
// Use the token in your server code
|
| 156 |
-
function makeGithubRequest() {
|
| 157 |
-
const headers = { "Authorization": `Bearer ${githubToken}` };
|
| 158 |
-
// ... rest of your code
|
| 159 |
-
}
|
| 160 |
-
```
|
| 161 |
-
|
| 162 |
-
</hfoption>
|
| 163 |
-
</hfoptions>
|
| 164 |
-
|
| 165 |
-
The corresponding configuration in `mcp.json` would look like this:
|
| 166 |
-
|
| 167 |
-
```json
|
| 168 |
-
{
|
| 169 |
-
"servers": [
|
| 170 |
-
{
|
| 171 |
-
"name": "GitHub API",
|
| 172 |
-
"transport": {
|
| 173 |
-
"type": "stdio",
|
| 174 |
-
"command": "python",
|
| 175 |
-
"args": ["/path/to/github_server.py"], // This is an example, we'll use a real server in the next unit
|
| 176 |
-
"env": {
|
| 177 |
-
"GITHUB_TOKEN": "your_github_token"
|
| 178 |
-
}
|
| 179 |
-
}
|
| 180 |
-
}
|
| 181 |
-
]
|
| 182 |
-
}
|
| 183 |
-
```
|
| 184 |
-
|
| 185 |
-
### Configuration Examples
|
| 186 |
-
|
| 187 |
-
Let's look at some real-world configuration scenarios:
|
| 188 |
-
|
| 189 |
-
#### Scenario 1: Local Server Configuration
|
| 190 |
-
|
| 191 |
-
In this scenario, we have a local server that is a Python script which could be a file explorer or a code editor.
|
| 192 |
-
|
| 193 |
-
```json
|
| 194 |
-
{
|
| 195 |
-
"servers": [
|
| 196 |
-
{
|
| 197 |
-
"name": "File Explorer",
|
| 198 |
-
"transport": {
|
| 199 |
-
"type": "stdio",
|
| 200 |
-
"command": "python",
|
| 201 |
-
"args": ["/path/to/file_explorer_server.py"] // This is an example, we'll use a real server in the next unit
|
| 202 |
-
}
|
| 203 |
-
}
|
| 204 |
-
]
|
| 205 |
-
}
|
| 206 |
-
```
|
| 207 |
-
|
| 208 |
-
#### Scenario 2: Remote Server Configuration
|
| 209 |
-
|
| 210 |
-
In this scenario, we have a remote server that is a weather API.
|
| 211 |
-
|
| 212 |
-
```json
|
| 213 |
-
{
|
| 214 |
-
"servers": [
|
| 215 |
-
{
|
| 216 |
-
"name": "Weather API",
|
| 217 |
-
"transport": {
|
| 218 |
-
"type": "sse",
|
| 219 |
-
"url": "https://example.com/mcp-server" // This is an example, we'll use a real server in the next unit
|
| 220 |
-
}
|
| 221 |
-
}
|
| 222 |
-
]
|
| 223 |
-
}
|
| 224 |
-
```
|
| 225 |
-
|
| 226 |
-
Proper configuration is essential for successfully deploying MCP integrations. By understanding these aspects, you can create robust and reliable connections between AI applications and external capabilities.
|
| 227 |
-
|
| 228 |
-
In the next section, we'll explore the ecosystem of MCP servers available on Hugging Face Hub and how to publish your own servers there.
|
| 229 |
-
|
| 230 |
-
## Tiny Agents Clients
|
| 231 |
-
|
| 232 |
-
Now, let's explore how to use MCP Clients within code.
|
| 233 |
-
|
| 234 |
-
You can also use tiny agents as MCP Clients to connect directly to MCP servers from your code. Tiny agents provide a simple way to create AI agents that can use tools from MCP servers.
|
| 235 |
-
|
| 236 |
-
Tiny Agent can run MCP servers with a command line environment. To do this, we will need to install `npm` and run the server with `npx`. **We'll need these for both Python and JavaScript.**
|
| 237 |
-
|
| 238 |
-
Let's install `npx` with `npm`. If you don't have `npm` installed, check out the [npm documentation](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
|
| 239 |
-
|
| 240 |
-
### Setup
|
| 241 |
-
|
| 242 |
-
First, we will need to install `npx` if you don't have it installed. You can do this with the following command:
|
| 243 |
-
|
| 244 |
-
```bash
|
| 245 |
-
# install npx
|
| 246 |
-
npm install -g npx
|
| 247 |
-
```
|
| 248 |
-
|
| 249 |
-
Then, we will need to install the huggingface_hub package with the MCP support. This will allow us to run MCP servers and clients.
|
| 250 |
-
|
| 251 |
-
```bash
|
| 252 |
-
pip install "huggingface_hub[mcp]>=0.32.0"
|
| 253 |
-
```
|
| 254 |
-
|
| 255 |
-
Then, we will need to log in to the Hugging Face Hub to access the MCP servers. You can do this with the `huggingface-cli` command line tool. You will need a [login token](https://huggingface.co/docs/huggingface_hub/v0.32.3/en/quick-start#authentication) to do this.
|
| 256 |
-
|
| 257 |
-
```bash
|
| 258 |
-
huggingface-cli login
|
| 259 |
-
```
|
| 260 |
-
|
| 261 |
-
<hfoptions id="language">
|
| 262 |
-
<hfoption id="python">
|
| 263 |
-
|
| 264 |
-
### Connecting to MCP Servers
|
| 265 |
-
|
| 266 |
-
Now, let's create an agent configuration file `agent.json`.
|
| 267 |
-
|
| 268 |
-
```json
|
| 269 |
-
{
|
| 270 |
-
"model": "Qwen/Qwen2.5-72B-Instruct",
|
| 271 |
-
"provider": "nebius",
|
| 272 |
-
"servers": [
|
| 273 |
-
{
|
| 274 |
-
"type": "stdio",
|
| 275 |
-
"config": {
|
| 276 |
-
"command": "npx",
|
| 277 |
-
"args": ["@playwright/mcp@latest"]
|
| 278 |
-
}
|
| 279 |
-
}
|
| 280 |
-
]
|
| 281 |
-
}
|
| 282 |
-
```
|
| 283 |
-
|
| 284 |
-
In this configuration, we are using the `@playwright/mcp` MCP server. This is a MCP server that can control a browser with Playwright.
|
| 285 |
-
|
| 286 |
-
Now you can run the agent:
|
| 287 |
-
|
| 288 |
-
```bash
|
| 289 |
-
tiny-agents run agent.json
|
| 290 |
-
```
|
| 291 |
-
</hfoption>
|
| 292 |
-
<hfoption id="javascript">
|
| 293 |
-
|
| 294 |
-
First, install the tiny agents package with [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
|
| 295 |
-
|
| 296 |
-
```bash
|
| 297 |
-
npm install @huggingface/tiny-agents
|
| 298 |
-
```
|
| 299 |
-
|
| 300 |
-
### Connecting to MCP Servers
|
| 301 |
-
|
| 302 |
-
Make an agent project directory and create an `agent.json` file.
|
| 303 |
-
|
| 304 |
-
```bash
|
| 305 |
-
mkdir my-agent
|
| 306 |
-
touch my-agent/agent.json
|
| 307 |
-
```
|
| 308 |
-
|
| 309 |
-
Create an agent configuration file at `my-agent/agent.json`:
|
| 310 |
-
|
| 311 |
-
```json
|
| 312 |
-
{
|
| 313 |
-
"model": "Qwen/Qwen2.5-72B-Instruct",
|
| 314 |
-
"provider": "nebius",
|
| 315 |
-
"servers": [
|
| 316 |
-
{
|
| 317 |
-
"type": "stdio",
|
| 318 |
-
"config": {
|
| 319 |
-
"command": "npx",
|
| 320 |
-
"args": ["@playwright/mcp@latest"]
|
| 321 |
-
}
|
| 322 |
-
}
|
| 323 |
-
]
|
| 324 |
-
}
|
| 325 |
-
```
|
| 326 |
-
|
| 327 |
-
Now you can run the agent:
|
| 328 |
-
|
| 329 |
-
```bash
|
| 330 |
-
npx @huggingface/tiny-agents run ./my-agent
|
| 331 |
-
```
|
| 332 |
-
|
| 333 |
-
</hfoption>
|
| 334 |
-
</hfoptions>
|
| 335 |
-
|
| 336 |
-
In the video below, we run the agent and ask it to open a new tab in the browser.
|
| 337 |
-
|
| 338 |
-
The following example shows a web-browsing agent configured to use the [Qwen/Qwen2.5-72B-Instruct](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct) model via Nebius inference provider, and it comes equipped with a playwright MCP server, which lets it use a web browser! The agent config is loaded specifying [its path in the `tiny-agents/tiny-agents`](https://huggingface.co/datasets/tiny-agents/tiny-agents/tree/main/celinah/web-browser) Hugging Face dataset.
|
| 339 |
-
|
| 340 |
-
<video controls autoplay loop>
|
| 341 |
-
<source src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/python-tiny-agents/web_browser_agent.mp4" type="video/mp4">
|
| 342 |
-
</video>
|
| 343 |
-
|
| 344 |
-
When you run the agent, you'll see it load, listing the tools it has discovered from its connected MCP servers. Then, it's ready for your prompts!
|
| 345 |
-
|
| 346 |
-
Prompt used in this demo:
|
| 347 |
-
|
| 348 |
-
> do a Web Search for HF inference providers on Brave Search and open the first result and then give me the list of the inference providers supported on Hugging Face
|
| 349 |
-
|
| 350 |
-
## Next Steps
|
| 351 |
-
|
| 352 |
-
Now that you understand MCP Clients, you're ready to:
|
| 353 |
-
* Explore specific MCP Server implementations
|
| 354 |
-
* Learn about creating custom MCP Clients
|
| 355 |
-
* Dive into advanced MCP integration patterns
|
| 356 |
-
|
| 357 |
-
Let's continue our journey into the world of Model Context Protocol!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/quiz1.mdx
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
# Quiz 1: MCP Fundamentals
|
| 2 |
-
|
| 3 |
-
Test your knowledge of the core concepts of Model Context Protocol.
|
| 4 |
-
|
| 5 |
-
### Q1: What is the primary purpose of Model Context Protocol (MCP)?
|
| 6 |
-
|
| 7 |
-
<Question
|
| 8 |
-
choices={[
|
| 9 |
-
{
|
| 10 |
-
text: "To limit the training data of AI models",
|
| 11 |
-
explain: "MCP aims to expand, not limit, the contexts AI models can access."
|
| 12 |
-
},
|
| 13 |
-
{
|
| 14 |
-
text: "To enable AI models to connect with external data sources, tools, and environments",
|
| 15 |
-
explain: "Correct! MCP's main goal is to facilitate interoperability.",
|
| 16 |
-
correct: true
|
| 17 |
-
},
|
| 18 |
-
{
|
| 19 |
-
text: "To replace prompting when using Large Language Models",
|
| 20 |
-
explain: "MCP is a protocol that enhances prompting, not a replacement for it."
|
| 21 |
-
},
|
| 22 |
-
{
|
| 23 |
-
text: "To create a new programming language for AI",
|
| 24 |
-
explain: "MCP is a protocol, not a programming language."
|
| 25 |
-
}
|
| 26 |
-
]}
|
| 27 |
-
/>
|
| 28 |
-
|
| 29 |
-
### Q2: What problem does MCP primarily aim to solve?
|
| 30 |
-
|
| 31 |
-
<Question
|
| 32 |
-
choices={[
|
| 33 |
-
{
|
| 34 |
-
text: "The lack of AI models",
|
| 35 |
-
explain: "MCP addresses integration challenges, not the availability of AI models themselves."
|
| 36 |
-
},
|
| 37 |
-
{
|
| 38 |
-
text: "The high cost of training LLMs",
|
| 39 |
-
explain: "While MCP can improve efficiency, its primary focus is not on reducing training costs directly."
|
| 40 |
-
},
|
| 41 |
-
{
|
| 42 |
-
text: "The M×N Integration Problem",
|
| 43 |
-
explain: "Correct! MCP standardizes connections to avoid M×N custom integrations.",
|
| 44 |
-
correct: true
|
| 45 |
-
},
|
| 46 |
-
{
|
| 47 |
-
text: "The difficulty in creating new AI algorithms",
|
| 48 |
-
explain: "MCP facilitates using existing algorithms and tools, not creating new ones from scratch."
|
| 49 |
-
}
|
| 50 |
-
]}
|
| 51 |
-
/>
|
| 52 |
-
|
| 53 |
-
### Q3: Which of the following is a key benefit of MCP?
|
| 54 |
-
|
| 55 |
-
<Question
|
| 56 |
-
choices={[
|
| 57 |
-
{
|
| 58 |
-
text: "Reduced AI model accuracy",
|
| 59 |
-
explain: "MCP aims to enhance AI capabilities, which should ideally lead to improved or maintained accuracy, not reduced."
|
| 60 |
-
},
|
| 61 |
-
{
|
| 62 |
-
text: "Increased complexity in AI development",
|
| 63 |
-
explain: "MCP aims to simplify integration, thereby reducing complexity."
|
| 64 |
-
},
|
| 65 |
-
{
|
| 66 |
-
text: "Standardization and interoperability in the AI ecosystem",
|
| 67 |
-
explain: "Correct! This is a primary goal and benefit of MCP.",
|
| 68 |
-
correct: true
|
| 69 |
-
},
|
| 70 |
-
{
|
| 71 |
-
text: "Isolation of AI models from external systems",
|
| 72 |
-
explain: "MCP promotes connection and interaction, not isolation."
|
| 73 |
-
}
|
| 74 |
-
]}
|
| 75 |
-
/>
|
| 76 |
-
|
| 77 |
-
### Q4: In MCP terminology, what is a "Host"?
|
| 78 |
-
|
| 79 |
-
<Question
|
| 80 |
-
choices={[
|
| 81 |
-
{
|
| 82 |
-
text: "The external program exposing capabilities",
|
| 83 |
-
explain: "This describes an MCP Server."
|
| 84 |
-
},
|
| 85 |
-
{
|
| 86 |
-
text: "The user-facing AI application",
|
| 87 |
-
explain: "Correct! The Host is the application users interact with.",
|
| 88 |
-
correct: true
|
| 89 |
-
},
|
| 90 |
-
{
|
| 91 |
-
text: "A read-only data source",
|
| 92 |
-
explain: "This describes a type of MCP Capability (Resource)."
|
| 93 |
-
},
|
| 94 |
-
{
|
| 95 |
-
text: "A pre-defined template for interactions",
|
| 96 |
-
explain: "This describes a type of MCP Capability (Prompt)."
|
| 97 |
-
}
|
| 98 |
-
]}
|
| 99 |
-
/>
|
| 100 |
-
|
| 101 |
-
### Q5: What does "M×N Integration Problem" refer to in the context of AI applications?
|
| 102 |
-
|
| 103 |
-
<Question
|
| 104 |
-
choices={[
|
| 105 |
-
{
|
| 106 |
-
text: "The difficulty of training M models with N datasets",
|
| 107 |
-
explain: "This relates to model training, not the integration problem MCP addresses."
|
| 108 |
-
},
|
| 109 |
-
{
|
| 110 |
-
text: "The challenge of connecting M AI applications to N external tools without a standard",
|
| 111 |
-
explain: "Correct! MCP provides the standard to solve this M*N complexity.",
|
| 112 |
-
correct: true
|
| 113 |
-
},
|
| 114 |
-
{
|
| 115 |
-
text: "The problem of managing M users across N applications",
|
| 116 |
-
explain: "This is a user management or identity problem, not the focus of MCP."
|
| 117 |
-
},
|
| 118 |
-
{
|
| 119 |
-
text: "The complexity of developing M features for N different user segments",
|
| 120 |
-
explain: "This relates to product development strategy, not system integration in the way MCP defines."
|
| 121 |
-
}
|
| 122 |
-
]}
|
| 123 |
-
/>
|
| 124 |
-
|
| 125 |
-
Congrats on finishing this Quiz 🥳! If you need to review any elements, take the time to revisit the chapter to reinforce your knowledge.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/quiz2.mdx
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
# Quiz 2: MCP SDK
|
| 2 |
-
|
| 3 |
-
Test your knowledge of the MCP SDKs and their functionalities.
|
| 4 |
-
|
| 5 |
-
### Q1: What is the main purpose of the MCP SDKs?
|
| 6 |
-
|
| 7 |
-
<Question
|
| 8 |
-
choices={[
|
| 9 |
-
{
|
| 10 |
-
text: "To define the MCP protocol specification",
|
| 11 |
-
explain: "The SDKs implement the protocol, they don't define it. The specification is separate."
|
| 12 |
-
},
|
| 13 |
-
{
|
| 14 |
-
text: "To make it easier to implement MCP clients and servers",
|
| 15 |
-
explain: "Correct! SDKs abstract away low-level protocol details.",
|
| 16 |
-
correct: true
|
| 17 |
-
},
|
| 18 |
-
{
|
| 19 |
-
text: "To provide a visual interface for MCP interactions",
|
| 20 |
-
explain: "While some tools might offer this (like MCP Inspector), it's not the primary purpose of the SDKs themselves."
|
| 21 |
-
},
|
| 22 |
-
{
|
| 23 |
-
text: "To replace the need for programming languages",
|
| 24 |
-
explain: "SDKs are libraries used within programming languages."
|
| 25 |
-
}
|
| 26 |
-
]}
|
| 27 |
-
/>
|
| 28 |
-
|
| 29 |
-
### Q2: Which of the following functionalities do the MCP SDKs typically handle?
|
| 30 |
-
|
| 31 |
-
<Question
|
| 32 |
-
choices={[
|
| 33 |
-
{
|
| 34 |
-
text: "Optimizing MCP Servers",
|
| 35 |
-
explain: "This is outside the scope of MCP SDKs, which focus on protocol implementation."
|
| 36 |
-
},
|
| 37 |
-
{
|
| 38 |
-
text: "Defining new AI algorithms",
|
| 39 |
-
explain: "This is outside the scope of MCP SDKs, which focus on protocol implementation."
|
| 40 |
-
},
|
| 41 |
-
{
|
| 42 |
-
text: "Message serialization/deserialization",
|
| 43 |
-
explain: "Correct! This is a core function for handling JSON-RPC messages.",
|
| 44 |
-
correct: true
|
| 45 |
-
},
|
| 46 |
-
{
|
| 47 |
-
text: "Hosting Large Language Models",
|
| 48 |
-
explain: "MCP enables connection to LLMs, but the SDKs themselves don't host them."
|
| 49 |
-
}
|
| 50 |
-
]}
|
| 51 |
-
/>
|
| 52 |
-
|
| 53 |
-
### Q3: According to the provided text, which company maintains the official Python SDK for MCP?
|
| 54 |
-
|
| 55 |
-
<Question
|
| 56 |
-
choices={[
|
| 57 |
-
{
|
| 58 |
-
text: "Google",
|
| 59 |
-
explain: "The text lists Anthropic as the maintainer."
|
| 60 |
-
},
|
| 61 |
-
{
|
| 62 |
-
text: "Anthropic",
|
| 63 |
-
explain: "Correct! The course material indicates Anthropic maintains the Python SDK.",
|
| 64 |
-
correct: true
|
| 65 |
-
},
|
| 66 |
-
{
|
| 67 |
-
text: "Microsoft",
|
| 68 |
-
explain: "Microsoft maintains the C# SDK according to the text."
|
| 69 |
-
},
|
| 70 |
-
{
|
| 71 |
-
text: "JetBrains",
|
| 72 |
-
explain: "JetBrains maintains the Kotlin SDK according to the text."
|
| 73 |
-
}
|
| 74 |
-
]}
|
| 75 |
-
/>
|
| 76 |
-
|
| 77 |
-
### Q4: What command is used to start a development MCP server using a Python file named `server.py`?
|
| 78 |
-
|
| 79 |
-
<Question
|
| 80 |
-
choices={[
|
| 81 |
-
{
|
| 82 |
-
text: "python server.py run",
|
| 83 |
-
explain: "While you run Python scripts with `python`, MCP has a specific CLI command."
|
| 84 |
-
},
|
| 85 |
-
{
|
| 86 |
-
text: "mcp start server.py",
|
| 87 |
-
explain: "The command is `mcp dev`, not `mcp start`."
|
| 88 |
-
},
|
| 89 |
-
{
|
| 90 |
-
text: "mcp dev server.py",
|
| 91 |
-
explain: "Correct! This command initializes the development server.",
|
| 92 |
-
correct: true
|
| 93 |
-
},
|
| 94 |
-
{
|
| 95 |
-
text: "serve mcp server.py",
|
| 96 |
-
explain: "This is not the standard MCP CLI command shown in the course material."
|
| 97 |
-
}
|
| 98 |
-
]}
|
| 99 |
-
/>
|
| 100 |
-
|
| 101 |
-
### Q5: What is the role of JSON-RPC 2.0 in MCP?
|
| 102 |
-
|
| 103 |
-
<Question
|
| 104 |
-
choices={[
|
| 105 |
-
{
|
| 106 |
-
text: "As a primary transport mechanism for remote communication",
|
| 107 |
-
explain: "HTTP+SSE or Streamable HTTP are transport mechanisms; JSON-RPC is the message format."
|
| 108 |
-
},
|
| 109 |
-
{
|
| 110 |
-
text: "As the message format for all communication between Clients and Servers",
|
| 111 |
-
explain: "Correct! MCP uses JSON-RPC 2.0 for structuring messages.",
|
| 112 |
-
correct: true
|
| 113 |
-
},
|
| 114 |
-
{
|
| 115 |
-
text: "As a tool for debugging AI models",
|
| 116 |
-
explain: "While its human-readable nature helps in debugging communications, it's not a debugging tool for AI models themselves."
|
| 117 |
-
},
|
| 118 |
-
{
|
| 119 |
-
text: "As a method for defining AI capabilities like Tools and Resources",
|
| 120 |
-
explain: "Capabilities are defined by their own schemas; JSON-RPC is used to invoke them and exchange data."
|
| 121 |
-
}
|
| 122 |
-
]}
|
| 123 |
-
/>
|
| 124 |
-
|
| 125 |
-
Congrats on finishing this Quiz 🥳! If you need to review any elements, take the time to revisit the chapter to reinforce your knowledge.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/sdk.mdx
DELETED
|
@@ -1,169 +0,0 @@
|
|
| 1 |
-
# MCP SDK
|
| 2 |
-
|
| 3 |
-
The Model Context Protocol provides official SDKs for both JavaScript, Python and other languages. This makes it easy to implement MCP clients and servers in your applications. These SDKs handle the low-level protocol details, allowing you to focus on building your application's capabilities.
|
| 4 |
-
|
| 5 |
-
## SDK Overview
|
| 6 |
-
|
| 7 |
-
Both SDKs provide similar core functionality, following the MCP protocol specification we discussed earlier. They handle:
|
| 8 |
-
|
| 9 |
-
- Protocol-level communication
|
| 10 |
-
- Capability registration and discovery
|
| 11 |
-
- Message serialization/deserialization
|
| 12 |
-
- Connection management
|
| 13 |
-
- Error handling
|
| 14 |
-
|
| 15 |
-
## Core Primitives Implementation
|
| 16 |
-
|
| 17 |
-
Let's explore how to implement each of the core primitives (Tools, Resources, and Prompts) using both SDKs.
|
| 18 |
-
|
| 19 |
-
<hfoptions id="server-implementation">
|
| 20 |
-
<hfoption id="python">
|
| 21 |
-
|
| 22 |
-
<Youtube id="exzrb5QNUis" />
|
| 23 |
-
|
| 24 |
-
```python
|
| 25 |
-
from mcp.server.fastmcp import FastMCP
|
| 26 |
-
|
| 27 |
-
# Create an MCP server
|
| 28 |
-
mcp = FastMCP("Weather Service")
|
| 29 |
-
|
| 30 |
-
# Tool implementation
|
| 31 |
-
@mcp.tool()
|
| 32 |
-
def get_weather(location: str) -> str:
|
| 33 |
-
"""Get the current weather for a specified location."""
|
| 34 |
-
return f"Weather in {location}: Sunny, 72°F"
|
| 35 |
-
|
| 36 |
-
# Resource implementation
|
| 37 |
-
@mcp.resource("weather://{location}")
|
| 38 |
-
def weather_resource(location: str) -> str:
|
| 39 |
-
"""Provide weather data as a resource."""
|
| 40 |
-
return f"Weather data for {location}: Sunny, 72°F"
|
| 41 |
-
|
| 42 |
-
# Prompt implementation
|
| 43 |
-
@mcp.prompt()
|
| 44 |
-
def weather_report(location: str) -> str:
|
| 45 |
-
"""Create a weather report prompt."""
|
| 46 |
-
return f"""You are a weather reporter. Weather report for {location}?"""
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
# Run the server
|
| 50 |
-
if __name__ == "__main__":
|
| 51 |
-
mcp.run()
|
| 52 |
-
|
| 53 |
-
```
|
| 54 |
-
|
| 55 |
-
</hfoption>
|
| 56 |
-
<hfoption id="javascript">
|
| 57 |
-
|
| 58 |
-
```javascript
|
| 59 |
-
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
| 60 |
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
| 61 |
-
import { z } from "zod";
|
| 62 |
-
|
| 63 |
-
// Create an MCP server
|
| 64 |
-
const server = new McpServer({
|
| 65 |
-
name: "Weather Service",
|
| 66 |
-
version: "1.0.0"
|
| 67 |
-
});
|
| 68 |
-
|
| 69 |
-
// Tool implementation
|
| 70 |
-
server.tool("get_weather",
|
| 71 |
-
{ location: z.string() },
|
| 72 |
-
async ({ location }) => ({
|
| 73 |
-
content: [{
|
| 74 |
-
type: "text",
|
| 75 |
-
text: `Weather in ${location}: Sunny, 72°F`
|
| 76 |
-
}]
|
| 77 |
-
})
|
| 78 |
-
);
|
| 79 |
-
|
| 80 |
-
// Resource implementation
|
| 81 |
-
server.resource(
|
| 82 |
-
"weather",
|
| 83 |
-
new ResourceTemplate("weather://{location}", { list: undefined }),
|
| 84 |
-
async (uri, { location }) => ({
|
| 85 |
-
contents: [{
|
| 86 |
-
uri: uri.href,
|
| 87 |
-
text: `Weather data for ${location}: Sunny, 72°F`
|
| 88 |
-
}]
|
| 89 |
-
})
|
| 90 |
-
);
|
| 91 |
-
|
| 92 |
-
// Prompt implementation
|
| 93 |
-
server.prompt(
|
| 94 |
-
"weather_report",
|
| 95 |
-
{ location: z.string() },
|
| 96 |
-
async ({ location }) => ({
|
| 97 |
-
messages: [
|
| 98 |
-
{
|
| 99 |
-
role: "assistant",
|
| 100 |
-
content: {
|
| 101 |
-
type: "text",
|
| 102 |
-
text: "You are a weather reporter."
|
| 103 |
-
}
|
| 104 |
-
},
|
| 105 |
-
{
|
| 106 |
-
role: "user",
|
| 107 |
-
content: {
|
| 108 |
-
type: "text",
|
| 109 |
-
text: `Weather report for ${location}?`
|
| 110 |
-
}
|
| 111 |
-
}
|
| 112 |
-
]
|
| 113 |
-
})
|
| 114 |
-
);
|
| 115 |
-
|
| 116 |
-
// Run the server
|
| 117 |
-
const transport = new StdioServerTransport();
|
| 118 |
-
await server.connect(transport);
|
| 119 |
-
```
|
| 120 |
-
|
| 121 |
-
</hfoption>
|
| 122 |
-
</hfoptions>
|
| 123 |
-
|
| 124 |
-
Once you have your server implemented, you can start it by running the server script.
|
| 125 |
-
|
| 126 |
-
```bash
|
| 127 |
-
mcp dev server.py
|
| 128 |
-
```
|
| 129 |
-
|
| 130 |
-
This will initialize a development server running the file `server.py`. And log the following output:
|
| 131 |
-
|
| 132 |
-
```bash
|
| 133 |
-
Starting MCP inspector...
|
| 134 |
-
⚙️ Proxy server listening on port 6277
|
| 135 |
-
Spawned stdio transport
|
| 136 |
-
Connected MCP client to backing server transport
|
| 137 |
-
Created web app transport
|
| 138 |
-
Set up MCP proxy
|
| 139 |
-
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
|
| 140 |
-
```
|
| 141 |
-
|
| 142 |
-
You can then open the MCP Inspector at [http://127.0.0.1:6274](http://127.0.0.1:6274) to see the server's capabilities and interact with them.
|
| 143 |
-
|
| 144 |
-
You'll see the server's capabilities and the ability to call them via the UI.
|
| 145 |
-
|
| 146 |
-

|
| 147 |
-
|
| 148 |
-
## MCP SDKs
|
| 149 |
-
|
| 150 |
-
MCP is designed to be language-agnostic, and there are official SDKs available for several popular programming languages:
|
| 151 |
-
|
| 152 |
-
| Language | Repository | Maintainer(s) | Status |
|
| 153 |
-
|----------|------------|---------------|--------|
|
| 154 |
-
| TypeScript | [github.com/modelcontextprotocol/typescript-sdk](https://github.com/modelcontextprotocol/typescript-sdk) | Anthropic | Active |
|
| 155 |
-
| Python | [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) | Anthropic | Active |
|
| 156 |
-
| Java | [github.com/modelcontextprotocol/java-sdk](https://github.com/modelcontextprotocol/java-sdk) | Spring AI (VMware) | Active |
|
| 157 |
-
| Kotlin | [github.com/modelcontextprotocol/kotlin-sdk](https://github.com/modelcontextprotocol/kotlin-sdk) | JetBrains | Active |
|
| 158 |
-
| C# | [github.com/modelcontextprotocol/csharp-sdk](https://github.com/modelcontextprotocol/csharp-sdk) | Microsoft | Active (Preview) |
|
| 159 |
-
| Swift | [github.com/modelcontextprotocol/swift-sdk](https://github.com/modelcontextprotocol/swift-sdk) | loopwork-ai | Active |
|
| 160 |
-
| Rust | [github.com/modelcontextprotocol/rust-sdk](https://github.com/modelcontextprotocol/rust-sdk) | Anthropic/Community | Active |
|
| 161 |
-
| Dart | [https://github.com/leehack/mcp_dart](https://github.com/leehack/mcp_dart) | Flutter Community | Active |
|
| 162 |
-
|
| 163 |
-
These SDKs provide language-specific abstractions that simplify working with the MCP protocol, allowing you to focus on implementing the core logic of your servers or clients rather than dealing with low-level protocol details.
|
| 164 |
-
|
| 165 |
-
## Next Steps
|
| 166 |
-
|
| 167 |
-
We've only scratched the surface of what you can do with the MCP but you've already got a basic server running. In fact, you've also connected to it using the MCP Client in the browser.
|
| 168 |
-
|
| 169 |
-
In the next section, we'll look at how to connect to your server from an LLM.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit1/unit1-recap.mdx
DELETED
|
@@ -1,45 +0,0 @@
|
|
| 1 |
-
# Unit1 recap
|
| 2 |
-
|
| 3 |
-
## Model Context Protocol (MCP)
|
| 4 |
-
|
| 5 |
-
The MCP is a standardized protocol designed to connect AI models with external tools, data sources, and environments. It addresses the limitations of existing AI systems by enabling interoperability and access to real-time information.
|
| 6 |
-
|
| 7 |
-
## Key Concepts
|
| 8 |
-
|
| 9 |
-
### Client-Server Architecture
|
| 10 |
-
MCP follows a client-server model where clients manage communication between users and servers. This architecture promotes modularity, allowing for easy addition of new servers without requiring changes to existing hosts.
|
| 11 |
-
|
| 12 |
-
### Components
|
| 13 |
-
#### Host
|
| 14 |
-
The user-facing AI application that serves as the interface for end-users.
|
| 15 |
-
|
| 16 |
-
##### Client
|
| 17 |
-
A component within the host application responsible for managing communication with a specific MCP server. Clients maintain 1:1 connections with servers and handle protocol-level details.
|
| 18 |
-
|
| 19 |
-
#### Server
|
| 20 |
-
An external program or service that provides access to tools, data sources, or services via the MCP protocol. Servers act as lightweight wrappers around existing functionalities.
|
| 21 |
-
|
| 22 |
-
### Capabilities
|
| 23 |
-
#### Tools
|
| 24 |
-
Executable functions that can perform actions (e.g., sending messages, querying APIs). Tools are typically model-controlled and require user approval due to their ability to perform actions with side effects.
|
| 25 |
-
|
| 26 |
-
#### Resources
|
| 27 |
-
Read-only data sources for context retrieval without significant computation. Resources are application-controlled and designed for data retrieval similar to GET endpoints in REST APIs.
|
| 28 |
-
|
| 29 |
-
#### Prompts
|
| 30 |
-
Pre-defined templates or workflows that guide interactions between users, AI models, and available capabilities. Prompts are user-controlled and set the context for interactions.
|
| 31 |
-
|
| 32 |
-
#### Sampling
|
| 33 |
-
Server-initiated requests for LLM processing, enabling server-driven agentic behaviors and potentially recursive or multi-step interactions. Sampling operations typically require user approval.
|
| 34 |
-
|
| 35 |
-
### Communication Protocol
|
| 36 |
-
The MCP protocol uses JSON-RPC 2.0 as the message format for communication between clients and servers. Two primary transport mechanisms are supported: stdio (for local communication) and HTTP+SSE (for remote communication). Messages include requests, responses, and notifications.
|
| 37 |
-
|
| 38 |
-
### Discovery Process
|
| 39 |
-
MCP allows clients to dynamically discover available tools, resources, and prompts through list methods (e.g., `tools/list`). This dynamic discovery mechanism enables clients to adapt to the specific capabilities each server offers without requiring hardcoded knowledge of server functionality.
|
| 40 |
-
|
| 41 |
-
### MCP SDKs
|
| 42 |
-
Official SDKs are available in various programming languages for implementing MCP clients and servers. These SDKs handle protocol-level communication, capability registration, and error handling, simplifying the development process.
|
| 43 |
-
|
| 44 |
-
### Gradio Integration
|
| 45 |
-
Gradio allows easy creation of web interfaces that expose capabilities to the MCP protocol, making it accessible for both humans and AI models. This integration provides a human-friendly interface alongside AI-accessible tools with minimal code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit2/clients.mdx
DELETED
|
@@ -1,136 +0,0 @@
|
|
| 1 |
-
# Building MCP Clients
|
| 2 |
-
|
| 3 |
-
In this section, we'll create clients that can interact with our MCP server using different programming languages. We'll implement both a JavaScript client using HuggingFace.js and a Python client using smolagents.
|
| 4 |
-
|
| 5 |
-
## Configuring MCP Clients
|
| 6 |
-
|
| 7 |
-
Effective deployment of MCP servers and clients requires proper configuration. The MCP specification is still evolving, so the configuration methods are subject to evolution. We'll focus on the current best practices for configuration.
|
| 8 |
-
|
| 9 |
-
### MCP Configuration Files
|
| 10 |
-
|
| 11 |
-
MCP hosts use configuration files to manage server connections. These files define which servers are available and how to connect to them.
|
| 12 |
-
|
| 13 |
-
The configuration files are very simple, easy to understand, and consistent across major MCP hosts.
|
| 14 |
-
|
| 15 |
-
#### `mcp.json` Structure
|
| 16 |
-
|
| 17 |
-
The standard configuration file for MCP is named `mcp.json`. Here's the basic structure:
|
| 18 |
-
|
| 19 |
-
```json
|
| 20 |
-
{
|
| 21 |
-
"servers": [
|
| 22 |
-
{
|
| 23 |
-
"name": "MCP Server",
|
| 24 |
-
"transport": {
|
| 25 |
-
"type": "sse",
|
| 26 |
-
"url": "http://localhost:7860/gradio_api/mcp/sse"
|
| 27 |
-
}
|
| 28 |
-
}
|
| 29 |
-
]
|
| 30 |
-
}
|
| 31 |
-
```
|
| 32 |
-
|
| 33 |
-
In this example, we have a single server configured to use SSE transport, connecting to a local Gradio server running on port 7860.
|
| 34 |
-
|
| 35 |
-
<Tip>
|
| 36 |
-
|
| 37 |
-
We've connected to the Gradio app via SSE transport because we assume that the gradio app is running on a remote server. However, if you want to connect to a local script, `stdio` transport instead of `sse` transport is a better option.
|
| 38 |
-
|
| 39 |
-
</Tip>
|
| 40 |
-
|
| 41 |
-
#### Configuration for HTTP+SSE Transport
|
| 42 |
-
|
| 43 |
-
For remote servers using HTTP+SSE transport, the configuration includes the server URL:
|
| 44 |
-
|
| 45 |
-
```json
|
| 46 |
-
{
|
| 47 |
-
"servers": [
|
| 48 |
-
{
|
| 49 |
-
"name": "Remote MCP Server",
|
| 50 |
-
"transport": {
|
| 51 |
-
"type": "sse",
|
| 52 |
-
"url": "https://example.com/gradio_api/mcp/sse"
|
| 53 |
-
}
|
| 54 |
-
}
|
| 55 |
-
]
|
| 56 |
-
}
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
This configuration allows your UI client to communicate with the Gradio MCP server using the MCP protocol, enabling seamless integration between your frontend and the MCP service.
|
| 60 |
-
|
| 61 |
-
## Configuring a UI MCP Client
|
| 62 |
-
|
| 63 |
-
When working with Gradio MCP servers, you can configure your UI client to connect to the server using the MCP protocol. Here's how to set it up:
|
| 64 |
-
|
| 65 |
-
### Basic Configuration
|
| 66 |
-
|
| 67 |
-
Create a new file called `config.json` with the following configuration:
|
| 68 |
-
|
| 69 |
-
```json
|
| 70 |
-
{
|
| 71 |
-
"mcpServers": {
|
| 72 |
-
"mcp": {
|
| 73 |
-
"url": "http://localhost:7860/gradio_api/mcp/sse"
|
| 74 |
-
}
|
| 75 |
-
}
|
| 76 |
-
}
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
-
This configuration allows your UI client to communicate with the Gradio MCP server using the MCP protocol, enabling seamless integration between your frontend and the MCP service.
|
| 80 |
-
|
| 81 |
-
## Configuring a MCP Client within Cursor IDE
|
| 82 |
-
|
| 83 |
-
Cursor provides built-in MCP support, allowing you to connect your deployed MCP servers directly to your development environment.
|
| 84 |
-
|
| 85 |
-
### Configuration
|
| 86 |
-
|
| 87 |
-
Open Cursor settings (`Ctrl + Shift + J` / `Cmd + Shift + J`) → **MCP** tab → **Add new global MCP server**:
|
| 88 |
-
|
| 89 |
-
**macOS:**
|
| 90 |
-
```json
|
| 91 |
-
{
|
| 92 |
-
"mcpServers": {
|
| 93 |
-
"sentiment-analysis": {
|
| 94 |
-
"command": "npx",
|
| 95 |
-
"args": [
|
| 96 |
-
"-y",
|
| 97 |
-
"mcp-remote",
|
| 98 |
-
"https://YOURUSENAME-mcp-sentiment.hf.space/gradio_api/mcp/sse",
|
| 99 |
-
"--transport",
|
| 100 |
-
"sse-only"
|
| 101 |
-
]
|
| 102 |
-
}
|
| 103 |
-
}
|
| 104 |
-
}
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
**Windows:**
|
| 108 |
-
```json
|
| 109 |
-
{
|
| 110 |
-
"mcpServers": {
|
| 111 |
-
"sentiment-analysis": {
|
| 112 |
-
"command": "cmd",
|
| 113 |
-
"args": [
|
| 114 |
-
"/c",
|
| 115 |
-
"npx",
|
| 116 |
-
"-y",
|
| 117 |
-
"mcp-remote",
|
| 118 |
-
"https://YOURUSENAME-mcp-sentiment.hf.space/gradio_api/mcp/sse",
|
| 119 |
-
"--transport",
|
| 120 |
-
"sse-only"
|
| 121 |
-
]
|
| 122 |
-
}
|
| 123 |
-
}
|
| 124 |
-
}
|
| 125 |
-
```
|
| 126 |
-
|
| 127 |
-
### Why We Use mcp-remote
|
| 128 |
-
|
| 129 |
-
Most MCP clients, including Cursor, currently only support local servers via stdio transport and don't yet support remote servers with OAuth authentication. The `mcp-remote` tool serves as a bridge solution that:
|
| 130 |
-
|
| 131 |
-
- Runs locally on your machine
|
| 132 |
-
- Forwards requests from Cursor to the remote MCP server
|
| 133 |
-
- Uses the familiar configuration file format
|
| 134 |
-
|
| 135 |
-
Once configured, you can ask Cursor to use your sentiment analysis tool for tasks like analyzing code comments, user feedback, or pull request descriptions.
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit2/gradio-client.mdx
DELETED
|
@@ -1,179 +0,0 @@
|
|
| 1 |
-
# Gradio as an MCP Client
|
| 2 |
-
|
| 3 |
-
In the previous section, we explored how to create an MCP Server using Gradio and connect to it using an MCP Client. In this section, we're going to explore how to use Gradio as an MCP Client to connect to an MCP Server.
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
Gradio is best suited to the creation of UI clients and MCP servers, but it is also possible to use it as an MCP Client and expose that as a UI.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
We'll connect to the MCP server we created in the previous section and use it to answer questions.
|
| 12 |
-
|
| 13 |
-
## MCP Client in Gradio
|
| 14 |
-
|
| 15 |
-
### Connect to an example MCP Server
|
| 16 |
-
|
| 17 |
-
Let's connect to an example MCP Server that is already running on Hugging Face. We'll use [this one](https://huggingface.co/spaces/abidlabs/mcp-tools2) for this example. It's a space that contains a collection of MCP tools.
|
| 18 |
-
|
| 19 |
-
```python
|
| 20 |
-
from smolagents.mcp_client import MCPClient
|
| 21 |
-
|
| 22 |
-
with MCPClient(
|
| 23 |
-
{"url": "https://abidlabs-mcp-tools2.hf.space/gradio_api/mcp/sse"}
|
| 24 |
-
) as tools:
|
| 25 |
-
# Tools from the remote server are available
|
| 26 |
-
print("\n".join(f"{t.name}: {t.description}" for t in tools))
|
| 27 |
-
|
| 28 |
-
```
|
| 29 |
-
|
| 30 |
-
<details>
|
| 31 |
-
<summary>Output</summary>
|
| 32 |
-
<pre>
|
| 33 |
-
<code>
|
| 34 |
-
prime_factors: Compute the prime factorization of a positive integer.
|
| 35 |
-
generate_cheetah_image: Generate a cheetah image.
|
| 36 |
-
image_orientation: Returns whether image is portrait or landscape.
|
| 37 |
-
sepia: Apply a sepia filter to the input image.
|
| 38 |
-
</code>
|
| 39 |
-
</pre>
|
| 40 |
-
</details>
|
| 41 |
-
|
| 42 |
-
### Connect to your MCP Server from Gradio
|
| 43 |
-
|
| 44 |
-
Great, now that you've connected to an example MCP Server, let's connect to your own MCP Server from Gradio.
|
| 45 |
-
|
| 46 |
-
First, we need to install the `smolagents`, Gradio and mcp-client libraries, if we haven't already:
|
| 47 |
-
|
| 48 |
-
```bash
|
| 49 |
-
pip install "smolagents[mcp]" "gradio[mcp]" mcp fastmcp
|
| 50 |
-
```
|
| 51 |
-
|
| 52 |
-
Now, we can import the necessary libraries and create a simple Gradio interface that uses the MCP Client to connect to the MCP Server.
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
```python
|
| 56 |
-
import gradio as gr
|
| 57 |
-
import os
|
| 58 |
-
|
| 59 |
-
from mcp import StdioServerParameters
|
| 60 |
-
from smolagents import InferenceClientModel, CodeAgent, ToolCollection, MCPClient
|
| 61 |
-
```
|
| 62 |
-
|
| 63 |
-
Next, we'll connect to the MCP Server and get the tools that we can use to answer questions.
|
| 64 |
-
|
| 65 |
-
```python
|
| 66 |
-
mcp_client = MCPClient(
|
| 67 |
-
{"url": "http://localhost:7860/gradio_api/mcp/sse"} # This is the MCP Server we created in the previous section
|
| 68 |
-
)
|
| 69 |
-
tools = mcp_client.get_tools()
|
| 70 |
-
```
|
| 71 |
-
|
| 72 |
-
Now that we have the tools, we can create a simple agent that uses them to answer questions. We'll just use a simple `InferenceClientModel` and the default model from `smolagents` for now.
|
| 73 |
-
|
| 74 |
-
It is important to pass your api_key to the InferenceClientModel. You can access the token from your huggingface account. [check here.](https://huggingface.co/docs/hub/en/security-tokens), and set the access token with the environment variable `HF_TOKEN`.
|
| 75 |
-
|
| 76 |
-
```python
|
| 77 |
-
model = InferenceClientModel(token=os.getenv("HF_TOKEN"))
|
| 78 |
-
agent = CodeAgent(tools=[*tools], model=model)
|
| 79 |
-
```
|
| 80 |
-
|
| 81 |
-
Now, we can create a simple Gradio interface that uses the agent to answer questions.
|
| 82 |
-
|
| 83 |
-
```python
|
| 84 |
-
demo = gr.ChatInterface(
|
| 85 |
-
fn=lambda message, history: str(agent.run(message)),
|
| 86 |
-
type="messages",
|
| 87 |
-
examples=["Prime factorization of 68"],
|
| 88 |
-
title="Agent with MCP Tools",
|
| 89 |
-
description="This is a simple agent that uses MCP tools to answer questions."
|
| 90 |
-
)
|
| 91 |
-
|
| 92 |
-
demo.launch()
|
| 93 |
-
```
|
| 94 |
-
|
| 95 |
-
And that's it! We've created a simple Gradio interface that uses the MCP Client to connect to the MCP Server and answer questions.
|
| 96 |
-
|
| 97 |
-
<iframe
|
| 98 |
-
src="https://mcp-course-unit2-gradio-client.hf.space"
|
| 99 |
-
frameborder="0"
|
| 100 |
-
width="850"
|
| 101 |
-
height="450"
|
| 102 |
-
></iframe>
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
## Complete Example
|
| 106 |
-
|
| 107 |
-
Here's the complete example of the MCP Client in Gradio:
|
| 108 |
-
|
| 109 |
-
```python
|
| 110 |
-
import gradio as gr
|
| 111 |
-
import os
|
| 112 |
-
|
| 113 |
-
from mcp import StdioServerParameters
|
| 114 |
-
from smolagents import InferenceClientModel, CodeAgent, ToolCollection, MCPClient
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
try:
|
| 118 |
-
mcp_client = MCPClient(
|
| 119 |
-
{"url": "http://localhost:7860/gradio_api/mcp/sse"} # This is the MCP Server we created in the previous section
|
| 120 |
-
)
|
| 121 |
-
tools = mcp_client.get_tools()
|
| 122 |
-
|
| 123 |
-
model = InferenceClientModel(token=os.getenv("HUGGINGFACE_API_TOKEN"))
|
| 124 |
-
agent = CodeAgent(tools=[*tools], model=model)
|
| 125 |
-
|
| 126 |
-
demo = gr.ChatInterface(
|
| 127 |
-
fn=lambda message, history: str(agent.run(message)),
|
| 128 |
-
type="messages",
|
| 129 |
-
examples=["Prime factorization of 68"],
|
| 130 |
-
title="Agent with MCP Tools",
|
| 131 |
-
description="This is a simple agent that uses MCP tools to answer questions.",
|
| 132 |
-
)
|
| 133 |
-
|
| 134 |
-
demo.launch()
|
| 135 |
-
finally:
|
| 136 |
-
mcp_client.disconnect()
|
| 137 |
-
```
|
| 138 |
-
|
| 139 |
-
You'll notice that we're closing the MCP Client in the `finally` block. This is important because the MCP Client is a long-lived object that needs to be closed when the program exits.
|
| 140 |
-
|
| 141 |
-
## Deploying to Hugging Face Spaces
|
| 142 |
-
|
| 143 |
-
To make your server available to others, you can deploy it to Hugging Face Spaces, just like we did in the previous section.
|
| 144 |
-
To deploy your Gradio MCP client to Hugging Face Spaces:
|
| 145 |
-
|
| 146 |
-
1. Create a new Space on Hugging Face:
|
| 147 |
-
- Go to huggingface.co/spaces
|
| 148 |
-
- Click "Create new Space"
|
| 149 |
-
- Choose "Gradio" as the SDK
|
| 150 |
-
- Name your space (e.g., "mcp-client")
|
| 151 |
-
|
| 152 |
-
2. Update MCP Server URL in the code:
|
| 153 |
-
|
| 154 |
-
```python
|
| 155 |
-
mcp_client = MCPClient(
|
| 156 |
-
{"url": "http://localhost:7860/gradio_api/mcp/sse"} # This is the MCP Server we created in the previous section
|
| 157 |
-
)
|
| 158 |
-
```
|
| 159 |
-
|
| 160 |
-
3. Create a `requirements.txt` file:
|
| 161 |
-
```txt
|
| 162 |
-
gradio[mcp]
|
| 163 |
-
smolagents[mcp]
|
| 164 |
-
```
|
| 165 |
-
|
| 166 |
-
4. Push your code to the Space:
|
| 167 |
-
```bash
|
| 168 |
-
git init
|
| 169 |
-
git add server.py requirements.txt
|
| 170 |
-
git commit -m "Initial commit"
|
| 171 |
-
git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-client
|
| 172 |
-
git push -u origin main
|
| 173 |
-
```
|
| 174 |
-
|
| 175 |
-
## Conclusion
|
| 176 |
-
|
| 177 |
-
In this section, we've explored how to use Gradio as an MCP Client to connect to an MCP Server. We've also seen how to deploy the MCP Client in Hugging Face Spaces.
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit2/gradio-server.mdx
DELETED
|
@@ -1,190 +0,0 @@
|
|
| 1 |
-
# Building the Gradio MCP Server
|
| 2 |
-
|
| 3 |
-
In this section, we'll create our sentiment analysis MCP server using Gradio. This server will expose a sentiment analysis tool that can be used by both human users through a web interface and AI models through the MCP protocol.
|
| 4 |
-
|
| 5 |
-
## Introduction to Gradio MCP Integration
|
| 6 |
-
|
| 7 |
-
Gradio provides a straightforward way to create MCP servers by automatically converting your Python functions into MCP tools. When you set `mcp_server=True` in `launch()`, Gradio:
|
| 8 |
-
|
| 9 |
-
1. Automatically converts your functions into MCP Tools
|
| 10 |
-
2. Maps input components to tool argument schemas
|
| 11 |
-
3. Determines response formats from output components
|
| 12 |
-
4. Sets up JSON-RPC over HTTP+SSE for client-server communication
|
| 13 |
-
5. Creates both a web interface and an MCP server endpoint
|
| 14 |
-
|
| 15 |
-
## Setting Up the Project
|
| 16 |
-
|
| 17 |
-
First, let's create a new directory for our project and set up the required dependencies:
|
| 18 |
-
|
| 19 |
-
```bash
|
| 20 |
-
mkdir mcp-sentiment
|
| 21 |
-
cd mcp-sentiment
|
| 22 |
-
python -m venv venv
|
| 23 |
-
source venv/bin/activate # On Windows: venv\Scripts\activate
|
| 24 |
-
pip install "gradio[mcp]" textblob
|
| 25 |
-
```
|
| 26 |
-
|
| 27 |
-
## Creating the Server
|
| 28 |
-
|
| 29 |
-
> Hugging face spaces needs an app.py file to build the space. So the name of the python file has to be app.py
|
| 30 |
-
|
| 31 |
-
Create a new file called `app.py` with the following code:
|
| 32 |
-
|
| 33 |
-
```python
|
| 34 |
-
import gradio as gr
|
| 35 |
-
from textblob import TextBlob
|
| 36 |
-
|
| 37 |
-
def sentiment_analysis(text: str) -> dict:
|
| 38 |
-
"""
|
| 39 |
-
Analyze the sentiment of the given text.
|
| 40 |
-
|
| 41 |
-
Args:
|
| 42 |
-
text (str): The text to analyze
|
| 43 |
-
|
| 44 |
-
Returns:
|
| 45 |
-
dict: A dictionary containing polarity, subjectivity, and assessment
|
| 46 |
-
"""
|
| 47 |
-
blob = TextBlob(text)
|
| 48 |
-
sentiment = blob.sentiment
|
| 49 |
-
|
| 50 |
-
return {
|
| 51 |
-
"polarity": round(sentiment.polarity, 2), # -1 (negative) to 1 (positive)
|
| 52 |
-
"subjectivity": round(sentiment.subjectivity, 2), # 0 (objective) to 1 (subjective)
|
| 53 |
-
"assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
# Create the Gradio interface
|
| 57 |
-
demo = gr.Interface(
|
| 58 |
-
fn=sentiment_analysis,
|
| 59 |
-
inputs=gr.Textbox(placeholder="Enter text to analyze..."),
|
| 60 |
-
outputs=gr.JSON(),
|
| 61 |
-
title="Text Sentiment Analysis",
|
| 62 |
-
description="Analyze the sentiment of text using TextBlob"
|
| 63 |
-
)
|
| 64 |
-
|
| 65 |
-
# Launch the interface and MCP server
|
| 66 |
-
if __name__ == "__main__":
|
| 67 |
-
demo.launch(mcp_server=True)
|
| 68 |
-
```
|
| 69 |
-
|
| 70 |
-
## Understanding the Code
|
| 71 |
-
|
| 72 |
-
Let's break down the key components:
|
| 73 |
-
|
| 74 |
-
1. **Function Definition**:
|
| 75 |
-
- The `sentiment_analysis` function takes a text input and returns a dictionary
|
| 76 |
-
- It uses TextBlob to analyze the sentiment
|
| 77 |
-
- The docstring is crucial as it helps Gradio generate the MCP tool schema
|
| 78 |
-
- Type hints (`str` and `dict`) help define the input/output schema
|
| 79 |
-
|
| 80 |
-
2. **Gradio Interface**:
|
| 81 |
-
- `gr.Interface` creates both the web UI and MCP server
|
| 82 |
-
- The function is exposed as an MCP tool automatically
|
| 83 |
-
- Input and output components define the tool's schema
|
| 84 |
-
- The JSON output component ensures proper serialization
|
| 85 |
-
|
| 86 |
-
3. **MCP Server**:
|
| 87 |
-
- Setting `mcp_server=True` enables the MCP server
|
| 88 |
-
- The server will be available at `http://localhost:7860/gradio_api/mcp/sse`
|
| 89 |
-
- You can also enable it using the environment variable:
|
| 90 |
-
```bash
|
| 91 |
-
export GRADIO_MCP_SERVER=True
|
| 92 |
-
```
|
| 93 |
-
|
| 94 |
-
## Running the Server
|
| 95 |
-
|
| 96 |
-
Start the server by running:
|
| 97 |
-
|
| 98 |
-
```bash
|
| 99 |
-
python app.py
|
| 100 |
-
```
|
| 101 |
-
|
| 102 |
-
You should see output indicating that both the web interface and MCP server are running. The web interface will be available at `http://localhost:7860`, and the MCP server at `http://localhost:7860/gradio_api/mcp/sse`.
|
| 103 |
-
|
| 104 |
-
## Testing the Server
|
| 105 |
-
|
| 106 |
-
You can test the server in two ways:
|
| 107 |
-
|
| 108 |
-
1. **Web Interface**:
|
| 109 |
-
- Open `http://localhost:7860` in your browser
|
| 110 |
-
- Enter some text and click "Submit"
|
| 111 |
-
- You should see the sentiment analysis results
|
| 112 |
-
|
| 113 |
-
2. **MCP Schema**:
|
| 114 |
-
- Visit `http://localhost:7860/gradio_api/mcp/schema`
|
| 115 |
-
- This shows the MCP tool schema that clients will use
|
| 116 |
-
- You can also find this in the "View API" link in the footer of your Gradio app
|
| 117 |
-
|
| 118 |
-
## Troubleshooting Tips
|
| 119 |
-
|
| 120 |
-
1. **Type Hints and Docstrings**:
|
| 121 |
-
- Always provide type hints for your function parameters and return values
|
| 122 |
-
- Include a docstring with an "Args:" block for each parameter
|
| 123 |
-
- This helps Gradio generate accurate MCP tool schemas
|
| 124 |
-
|
| 125 |
-
2. **String Inputs**:
|
| 126 |
-
- When in doubt, accept input arguments as `str`
|
| 127 |
-
- Convert them to the desired type inside the function
|
| 128 |
-
- This provides better compatibility with MCP clients
|
| 129 |
-
|
| 130 |
-
3. **SSE Support**:
|
| 131 |
-
- Some MCP clients don't support SSE-based MCP Servers
|
| 132 |
-
- In those cases, use `mcp-remote`:
|
| 133 |
-
```json
|
| 134 |
-
{
|
| 135 |
-
"mcpServers": {
|
| 136 |
-
"gradio": {
|
| 137 |
-
"command": "npx",
|
| 138 |
-
"args": [
|
| 139 |
-
"mcp-remote",
|
| 140 |
-
"http://localhost:7860/gradio_api/mcp/sse"
|
| 141 |
-
]
|
| 142 |
-
}
|
| 143 |
-
}
|
| 144 |
-
}
|
| 145 |
-
```
|
| 146 |
-
|
| 147 |
-
4. **Connection Issues**:
|
| 148 |
-
- If you encounter connection problems, try restarting both the client and server
|
| 149 |
-
- Check that the server is running and accessible
|
| 150 |
-
- Verify that the MCP schema is available at the expected URL
|
| 151 |
-
|
| 152 |
-
## Deploying to Hugging Face Spaces
|
| 153 |
-
|
| 154 |
-
To make your server available to others, you can deploy it to Hugging Face Spaces:
|
| 155 |
-
|
| 156 |
-
1. Create a new Space on Hugging Face:
|
| 157 |
-
- Go to huggingface.co/spaces
|
| 158 |
-
- Click "Create new Space"
|
| 159 |
-
- Choose "Gradio" as the SDK
|
| 160 |
-
- Name your space (e.g., "mcp-sentiment")
|
| 161 |
-
|
| 162 |
-
2. Create a `requirements.txt` file:
|
| 163 |
-
```txt
|
| 164 |
-
gradio[mcp]
|
| 165 |
-
textblob
|
| 166 |
-
```
|
| 167 |
-
|
| 168 |
-
3. Push your code to the Space:
|
| 169 |
-
```bash
|
| 170 |
-
git init
|
| 171 |
-
git add app.py requirements.txt
|
| 172 |
-
git commit -m "Initial commit"
|
| 173 |
-
git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-sentiment
|
| 174 |
-
git push -u origin main
|
| 175 |
-
```
|
| 176 |
-
|
| 177 |
-
Your MCP server will now be available at:
|
| 178 |
-
```
|
| 179 |
-
https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse
|
| 180 |
-
```
|
| 181 |
-
|
| 182 |
-
## Next Steps
|
| 183 |
-
|
| 184 |
-
Now that we have our MCP server running, we'll create clients to interact with it. In the next sections, we'll:
|
| 185 |
-
|
| 186 |
-
1. Create a HuggingFace.js-based client inspired by Tiny Agents
|
| 187 |
-
2. Implement a SmolAgents-based Python client
|
| 188 |
-
3. Test both clients with our deployed server
|
| 189 |
-
|
| 190 |
-
Let's move on to building our first client!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit2/introduction.mdx
DELETED
|
@@ -1,64 +0,0 @@
|
|
| 1 |
-
# Building an End-to-End MCP Application
|
| 2 |
-
|
| 3 |
-
Welcome to Unit 2 of the MCP Course!
|
| 4 |
-
|
| 5 |
-
In this unit, we'll build a complete MCP application from scratch, focusing on creating a server with Gradio and connecting it with multiple clients. This hands-on approach will give you practical experience with the entire MCP ecosystem.
|
| 6 |
-
|
| 7 |
-
<Tip>
|
| 8 |
-
|
| 9 |
-
In this unit, we're going to build a simple MCP server and client using Gradio and the HuggingFace hub. In the next unit, we'll build a more complex server that tackles a real-world use case.
|
| 10 |
-
|
| 11 |
-
</Tip>
|
| 12 |
-
|
| 13 |
-
## What You'll Learn
|
| 14 |
-
|
| 15 |
-
In this unit, you will:
|
| 16 |
-
|
| 17 |
-
- Create an MCP Server using Gradio's built-in MCP support
|
| 18 |
-
- Build a sentiment analysis tool that can be used by AI models
|
| 19 |
-
- Connect to the server using different client implementations:
|
| 20 |
-
- A HuggingFace.js-based client
|
| 21 |
-
- A SmolAgents-based client for Python
|
| 22 |
-
- Deploy your MCP Server to Hugging Face Spaces
|
| 23 |
-
- Test and debug the complete system
|
| 24 |
-
|
| 25 |
-
By the end of this unit, you'll have a working MCP application that demonstrates the power and flexibility of the protocol.
|
| 26 |
-
|
| 27 |
-
## Prerequisites
|
| 28 |
-
|
| 29 |
-
Before proceeding with this unit, make sure you:
|
| 30 |
-
|
| 31 |
-
- Have completed Unit 1 or have a basic understanding of MCP concepts
|
| 32 |
-
- Are comfortable with both Python and JavaScript/TypeScript
|
| 33 |
-
- Have a basic understanding of APIs and client-server architecture
|
| 34 |
-
- Have a development environment with:
|
| 35 |
-
- Python 3.10+
|
| 36 |
-
- Node.js 18+
|
| 37 |
-
- A Hugging Face account (for deployment)
|
| 38 |
-
|
| 39 |
-
## Our End-to-End Project
|
| 40 |
-
|
| 41 |
-
We'll build a sentiment analysis application that consists of three main parts: the server, the client, and the deployment.
|
| 42 |
-
|
| 43 |
-

|
| 44 |
-
|
| 45 |
-
### Server Side
|
| 46 |
-
|
| 47 |
-
- Uses Gradio to create a web interface and MCP server via `gr.Interface`
|
| 48 |
-
- Implements a sentiment analysis tool using TextBlob
|
| 49 |
-
- Exposes the tool through both HTTP and MCP protocols
|
| 50 |
-
|
| 51 |
-
### Client Side
|
| 52 |
-
|
| 53 |
-
- Implements a HuggingFace.js client
|
| 54 |
-
- Or, creates a smolagents Python client
|
| 55 |
-
- Demonstrates how to use the same server with different client implementations
|
| 56 |
-
|
| 57 |
-
### Deployment
|
| 58 |
-
|
| 59 |
-
- Deploys the server to Hugging Face Spaces
|
| 60 |
-
- Configures the clients to work with the deployed server
|
| 61 |
-
|
| 62 |
-
## Let's Get Started!
|
| 63 |
-
|
| 64 |
-
Are you ready to build your first end-to-end MCP application? Let's begin by setting up the development environment and creating our Gradio MCP server.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit2/tiny-agents.mdx
DELETED
|
@@ -1,274 +0,0 @@
|
|
| 1 |
-
# Building Tiny Agents with MCP and the Hugging Face Hub
|
| 2 |
-
|
| 3 |
-
Now that we've built MCP servers in Gradio and learned about creating MCP clients, let's complete our end-to-end application by building an agent that can seamlessly interact with our sentiment analysis tool. This section builds on the project [Tiny Agents](https://huggingface.co/blog/tiny-agents), which demonstrates a super simple way of deploying MCP clients that can connect to services like our Gradio sentiment analysis server.
|
| 4 |
-
|
| 5 |
-
In this final exercise of Unit 2, we will walk you through how to implement both TypeScript (JS) and Python MCP clients that can communicate with any MCP server, including the Gradio-based sentiment analysis server we built in the previous sections. This completes our end-to-end MCP application flow: from building a Gradio MCP server exposing a sentiment analysis tool, to creating a flexible agent that can use this tool alongside other capabilities.
|
| 6 |
-
|
| 7 |
-

|
| 8 |
-
<figcaption>Image credit https://x.com/adamdotdev</figcaption>
|
| 9 |
-
|
| 10 |
-
## Installation
|
| 11 |
-
|
| 12 |
-
Let's install the necessary packages to build our Tiny Agents.
|
| 13 |
-
|
| 14 |
-
<Tip>
|
| 15 |
-
|
| 16 |
-
Some MCP Clients, notably Claude Desktop, do not yet support SSE-based MCP Servers. In those cases, you can use a tool such as [mcp-remote](https://github.com/geelen/mcp-remote). First install Node.js. Then, add the following to your own MCP Client config:
|
| 17 |
-
|
| 18 |
-
</Tip>
|
| 19 |
-
|
| 20 |
-
Tiny Agent can run MCP servers with a command line environment. To do this, we will need to install `npm` and run the server with `npx`. **We'll need these for both Python and JavaScript.**
|
| 21 |
-
|
| 22 |
-
Let's install `npx` with `npm`. If you don't have `npm` installed, check out the [npm documentation](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
|
| 23 |
-
|
| 24 |
-
```bash
|
| 25 |
-
# install npx
|
| 26 |
-
npm install -g npx
|
| 27 |
-
```
|
| 28 |
-
|
| 29 |
-
Then, we need to install the `mcp-remote` package.
|
| 30 |
-
|
| 31 |
-
```bash
|
| 32 |
-
npm i mcp-remote
|
| 33 |
-
```
|
| 34 |
-
|
| 35 |
-
<hfoptions id="tiny-agents">
|
| 36 |
-
<hfoption id="typescript">
|
| 37 |
-
|
| 38 |
-
For JavaScript, we need to install the `tiny-agents` package.
|
| 39 |
-
|
| 40 |
-
```bash
|
| 41 |
-
npm install @huggingface/tiny-agents
|
| 42 |
-
```
|
| 43 |
-
|
| 44 |
-
</hfoption>
|
| 45 |
-
<hfoption id="python">
|
| 46 |
-
|
| 47 |
-
For Python, you need to install the latest version of `huggingface_hub` with the `mcp` extra to get all the necessary components.
|
| 48 |
-
|
| 49 |
-
```bash
|
| 50 |
-
pip install "huggingface_hub[mcp]>=0.32.0"
|
| 51 |
-
```
|
| 52 |
-
|
| 53 |
-
</hfoption>
|
| 54 |
-
</hfoptions>
|
| 55 |
-
|
| 56 |
-
## Tiny Agents MCP Client in the Command Line
|
| 57 |
-
|
| 58 |
-
Let's repeat the example from [Unit 1](../unit1/mcp-clients.mdx) to create a basic Tiny Agent. Tiny Agents can create MCP clients from the command line based on JSON configuration files.
|
| 59 |
-
|
| 60 |
-
<hfoptions id="tiny-agents">
|
| 61 |
-
<hfoption id="typescript">
|
| 62 |
-
|
| 63 |
-
Let's setup a project with a basic Tiny Agent.
|
| 64 |
-
|
| 65 |
-
```bash
|
| 66 |
-
mkdir my-agent
|
| 67 |
-
touch my-agent/agent.json
|
| 68 |
-
```
|
| 69 |
-
|
| 70 |
-
The JSON file will look like this:
|
| 71 |
-
|
| 72 |
-
```json
|
| 73 |
-
{
|
| 74 |
-
"model": "Qwen/Qwen2.5-72B-Instruct",
|
| 75 |
-
"provider": "nebius",
|
| 76 |
-
"servers": [
|
| 77 |
-
{
|
| 78 |
-
"type": "stdio",
|
| 79 |
-
"config": {
|
| 80 |
-
"command": "npx",
|
| 81 |
-
"args": [
|
| 82 |
-
"mcp-remote",
|
| 83 |
-
"http://localhost:7860/gradio_api/mcp/sse" // This is the MCP Server we created in the previous section
|
| 84 |
-
]
|
| 85 |
-
}
|
| 86 |
-
}
|
| 87 |
-
]
|
| 88 |
-
}
|
| 89 |
-
```
|
| 90 |
-
|
| 91 |
-
We can then run the agent with the following command:
|
| 92 |
-
|
| 93 |
-
```bash
|
| 94 |
-
npx @huggingface/tiny-agents run ./my-agent
|
| 95 |
-
```
|
| 96 |
-
|
| 97 |
-
</hfoption>
|
| 98 |
-
<hfoption id="python">
|
| 99 |
-
|
| 100 |
-
Let's setup a project with a basic Tiny Agent.
|
| 101 |
-
|
| 102 |
-
```bash
|
| 103 |
-
mkdir my-agent
|
| 104 |
-
touch my-agent/agent.json
|
| 105 |
-
cd my-agent
|
| 106 |
-
```
|
| 107 |
-
|
| 108 |
-
The JSON file will look like this:
|
| 109 |
-
|
| 110 |
-
```json
|
| 111 |
-
{
|
| 112 |
-
"model": "Qwen/Qwen2.5-72B-Instruct",
|
| 113 |
-
"provider": "nebius",
|
| 114 |
-
"servers": [
|
| 115 |
-
{
|
| 116 |
-
"type": "stdio",
|
| 117 |
-
"config": {
|
| 118 |
-
"command": "npx",
|
| 119 |
-
"args": [
|
| 120 |
-
"mcp-remote",
|
| 121 |
-
"http://localhost:7860/gradio_api/mcp/sse"
|
| 122 |
-
]
|
| 123 |
-
}
|
| 124 |
-
}
|
| 125 |
-
]
|
| 126 |
-
}
|
| 127 |
-
```
|
| 128 |
-
|
| 129 |
-
We can then run the agent with the following command:
|
| 130 |
-
|
| 131 |
-
```bash
|
| 132 |
-
tiny-agents run agent.json
|
| 133 |
-
```
|
| 134 |
-
|
| 135 |
-
</hfoption>
|
| 136 |
-
</hfoptions>
|
| 137 |
-
|
| 138 |
-
Here we have a basic Tiny Agent that can connect to our Gradio MCP server. It includes a model, provider, and a server configuration.
|
| 139 |
-
|
| 140 |
-
| Field | Description |
|
| 141 |
-
|-------|-------------|
|
| 142 |
-
| `model` | The open source model to use for the agent |
|
| 143 |
-
| `provider` | The inference provider to use for the agent |
|
| 144 |
-
| `servers` | The servers to use for the agent. We'll use the `mcp-remote` server for our Gradio MCP server. |
|
| 145 |
-
|
| 146 |
-
<Tip>
|
| 147 |
-
|
| 148 |
-
We could also use an open source model running locally with Tiny Agents. If we start a local inference server with
|
| 149 |
-
|
| 150 |
-
```json
|
| 151 |
-
{
|
| 152 |
-
"model": "Qwen/Qwen3-32B",
|
| 153 |
-
"endpointUrl": "http://localhost:1234/v1",
|
| 154 |
-
"servers": [
|
| 155 |
-
{
|
| 156 |
-
"type": "stdio",
|
| 157 |
-
"config": {
|
| 158 |
-
"command": "npx",
|
| 159 |
-
"args": [
|
| 160 |
-
"mcp-remote",
|
| 161 |
-
"http://localhost:1234/v1/mcp/sse"
|
| 162 |
-
]
|
| 163 |
-
}
|
| 164 |
-
}
|
| 165 |
-
]
|
| 166 |
-
}
|
| 167 |
-
```
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
Here we have a Tiny Agent that can connect to a local model. It includes a model, endpoint URL (`http://localhost:1234/v1`), and a server configuration. The endpoint should be an OpenAI-compatible endpoint.
|
| 171 |
-
|
| 172 |
-
</Tip>
|
| 173 |
-
|
| 174 |
-
## Custom Tiny Agents MCP Client
|
| 175 |
-
|
| 176 |
-
Now that we understand both Tiny Agents and Gradio MCP servers, let's see how they work together! The beauty of MCP is that it provides a standardized way for agents to interact with any MCP-compatible server, including our Gradio-based sentiment analysis server from earlier sections.
|
| 177 |
-
|
| 178 |
-
### Using the Gradio Server with Tiny Agents
|
| 179 |
-
|
| 180 |
-
To connect our Tiny Agent to the Gradio sentiment analysis server we built earlier in this unit, we just need to add it to our list of servers. Here's how we can modify our agent configuration:
|
| 181 |
-
|
| 182 |
-
<hfoptions id="tiny-agents">
|
| 183 |
-
<hfoption id="typescript">
|
| 184 |
-
|
| 185 |
-
```ts
|
| 186 |
-
const agent = new Agent({
|
| 187 |
-
provider: process.env.PROVIDER ?? "nebius",
|
| 188 |
-
model: process.env.MODEL_ID ?? "Qwen/Qwen2.5-72B-Instruct",
|
| 189 |
-
apiKey: process.env.HF_TOKEN,
|
| 190 |
-
servers: [
|
| 191 |
-
// ... existing servers ...
|
| 192 |
-
{
|
| 193 |
-
command: "npx",
|
| 194 |
-
args: [
|
| 195 |
-
"mcp-remote",
|
| 196 |
-
"http://localhost:7860/gradio_api/mcp/sse" // Your Gradio MCP server
|
| 197 |
-
]
|
| 198 |
-
}
|
| 199 |
-
],
|
| 200 |
-
});
|
| 201 |
-
```
|
| 202 |
-
|
| 203 |
-
</hfoption>
|
| 204 |
-
<hfoption id="python">
|
| 205 |
-
|
| 206 |
-
```python
|
| 207 |
-
import os
|
| 208 |
-
|
| 209 |
-
from huggingface_hub import Agent
|
| 210 |
-
|
| 211 |
-
agent = Agent(
|
| 212 |
-
model="Qwen/Qwen2.5-72B-Instruct",
|
| 213 |
-
provider="nebius",
|
| 214 |
-
servers=[
|
| 215 |
-
{
|
| 216 |
-
"command": "npx",
|
| 217 |
-
"args": [
|
| 218 |
-
"mcp-remote",
|
| 219 |
-
"http://localhost:7860/gradio_api/mcp/sse" # Your Gradio MCP server
|
| 220 |
-
]
|
| 221 |
-
}
|
| 222 |
-
],
|
| 223 |
-
)
|
| 224 |
-
```
|
| 225 |
-
|
| 226 |
-
</hfoption>
|
| 227 |
-
</hfoptions>
|
| 228 |
-
|
| 229 |
-
Now our agent can use the sentiment analysis tool alongside other tools! For example, it could:
|
| 230 |
-
1. Read text from a file using the filesystem server
|
| 231 |
-
2. Analyze its sentiment using our Gradio server
|
| 232 |
-
3. Write the results back to a file
|
| 233 |
-
|
| 234 |
-
### Deployment Considerations
|
| 235 |
-
|
| 236 |
-
When deploying your Gradio MCP server to Hugging Face Spaces, you'll need to update the server URL in your agent configuration to point to your deployed space:
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
```json
|
| 240 |
-
{
|
| 241 |
-
command: "npx",
|
| 242 |
-
args: [
|
| 243 |
-
"mcp-remote",
|
| 244 |
-
"https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse"
|
| 245 |
-
]
|
| 246 |
-
}
|
| 247 |
-
```
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
This allows your agent to use the sentiment analysis tool from anywhere, not just locally!
|
| 251 |
-
|
| 252 |
-
## Conclusion: Our Complete End-to-End MCP Application
|
| 253 |
-
|
| 254 |
-
In this unit, we've gone from understanding MCP basics to building a complete end-to-end application:
|
| 255 |
-
|
| 256 |
-
1. We created a Gradio MCP server that exposes a sentiment analysis tool
|
| 257 |
-
2. We learned how to connect to this server using MCP clients
|
| 258 |
-
3. We built a tiny agent in TypeScript and Python that can interact with our tool
|
| 259 |
-
|
| 260 |
-
This demonstrates the power of the Model Context Protocol - we can create specialized tools using frameworks we're familiar with (like Gradio), expose them through a standardized interface (MCP), and then have agents seamlessly use these tools alongside other capabilities.
|
| 261 |
-
|
| 262 |
-
The complete flow we've built allows an agent to:
|
| 263 |
-
- Connect to multiple tool providers
|
| 264 |
-
- Dynamically discover available tools
|
| 265 |
-
- Use our custom sentiment analysis tool
|
| 266 |
-
- Combine it with other capabilities like file system access and web browsing
|
| 267 |
-
|
| 268 |
-
This modular approach is what makes MCP so powerful for building flexible AI applications.
|
| 269 |
-
|
| 270 |
-
## Next Steps
|
| 271 |
-
|
| 272 |
-
- Check out the Tiny Agents blog posts in [Python](https://huggingface.co/blog/python-tiny-agents) and [TypeScript](https://huggingface.co/blog/tiny-agents)
|
| 273 |
-
- Review the [Tiny Agents documentation](https://huggingface.co/docs/huggingface.js/main/en/tiny-agents/README)
|
| 274 |
-
- Build something with Tiny Agents!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit3/introduction.mdx
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
# Coming Soon
|
| 2 |
-
|
| 3 |
-
This will be another use case that dives deeper into the MCP protocol and how to use it in more complex ways.
|
|
|
|
|
|
|
|
|
|
|
|
units/en/unit4/introduction.mdx
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
# Coming Soon
|
| 2 |
-
|
| 3 |
-
This unit will be a collaboration with partners from the AI community.
|
| 4 |
-
|
| 5 |
-
If you're building tools for MCP, please reach out to us and we'll add you to the unit. Open a [discussion](https://huggingface.co/spaces/mcp-course/README/discussions) on the hub organization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/_toctree.yml
DELETED
|
@@ -1,46 +0,0 @@
|
|
| 1 |
-
- title: "0. Chào mừng đến với Khóa học MCP"
|
| 2 |
-
sections:
|
| 3 |
-
- local: unit0/introduction
|
| 4 |
-
title: Chào mừng đến với Khóa học MCP
|
| 5 |
-
|
| 6 |
-
- title: "1. Giới thiệu về Giao Thức Ngữ Cảnh Mô Hình (MCP)"
|
| 7 |
-
sections:
|
| 8 |
-
- local: unit1/introduction
|
| 9 |
-
title: Giới thiệu về Giao Thức Ngữ Cảnh Mô Hình (MCP)
|
| 10 |
-
- local: unit1/key-concepts
|
| 11 |
-
title: Khái niệm và Thuật ngữ chính
|
| 12 |
-
- local: unit1/architectural-components
|
| 13 |
-
title: Các thành phần kiến trúc
|
| 14 |
-
- local: unit1/communication-protocol
|
| 15 |
-
title: Giao thức truyền thông
|
| 16 |
-
- local: unit1/capabilities
|
| 17 |
-
title: Hiểu về khả năng của MCP
|
| 18 |
-
- local: unit1/sdk
|
| 19 |
-
title: MCP SDK
|
| 20 |
-
- local: unit1/mcp-clients
|
| 21 |
-
title: MCP Clients
|
| 22 |
-
- local: unit1/gradio-mcp
|
| 23 |
-
title: Tích hợp Gradio với MCP
|
| 24 |
-
|
| 25 |
-
- title: "2. Trường hợp sử dụng: Ứng dụng MCP đầu cuối"
|
| 26 |
-
sections:
|
| 27 |
-
- local: unit2/introduction
|
| 28 |
-
title: Giới thiệu về Xây dựng Ứng dụng MCP
|
| 29 |
-
- local: unit2/gradio-server
|
| 30 |
-
title: Xây dựng Máy chủ Gradio MCP
|
| 31 |
-
- local: unit2/clients
|
| 32 |
-
title: Sử dụng MCP Clients với ứng dụng của bạn
|
| 33 |
-
- local: unit2/gradio-client
|
| 34 |
-
title: Xây dựng MCP Clients bằng Gradio
|
| 35 |
-
- local: unit2/tiny-agents
|
| 36 |
-
title: Xây dựng Tiny Agent với TypeScript
|
| 37 |
-
|
| 38 |
-
- title: "3. Trường hợp sử dụng: Phát triển MCP Nâng cao"
|
| 39 |
-
sections:
|
| 40 |
-
- local: unit3/introduction
|
| 41 |
-
title: Sắp ra mắt
|
| 42 |
-
|
| 43 |
-
- title: "Các chương bổ trợ"
|
| 44 |
-
sections:
|
| 45 |
-
- local: unit4/introduction
|
| 46 |
-
title: Sắp ra mắt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit0/introduction.mdx
DELETED
|
@@ -1,135 +0,0 @@
|
|
| 1 |
-
# Chào mừng bạn đến với 🤗 Khóa học Giao Thức Ngữ Cảnh Mô Hình (MCP)
|
| 2 |
-
|
| 3 |
-

|
| 4 |
-
|
| 5 |
-
Chào mừng các bạn đến với chủ đề thú vị nhất trong AI hiện nay: **Giao Thức Ngữ Cảnh Mô Hình (MCP)**!
|
| 6 |
-
|
| 7 |
-
Khóa học miễn phí này sẽ dẫn dắt các bạn **từ người mới bắt đầu trở thành người am hiểu** về cách sử dụng và xây dựng ứng dụng với MCP.
|
| 8 |
-
|
| 9 |
-
Chương đầu tiên sẽ giúp bạn làm quen:
|
| 10 |
-
* Khám phá **giáo trình khóa học**
|
| 11 |
-
* **Nhận thêm thông tin về quy trình cấp chứng chỉ và lịch trình**
|
| 12 |
-
* Làm quen với đội ngũ xây dựng khóa học
|
| 13 |
-
* Tạo **tài khoản** của bạn
|
| 14 |
-
* **Tham gia Discord** để gặp gỡ bạn học và chúng mình
|
| 15 |
-
|
| 16 |
-
Cùng bắt đầu thôi!
|
| 17 |
-
|
| 18 |
-
## Bạn sẽ học được gì từ khóa học này?
|
| 19 |
-
|
| 20 |
-
Trong khóa học này, các bạn sẽ:
|
| 21 |
-
* 📖 Nghiên cứu MCP về **lý thuyết, thiết kế và thực hành**
|
| 22 |
-
* 🧑💻 Học cách **sử dụng các SDK và framework MCP phổ biến**
|
| 23 |
-
* 💾 **Chia sẻ dự án** và khám phá ứng dụng từ cộng đồng
|
| 24 |
-
* 🏆 Tham gia các bài tập lớn để **đánh giá cách triển khai MCP của bạn so với các học viên khác**
|
| 25 |
-
* 🎓 **Nhận chứng chỉ hoàn thành** bằng cách hoàn thành các bài tập
|
| 26 |
-
|
| 27 |
-
Và còn nhiều hơn thế!
|
| 28 |
-
|
| 29 |
-
Kết thúc khóa học, bạn sẽ hiểu **cách MCP hoạt động và cách xây dựng ứng dụng AI sử dụng dữ liệu/công cụ bên ngoài theo chuẩn MCP mới nhất**.
|
| 30 |
-
|
| 31 |
-
Đừng quên [**đăng ký khóa học!**](https://huggingface.co/mcp-course)
|
| 32 |
-
|
| 33 |
-
## Cấu trúc khóa học như thế nào?
|
| 34 |
-
|
| 35 |
-
Khóa học bao gồm:
|
| 36 |
-
* _Chương nền tảng_: nơi bạn học **khái niệm lý thuyết** về MCP
|
| 37 |
-
* _Thực hành_: nơi bạn học **cách sử dụng SDK MCP** để xây dựng ứng dụng. Các phần thực hành sẽ có môi trường được cấu hình sẵn
|
| 38 |
-
* _Bài tập tình huống_: nơi bạn áp dụng kiến thức đã học để giải quyết vấn đề thực tế do bạn lựa chọn
|
| 39 |
-
* _Hợp tác_: Chúng tôi hợp tác với các đối tác của Hugging Face để mang đến cho bạn những triển khai MCP mới nhất
|
| 40 |
-
|
| 41 |
-
**Khóa học này là dự án sống, phát triển cùng phản hồi và đóng góp của bạn!** Hãy thoải mái tạo issue/PR trên GitHub và thảo luận tại Discord server của chúng ta.
|
| 42 |
-
|
| 43 |
-
Sau khi hoàn thành khóa học, bạn có thể gửi phản hồi 👉 qua [biểu mẫu này]
|
| 44 |
-
|
| 45 |
-
## Giáo trình chi tiết
|
| 46 |
-
|
| 47 |
-
Dưới đây là **giáo trình tổng quan**. Danh sách chi tiết sẽ được cập nhật theo từng chương.
|
| 48 |
-
|
| 49 |
-
| Chương | Chủ đề | Mô tả |
|
| 50 |
-
| ------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
| 51 |
-
| 0 | Làm quen | Thiết lập công cụ và nền tảng cần dùng |
|
| 52 |
-
| 1 | Nguyên lý, kiến trúc và khái niệm cốt lõi của MCP | Giải thích khái niệm cơ bản, kiến trúc và thành phần của MCP. Minh họa trường hợp sử dụng đơn giản với MCP |
|
| 53 |
-
| 2 | Ứng dụng end-to-end: MCP trong thực tế | Xây dựng ứng dụng MCP end-to-end đơn giản để chia sẻ với cộng đồng |
|
| 54 |
-
| 3 | Triển khai ứng dụng: MCP trong thực tế | Xây dựng ứng dụng MCP triển khai thực tế sử dụng hệ sinh thái Hugging Face và dịch vụ đối tác |
|
| 55 |
-
| 4 | Chương bổ trợ | Các chương nâng cao giúp bạn tận dụng tối đa khóa học, làm việc với thư viện và dịch vụ đối tác |
|
| 56 |
-
|
| 57 |
-
## Yêu cầu đầu vào
|
| 58 |
-
|
| 59 |
-
Để theo học hiệu quả, bạn cần:
|
| 60 |
-
* Hiểu biết cơ bản về AI và các khái niệm LLM
|
| 61 |
-
* Quen thuộc với nguyên tắc phát triển phần mềm và khái niệm API
|
| 62 |
-
* Có kinh nghiệm với ít nhất một ngôn ngữ lập trình (ví dụ Python hoặc TypeScript sẽ được sử dụng minh họa)
|
| 63 |
-
|
| 64 |
-
Nếu bạn chưa có những kiến thức này, đừng lo! Dưới đây là một số tài nguyên hữu ích:
|
| 65 |
-
|
| 66 |
-
* [LLM Course](https://huggingface.co/learn/llm-course/) sẽ hướng dẫn bạn những kiến thức cơ bản về sử dụng và xây dựng với LLMs.
|
| 67 |
-
* [Agents Course](https://huggingface.co/learn/agents-course/) sẽ hướng dẫn bạn cách xây dựng AI Agents với LLMs.
|
| 68 |
-
|
| 69 |
-
<Tip>
|
| 70 |
-
|
| 71 |
-
Các khóa học trên không phải là điều kiện bắt buộc, vì vậy nếu bạn đã hiểu các khái niệm về LLM và Agents, các bạn có thể bắt đầu khóa học ngay bây giờ!
|
| 72 |
-
|
| 73 |
-
</Tip>
|
| 74 |
-
|
| 75 |
-
## Tôi cần những công cụ gì?
|
| 76 |
-
|
| 77 |
-
Bạn chỉ cần 2 thứ:
|
| 78 |
-
|
| 79 |
-
* _Một máy tính_ có kết nối internet.
|
| 80 |
-
* _Tài khoản_: để truy cập tài nguyên khóa học và tạo dự án. Nếu chưa có tài khoản, bạn có thể tạo [tại đây](https://huggingface.co/join) (miễn phí).
|
| 81 |
-
|
| 82 |
-
## Quy trình cấp chứng chỉ
|
| 83 |
-
|
| 84 |
-
Bạn có thể chọn học khóa học này ở _chế độ audit_, hoặc hoàn thành các hoạt động và _nhận một trong hai chứng chỉ mà chúng tôi cấp_. Nếu chọn audit, bạn vẫn có thể tham gia tất cả bài tập lớn và làm bài tập nếu muốn, **bạn không cần thông báo với chúng tôi**.
|
| 85 |
-
|
| 86 |
-
Quy trình cấp chứng chỉ **hoàn toàn miễn phí**:
|
| 87 |
-
|
| 88 |
-
* _Để nhận chứng chỉ kiến thức cơ bản_: bạn cần hoàn thành Chương 1. Dành cho học viên muốn cập nhật xu hướng mới nhất về MCP mà không cần xây dựng ứng dụng đầy đủ.
|
| 89 |
-
* _Để nhận chứng chỉ hoàn thành_: bạn cần hoàn thành các chương ứng dụng (2 và 3). Dành cho học viên muốn xây dựng ứng dụng hoàn chỉnh và chia sẻ với cộng đồng.
|
| 90 |
-
|
| 91 |
-
## Tốc độ học được khuyến nghị?
|
| 92 |
-
|
| 93 |
-
Mỗi chương trong khóa học được thiết kế **để hoàn thành trong 1 tuần, với khoảng 3-4 giờ học mỗi tuần**.
|
| 94 |
-
|
| 95 |
-
Vì có thời hạn cụ thể, chúng tôi đưa ra lộ trình khuyến nghị:
|
| 96 |
-
|
| 97 |
-

|
| 98 |
-
|
| 99 |
-
## Làm thế nào để học hiệu quả nhất?
|
| 100 |
-
|
| 101 |
-
Để học hiệu quả nhất, chúng tôi có vài lời khuyên:
|
| 102 |
-
|
| 103 |
-
1. Tham gia nhóm học tập trên Discord: học cùng nhau luôn dễ dàng hơn. Hãy tham gia Discord của chúng tôi và xác thực tài khoản.
|
| 104 |
-
2. **Làm bài kiểm tra và bài tập**: cách học tốt nhất là qua thực hành và tự đánh giá.
|
| 105 |
-
3. **Lập lịch học để theo kịp tiến độ**: bạn có thể dùng lộ trình khuyến nghị bên dưới hoặc tự tạo lịch riêng.
|
| 106 |
-
|
| 107 |
-

|
| 108 |
-
|
| 109 |
-
## Về chúng tôi
|
| 110 |
-
|
| 111 |
-
Thông tin tác giả:
|
| 112 |
-
|
| 113 |
-
### Ben Burtenshaw
|
| 114 |
-
|
| 115 |
-
Ben là Kỹ sư Máy học tại Hugging Face, tập trung vào xây dựng các ứng dụng LLM với phương pháp hậu huấn luyện và agentic.
|
| 116 |
-
|
| 117 |
-
<!-- ## Acknowledgments -->
|
| 118 |
-
|
| 119 |
-
<!-- We would like to extend our gratitude to the following individuals and partners for their invaluable contributions and support: -->
|
| 120 |
-
|
| 121 |
-
<!-- TODO: @burtenshaw add contributors and partners -->
|
| 122 |
-
|
| 123 |
-
## Tôi phát hiện lỗi hoặc muốn cải thiện khóa học
|
| 124 |
-
|
| 125 |
-
Mọi đóng góp đều **được chào đón** 🤗
|
| 126 |
-
|
| 127 |
-
* Nếu bạn _phát hiện lỗi 🐛 trong notebook_, hãy mở một issue và **mô tả vấn đề**.
|
| 128 |
-
* Nếu bạn _muốn cải thiện khóa học_, bạn có thể mở một Pull Request.
|
| 129 |
-
* Nếu bạn _muốn thêm một mục đầy đủ hoặc một Chương mới_, cách tốt nhất là mở một issue và **mô tả nội dung bạn muốn thêm trước khi bắt đầu viết để chúng tôi có thể hướng dẫn bạn**.
|
| 130 |
-
|
| 131 |
-
## Tôi vẫn còn thắc mắc
|
| 132 |
-
|
| 133 |
-
Hãy đặt câu hỏi của bạn trên máy chủ Discord của chúng tôi tại kênh #mcp-course-questions.
|
| 134 |
-
|
| 135 |
-
Giờ bạn đã có đầy đủ thông tin, hãy cùng nhau lên đường ⛵
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/architectural-components.mdx
DELETED
|
@@ -1,85 +0,0 @@
|
|
| 1 |
-
# Các thành phần kiến trúc của MCP
|
| 2 |
-
|
| 3 |
-
Ở chương trước, chúng ta đã thảo luận về các khái niệm và thuật ngữ chính của MCP. Giờ hãy cùng đi sâu hơn vào các thành phần kiến trúc tạo nên hệ sinh thái MCP.
|
| 4 |
-
|
| 5 |
-
## Host, Client và Server
|
| 6 |
-
|
| 7 |
-
Giao Thức Ngữ Cảnh Mô Hình (MCP) được xây dựng trên kiến trúc client-server để kích hoạt giao tiếp có cấu trúc giữa các mô hình AI và hệ thống bên ngoài.
|
| 8 |
-
|
| 9 |
-

|
| 10 |
-
|
| 11 |
-
Kiến trúc MCP bao gồm ba thành phần chính với vai trò và trách nhiệm được xác định rõ ràng: Host, Client và Server. Chúng ta đã đề cập sơ qua ở phần trước, giờ hãy phân tích kỹ hơn từng thành phần.
|
| 12 |
-
|
| 13 |
-
### Host
|
| 14 |
-
|
| 15 |
-
**Host** là ứng dụng AI tiếp xúc trực tiếp với người dùng cuối.
|
| 16 |
-
|
| 17 |
-
Ví dụ bao gồm:
|
| 18 |
-
- Ứng dụng chat AI như OpenAI ChatGPT hay Claude Desktop của Anthropic
|
| 19 |
-
- IDE tích hợp AI như Cursor, hoặc các công cụ như Continue.dev
|
| 20 |
-
- Các agent AI tùy chỉnh và ứng dụng xây dựng bằng thư viện như LangChain hay smolagents
|
| 21 |
-
|
| 22 |
-
Trách nhiệm của Host:
|
| 23 |
-
- Quản lý tương tác và quyền hạn người dùng
|
| 24 |
-
- Thiết lập kết nối tới MCP Server thông qua MCP Client
|
| 25 |
-
- Điều phối luồng xử lý giữa yêu cầu người dùng, xử lý LLM và công cụ bên ngoài
|
| 26 |
-
- Hiển thị kết quả cho người dùng dưới định dạng mạch lạc
|
| 27 |
-
|
| 28 |
-
Thông thường, người dùng sẽ chọn ứng dụng Host dựa trên nhu cầu cá nhân. Ví dụ, nhà phát triển có thể chọn Cursor cho khả năng chỉnh sửa mã mạnh mẽ, trong khi chuyên gia nghiệp vụ có thể dùng ứng dụng tùy chỉnh xây bằng smolagents.
|
| 29 |
-
|
| 30 |
-
### Client
|
| 31 |
-
|
| 32 |
-
**Client** là thành phần trong ứng dụng Host quản lý giao tiếp với một MCP Server cụ thể. Đặc điểm chính:
|
| 33 |
-
|
| 34 |
-
- Mỗi Client duy trì kết nối 1:1 với một Server
|
| 35 |
-
- Xử lý các chi tiết giao thức của MCP
|
| 36 |
-
- Đóng vai trò trung gian giữa logic của Host và Server bên ngoài
|
| 37 |
-
|
| 38 |
-
### Server
|
| 39 |
-
|
| 40 |
-
**Server** là chương trình/dịch vụ bên ngoài cung cấp khả năng truy cập vào các công cụ, nguồn dữ liệu hoặc dịch vụ thông qua giao thức MCP. Server:
|
| 41 |
-
|
| 42 |
-
- Cung cấp quyền truy cập vào các công cụ/dịch vụ bên ngoài
|
| 43 |
-
- Đóng vai trò lớp bao bọc nhẹ cho chức năng có sẵn
|
| 44 |
-
- Có thể chạy cục bộ (cùng máy với Host) hoặc từ xa (qua mạng)
|
| 45 |
-
- Cung cấp khả năng dưới định dạng chuẩn để Client khám phá và sử dụng
|
| 46 |
-
|
| 47 |
-
## Luồng giao tiếp
|
| 48 |
-
|
| 49 |
-
Cùng xem cách các thành phần tương tác trong quy trình MCP điển hình:
|
| 50 |
-
|
| 51 |
-
<Tip>
|
| 52 |
-
|
| 53 |
-
Trong phần tiếp theo, chúng ta sẽ khám phá sâu hơn về giao thức giao tiếp với các ví dụ thực tế.
|
| 54 |
-
|
| 55 |
-
</Tip>
|
| 56 |
-
|
| 57 |
-
1. **Tương tác người dùng**: Người dùng tương tác với ứng dụng **Host**, thể hiện nhu cầu hoặc truy vấn.
|
| 58 |
-
|
| 59 |
-
2. **Xử lý Host**: **Host** xử lý đầu vào, có thể dùng LLM để hiểu yêu cầu và xác định cần dùng công cụ nào.
|
| 60 |
-
|
| 61 |
-
3. **Kết nối Client**: **Host** hướng dẫn **Client** kết nối tới Server phù hợp.
|
| 62 |
-
|
| 63 |
-
4. **Khám phá khả năng**: **Client** truy vấn **Server** để biết các khả năng (Công cụ, Tài nguyên, Prompt) mà nó cung cấp.
|
| 64 |
-
|
| 65 |
-
5. **Kích hoạt khả năng**: Dựa trên nhu cầu người dùng hoặc quyết định của LLM, Host yêu cầu **Client** kích hoạt khả năng cụ thể từ **Server**.
|
| 66 |
-
|
| 67 |
-
6. **Thực thi Server**: **Server** thực thi chức năng được yêu cầu và trả kết quả về **Client**.
|
| 68 |
-
|
| 69 |
-
7. **Tích hợp kết quả**: **Client** chuyển kết quả về **Host**, nơi tích hợp chúng vào ngữ cảnh LLM hoặc hiển thị trực tiếp cho người dùng.
|
| 70 |
-
|
| 71 |
-
Ưu điểm chính của kiến trúc này là tính mô-đun. Một Host duy nhất có thể kết nối với nhiều Server cùng lúc thông qua các Client khác nhau. Có thể thêm Server mới vào hệ sinh thái mà không cần thay đổi Host hiện có. Có thể dễ dàng kết hợp các khả năng trên nhiều Server khác nhau.
|
| 72 |
-
|
| 73 |
-
<Tip>
|
| 74 |
-
|
| 75 |
-
Như đã thảo luận ở phần trước, tính mô-đun này biến bài toán tích hợp M×N truyền thống (khi M ứng dụng AI kết nối với N công cụ/dịch vụ) thành một bài toán M+N dễ quản lý hơn - nơi mỗi Host và Server chỉ cần triển khai chuẩn MCP một lần.
|
| 76 |
-
|
| 77 |
-
</Tip>
|
| 78 |
-
|
| 79 |
-
Kiến trúc này trông có vẻ đơn giản, nhưng sức mạnh thực sự nằm ở việc chuẩn hóa giao thức truyền thông và sự phân tách rõ ràng trách nhiệm giữa các thành phần. Thiết kế này cho phép tạo ra một hệ sinh thái gắn kết nơi các mô hình AI có thể kết nối liền mạch với một mảng các công cụ và nguồn dữ liệu bên ngoài ngày càng phát triển.
|
| 80 |
-
|
| 81 |
-
## Kết luận
|
| 82 |
-
|
| 83 |
-
Những mẫu tương tác này được định hướng bởi các nguyên tắc chính định hình thiết kế và sự phát triển của MCP. Giao thức nhấn mạnh **tính chuẩn hóa** thông qua việc cung cấp một giao thức kết nối phổ quát cho AI, đồng thời duy trì **sự đơn giản** bằng cách giữ phần lõi giao thức dễ hiểu nhưng vẫn hỗ trợ các tính năng nâng cao. **An toàn** được ưu tiên thông qua yêu cầu phê duyệt rõ ràng từ người dùng cho các thao tác nhạy cảm, trong khi khả năng khám phá cho phép phát hiện động các chức năng. Giao thức được xây dựng với tư duy **mở rộng**, hỗ trợ phát triển thông qua phiên bản hóa và đàm phán chức năng, đồng thời đảm bảo **khả năng tương tác** giữa các triển khai và môi trường khác nhau.
|
| 84 |
-
|
| 85 |
-
Trong phần tiếp theo, chúng ta sẽ khám phá giao thức truyền thông giúp các thành phần này phối hợp hiệu quả với nhau.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/capabilities.mdx
DELETED
|
@@ -1,377 +0,0 @@
|
|
| 1 |
-
# Hiểu về Khả năng của MCP
|
| 2 |
-
|
| 3 |
-
Các MCP Server cung cấp nhiều khả năng khác nhau cho Client thông qua giao thức truyền thông. Những khả năng này được chia thành bốn loại chính, mỗi loại có đặc điểm và trường hợp sử dụng riêng. Hãy cùng khám phá các nguyên thủy cốt lõi tạo nền tảng cho chức năng của MCP.
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
Trong phần này, chúng ta sẽ xem các ví dụ dưới dạng hàm độc lập với framework trong mỗi ngôn ngữ. Mục đích là tập trung vào khái niệm và cách chúng phối hợp với nhau, thay vì sự phức tạp của bất kỳ framework cụ thể nào.
|
| 8 |
-
|
| 9 |
-
Trong các chương tiếp theo, chúng ta sẽ xem cách triển khai các khái niệm này trong mã cụ thể của MCP.
|
| 10 |
-
|
| 11 |
-
</Tip>
|
| 12 |
-
|
| 13 |
-
## Công cụ (Tools)
|
| 14 |
-
|
| 15 |
-
Công cụ là các hàm hoặc hành động có thể thực thi mà mô hình AI có thể gọi thông qua giao thức MCP.
|
| 16 |
-
|
| 17 |
-
- **Kiểm soát**: Công cụ thường **được kiểm soát bởi mô hình** (model-controlled), nghĩa là mô hình AI (LLM) quyết định khi nào gọi chúng dựa trên yêu cầu và ngữ cảnh của người dùng.
|
| 18 |
-
- **An toàn**: Do khả năng thực hiện các hành động có tác dụng phụ, việc thực thi công cụ có thể nguy hiểm. Vì vậy chúng thường yêu cầu sự chấp thuận rõ ràng từ người dùng.
|
| 19 |
-
- **Trường hợp sử dụng**: Gửi tin nhắn, tạo ticket, truy vấn API, thực hiện tính toán.
|
| 20 |
-
|
| 21 |
-
**Ví dụ**: Một công cụ thời tiết lấy dữ liệu thời tiết hiện tại cho một địa điểm:
|
| 22 |
-
|
| 23 |
-
<hfoptions id="tool-example">
|
| 24 |
-
<hfoption id="python">
|
| 25 |
-
|
| 26 |
-
<details>
|
| 27 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 28 |
-
|
| 29 |
-
```python
|
| 30 |
-
def get_weather(location: str) -> dict:
|
| 31 |
-
"""Nhận thông tin thời tiết hiện tại ở một địa điểm cụ thể."""
|
| 32 |
-
# Connect to weather API and fetch data
|
| 33 |
-
return {
|
| 34 |
-
"temperature": 72,
|
| 35 |
-
"conditions": "Sunny",
|
| 36 |
-
"humidity": 45
|
| 37 |
-
}
|
| 38 |
-
```
|
| 39 |
-
</details>
|
| 40 |
-
|
| 41 |
-
```python
|
| 42 |
-
def get_weather(location: str) -> dict:
|
| 43 |
-
"""Get the current weather for a specified location."""
|
| 44 |
-
# Connect to weather API and fetch data
|
| 45 |
-
return {
|
| 46 |
-
"temperature": 72,
|
| 47 |
-
"conditions": "Sunny",
|
| 48 |
-
"humidity": 45
|
| 49 |
-
}
|
| 50 |
-
```
|
| 51 |
-
|
| 52 |
-
</hfoption>
|
| 53 |
-
<hfoption id="javascript">
|
| 54 |
-
|
| 55 |
-
<details>
|
| 56 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 57 |
-
|
| 58 |
-
```javascript
|
| 59 |
-
function getWeather(location) {
|
| 60 |
-
// Kết nối đến API thời tiết và lấy dữ liệu
|
| 61 |
-
return {
|
| 62 |
-
temperature: 72,
|
| 63 |
-
conditions: 'Sunny',
|
| 64 |
-
humidity: 45
|
| 65 |
-
};
|
| 66 |
-
}
|
| 67 |
-
```
|
| 68 |
-
</details>
|
| 69 |
-
|
| 70 |
-
```javascript
|
| 71 |
-
function getWeather(location) {
|
| 72 |
-
// Connect to weather API and fetch data
|
| 73 |
-
return {
|
| 74 |
-
temperature: 72,
|
| 75 |
-
conditions: 'Sunny',
|
| 76 |
-
humidity: 45
|
| 77 |
-
};
|
| 78 |
-
}
|
| 79 |
-
```
|
| 80 |
-
|
| 81 |
-
</hfoption>
|
| 82 |
-
</hfoptions>
|
| 83 |
-
|
| 84 |
-
## Tài nguyên (Resources)
|
| 85 |
-
|
| 86 |
-
Tài nguyên cung cấp quyền truy cập chỉ đọc (read-only) vào các nguồn dữ liệu, cho phép mô hình AI truy xuất ngữ cảnh mà không cần thực thi logic phức tạp.
|
| 87 |
-
|
| 88 |
-
- **Kiểm soát**: Tài nguyên **được kiểm soát bởi ứng dụng** (application-controlled), nghĩa là ứng dụng Host thường quyết định khi nào truy cập chúng.
|
| 89 |
-
- **Bản chất**: Được thiết kế để truy xuất dữ liệu với tính toán tối thiểu, tương tự các endpoint GET trong REST API.
|
| 90 |
-
- **An toàn**: Vì chỉ đọc nên chúng thường ít rủi ro bảo mật hơn so với Công cụ.
|
| 91 |
-
- **Trường hợp sử dụng**: Truy cập nội dung file, lấy bản ghi cơ sở dữ liệu, đọc thông tin cấu hình.
|
| 92 |
-
|
| 93 |
-
**Ví dụ**: Một tài nguyên cung cấp quyền truy cập vào nội dung file:
|
| 94 |
-
|
| 95 |
-
<hfoptions id="resource-example">
|
| 96 |
-
<hfoption id="python">
|
| 97 |
-
|
| 98 |
-
<details>
|
| 99 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 100 |
-
|
| 101 |
-
```python
|
| 102 |
-
def read_file(file_path: str) -> str:
|
| 103 |
-
"""Đọc nội dung của file tại đường dẫn được chỉ định."""
|
| 104 |
-
with open(file_path, 'r') as f:
|
| 105 |
-
return f.read()
|
| 106 |
-
```
|
| 107 |
-
</details>
|
| 108 |
-
|
| 109 |
-
```python
|
| 110 |
-
def read_file(file_path: str) -> str:
|
| 111 |
-
"""Read the contents of a file at the specified path."""
|
| 112 |
-
with open(file_path, 'r') as f:
|
| 113 |
-
return f.read()
|
| 114 |
-
```
|
| 115 |
-
|
| 116 |
-
</hfoption>
|
| 117 |
-
<hfoption id="javascript">
|
| 118 |
-
|
| 119 |
-
<details>
|
| 120 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 121 |
-
|
| 122 |
-
```javascript
|
| 123 |
-
function readFile(filePath) {
|
| 124 |
-
// Sử dụng fs.readFile để đọc nội dung file
|
| 125 |
-
const fs = require('fs');
|
| 126 |
-
return new Promise((resolve, reject) => {
|
| 127 |
-
fs.readFile(filePath, 'utf8', (err, data) => {
|
| 128 |
-
if (err) {
|
| 129 |
-
reject(err);
|
| 130 |
-
return;
|
| 131 |
-
}
|
| 132 |
-
resolve(data);
|
| 133 |
-
});
|
| 134 |
-
});
|
| 135 |
-
}
|
| 136 |
-
```
|
| 137 |
-
</details>
|
| 138 |
-
|
| 139 |
-
```javascript
|
| 140 |
-
function readFile(filePath) {
|
| 141 |
-
// Using fs.readFile to read file contents
|
| 142 |
-
const fs = require('fs');
|
| 143 |
-
return new Promise((resolve, reject) => {
|
| 144 |
-
fs.readFile(filePath, 'utf8', (err, data) => {
|
| 145 |
-
if (err) {
|
| 146 |
-
reject(err);
|
| 147 |
-
return;
|
| 148 |
-
}
|
| 149 |
-
resolve(data);
|
| 150 |
-
});
|
| 151 |
-
});
|
| 152 |
-
}
|
| 153 |
-
```
|
| 154 |
-
|
| 155 |
-
</hfoption>
|
| 156 |
-
</hfoptions>
|
| 157 |
-
|
| 158 |
-
## Lời nhắc
|
| 159 |
-
|
| 160 |
-
Lời nhắc (Prompts) là các mẫu hoặc quy trình làm việc được định nghĩa trước nhằm hướng dẫn tương tác giữa người dùng, Mô hình AI và khả năng của Server.
|
| 161 |
-
|
| 162 |
-
- **Kiểm soát**: Lời nhắc **do người dùng kiểm soát**, thường được hiển thị dưới dạng các tùy chọn trong giao diện ứng dụng Host.
|
| 163 |
-
- **Mục đích**: Chúng cấu trúc các tương tác để tối ưu hóa việc sử dụng Công cụ và Tài nguyên sẵn có.
|
| 164 |
-
- **Lựa chọn**: Người dùng thường chọn một lời nhắc trước khi Mô hình AI bắt đầu xử lý, thiết lập ngữ cảnh cho tương tác.
|
| 165 |
-
- **Trường hợp sử dụng**: Quy trình làm việc phổ biến, mẫu tác vụ chuyên biệt, tương tác có hướng dẫn.
|
| 166 |
-
|
| 167 |
-
**Ví dụ**: Mẫu lời nhắc để tạo đánh giá mã nguồn:
|
| 168 |
-
|
| 169 |
-
<hfoptions id="prompt-example">
|
| 170 |
-
<hfoption id="python">
|
| 171 |
-
|
| 172 |
-
<details>
|
| 173 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 174 |
-
|
| 175 |
-
```python
|
| 176 |
-
def code_review(code: str, language: str) -> list:
|
| 177 |
-
"""Tạo đánh giá mã nguồn cho đoạn code được cung cấp."""
|
| 178 |
-
return [
|
| 179 |
-
{
|
| 180 |
-
"role": "system",
|
| 181 |
-
"content": f"You are a code reviewer examining {language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement."
|
| 182 |
-
},
|
| 183 |
-
{
|
| 184 |
-
"role": "user",
|
| 185 |
-
"content": f"Please review this {language} code:\n\n```{language}\n{code}\n```"
|
| 186 |
-
}
|
| 187 |
-
]
|
| 188 |
-
```
|
| 189 |
-
</details>
|
| 190 |
-
|
| 191 |
-
```python
|
| 192 |
-
def code_review(code: str, language: str) -> list:
|
| 193 |
-
"""Generate a code review for the provided code snippet."""
|
| 194 |
-
return [
|
| 195 |
-
{
|
| 196 |
-
"role": "system",
|
| 197 |
-
"content": f"You are a code reviewer examining {language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement."
|
| 198 |
-
},
|
| 199 |
-
{
|
| 200 |
-
"role": "user",
|
| 201 |
-
"content": f"Please review this {language} code:\n\n```{language}\n{code}\n```"
|
| 202 |
-
}
|
| 203 |
-
]
|
| 204 |
-
```
|
| 205 |
-
|
| 206 |
-
</hfoption>
|
| 207 |
-
<hfoption id="javascript">
|
| 208 |
-
|
| 209 |
-
<details>
|
| 210 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 211 |
-
|
| 212 |
-
```javascript
|
| 213 |
-
function codeReview(code, language) {
|
| 214 |
-
return [
|
| 215 |
-
{
|
| 216 |
-
role: 'system',
|
| 217 |
-
content: `You are a code reviewer examining ${language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement.`
|
| 218 |
-
},
|
| 219 |
-
{
|
| 220 |
-
role: 'user',
|
| 221 |
-
content: `Please review this ${language} code:\n\n\`\`\`${language}\n${code}\n\`\`\``
|
| 222 |
-
}
|
| 223 |
-
];
|
| 224 |
-
}
|
| 225 |
-
```
|
| 226 |
-
</details>
|
| 227 |
-
|
| 228 |
-
```javascript
|
| 229 |
-
function codeReview(code, language) {
|
| 230 |
-
return [
|
| 231 |
-
{
|
| 232 |
-
role: 'system',
|
| 233 |
-
content: `You are a code reviewer examining ${language} code. Provide a detailed review highlighting best practices, potential issues, and suggestions for improvement.`
|
| 234 |
-
},
|
| 235 |
-
{
|
| 236 |
-
role: 'user',
|
| 237 |
-
content: `Please review this ${language} code:\n\n\`\`\`${language}\n${code}\n\`\`\``
|
| 238 |
-
}
|
| 239 |
-
];
|
| 240 |
-
}
|
| 241 |
-
```
|
| 242 |
-
|
| 243 |
-
</hfoption>
|
| 244 |
-
</hfoptions>
|
| 245 |
-
|
| 246 |
-
## Lấy mẫu (Sampling)
|
| 247 |
-
|
| 248 |
-
Lấy mẫu cho phép Server yêu cầu Client (cụ thể là ứng dụng Host) thực hiện các tương tác LLM.
|
| 249 |
-
|
| 250 |
-
- **Kiểm soát**: Lấy mẫu **do Server khởi xướng** nhưng cần sự hỗ trợ từ Client/Host.
|
| 251 |
-
- **Mục đích**: Kích hoạt các hành vi tự chủ từ Server và các tương tác đệ quy/đa bước tiềm năng.
|
| 252 |
-
- **An toàn**: Giống như Công cụ, các thao tác lấy mẫu thường yêu cầu sự chấp thuận của người dùng.
|
| 253 |
-
- **Trường hợp sử dụng**: Các tác vụ đa bước phức tạp, quy trình làm việc của agent tự động, quá trình tương tác.
|
| 254 |
-
|
| 255 |
-
**Ví dụ**: Server có thể yêu cầu Client phân tích dữ liệu đã xử lý:
|
| 256 |
-
|
| 257 |
-
<hfoptions id="sampling-example">
|
| 258 |
-
<hfoption id="python">
|
| 259 |
-
|
| 260 |
-
<details>
|
| 261 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 262 |
-
```python
|
| 263 |
-
def request_sampling(messages, system_prompt=None, include_context="none"):
|
| 264 |
-
"""Yêu cầu lấy mẫu LLM từ máy khách."""
|
| 265 |
-
# Trong triển khai thực tế, phần này sẽ gửi yêu cầu đến máy khách
|
| 266 |
-
return {
|
| 267 |
-
"role": "assistant",
|
| 268 |
-
"content": "Analysis of the provided data..."
|
| 269 |
-
}
|
| 270 |
-
```
|
| 271 |
-
</details>
|
| 272 |
-
|
| 273 |
-
```python
|
| 274 |
-
def request_sampling(messages, system_prompt=None, include_context="none"):
|
| 275 |
-
"""Request LLM sampling from the client."""
|
| 276 |
-
# In a real implementation, this would send a request to the client
|
| 277 |
-
return {
|
| 278 |
-
"role": "assistant",
|
| 279 |
-
"content": "Analysis of the provided data..."
|
| 280 |
-
}
|
| 281 |
-
```
|
| 282 |
-
|
| 283 |
-
</hfoption>
|
| 284 |
-
<hfoption id="javascript">
|
| 285 |
-
|
| 286 |
-
<details>
|
| 287 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 288 |
-
```javascript
|
| 289 |
-
function requestSampling(messages, systemPrompt = null, includeContext = 'none') {
|
| 290 |
-
// Trong triển khai thực tế, phần này sẽ gửi yêu cầu đến máy khách
|
| 291 |
-
return {
|
| 292 |
-
role: 'assistant',
|
| 293 |
-
content: 'Analysis of the provided data...'
|
| 294 |
-
};
|
| 295 |
-
}
|
| 296 |
-
|
| 297 |
-
function handleSamplingRequest(request) {
|
| 298 |
-
const { messages, systemPrompt, includeContext } = request;
|
| 299 |
-
// Trong triển khai thực tế, phần này sẽ xử lý yêu cầu và trả về phản hồi
|
| 300 |
-
return {
|
| 301 |
-
role: 'assistant',
|
| 302 |
-
content: 'Response to the sampling request...'
|
| 303 |
-
};
|
| 304 |
-
}
|
| 305 |
-
```
|
| 306 |
-
</details>
|
| 307 |
-
|
| 308 |
-
```javascript
|
| 309 |
-
function requestSampling(messages, systemPrompt = null, includeContext = 'none') {
|
| 310 |
-
// In a real implementation, this would send a request to the client
|
| 311 |
-
return {
|
| 312 |
-
role: 'assistant',
|
| 313 |
-
content: 'Analysis of the provided data...'
|
| 314 |
-
};
|
| 315 |
-
}
|
| 316 |
-
|
| 317 |
-
function handleSamplingRequest(request) {
|
| 318 |
-
const { messages, systemPrompt, includeContext } = request;
|
| 319 |
-
// In a real implementation, this would process the request and return a response
|
| 320 |
-
return {
|
| 321 |
-
role: 'assistant',
|
| 322 |
-
content: 'Response to the sampling request...'
|
| 323 |
-
};
|
| 324 |
-
}
|
| 325 |
-
```
|
| 326 |
-
|
| 327 |
-
</hfoption>
|
| 328 |
-
</hfoptions>
|
| 329 |
-
|
| 330 |
-
Quy trình lấy mẫu (sampling) diễn ra theo các bước sau:
|
| 331 |
-
1. Server gửi yêu cầu `sampling/createMessage` đến client
|
| 332 |
-
2. Client xem xét và có thể chỉnh sửa yêu cầu này
|
| 333 |
-
3. Client lấy mẫu từ một LLM
|
| 334 |
-
4. Client kiểm tra kết quả hoàn thiện
|
| 335 |
-
5. Client trả kết quả về cho server
|
| 336 |
-
|
| 337 |
-
<Tip>
|
| 338 |
-
|
| 339 |
-
Thiết kế human-in-the-loop (có sự tham gia của con người trong vòng lặp) này đảm bảo người dùng duy trì quyền kiểm soát những gì LLM nhìn thấy và tạo ra. Khi triển khai sampling, điều quan trọng là phải cung cấp các lời nhắc rõ ràng, được cấu trúc tốt và bao gồm ngữ cảnh liên quan.
|
| 340 |
-
|
| 341 |
-
</Tip>
|
| 342 |
-
|
| 343 |
-
## Cách Các Khả Năng Phối Hợp
|
| 344 |
-
|
| 345 |
-
Hãy cùng xem cách các khả năng này phối hợp với nhau để tạo ra các tương tác phức tạp. Trong bảng dưới đây, chúng ta đã liệt kê các khả năng, đối tượng kiểm soát, hướng kiểm soát và một số chi tiết khác.
|
| 346 |
-
|
| 347 |
-
| Khả năng | Được kiểm soát bởi | Hướng | Tác dụng phụ | Cần phê duyệt | Trường hợp sử dụng điển hình |
|
| 348 |
-
|------------|-------------------|-----------|--------------------|---------------|-----------------------------------|
|
| 349 |
-
| Tools | Mô hình (LLM) | Client → Server | Có (có thể) | Có | Hành động, gọi API, thao tác dữ liệu |
|
| 350 |
-
| Resources | Ứng dụng | Client → Server | Không (chỉ đọc) | Thường không | Truy xuất dữ liệu, thu thập ngữ cảnh |
|
| 351 |
-
| Prompts | Người dùng | Server → Client | Không | Không (do người dùng chọn) | Quy trình làm việc có hướng dẫn, mẫu chuyên biệt |
|
| 352 |
-
| Sampling | Server | Server → Client → Server | Gián tiếp | Có | Tác vụ nhiều bước, hành vi agentic |
|
| 353 |
-
|
| 354 |
-
Các khả năng này được thiết kế để bổ trợ cho nhau theo những cách sau:
|
| 355 |
-
|
| 356 |
-
1. Người dùng có thể chọn **Prompt** để bắt đầu quy trình làm việc chuyên biệt
|
| 357 |
-
2. Prompt có thể bao gồm ngữ cảnh từ **Tài nguyên**
|
| 358 |
-
3. Trong quá trình xử lý, mô hình AI có thể gọi **Công cụ** để thực hiện hành động cụ thể
|
| 359 |
-
4. Với các thao tác phức tạp, Server có thể sử dụng **Sampling** để yêu cầu xử lý LLM bổ sung
|
| 360 |
-
|
| 361 |
-
Sự phân biệt giữa chúng tạo ra cấu trúc rõ ràng cho các tương tác MCP, cho phép các mô hình AI truy cập thông tin, thực hiện hành động và tham gia vào các quy trình làm việc phức tạp trong khi vẫn duy trì các ranh giới kiểm soát phù hợp.
|
| 362 |
-
|
| 363 |
-
## Quá Trình Khám Phá
|
| 364 |
-
|
| 365 |
-
Một tính năng chính của MCP là khả năng khám phá động. Khi Client kết nối với Server, nó có thể truy vấn các Tools, Resources và Prompts khả dụng thông qua các phương thức danh sách cụ thể:
|
| 366 |
-
|
| 367 |
-
- `tools/list`: Khám phá Tools khả dụng
|
| 368 |
-
- `resources/list`: Khám phá Resources khả dụng
|
| 369 |
-
- `prompts/list`: Khám phá Prompts khả dụng
|
| 370 |
-
|
| 371 |
-
Cơ chế khám phá động này cho phép Client thích ứng với các khả năng cụ thể mà mỗi Server cung cấp mà không cần biết trước về chức năng của Server.
|
| 372 |
-
|
| 373 |
-
## Kết Luận
|
| 374 |
-
|
| 375 |
-
Hiểu rõ các yếu tố cốt lõi này là điều cần thiết để làm việc hiệu quả với MCP. Bằng cách cung cấp các loại khả năng riêng biệt với ranh giới kiểm soát rõ ràng, MCP cho phép các tương tác mạnh mẽ giữa mô hình AI và hệ thống bên ngoài trong khi vẫn duy trì các cơ chế an toàn và kiểm soát phù hợp.
|
| 376 |
-
|
| 377 |
-
Trong phần tiếp theo, chúng ta sẽ khám phá cách Gradio tích hợp với MCP để cung cấp các giao diện dễ sử dụng cho các khả năng này.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/communication-protocol.mdx
DELETED
|
@@ -1,223 +0,0 @@
|
|
| 1 |
-
# Giao Thức Truyền Thông
|
| 2 |
-
|
| 3 |
-
MCP định nghĩa một giao thức truyền thông chuẩn hóa cho phép Client và Server trao đổi thông điệp một cách nhất quán, dễ dự đoán. Sự chuẩn hóa này rất quan trọng để đảm bảo khả năng tương tác trong cộng đồng. Trong phần này, chúng ta sẽ khám phá cấu trúc giao thức và cơ chế vận chuyển được sử dụng trong MCP.
|
| 4 |
-
|
| 5 |
-
<Tip warning={true}>
|
| 6 |
-
|
| 7 |
-
Chúng ta đang đi sâu vào những chi tiết phức tạp của giao thức MCP (nguyên văn: "nitty-gritty" - chỉ những chi tiết quan trọng và phức tạp). Bạn không cần biết tất cả những điều này để xây dựng với MCP, nhưng nên biết về sự tồn tại và cách hoạt động của nó.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
## JSON-RPC: Nền Tảng
|
| 12 |
-
|
| 13 |
-
Cốt lõi của MCP sử dụng **JSON-RPC 2.0** làm định dạng thông điệp cho mọi giao tiếp giữa Client và Server. JSON-RPC là giao thức gọi thủ tục từ xa nhẹ được mã hóa bằng JSON, mang lại các ưu điểm:
|
| 14 |
-
|
| 15 |
-
- Dễ đọc và dễ gỡ lỗi
|
| 16 |
-
- Không phụ thuộc ngôn ngữ, hỗ trợ triển khai trên mọi môi trường lập trình
|
| 17 |
-
- Được thiết lập tốt với đặc tả rõ ràng và được áp dụng rộng rãi
|
| 18 |
-
|
| 19 |
-

|
| 20 |
-
|
| 21 |
-
Giao thức định nghĩa ba loại thông điệp:
|
| 22 |
-
|
| 23 |
-
### 1. Yêu Cầu (Requests)
|
| 24 |
-
|
| 25 |
-
Được gửi từ Client đến Server để khởi tạo một thao tác. Thông điệp Yêu cầu bao gồm:
|
| 26 |
-
- Định danh duy nhất (`id`)
|
| 27 |
-
- Tên phương thức cần gọi (ví dụ: `tools/call`)
|
| 28 |
-
- Tham số cho phương thức (nếu có)
|
| 29 |
-
|
| 30 |
-
Ví dụ Yêu cầu:
|
| 31 |
-
|
| 32 |
-
```json
|
| 33 |
-
{
|
| 34 |
-
"jsonrpc": "2.0",
|
| 35 |
-
"id": 1,
|
| 36 |
-
"method": "tools/call",
|
| 37 |
-
"params": {
|
| 38 |
-
"name": "weather",
|
| 39 |
-
"arguments": {
|
| 40 |
-
"location": "San Francisco"
|
| 41 |
-
}
|
| 42 |
-
}
|
| 43 |
-
}
|
| 44 |
-
```
|
| 45 |
-
|
| 46 |
-
### 2. Phản Hồi (Responses)
|
| 47 |
-
|
| 48 |
-
Được gửi từ Server đến Client để trả lời Yêu cầu. Thông điệp Phản hồi bao gồm:
|
| 49 |
-
- `id` giống với Yêu cầu tương ứng
|
| 50 |
-
- Hoặc `result` (thành công) hoặc `error` (thất bại)
|
| 51 |
-
|
| 52 |
-
Ví dụ Phản hồi Thành công:
|
| 53 |
-
```json
|
| 54 |
-
{
|
| 55 |
-
"jsonrpc": "2.0",
|
| 56 |
-
"id": 1,
|
| 57 |
-
"result": {
|
| 58 |
-
"temperature": 62,
|
| 59 |
-
"conditions": "Partly cloudy"
|
| 60 |
-
}
|
| 61 |
-
}
|
| 62 |
-
```
|
| 63 |
-
|
| 64 |
-
Ví dụ Phản hồi Lỗi:
|
| 65 |
-
```json
|
| 66 |
-
{
|
| 67 |
-
"jsonrpc": "2.0",
|
| 68 |
-
"id": 1,
|
| 69 |
-
"error": {
|
| 70 |
-
"code": -32602,
|
| 71 |
-
"message": "Invalid location parameter"
|
| 72 |
-
}
|
| 73 |
-
}
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
-
### 3. Thông Báo
|
| 77 |
-
|
| 78 |
-
Thông điệp một chiều không yêu cầu phản hồi. Thường được gửi từ Server đến Client để cập nhật tiến trình hoặc thông báo sự kiện.
|
| 79 |
-
|
| 80 |
-
Ví dụ Thông Báo:
|
| 81 |
-
```json
|
| 82 |
-
{
|
| 83 |
-
"jsonrpc": "2.0",
|
| 84 |
-
"method": "progress",
|
| 85 |
-
"params": {
|
| 86 |
-
"message": "Processing data...",
|
| 87 |
-
"percent": 50
|
| 88 |
-
}
|
| 89 |
-
}
|
| 90 |
-
```
|
| 91 |
-
|
| 92 |
-
## Cơ Chế Vận Chuyển
|
| 93 |
-
|
| 94 |
-
JSON-RPC định nghĩa định dạng thông điệp, nhưng MCP cũng chỉ định cách thức các thông điệp này được truyền tải giữa Server đến Client. Hai cơ chế vận chuyển chính được hỗ trợ:
|
| 95 |
-
|
| 96 |
-
### stdio (Đầu vào/Đầu ra chuẩn)
|
| 97 |
-
|
| 98 |
-
Cơ chế stdio được dùng cho giao tiếp cục bộ, khi Client và Server chạy trên cùng máy:
|
| 99 |
-
|
| 100 |
-
Ứng dụng chủ khởi chạy Server như một tiến trình con và giao tiếp bằng cách ghi vào đầu vào chuẩn (stdin) và đọc từ đầu ra chuẩn (stdout).
|
| 101 |
-
|
| 102 |
-
<Tip>
|
| 103 |
-
|
| 104 |
-
**Trường hợp sử dụng** cho phương thức truyền tải này là các công cụ local như truy cập hệ thống file hoặc chạy script local.
|
| 105 |
-
|
| 106 |
-
</Tip>
|
| 107 |
-
|
| 108 |
-
**Ưu điểm** chính của phương thức này là đơn giản, không yêu cầu cấu hình mạng và được hệ điều hành cách ly an toàn.
|
| 109 |
-
|
| 110 |
-
### HTTP + SSE (Server-Sent Events) / HTTP có thể streaming
|
| 111 |
-
|
| 112 |
-
Phương thức HTTP + SSE được dùng cho giao tiếp từ xa khi Client và Server có thể ở các máy khác nhau:
|
| 113 |
-
|
| 114 |
-
Giao tiếp diễn ra qua HTTP, với Server sử dụng Server-Sent Events (SSE) để đẩy các cập nhật tới Client qua kết nối liên tục.
|
| 115 |
-
|
| 116 |
-
<Tip>
|
| 117 |
-
|
| 118 |
-
**Trường hợp sử dụng** cho phương thức này là kết nối tới API từ xa, dịch vụ đám mây hoặc tài nguyên dùng chung.
|
| 119 |
-
|
| 120 |
-
</Tip>
|
| 121 |
-
|
| 122 |
-
**Ưu điểm** chính là hoạt động được qua mạng, tích hợp được với dịch vụ web và tương thích với môi trường serverless.
|
| 123 |
-
|
| 124 |
-
Các bản cập nhật gần đây của chuẩn MCP đã giới thiệu hoặc cải tiến "Streamable HTTP", mang lại tính linh hoạt cao hơn bằng cách cho phép Server nâng cấp động lên SSE để streaming khi cần, đồng thời vẫn giữ được tính tương thích với môi trường serverless.
|
| 125 |
-
|
| 126 |
-
## Vòng đời tương tác
|
| 127 |
-
|
| 128 |
-
Ở phần trước, chúng ta đã thảo luận về vòng đời của một lượt tương tác đơn lẻ giữa Client (💻) và Server (🌐). Giờ h��y xem xét vòng đời của một lượt tương tác hoàn chỉnh trong ngữ cảnh giao thức MCP.
|
| 129 |
-
|
| 130 |
-
Giao thức MCP định nghĩa vòng đời tương tác có cấu trúc giữa Client và Server:
|
| 131 |
-
|
| 132 |
-
### Khởi tạo
|
| 133 |
-
|
| 134 |
-
Client kết nối tới Server và hai bên trao đổi phiên bản giao thức cùng các tính năng hỗ trợ, Server phản hồi với phiên bản giao thức và tính năng mà nó hỗ trợ.
|
| 135 |
-
|
| 136 |
-
<table style="width: 100%;">
|
| 137 |
-
<tr>
|
| 138 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 139 |
-
<td style="text-align: center;">→<br>initialize</td>
|
| 140 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 141 |
-
</tr>
|
| 142 |
-
<tr>
|
| 143 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 144 |
-
<td style="text-align: center;">←<br>response</td>
|
| 145 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 146 |
-
</tr>
|
| 147 |
-
<tr>
|
| 148 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 149 |
-
<td style="text-align: center;">→<br>initialized</td>
|
| 150 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 151 |
-
</tr>
|
| 152 |
-
</table>
|
| 153 |
-
|
| 154 |
-
Client xác nhận hoàn tất khởi tạo qua thông báo.
|
| 155 |
-
|
| 156 |
-
### Khám phá
|
| 157 |
-
|
| 158 |
-
Client yêu cầu thông tin về các tính năng khả dụng và Server phản hồi với danh sách công cụ có sẵn.
|
| 159 |
-
|
| 160 |
-
<table style="width: 100%;">
|
| 161 |
-
<tr>
|
| 162 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 163 |
-
<td style="text-align: center;">→<br>tools/list</td>
|
| 164 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 165 |
-
</tr>
|
| 166 |
-
<tr>
|
| 167 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 168 |
-
<td style="text-align: center;">←<br>response</td>
|
| 169 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 170 |
-
</tr>
|
| 171 |
-
</table>
|
| 172 |
-
|
| 173 |
-
Quá trình này có thể được lặp lại cho từng công cụ, tài nguyên hoặc loại prompt.
|
| 174 |
-
|
| 175 |
-
### Thực thi
|
| 176 |
-
|
| 177 |
-
Client kích hoạt các khả năng dựa trên nhu cầu của Host.
|
| 178 |
-
|
| 179 |
-
<table style="width: 100%;">
|
| 180 |
-
<tr>
|
| 181 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 182 |
-
<td style="text-align: center;">→<br>tools/call</td>
|
| 183 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 184 |
-
</tr>
|
| 185 |
-
<tr>
|
| 186 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 187 |
-
<td style="text-align: center;">←<br>thông báo (tiến trình tùy chọn)</td>
|
| 188 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 189 |
-
</tr>
|
| 190 |
-
<tr>
|
| 191 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 192 |
-
<td style="text-align: center;">←<br>phản hồi</td>
|
| 193 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 194 |
-
</tr>
|
| 195 |
-
</table>
|
| 196 |
-
|
| 197 |
-
### Kết thúc
|
| 198 |
-
|
| 199 |
-
Kết nối được đóng một cách hợp lệ khi không còn cần thiết và Server xác nhận yêu cầu tắt.
|
| 200 |
-
|
| 201 |
-
<table style="width: 100%;">
|
| 202 |
-
<tr>
|
| 203 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 204 |
-
<td style="text-align: center;">→<br>tắt máy</td>
|
| 205 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 206 |
-
</tr>
|
| 207 |
-
<tr>
|
| 208 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 209 |
-
<td style="text-align: center;">←<br>phản hồi</td>
|
| 210 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 211 |
-
</tr>
|
| 212 |
-
<tr>
|
| 213 |
-
<td style="background-color: lightgreen; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">💻</td>
|
| 214 |
-
<td style="text-align: center;">→<br>thoát</td>
|
| 215 |
-
<td style="background-color: lightblue; text-align: center; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">🌐</td>
|
| 216 |
-
</tr>
|
| 217 |
-
</table>
|
| 218 |
-
|
| 219 |
-
Client gửi thông điệp thoát cuối cùng để hoàn tất việc kết thúc.
|
| 220 |
-
|
| 221 |
-
## Tiến h��a của Giao thức
|
| 222 |
-
|
| 223 |
-
Giao thức MCP được thiết kế để có thể mở rộng và thích ứng. Giai đoạn khởi tạo bao gồm thương lượng phiên bản, cho phép tương thích ngược khi giao thức phát triển. Bên cạnh đó, việc khám phá khả năng cho phép Client thích ứng với các tính năng cụ thể mà mỗi Server cung cấp, cho phép kết hợp cả Máy chủ cơ bản và nâng cao trong cùng một hệ sinh thái.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/gradio-mcp.mdx
DELETED
|
@@ -1,188 +0,0 @@
|
|
| 1 |
-
# Tích hợp Gradio với MCP
|
| 2 |
-
|
| 3 |
-
Giờ chúng ta đã tìm hiểu các khái niệm cốt lõi của Giao Thức Ngữ Cảnh Mô Hình (MCP) và cách triển khai MCP Servers và Clients. Trong phần này, chúng ta sẽ làm mọi thứ dễ dàng hơn bằng cách sử dụng Gradio để tạo một MCP Server!
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
Gradio là thư viện Python nổi tiếng giúp tạo giao diện web tùy chỉnh nhanh chóng cho các mô hình học máy.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
## Giới thiệu về Gradio
|
| 12 |
-
|
| 13 |
-
Gradio cho phép các nhà phát triển tạo giao diện người dùng (UI) cho mô hình của họ chỉ với vài dòng mã Python. Thư viện này đặc biệt hữu ích cho:
|
| 14 |
-
|
| 15 |
-
- Tạo demo và nguyên mẫu
|
| 16 |
-
- Chia sẻ mô hình với người dùng không chuyên về kỹ thuật
|
| 17 |
-
- Kiểm tra và gỡ lỗi hành vi của mô hình
|
| 18 |
-
|
| 19 |
-
Với việc hỗ trợ thêm MCP, Gradio giờ đây cung cấp cách đơn giản để hiển thị các khả năng của mô hình AI thông qua giao thức MCP chuẩn hóa.
|
| 20 |
-
|
| 21 |
-
Kết hợp Gradio với MCP cho phép bạn tạo cả giao diện thân thiện với con người và công cụ truy cập được bằng AI với mã tối thiểu. Điều tuyệt nhất là Gradio đã được cộng đồng AI sử dụng rộng rãi, vì vậy bạn có thể dùng nó để chia sẻ MCP Servers của mình với người khác.
|
| 22 |
-
|
| 23 |
-
## Điều kiện tiên quyết
|
| 24 |
-
|
| 25 |
-
Để sử dụng Gradio với hỗ trợ MCP, bạn cần cài đặt Gradio với phần mở rộng MCP:
|
| 26 |
-
|
| 27 |
-
```bash
|
| 28 |
-
pip install "gradio[mcp]"
|
| 29 |
-
```
|
| 30 |
-
|
| 31 |
-
Bạn cũng cần một ứng dụng LLM hỗ trợ gọi công cụ sử dụng giao thức MCP, như Cursor (được gọi là "MCP Hosts").
|
| 32 |
-
|
| 33 |
-
## Tạo MCP Server với Gradio
|
| 34 |
-
|
| 35 |
-
Hãy cùng xem qua ví dụ cơ bản về cách tạo MCP Server bằng Gradio:
|
| 36 |
-
|
| 37 |
-
<details>
|
| 38 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 39 |
-
```python
|
| 40 |
-
import gradio as gr
|
| 41 |
-
|
| 42 |
-
def letter_counter(word: str, letter: str) -> int:
|
| 43 |
-
"""
|
| 44 |
-
Đếm số lần xuất hiện của một ký tự trong từ hoặc văn bản.
|
| 45 |
-
|
| 46 |
-
Args:
|
| 47 |
-
word (str): Văn bản đầu vào để tìm kiếm
|
| 48 |
-
letter (str): Ký tự cần tìm
|
| 49 |
-
|
| 50 |
-
Returns:
|
| 51 |
-
int: Số lần ký tự xuất hiện trong văn bản
|
| 52 |
-
"""
|
| 53 |
-
word = word.lower()
|
| 54 |
-
letter = letter.lower()
|
| 55 |
-
count = word.count(letter)
|
| 56 |
-
return count
|
| 57 |
-
|
| 58 |
-
# Tạo giao diện Gradio tiêu chuẩn
|
| 59 |
-
demo = gr.Interface(
|
| 60 |
-
fn=letter_counter,
|
| 61 |
-
inputs=["textbox", "textbox"],
|
| 62 |
-
outputs="number",
|
| 63 |
-
title="Bộ đếm ký tự",
|
| 64 |
-
description="Nhập văn bản và một ký tự để đếm số lần ký tự đó xuất hiện trong văn bản."
|
| 65 |
-
)
|
| 66 |
-
|
| 67 |
-
# Khởi chạy cả giao diện web Gradio và MCP Server
|
| 68 |
-
if __name__ == "__main__":
|
| 69 |
-
demo.launch(mcp_server=True)
|
| 70 |
-
```
|
| 71 |
-
</details>
|
| 72 |
-
|
| 73 |
-
```python
|
| 74 |
-
import gradio as gr
|
| 75 |
-
|
| 76 |
-
def letter_counter(word: str, letter: str) -> int:
|
| 77 |
-
"""
|
| 78 |
-
Count the number of occurrences of a letter in a word or text.
|
| 79 |
-
|
| 80 |
-
Args:
|
| 81 |
-
word (str): The input text to search through
|
| 82 |
-
letter (str): The letter to search for
|
| 83 |
-
|
| 84 |
-
Returns:
|
| 85 |
-
int: The number of times the letter appears in the text
|
| 86 |
-
"""
|
| 87 |
-
word = word.lower()
|
| 88 |
-
letter = letter.lower()
|
| 89 |
-
count = word.count(letter)
|
| 90 |
-
return count
|
| 91 |
-
|
| 92 |
-
# Create a standard Gradio interface
|
| 93 |
-
demo = gr.Interface(
|
| 94 |
-
fn=letter_counter,
|
| 95 |
-
inputs=["textbox", "textbox"],
|
| 96 |
-
outputs="number",
|
| 97 |
-
title="Letter Counter",
|
| 98 |
-
description="Enter text and a letter to count how many times the letter appears in the text."
|
| 99 |
-
)
|
| 100 |
-
|
| 101 |
-
# Launch both the Gradio web interface and the MCP server
|
| 102 |
-
if __name__ == "__main__":
|
| 103 |
-
demo.launch(mcp_server=True)
|
| 104 |
-
```
|
| 105 |
-
|
| 106 |
-
Với thiết lập này, hàm đếm ký tự của bạn giờ có thể truy cập qua:
|
| 107 |
-
|
| 108 |
-
1. Giao diện web Gradio truyền thống cho tương tác trực tiếp của con người
|
| 109 |
-
2. MCP Server có thể kết nối với các clients tương thích
|
| 110 |
-
|
| 111 |
-
MCP server sẽ truy cập được tại:
|
| 112 |
-
```
|
| 113 |
-
http://your-server:port/gradio_api/mcp/sse
|
| 114 |
-
```
|
| 115 |
-
|
| 116 |
-
Ứng dụng trông như thế này:
|
| 117 |
-
|
| 118 |
-

|
| 119 |
-
|
| 120 |
-
## Cách thức hoạt động đằng sau hậu trường
|
| 121 |
-
|
| 122 |
-
Khi bạn thiết lập `mcp_server=True` trong `launch()`, những điều sau sẽ xảy ra:
|
| 123 |
-
|
| 124 |
-
1. Các hàm Gradio được tự động chuyển đổi thành MCP Tools
|
| 125 |
-
2. Các thành phần đầu vào ánh xạ thành lược đồ tham số công cụ
|
| 126 |
-
3. Các thành phần đầu xác định định dạng phản hồi
|
| 127 |
-
4. Server Gradio giờ cũng lắng nghe các tin nhắn theo giao thức MCP
|
| 128 |
-
5. JSON-RPC qua HTTP+SSE được thiết lập cho giao tiếp client-server
|
| 129 |
-
|
| 130 |
-
## Tính năng chính của tích hợp Gradio <> MCP
|
| 131 |
-
|
| 132 |
-
1. **Chuyển đổi công cụ**: Mỗi API endpoint trong ứng dụng Gradio của bạn sẽ tự động chuyển thành MCP tool với tên, mô tả và lược đồ đầu vào tương ứng. Để xem các công cụ và lược đồ, truy cập `http://your-server:port/gradio_api/mcp/schema` hoặc vào link "View API" ở footer ứng dụng Gradio, sau đó click vào "MCP".
|
| 133 |
-
|
| 134 |
-
2. **Hỗ trợ biến môi trường**: Có hai cách để kích hoạt chức năng MCP server:
|
| 135 |
-
- Dùng tham số `mcp_server` trong `launch()`:
|
| 136 |
-
```python
|
| 137 |
-
demo.launch(mcp_server=True)
|
| 138 |
-
```
|
| 139 |
-
- Dùng biến môi trường:
|
| 140 |
-
```bash
|
| 141 |
-
export GRADIO_MCP_SERVER=True
|
| 142 |
-
```
|
| 143 |
-
|
| 144 |
-
3. **Xử lý file**: Server tự động xử lý chuyển đổi dữ liệu file bao gồm:
|
| 145 |
-
- Chuyển đổi chuỗi mã hóa base64 thành dữ liệu file
|
| 146 |
-
- Xử lý file ảnh và trả về đúng định dạng
|
| 147 |
-
- Quản lý bộ nhớ file tạm
|
| 148 |
-
|
| 149 |
-
Chúng ta **nên** truyền ảnh/file đầu vào dưới dạng URL đầy đủ ("http://..." hoặc "https://...") vì MCP Client không phải lúc nào cũng xử lý đúng file local.
|
| 150 |
-
|
| 151 |
-
4. **Server MCP được host trên 🤗 Spaces**: Bạn có thể publish ứng dụng Gradio miễn phí trên Hugging Face Spaces để có MCP server được host miễn phí. Đây là ví dụ một Space như vậy: https://huggingface.co/spaces/abidlabs/mcp-tools
|
| 152 |
-
|
| 153 |
-
## Mẹo xử lý sự cố
|
| 154 |
-
|
| 155 |
-
1. **Gợi ý kiểu và chuỗi tài liệu**: Đảm bảo bạn cung cấp gợi ý kiểu và chuỗi tài liệu hợp lệ cho hàm. Chuỗi tài liệu cần có khối "Args:" với các tham số được thụt lề.
|
| 156 |
-
|
| 157 |
-
2. **Đầu vào dạng chuỗi**: Khi không chắc chắn, hãy chấp nhận đối số đầu vào dạng `str` và chuyển đổi sang kiểu mong muốn bên trong hàm.
|
| 158 |
-
|
| 159 |
-
3. **Hỗ trợ SSE**: Một số MCP Host không hỗ trợ MCP Server dùng SSE. Trong trường hợp đó, bạn có thể dùng `mcp-remote`:
|
| 160 |
-
```json
|
| 161 |
-
{
|
| 162 |
-
"mcpServers": {
|
| 163 |
-
"gradio": {
|
| 164 |
-
"command": "npx",
|
| 165 |
-
"args": [
|
| 166 |
-
"mcp-remote",
|
| 167 |
-
"http://your-server:port/gradio_api/mcp/sse"
|
| 168 |
-
]
|
| 169 |
-
}
|
| 170 |
-
}
|
| 171 |
-
}
|
| 172 |
-
```
|
| 173 |
-
|
| 174 |
-
4. **Khởi động lại**: Nếu gặp vấn đề kết nối, hãy thử khởi động lại cả MCP Client và MCP Server.
|
| 175 |
-
|
| 176 |
-
## Chia sẻ MCP Server của bạn
|
| 177 |
-
|
| 178 |
-
Bạn có thể chia sẻ MCP Server bằng cách publish ứng dụng Gradio lên Hugging Face Spaces. Video dưới đây hướng dẫn cách tạo Hugging Face Space.
|
| 179 |
-
|
| 180 |
-
<Youtube id="3bSVKNKb_PY" />
|
| 181 |
-
|
| 182 |
-
Giờ bạn có thể chia sẻ MCP Server với người khác bằng cách chia sẻ Hugging Face Space của mình.
|
| 183 |
-
|
| 184 |
-
## Kết luận
|
| 185 |
-
|
| 186 |
-
Việc tích hợp Gradio với MCP mang đến điểm khởi đầu dễ tiếp cận vào hệ sinh thái MCP. Bằng cách tận dụng sự đơn giản của Gradio và thêm chuẩn hóa từ MCP, các bạn có thể nhanh chóng tạo cả giao diện thân thiện với người dùng lẫn công cụ truy cập được bằng AI với ít code nhất.
|
| 187 |
-
|
| 188 |
-
Trong suốt khóa học này, chúng ta sẽ khám phá thêm nhiều cách triển khai MCP phức tạp hơn, nhưng Gradio vẫn là điểm khởi đầu tuyệt vời để hiểu và thử nghiệm với giao thức
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/introduction.mdx
DELETED
|
@@ -1,33 +0,0 @@
|
|
| 1 |
-
# Giới thiệu về Giao Thức Ngữ Cảnh Mô Hình (MCP)
|
| 2 |
-
|
| 3 |
-
Chào mừng các bạn đến với Chương 1 của Khóa học MCP! Trong chương này, chúng ta sẽ cùng khám phá những nguyên tắc cơ bản của Giao Thức Ngữ Cảnh Mô Hình.
|
| 4 |
-
|
| 5 |
-
## Những gì bạn sẽ học
|
| 6 |
-
|
| 7 |
-
Trong chương này, các bạn sẽ:
|
| 8 |
-
|
| 9 |
-
* Hiểu MCP là gì và tại sao nó quan trọng
|
| 10 |
-
* Nắm được các khái niệm chính và thuật ngữ liên quan đến MCP
|
| 11 |
-
* Khám phá những thách thức tích hợp mà MCP giải quyết
|
| 12 |
-
* Tìm hiểu các lợi ích và mục tiêu chính của MCP
|
| 13 |
-
* Xem ví dụ đơn giản về tích hợp MCP trong thực tế
|
| 14 |
-
|
| 15 |
-
Khi kết thúc chương này, các bạn sẽ nắm vững những khái niệm nền tảng về MCP và sẵn sàng đi sâu vào kiến trúc và cách triển khai ở chương tiếp theo.
|
| 16 |
-
|
| 17 |
-
## Tầm quan trọng của MCP
|
| 18 |
-
|
| 19 |
-
Hệ sinh thái AI đang phát triển nhanh chóng với các Mô hình Ngôn ngữ Lớn (LLMs) và hệ thống AI khác ngày càng mạnh mẽ. Tuy nhiên, các mô hình này thường bị giới hạn bởi dữ liệu huấn luyện và thiếu khả năng truy cập thông tin thời gian thực hay các công cụ chuyên biệt. Hạn chế này cản trở tiềm năng của hệ thống AI trong việc đưa ra phản hồi thực sự phù hợp, chính xác và hữu ích.
|
| 20 |
-
|
| 21 |
-
Đây chính là lúc Giao Thức Ngữ Cảnh Mô Hình (MCP) phát huy tác dụng. MCP cho phép các mô hình AI kết nối với nguồn dữ liệu bên ngoài, công cụ và môi trường, tạo điều kiện trao đổi thông tin liền mạch giữa hệ thống AI và thế giới số. Khả năng tương tác này rất quan trọng cho sự phát triển và ứng dụng rộng rãi của các ứng dụng AI thực sự hữu ích.
|
| 22 |
-
|
| 23 |
-
## Tổng quan Chương 1
|
| 24 |
-
|
| 25 |
-
Dưới đây là những nội dung chính chúng ta sẽ đề cập:
|
| 26 |
-
|
| 27 |
-
1. **MCP là gì?** - Bắt đầu với định nghĩa về MCP và vai trò của nó trong hệ sinh thái AI
|
| 28 |
-
2. **Khái niệm chính** - Khám phá những khái niệm nền tảng và thuật ngữ liên quan
|
| 29 |
-
3. **Thách thức tích hợp** - Phân tích các vấn đề MCP hướng tới giải quyết, đặc biệt là "Bài toán tích hợp M×N"
|
| 30 |
-
4. **Lợi ích và mục tiêu** - Thảo luận về các ưu điểm và mục đích chính của MCP như chuẩn hóa, nâng cao khả năng AI và khả năng tương tác
|
| 31 |
-
5. **Ví dụ đơn giản** - Cùng xem qua ví dụ thực tế về tích hợp MCP
|
| 32 |
-
|
| 33 |
-
Hãy cùng bắt đầu hành trình khám phá thế giới thú vị của Giao Thức Ngữ Cảnh Mô Hình!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/key-concepts.mdx
DELETED
|
@@ -1,88 +0,0 @@
|
|
| 1 |
-
# Các Khái Niệm và Thuật Ngữ Chính
|
| 2 |
-
|
| 3 |
-
Trước khi đi sâu vào Giao Thức Ngữ Cảnh Mô Hình (MCP), chúng ta cần hiểu các khái niệm và thuật ngữ then chốt tạo nền tảng cho MCP. Chương này sẽ giới thiệu những ý tưởng cốt lõi cùng bộ từ vựng chung để thảo luận về các triển khai MCP xuyên suốt khóa học.
|
| 4 |
-
|
| 5 |
-
MCP thường được ví như "USB-C cho các ứng dụng AI". Giống như USB-C cung cấp giao diện vật lý và logic chuẩn hóa để kết nối các thiết bị ngoại vi với máy tính, MCP đưa ra giao thức đồng nhất để liên kết các mô hình AI với khả năng mở rộng. Sự chuẩn hóa này mang lợi ích cho toàn bộ hệ sinh thái:
|
| 6 |
-
|
| 7 |
-
- **Người dùng** được trải nghiệm đơn giản và nhất quán hơn trên mọi ứng dụng AI
|
| 8 |
-
- **Nhà phát triển ứng dụng AI** dễ dàng tích hợp với hệ sinh thái công cụ và nguồn dữ liệu ngày càng phong phú
|
| 9 |
-
- **Nhà cung cấp công cụ/dữ liệu** chỉ cần xây dựng một triển khai duy nhất tương thích với nhiều ứng dụng AI
|
| 10 |
-
- **Toàn hệ sinh thái** hưởng lợi từ khả năng tương tác cao hơn, đổi mới mạnh mẽ hơn và giảm phân mảnh
|
| 11 |
-
|
| 12 |
-
## Bài Toán Tích Hợp
|
| 13 |
-
|
| 14 |
-
**Bài Toán Tích Hợp M×N** ám chỉ thách thức khi kết nối M ứng dụng AI khác nhau với N công cụ/nguồn dữ liệu ngoài mà không có phương pháp chuẩn hóa.
|
| 15 |
-
|
| 16 |
-
### Không có MCP (Bài Toán M×N)
|
| 17 |
-
|
| 18 |
-
Không có giao thức như MCP, nhà phát triển phải tạo M×N tích hợp tùy biến - mỗi tích hợp cho một cặp ứng dụng AI với khả năng mở rộng.
|
| 19 |
-
|
| 20 |
-

|
| 21 |
-
|
| 22 |
-
Mỗi ứng dụng AI cần tích hợp riêng lẻ với từng công cụ/nguồn dữ liệu. Quá trình này rất phức tạp, tốn kém và gây nhiều khó khăn cho nhà phát triển, đồng thời làm tăng chi phí bảo trì.
|
| 23 |
-
|
| 24 |
-
### Với MCP (Giải Pháp M+N)
|
| 25 |
-
|
| 26 |
-
MCP biến bài toán này thành M+N bằng cách cung cấp giao diện chuẩn: mỗi ứng dụng AI triển khai phía Máy khách MCP một lần, mỗi công cụ/nguồn dữ liệu triển khai phía Máy chủ một lần. Cách này giảm đáng kể độ phức tạp tích hợp và gánh nặng bảo trì.
|
| 27 |
-
|
| 28 |
-

|
| 29 |
-
|
| 30 |
-
Mỗi ứng dụng AI triển khai phía Máy khách MCP một lần, mỗi công cụ/nguồn dữ liệu triển khai phía Máy chủ một lần.
|
| 31 |
-
|
| 32 |
-
## Thuật ngữ cốt lõi trong MCP
|
| 33 |
-
|
| 34 |
-
Giờ chúng ta đã hiểu vấn đề mà MCP giải quyết, hãy cùng khám phá các thuật ngữ và khái niệm cốt lõi tạo nên giao thức MCP.
|
| 35 |
-
|
| 36 |
-
<Tip>
|
| 37 |
-
|
| 38 |
-
MCP là một chuẩn như HTTP hay USB-C, và là giao thức để kết nối các ứng dụng AI với công cụ và nguồn dữ liệu bên ngoài. Vì vậy, việc sử dụng thuật ngữ chuẩn là cực kỳ quan trọng để MCP hoạt động hiệu quả.
|
| 39 |
-
|
| 40 |
-
Khi viết tài liệu ứng dụng và trao đổi với cộng đồng, chúng ta nên sử dụng các thuật ngữ sau đây.
|
| 41 |
-
|
| 42 |
-
</Tip>
|
| 43 |
-
|
| 44 |
-
### Thành phần
|
| 45 |
-
|
| 46 |
-
Tương tự như mối quan hệ client-server trong HTTP, MCP có client (máy khách) và server (máy chủ).
|
| 47 |
-
|
| 48 |
-

|
| 49 |
-
|
| 50 |
-
- **Host**: Ứng dụng AI mà người dùng cuối tương tác trực tiếp. Ví dụ: Claude Desktop của Anthropic, các IDE tích hợp AI như Cursor, thư viện inference như Hugging Face Python SDK, hoặc ứng dụng tùy chỉnh xây dựng bằng thư viện như LangChain hay smolagents. Host khởi tạo kết nối đến Máy chủ MCP và điều phối luồng làm việc giữa yêu cầu người dùng, xử lý LLM và công cụ bên ngoài.
|
| 51 |
-
|
| 52 |
-
- **Client**: Thành phần trong ứng dụng Host quản lý giao tiếp với một MCP Server cụ thể. Mỗi Client duy trì kết nối 1:1 với một Server, xử lý các chi tiết giao thức của MCP và đóng vai trò trung gian giữa logic của Host và Server bên ngoài.
|
| 53 |
-
|
| 54 |
-
- **Server**: Chương trình hoặc dịch vụ bên ngoài cung cấp các khả năng (Tools, Resources, Prompts) thông qua giao thức MCP.
|
| 55 |
-
|
| 56 |
-
<Tip warning={true}>
|
| 57 |
-
|
| 58 |
-
Nhiều tài liệu sử dụng 'Client' và 'Host' thay thế cho nhau. Về mặt kỹ thuật, Host là ứng dụng hướng đến người dùng, còn Client là thành phần bên trong ứng dụng Host quản lý giao tiếp với MCP Server.
|
| 59 |
-
|
| 60 |
-
</Tip>
|
| 61 |
-
|
| 62 |
-
### Khả năng
|
| 63 |
-
|
| 64 |
-
Tất nhiên, giá trị ứng dụng của bạn được quyết định bởi tổng các khả năng mà nó cung cấp. Các khả năng là phần quan trọng nhất trong ứng dụng. MCP có thể kết nối với mọi dịch vụ phần mềm, nhưng có một số khả năng phổ biến được dùng cho nhiều ứng dụng AI.
|
| 65 |
-
|
| 66 |
-
| Khả năng | Mô tả | Ví dụ |
|
| 67 |
-
| ------------ | ------------- | ------------- |
|
| 68 |
-
| **Tools** | Các hàm có thể thực thi mà mô hình AI có thể gọi để thực hiện hành động hoặc truy xuất dữ liệu đã tính toán. Thường liên quan đến use case của ứng dụng. | Một tool cho ứng dụng thời tiết có thể là hàm trả về thời tiết ở địa điểm cụ thể. |
|
| 69 |
-
| **Resources** | Nguồn dữ liệu chỉ đọc cung cấp ngữ cảnh mà không cần tính toán phức tạp. | Trợ lý nghiên cứu có thể có nguồn về các bài báo khoa học. |
|
| 70 |
-
| **Prompts** | Các mẫu hoặc quy trình làm việc được định nghĩa sẵn để hướng dẫn tương tác giữa người dùng, mô hình AI và các khả năng có sẵn. | Prompt tóm tắt văn bản. |
|
| 71 |
-
| **Sampling** | Các yêu cầu do Máy chủ khởi tạo để Client/Host thực hiện tương tác LLM, cho phép hành động đệ quy nơi LLM có thể xem xét nội dung đã tạo và đưa ra quyết định tiếp theo. | Ứng dụng viết lách tự đánh giá output và quyết định cải thiện thêm. |
|
| 72 |
-
|
| 73 |
-
Trong sơ đồ sau, chúng ta có thể thấy các khả năng được áp dụng cho use case của một CodeAgent.
|
| 74 |
-
|
| 75 |
-

|
| 76 |
-
|
| 77 |
-
Ứng dụng này có thể sử dụng các thực thể MCP theo cách sau:
|
| 78 |
-
|
| 79 |
-
| Thực thể | Tên | Mô tả |
|
| 80 |
-
| -------- | -------------- | ------------------------- |
|
| 81 |
-
| Tool | Code Interpreter | Công cụ có thể thực thi mã mà LLM viết. |
|
| 82 |
-
| Resource | Documentation | Tài nguyên chứa tài liệu hướng dẫn của ứng dụng. |
|
| 83 |
-
| Prompt | Code Style | Prompt hướng dẫn LLM tạo mã. |
|
| 84 |
-
| Sampling | Code Review | Sampling cho phép LLM review mã và đưa ra quyết định tiếp theo.|
|
| 85 |
-
|
| 86 |
-
### Kết luận
|
| 87 |
-
|
| 88 |
-
Hiểu rõ những khái niệm và thuật ngữ chính này sẽ tạo nền tảng để làm việc hiệu quả với MCP (Giao Thức Ngữ Cảnh Mô Hình). Trong các phần tiếp theo, chúng ta sẽ xây dựng dựa trên nền tảng này để khám phá các thành phần kiến trúc, giao thức truyền thông và tính năng tạo nên Giao Thức Ngữ Cảnh Mô Hình.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/mcp-clients.mdx
DELETED
|
@@ -1,422 +0,0 @@
|
|
| 1 |
-
# MCP Clients
|
| 2 |
-
|
| 3 |
-
Giờ khi đã hiểu cơ bản về Giao Thức Ngữ Cảnh Mô Hình (MCP), chúng ta có thể khám phá vai trò quan trọng của Client MCP trong hệ sinh thái MCP.
|
| 4 |
-
|
| 5 |
-
Trong phần này của Chương 1, chúng ta sẽ khám phá vai trò thiết yếu của Client MCP trong hệ sinh thái MCP.
|
| 6 |
-
|
| 7 |
-
Trong phần này, các bạn sẽ:
|
| 8 |
-
|
| 9 |
-
* Hiểu Client MCP là gì và vai trò của chúng trong kiến trúc MCP
|
| 10 |
-
* Tìm hiểu về các trách nhiệm chính của Client MCP
|
| 11 |
-
* Khám phá các triển khai Client MCP chính
|
| 12 |
-
* Khám phá cách sử dụng triển khai Client MCP của Hugging Face
|
| 13 |
-
* Xem các ví dụ thực tế về cách sử dụng Client MCP
|
| 14 |
-
|
| 15 |
-
## Hiểu về Client MCP
|
| 16 |
-
|
| 17 |
-
Client MCP là thành phần quan trọng đóng vai trò cầu nối giữa các ứng dụng AI (Server) và các khả năng bên ngoài được cung cấp bởi Server MCP. Hãy hình dung Server như ứng dụng chính của bạn (ví dụ: trợ lý AI hoặc IDE) và Client như một mô-đun chuyên biệt trong Server đó chịu trách nhiệm xử lý các giao tiếp MCP.
|
| 18 |
-
|
| 19 |
-
## Client giao diện người dùng
|
| 20 |
-
|
| 21 |
-
Hãy bắt đầu bằng cách khám phá các Client giao diện người dùng có sẵn cho MCP.
|
| 22 |
-
|
| 23 |
-
### Client giao diện chat
|
| 24 |
-
|
| 25 |
-
Claude Desktop của Anthropic là một trong những Client MCP nổi bật nhất, cung cấp tích hợp với nhiều Server MCP khác nhau.
|
| 26 |
-
|
| 27 |
-
### Client phát triển tương tác
|
| 28 |
-
|
| 29 |
-
Triển khai Client MCP của Cursor cho phép trợ lý lập trình hỗ trợ AI thông qua tích hợp trực tiếp với các tính năng chỉnh sửa code. Nó hỗ trợ nhiều kết nối Server MCP và cung cấp khả năng gọi công cụ thời gian thực khi lập trình, biến nó thành công cụ mạnh mẽ cho các nhà phát triển.
|
| 30 |
-
|
| 31 |
-
Continue.dev là một ví dụ khác về Client phát triển tương tác hỗ trợ MCP và kết nối với Server MCP từ VS Code.
|
| 32 |
-
|
| 33 |
-
## Cấu hình Client MCP
|
| 34 |
-
|
| 35 |
-
Giờ khi đã nắm được phần cốt lõi của giao thức MCP, hãy xem cách cấu hình các Server và Client MCP của bạn.
|
| 36 |
-
|
| 37 |
-
Triển khai hiệu quả các Server và Client MCP yêu cầu cấu hình đúng cách.
|
| 38 |
-
|
| 39 |
-
<Tip>
|
| 40 |
-
|
| 41 |
-
Đặc tả MCP vẫn đang phát triển, vì vậy các phương pháp cấu hình có thể thay đổi. Chúng ta sẽ tập trung vào các phương pháp tốt nhất hiện tại để cấu hình.
|
| 42 |
-
|
| 43 |
-
</Tip>
|
| 44 |
-
|
| 45 |
-
### Tệp cấu hình MCP
|
| 46 |
-
|
| 47 |
-
Các Server MCP sử dụng các tệp cấu hình để quản lý kết nối với Server. Những tệp này xác định các Server nào có sẵn và cách kết nối với chúng.
|
| 48 |
-
|
| 49 |
-
May mắn là các tệp cấu hình rất đơn giản, dễ hiểu và thống nhất giữa các Server MCP chính.
|
| 50 |
-
|
| 51 |
-
#### Cấu trúc `mcp.json`
|
| 52 |
-
|
| 53 |
-
Tệp cấu hình tiêu chuẩn cho MCP có tên `mcp.json`. Đây là cấu trúc cơ bản:
|
| 54 |
-
|
| 55 |
-
```json
|
| 56 |
-
{
|
| 57 |
-
"servers": [
|
| 58 |
-
{
|
| 59 |
-
"name": "Server Name",
|
| 60 |
-
"transport": {
|
| 61 |
-
"type": "stdio|sse",
|
| 62 |
-
// Cấu hình cụ thể cho phương thức truyền tải
|
| 63 |
-
}
|
| 64 |
-
}
|
| 65 |
-
]
|
| 66 |
-
}
|
| 67 |
-
```
|
| 68 |
-
|
| 69 |
-
Trong ví dụ này, chúng ta có một Server duy nhất với tên và loại phương thức truyền tải. Loại phương thức truyền tải có thể là `stdio` hoặc `sse`.
|
| 70 |
-
|
| 71 |
-
#### Cấu hình cho phương thức truyền tải stdio
|
| 72 |
-
|
| 73 |
-
Đối với các Server cục bộ sử dụng phương thức truyền tải stdio, cấu hình bao gồm lệnh và các đối số để khởi chạy tiến trình Server:
|
| 74 |
-
|
| 75 |
-
```json
|
| 76 |
-
{
|
| 77 |
-
"servers": [
|
| 78 |
-
{
|
| 79 |
-
"name": "File Explorer",
|
| 80 |
-
"transport": {
|
| 81 |
-
"type": "stdio",
|
| 82 |
-
"command": "python",
|
| 83 |
-
"args": ["/path/to/file_explorer_server.py"]
|
| 84 |
-
}
|
| 85 |
-
}
|
| 86 |
-
]
|
| 87 |
-
}
|
| 88 |
-
```
|
| 89 |
-
|
| 90 |
-
Ở đây, chúng ta có một Server có tên "File Explorer" là một tập lệnh cục bộ.
|
| 91 |
-
|
| 92 |
-
#### Cấu hình cho phương thức truyền tải HTTP+SSE
|
| 93 |
-
|
| 94 |
-
Đối với các Server từ xa sử dụng phương thức truyền tải HTTP+SSE, cấu hình bao gồm URL của Server:
|
| 95 |
-
|
| 96 |
-
```json
|
| 97 |
-
{
|
| 98 |
-
"servers": [
|
| 99 |
-
{
|
| 100 |
-
"name": "Remote API Server",
|
| 101 |
-
"transport": {
|
| 102 |
-
"type": "sse",
|
| 103 |
-
"url": "https://example.com/mcp-server"
|
| 104 |
-
}
|
| 105 |
-
}
|
| 106 |
-
]
|
| 107 |
-
}
|
| 108 |
-
```
|
| 109 |
-
|
| 110 |
-
#### Biến môi trường trong cấu hình
|
| 111 |
-
|
| 112 |
-
Các biến môi trường có thể được truyền vào tiến trình Server bằng cách sử dụng trường `env`. Đây là cách truy cập chúng trong mã Server của bạn:
|
| 113 |
-
|
| 114 |
-
<hfoptions id="env-variables">
|
| 115 |
-
<hfoption id="python">
|
| 116 |
-
|
| 117 |
-
Trong Python, chúng ta sử dụng module `os` để truy cập các biến môi trường:
|
| 118 |
-
|
| 119 |
-
<details>
|
| 120 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 121 |
-
```
|
| 122 |
-
import os
|
| 123 |
-
|
| 124 |
-
# Truy cập các biến môi trường
|
| 125 |
-
github_token = os.environ.get("GITHUB_TOKEN")
|
| 126 |
-
if not github_token:
|
| 127 |
-
raise ValueError("GITHUB_TOKEN environment variable is required")
|
| 128 |
-
|
| 129 |
-
# Sử dụng token trong mã Server
|
| 130 |
-
def make_github_request():
|
| 131 |
-
headers = {"Authorization": f"Bearer {github_token}"}
|
| 132 |
-
# ... phần còn lại của mã
|
| 133 |
-
```
|
| 134 |
-
</details>
|
| 135 |
-
```
|
| 136 |
-
import os
|
| 137 |
-
|
| 138 |
-
# Access environment variables
|
| 139 |
-
github_token = os.environ.get("GITHUB_TOKEN")
|
| 140 |
-
if not github_token:
|
| 141 |
-
raise ValueError("GITHUB_TOKEN environment variable is required")
|
| 142 |
-
|
| 143 |
-
# Use the token in your server code
|
| 144 |
-
def make_github_request():
|
| 145 |
-
headers = {"Authorization": f"Bearer {github_token}"}
|
| 146 |
-
# ... rest of your code
|
| 147 |
-
```
|
| 148 |
-
|
| 149 |
-
</hfoption>
|
| 150 |
-
<hfoption id="javascript">
|
| 151 |
-
|
| 152 |
-
Trong JavaScript, chúng ta sử dụng object `process.env` để truy cập các biến môi trường:
|
| 153 |
-
|
| 154 |
-
<details>
|
| 155 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 156 |
-
```
|
| 157 |
-
// Truy cập các biến môi trường
|
| 158 |
-
const githubToken = process.env.GITHUB_TOKEN;
|
| 159 |
-
if (!githubToken) {
|
| 160 |
-
throw new Error("GITHUB_TOKEN environment variable is required");
|
| 161 |
-
}
|
| 162 |
-
|
| 163 |
-
// Sử dụng token trong mã Server
|
| 164 |
-
function makeGithubRequest() {
|
| 165 |
-
const headers = { "Authorization": `Bearer ${githubToken}` };
|
| 166 |
-
// ... phần còn lại của mã
|
| 167 |
-
}
|
| 168 |
-
```
|
| 169 |
-
</details>
|
| 170 |
-
```
|
| 171 |
-
// Access environment variables
|
| 172 |
-
const githubToken = process.env.GITHUB_TOKEN;
|
| 173 |
-
if (!githubToken) {
|
| 174 |
-
throw new Error("GITHUB_TOKEN environment variable is required");
|
| 175 |
-
}
|
| 176 |
-
|
| 177 |
-
// Use the token in your server code
|
| 178 |
-
function makeGithubRequest() {
|
| 179 |
-
const headers = { "Authorization": `Bearer ${githubToken}` };
|
| 180 |
-
// ... rest of your code
|
| 181 |
-
}
|
| 182 |
-
```
|
| 183 |
-
|
| 184 |
-
</hfoption>
|
| 185 |
-
</hfoptions>
|
| 186 |
-
|
| 187 |
-
Cấu hình tương ứng trong `mcp.json` sẽ trông như thế này:
|
| 188 |
-
|
| 189 |
-
```json
|
| 190 |
-
{
|
| 191 |
-
"servers": [
|
| 192 |
-
{
|
| 193 |
-
"name": "GitHub API",
|
| 194 |
-
"transport": {
|
| 195 |
-
"type": "stdio",
|
| 196 |
-
"command": "python",
|
| 197 |
-
"args": ["/path/to/github_server.py"],
|
| 198 |
-
"env": {
|
| 199 |
-
"GITHUB_TOKEN": "your_github_token"
|
| 200 |
-
}
|
| 201 |
-
}
|
| 202 |
-
}
|
| 203 |
-
]
|
| 204 |
-
}
|
| 205 |
-
```
|
| 206 |
-
|
| 207 |
-
### Ví dụ về Cấu hình
|
| 208 |
-
|
| 209 |
-
Hãy cùng xem qua một số kịch bản cấu hình trong thực tế:
|
| 210 |
-
|
| 211 |
-
#### Kịch bản 1: Cấu hình Server Cục bộ
|
| 212 |
-
|
| 213 |
-
Trong kịch bản này, chúng ta có một Server cục bộ là script Python có thể là trình khám phá file hoặc trình chỉnh sửa code.
|
| 214 |
-
|
| 215 |
-
```json
|
| 216 |
-
{
|
| 217 |
-
"servers": [
|
| 218 |
-
{
|
| 219 |
-
"name": "File Explorer",
|
| 220 |
-
"transport": {
|
| 221 |
-
"type": "stdio",
|
| 222 |
-
"command": "python",
|
| 223 |
-
"args": ["/path/to/file_explorer_server.py"]
|
| 224 |
-
}
|
| 225 |
-
}
|
| 226 |
-
]
|
| 227 |
-
}
|
| 228 |
-
```
|
| 229 |
-
|
| 230 |
-
#### Kịch bản 2: Cấu hình Server Từ xa
|
| 231 |
-
|
| 232 |
-
Trong kịch bản này, chúng ta có một Server từ xa là API thời tiết.
|
| 233 |
-
|
| 234 |
-
```json
|
| 235 |
-
{
|
| 236 |
-
"servers": [
|
| 237 |
-
{
|
| 238 |
-
"name": "Weather API",
|
| 239 |
-
"transport": {
|
| 240 |
-
"type": "sse",
|
| 241 |
-
"url": "https://example.com/mcp-server"
|
| 242 |
-
}
|
| 243 |
-
}
|
| 244 |
-
]
|
| 245 |
-
}
|
| 246 |
-
```
|
| 247 |
-
|
| 248 |
-
Việc cấu hình đúng cách là yếu tố thiết yếu để triển khai thành công các tích hợp MCP. Bằng cách hiểu rõ các khía cạnh này, các bạn có thể tạo ra các kết nối mạnh mẽ và đáng tin cậy giữa các ứng dụng AI và các khả năng bên ngoài.
|
| 249 |
-
|
| 250 |
-
Trong phần tiếp theo, chúng ta sẽ khám phá hệ sinh thái các Server MCP có sẵn trên Hugging Face Hub và cách xuất bản Server của riêng bạn tại đó.
|
| 251 |
-
|
| 252 |
-
## Code Clients
|
| 253 |
-
|
| 254 |
-
Bạn cũng có thể sử dụng MCP Client trong code để các công cụ có sẵn cho LLM. Hãy cùng khám phá một số ví dụ trong `smolagents`.
|
| 255 |
-
|
| 256 |
-
Đầu tiên, hãy xem qua Server thời tiết từ trang trước. Trong `smolagents`, chúng ta có thể sử dụng lớp `ToolCollection` để tự động phát hiện và đăng ký các công cụ từ Server MCP. Việc này được thực hiện bằng cách truyền `StdioServerParameters` hoặc `SSEServerParameters` vào phương thức `ToolCollection.from_mcp`. Sau đó chúng ta có thể in các công cụ ra console.
|
| 257 |
-
|
| 258 |
-
<details>
|
| 259 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 260 |
-
```python
|
| 261 |
-
from smolagents import ToolCollection, CodeAgent
|
| 262 |
-
from mcp.client.stdio import StdioServerParameters
|
| 263 |
-
|
| 264 |
-
server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
|
| 265 |
-
|
| 266 |
-
with ToolCollection.from_mcp(
|
| 267 |
-
server_parameters, trust_remote_code=True
|
| 268 |
-
) as tools:
|
| 269 |
-
print("\n".join(f"{t.name}: {t.description}" for t in tools))
|
| 270 |
-
```
|
| 271 |
-
</details>
|
| 272 |
-
```python
|
| 273 |
-
from smolagents import ToolCollection, CodeAgent
|
| 274 |
-
from mcp.client.stdio import StdioServerParameters
|
| 275 |
-
|
| 276 |
-
server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
|
| 277 |
-
|
| 278 |
-
with ToolCollection.from_mcp(
|
| 279 |
-
server_parameters, trust_remote_code=True
|
| 280 |
-
) as tools:
|
| 281 |
-
print("\n".join(f"{t.name}: {t.description}" for t in tools))
|
| 282 |
-
|
| 283 |
-
```
|
| 284 |
-
|
| 285 |
-
<details>
|
| 286 |
-
<summary>
|
| 287 |
-
Kết quả
|
| 288 |
-
</summary>
|
| 289 |
-
|
| 290 |
-
```sh
|
| 291 |
-
Weather API: Get the weather in a specific location
|
| 292 |
-
|
| 293 |
-
```
|
| 294 |
-
|
| 295 |
-
</details>
|
| 296 |
-
|
| 297 |
-
Chúng ta cũng có thể kết nối đến Server MCP được host trên máy từ xa. Trong trường hợp này, chúng ta cần truyền `SSEServerParameters` vào phương thức `ToolCollection.from_mcp`.
|
| 298 |
-
|
| 299 |
-
<details>
|
| 300 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 301 |
-
```python
|
| 302 |
-
from smolagents.mcp_client import MCPClient
|
| 303 |
-
|
| 304 |
-
with MCPClient(
|
| 305 |
-
{"url": "https://abidlabs-mcp-tools2.hf.space/gradio_api/mcp/sse"}
|
| 306 |
-
) as tools:
|
| 307 |
-
# Tools from the remote server are available
|
| 308 |
-
print("\n".join(f"{t.name}: {t.description}" for t in tools))
|
| 309 |
-
```
|
| 310 |
-
</details>
|
| 311 |
-
```python
|
| 312 |
-
from smolagents.mcp_client import MCPClient
|
| 313 |
-
|
| 314 |
-
with MCPClient(
|
| 315 |
-
{"url": "https://abidlabs-mcp-tools2.hf.space/gradio_api/mcp/sse"}
|
| 316 |
-
) as tools:
|
| 317 |
-
# Tools from the remote server are available
|
| 318 |
-
print("\n".join(f"{t.name}: {t.description}" for t in tools))
|
| 319 |
-
```
|
| 320 |
-
|
| 321 |
-
<details>
|
| 322 |
-
<summary>
|
| 323 |
-
Kết quả
|
| 324 |
-
</summary>
|
| 325 |
-
|
| 326 |
-
```sh
|
| 327 |
-
prime_factors: Compute the prime factorization of a positive integer.
|
| 328 |
-
generate_cheetah_image: Generate a cheetah image.
|
| 329 |
-
image_orientation: Returns whether image is portrait or landscape.
|
| 330 |
-
sepia: Apply a sepia filter to the input image.
|
| 331 |
-
```
|
| 332 |
-
|
| 333 |
-
</details>
|
| 334 |
-
|
| 335 |
-
Bây giờ hãy xem cách sử dụng MCP Client trong một code agent.
|
| 336 |
-
|
| 337 |
-
<details>
|
| 338 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 339 |
-
```python
|
| 340 |
-
from smolagents import ToolCollection, CodeAgent
|
| 341 |
-
from mcp.client.stdio import StdioServerParameters
|
| 342 |
-
from smolagents import CodeAgent, InferenceClientModel
|
| 343 |
-
|
| 344 |
-
model = InferenceClientModel()
|
| 345 |
-
|
| 346 |
-
server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
|
| 347 |
-
|
| 348 |
-
with ToolCollection.from_mcp(
|
| 349 |
-
server_parameters, trust_remote_code=True
|
| 350 |
-
) as tool_collection:
|
| 351 |
-
agent = CodeAgent(tools=[*tool_collection.tools], model=model)
|
| 352 |
-
agent.run("What's the weather in Tokyo?")
|
| 353 |
-
```
|
| 354 |
-
</details>
|
| 355 |
-
```python
|
| 356 |
-
from smolagents import ToolCollection, CodeAgent
|
| 357 |
-
from mcp.client.stdio import StdioServerParameters
|
| 358 |
-
from smolagents import CodeAgent, InferenceClientModel
|
| 359 |
-
|
| 360 |
-
model = InferenceClientModel()
|
| 361 |
-
|
| 362 |
-
server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
|
| 363 |
-
|
| 364 |
-
with ToolCollection.from_mcp(
|
| 365 |
-
server_parameters, trust_remote_code=True
|
| 366 |
-
) as tool_collection:
|
| 367 |
-
agent = CodeAgent(tools=[*tool_collection.tools], model=model)
|
| 368 |
-
agent.run("What's the weather in Tokyo?")
|
| 369 |
-
|
| 370 |
-
```
|
| 371 |
-
|
| 372 |
-
<details>
|
| 373 |
-
<summary>
|
| 374 |
-
Kết quả
|
| 375 |
-
</summary>
|
| 376 |
-
|
| 377 |
-
```sh
|
| 378 |
-
The weather in Tokyo is sunny with a temperature of 20 degrees Celsius.
|
| 379 |
-
```
|
| 380 |
-
|
| 381 |
-
</details>
|
| 382 |
-
|
| 383 |
-
Chúng ta cũng có thể kết nối đến các gói MCP. Đây là ví dụ về cách kết nối đến gói `pubmedmcp`.
|
| 384 |
-
|
| 385 |
-
```python
|
| 386 |
-
from smolagents import ToolCollection, CodeAgent
|
| 387 |
-
from mcp import StdioServerParameters
|
| 388 |
-
|
| 389 |
-
server_parameters = StdioServerParameters(
|
| 390 |
-
command="uv",
|
| 391 |
-
args=["--quiet", "pubmedmcp@0.1.3"],
|
| 392 |
-
env={"UV_PYTHON": "3.12", **os.environ},
|
| 393 |
-
)
|
| 394 |
-
|
| 395 |
-
with ToolCollection.from_mcp(server_parameters, trust_remote_code=True) as tool_collection:
|
| 396 |
-
agent = CodeAgent(tools=[*tool_collection.tools], add_base_tools=True)
|
| 397 |
-
agent.run("Please find a remedy for hangover.")
|
| 398 |
-
```
|
| 399 |
-
|
| 400 |
-
<details>
|
| 401 |
-
<summary>Kết quả</summary>
|
| 402 |
-
|
| 403 |
-
<details>
|
| 404 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 405 |
-
```sh
|
| 406 |
-
Phương pháp chữa nôn nao là uống nước.
|
| 407 |
-
```
|
| 408 |
-
</details>
|
| 409 |
-
```sh
|
| 410 |
-
The remedy for hangover is to drink water.
|
| 411 |
-
```
|
| 412 |
-
|
| 413 |
-
</details>
|
| 414 |
-
|
| 415 |
-
## Bước tiếp theo
|
| 416 |
-
|
| 417 |
-
Giờ bạn đã hiểu về MCP Client, hãy sẵn sàng để:
|
| 418 |
-
* Khám phá các triển khai MCP Server cụ thể
|
| 419 |
-
* Tìm hiểu về cách tạo MCP Client tùy chỉnh
|
| 420 |
-
* Đi sâu vào các mẫu tích hợp MCP nâng cao
|
| 421 |
-
|
| 422 |
-
Hãy tiếp tục hành trình của chúng ta vào thế giới của Giao Thức Ngữ Cảnh Mô Hình!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit1/sdk.mdx
DELETED
|
@@ -1,279 +0,0 @@
|
|
| 1 |
-
# MCP SDK
|
| 2 |
-
|
| 3 |
-
Giao Thức Ngữ Cảnh Mô Hình (MCP) cung cấp SDK chính thức cho cả JavaScript, Python và các ngôn ngữ khác. Điều này giúp việc triển khai Client và Server MCP trong ứng dụng của bạn trở nên dễ dàng. Các SDK này xử lý các chi tiết giao thức cấp thấp, cho phép bạn tập trung vào việc xây dựng chức năng ứng dụng.
|
| 4 |
-
|
| 5 |
-
## Tổng quan về SDK
|
| 6 |
-
|
| 7 |
-
Cả hai SDK đều cung cấp chức năng cốt lõi tương tự, tuân theo đặc tả giao thức MCP mà chúng ta đã thảo luận trước đó. Chúng xử lý:
|
| 8 |
-
|
| 9 |
-
- Giao tiếp ở cấp độ giao thức
|
| 10 |
-
- Đăng ký và khám phá tính năng
|
| 11 |
-
- Tuần tự hóa/giải tuần tự hóa tin nhắn
|
| 12 |
-
- Quản lý kết nối
|
| 13 |
-
- Xử lý lỗi
|
| 14 |
-
|
| 15 |
-
## Triển khai các thành phần cốt lõi
|
| 16 |
-
|
| 17 |
-
Hãy cùng khám phá cách triển khai từng thành phần cốt lõi (Tools, Resources, và Prompts) bằng cả hai SDK.
|
| 18 |
-
|
| 19 |
-
<hfoptions id="server-implementation">
|
| 20 |
-
<hfoption id="python">
|
| 21 |
-
|
| 22 |
-
<Youtube id="exzrb5QNUis" />
|
| 23 |
-
|
| 24 |
-
<details>
|
| 25 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 26 |
-
```python
|
| 27 |
-
from mcp.server.fastmcp import FastMCP
|
| 28 |
-
|
| 29 |
-
# Tạo Server MCP
|
| 30 |
-
mcp = FastMCP("Dịch vụ Thời tiết")
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
@mcp.tool()
|
| 34 |
-
def get_weather(location: str) -> str:
|
| 35 |
-
"""Nhận thông tin thời tiết hiện tại ở một địa điểm cụ thể."""
|
| 36 |
-
return f"Weather in {location}: Sunny, 72°F"
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
@mcp.resource("weather://{location}")
|
| 40 |
-
def weather_resource(location: str) -> str:
|
| 41 |
-
"""Cung cấp dữ liệu thời tiết dưới dạng tài nguyên."""
|
| 42 |
-
return f"Weather data for {location}: Sunny, 72°F"
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
@mcp.prompt()
|
| 46 |
-
def weather_report(location: str) -> str:
|
| 47 |
-
"""Tạo lời nhắc báo cáo thời tiết."""
|
| 48 |
-
return f"""You are a weather reporter. Weather report for {location}?"""
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
# Chạy Server
|
| 52 |
-
if __name__ == "__main__":
|
| 53 |
-
mcp.run()
|
| 54 |
-
```
|
| 55 |
-
</details>
|
| 56 |
-
|
| 57 |
-
```python
|
| 58 |
-
from mcp.server.fastmcp import FastMCP
|
| 59 |
-
|
| 60 |
-
# Create an MCP server
|
| 61 |
-
mcp = FastMCP("Weather Service")
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
@mcp.tool()
|
| 65 |
-
def get_weather(location: str) -> str:
|
| 66 |
-
"""Get the current weather for a specified location."""
|
| 67 |
-
return f"Weather in {location}: Sunny, 72°F"
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
@mcp.resource("weather://{location}")
|
| 71 |
-
def weather_resource(location: str) -> str:
|
| 72 |
-
"""Provide weather data as a resource."""
|
| 73 |
-
return f"Weather data for {location}: Sunny, 72°F"
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
@mcp.prompt()
|
| 77 |
-
def weather_report(location: str) -> str:
|
| 78 |
-
"""Create a weather report prompt."""
|
| 79 |
-
return f"""You are a weather reporter. Weather report for {location}?"""
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
# Run the server
|
| 83 |
-
if __name__ == "__main__":
|
| 84 |
-
mcp.run()
|
| 85 |
-
|
| 86 |
-
```
|
| 87 |
-
|
| 88 |
-
</hfoption>
|
| 89 |
-
<hfoption id="javascript">
|
| 90 |
-
|
| 91 |
-
<details>
|
| 92 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 93 |
-
```javascript
|
| 94 |
-
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
| 95 |
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
| 96 |
-
import { z } from "zod";
|
| 97 |
-
|
| 98 |
-
// Tạo Server MCP
|
| 99 |
-
const server = new McpServer({
|
| 100 |
-
name: "Dịch vụ Thời tiết",
|
| 101 |
-
version: "1.0.0"
|
| 102 |
-
});
|
| 103 |
-
|
| 104 |
-
// Triển khai công cụ
|
| 105 |
-
server.tool("get_weather",
|
| 106 |
-
{ location: z.string() },
|
| 107 |
-
async ({ location }) => ({
|
| 108 |
-
content: [{
|
| 109 |
-
type: "text",
|
| 110 |
-
text: `Weather in ${location}: Sunny, 72°F`
|
| 111 |
-
}]
|
| 112 |
-
})
|
| 113 |
-
);
|
| 114 |
-
|
| 115 |
-
// Triển khai tài nguyên
|
| 116 |
-
server.resource(
|
| 117 |
-
"weather",
|
| 118 |
-
new ResourceTemplate("weather://{location}", { list: undefined }),
|
| 119 |
-
async (uri, { location }) => ({
|
| 120 |
-
contents: [{
|
| 121 |
-
uri: uri.href,
|
| 122 |
-
text: `Weather data for ${location}: Sunny, 72°F`
|
| 123 |
-
}]
|
| 124 |
-
})
|
| 125 |
-
);
|
| 126 |
-
|
| 127 |
-
// Triển khai prompt
|
| 128 |
-
server.prompt(
|
| 129 |
-
"weather_report",
|
| 130 |
-
{ location: z.string() },
|
| 131 |
-
async ({ location }) => ({
|
| 132 |
-
messages: [
|
| 133 |
-
{
|
| 134 |
-
role: "assistant",
|
| 135 |
-
content: {
|
| 136 |
-
type: "text",
|
| 137 |
-
text: "You are a weather reporter."
|
| 138 |
-
}
|
| 139 |
-
},
|
| 140 |
-
{
|
| 141 |
-
role: "user",
|
| 142 |
-
content: {
|
| 143 |
-
type: "text",
|
| 144 |
-
text: `Weather report for ${location}?`
|
| 145 |
-
}
|
| 146 |
-
}
|
| 147 |
-
]
|
| 148 |
-
})
|
| 149 |
-
);
|
| 150 |
-
|
| 151 |
-
// Chạy server
|
| 152 |
-
const transport = new StdioServerTransport();
|
| 153 |
-
await server.connect(transport);
|
| 154 |
-
```
|
| 155 |
-
</details>
|
| 156 |
-
|
| 157 |
-
```javascript
|
| 158 |
-
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
| 159 |
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
| 160 |
-
import { z } from "zod";
|
| 161 |
-
|
| 162 |
-
// Create an MCP server
|
| 163 |
-
const server = new McpServer({
|
| 164 |
-
name: "Weather Service",
|
| 165 |
-
version: "1.0.0"
|
| 166 |
-
});
|
| 167 |
-
|
| 168 |
-
// Tool implementation
|
| 169 |
-
server.tool("get_weather",
|
| 170 |
-
{ location: z.string() },
|
| 171 |
-
async ({ location }) => ({
|
| 172 |
-
content: [{
|
| 173 |
-
type: "text",
|
| 174 |
-
text: `Weather in ${location}: Sunny, 72°F`
|
| 175 |
-
}]
|
| 176 |
-
})
|
| 177 |
-
);
|
| 178 |
-
|
| 179 |
-
// Resource implementation
|
| 180 |
-
server.resource(
|
| 181 |
-
"weather",
|
| 182 |
-
new ResourceTemplate("weather://{location}", { list: undefined }),
|
| 183 |
-
async (uri, { location }) => ({
|
| 184 |
-
contents: [{
|
| 185 |
-
uri: uri.href,
|
| 186 |
-
text: `Weather data for ${location}: Sunny, 72°F`
|
| 187 |
-
}]
|
| 188 |
-
})
|
| 189 |
-
);
|
| 190 |
-
|
| 191 |
-
// Prompt implementation
|
| 192 |
-
server.prompt(
|
| 193 |
-
"weather_report",
|
| 194 |
-
{ location: z.string() },
|
| 195 |
-
async ({ location }) => ({
|
| 196 |
-
messages: [
|
| 197 |
-
{
|
| 198 |
-
role: "assistant",
|
| 199 |
-
content: {
|
| 200 |
-
type: "text",
|
| 201 |
-
text: "You are a weather reporter."
|
| 202 |
-
}
|
| 203 |
-
},
|
| 204 |
-
{
|
| 205 |
-
role: "user",
|
| 206 |
-
content: {
|
| 207 |
-
type: "text",
|
| 208 |
-
text: `Weather report for ${location}?`
|
| 209 |
-
}
|
| 210 |
-
}
|
| 211 |
-
]
|
| 212 |
-
})
|
| 213 |
-
);
|
| 214 |
-
|
| 215 |
-
// Run the server
|
| 216 |
-
const transport = new StdioServerTransport();
|
| 217 |
-
await server.connect(transport);
|
| 218 |
-
```
|
| 219 |
-
|
| 220 |
-
</hfoption>
|
| 221 |
-
</hfoptions>
|
| 222 |
-
|
| 223 |
-
Sau khi đã triển khai máy chủ của mình, bạn có thể khởi chạy nó bằng cách chạy script server.
|
| 224 |
-
|
| 225 |
-
```bash
|
| 226 |
-
mcp dev server.py
|
| 227 |
-
```
|
| 228 |
-
|
| 229 |
-
Lệnh này sẽ khởi tạo một máy chủ phát triển chạy file `server.py` và ghi lại output sau:
|
| 230 |
-
|
| 231 |
-
<details>
|
| 232 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 233 |
-
```
|
| 234 |
-
Starting MCP inspector...
|
| 235 |
-
⚙️ Proxy server listening on port 6277
|
| 236 |
-
Spawned stdio transport
|
| 237 |
-
Connected MCP client to backing server transport
|
| 238 |
-
Created web app transport
|
| 239 |
-
Set up MCP proxy
|
| 240 |
-
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
|
| 241 |
-
```
|
| 242 |
-
</details>
|
| 243 |
-
```bash
|
| 244 |
-
Starting MCP inspector...
|
| 245 |
-
⚙️ Proxy server listening on port 6277
|
| 246 |
-
Spawned stdio transport
|
| 247 |
-
Connected MCP client to backing server transport
|
| 248 |
-
Created web app transport
|
| 249 |
-
Set up MCP proxy
|
| 250 |
-
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
|
| 251 |
-
```
|
| 252 |
-
|
| 253 |
-
Bạn có thể mở MCP Inspector tại [http://127.0.0.1:6274](http://127.0.0.1:6274) để xem các tính năng của máy chủ và tương tác với chúng.
|
| 254 |
-
|
| 255 |
-
Bạn sẽ thấy các tính năng của máy chủ và khả năng gọi chúng thông qua giao diện người dùng.
|
| 256 |
-
|
| 257 |
-

|
| 258 |
-
|
| 259 |
-
## Bộ SDK MCP
|
| 260 |
-
|
| 261 |
-
MCP được thiết kế để độc lập với ngôn ngữ lập trình, và hiện có các SDK chính thức cho nhiều ngôn ngữ phổ biến:
|
| 262 |
-
|
| 263 |
-
| Ngôn ngữ | Kho lưu trữ | Người bảo trì | Trạng thái |
|
| 264 |
-
|----------|------------|---------------|--------|
|
| 265 |
-
| TypeScript | [github.com/modelcontextprotocol/typescript-sdk](https://github.com/modelcontextprotocol/typescript-sdk) | Anthropic | Hoạt động |
|
| 266 |
-
| Python | [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) | Anthropic | Hoạt động |
|
| 267 |
-
| Java | [github.com/modelcontextprotocol/java-sdk](https://github.com/modelcontextprotocol/java-sdk) | Spring AI (VMware) | Hoạt động |
|
| 268 |
-
| Kotlin | [github.com/modelcontextprotocol/kotlin-sdk](https://github.com/modelcontextprotocol/kotlin-sdk) | JetBrains | Hoạt động |
|
| 269 |
-
| C# | [github.com/modelcontextprotocol/csharp-sdk](https://github.com/modelcontextprotocol/csharp-sdk) | Microsoft | Hoạt động (Xem trước) |
|
| 270 |
-
| Swift | [github.com/modelcontextprotocol/swift-sdk](https://github.com/modelcontextprotocol/swift-sdk) | loopwork-ai | Hoạt động |
|
| 271 |
-
| Rust | [github.com/modelcontextprotocol/rust-sdk](https://github.com/modelcontextprotocol/rust-sdk) | Anthropic/Cộng đồng | Hoạt động |
|
| 272 |
-
|
| 273 |
-
Các SDK này cung cấp các abstraction đặc thù cho từng ngôn ngữ, giúp đơn giản hóa việc làm việc với giao thức MCP, cho phép bạn tập trung vào việc triển khai logic cốt lõi của máy chủ hoặc máy khách thay vì xử lý các chi tiết giao thức cấp thấp.
|
| 274 |
-
|
| 275 |
-
## Bước tiếp theo
|
| 276 |
-
|
| 277 |
-
Chúng ta mới chỉ chạm vào bề mặt của những gì có thể làm với MCP nhưng bạn đã có một máy chủ cơ bản đang chạy. Thực tế, bạn cũng đã kết nối với nó bằng MCP Client trên trình duyệt.
|
| 278 |
-
|
| 279 |
-
Trong phần tiếp theo, chúng ta sẽ xem cách kết nối với máy chủ từ một LLM.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit2/clients.mdx
DELETED
|
@@ -1,79 +0,0 @@
|
|
| 1 |
-
# Xây dựng MCP Clients
|
| 2 |
-
|
| 3 |
-
Trong phần này, chúng ta sẽ tạo các client có thể tương tác với MCP server bằng các ngôn ngữ lập trình khác nhau. Chúng ta sẽ triển khai cả client JavaScript sử dụng HuggingFace.js và client Python sử dụng smolagents.
|
| 4 |
-
|
| 5 |
-
## Cấu hình MCP Clients
|
| 6 |
-
|
| 7 |
-
Việc triển khai hiệu quả MCP servers và clients yêu cầu cấu hình phù hợp. Đặc tả MCP vẫn đang phát triển, vì vậy các phương pháp cấu hình có thể thay đổi. Chúng ta sẽ tập trung vào các best practice hiện tại về cấu hình.
|
| 8 |
-
|
| 9 |
-
### Cấu hình Files của MCP
|
| 10 |
-
|
| 11 |
-
Các MCP hosts sử dụng configuration files để quản lý kết nối server. Những files này xác định các servers nào có sẵn và cách kết nối đến chúng.
|
| 12 |
-
|
| 13 |
-
Các configuration files rất đơn giản, dễ hiểu và thống nhất giữa các MCP hosts chính.
|
| 14 |
-
|
| 15 |
-
#### Cấu trúc `mcp.json`
|
| 16 |
-
|
| 17 |
-
File cấu hình chuẩn cho MCP có tên `mcp.json`. Đây là cấu trúc cơ bản:
|
| 18 |
-
|
| 19 |
-
```json
|
| 20 |
-
{
|
| 21 |
-
"servers": [
|
| 22 |
-
{
|
| 23 |
-
"name": "MCP Server",
|
| 24 |
-
"transport": {
|
| 25 |
-
"type": "sse",
|
| 26 |
-
"url": "http://localhost:7860/gradio_api/mcp/sse"
|
| 27 |
-
}
|
| 28 |
-
}
|
| 29 |
-
]
|
| 30 |
-
}
|
| 31 |
-
```
|
| 32 |
-
|
| 33 |
-
Trong ví dụ này, chúng ta có một server được cấu hình sử dụng SSE transport, kết nối đến Gradio server local chạy trên cổng 7860.
|
| 34 |
-
|
| 35 |
-
<Tip>
|
| 36 |
-
|
| 37 |
-
Chúng ta đã kết nối đến ứng dụng Gradio qua giao thức SSE vì giả định rằng ứng dụng gradio đang chạy trên một Server từ xa. Tuy nhiên nếu bạn muốn kết nối đến script local, `stdio` transport thay vì `sse` transport là lựa chọn tốt hơn.
|
| 38 |
-
|
| 39 |
-
</Tip>
|
| 40 |
-
|
| 41 |
-
#### Cấu hình cho HTTP+SSE Transport
|
| 42 |
-
|
| 43 |
-
Với các servers từ xa sử dụng HTTP+SSE transport, cấu hình bao gồm URL của server:
|
| 44 |
-
|
| 45 |
-
```json
|
| 46 |
-
{
|
| 47 |
-
"servers": [
|
| 48 |
-
{
|
| 49 |
-
"name": "Remote MCP Server",
|
| 50 |
-
"transport": {
|
| 51 |
-
"type": "sse",
|
| 52 |
-
"url": "https://example.com/gradio_api/mcp/sse"
|
| 53 |
-
}
|
| 54 |
-
}
|
| 55 |
-
]
|
| 56 |
-
}
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
Cấu hình này cho phép UI client của bạn giao tiếp với Gradio MCP server sử dụng MCP protocol, giúp tích hợp liền mạch giữa frontend và dịch vụ MCP.
|
| 60 |
-
|
| 61 |
-
## Cấu hình UI MCP Client
|
| 62 |
-
|
| 63 |
-
Khi làm việc với Gradio MCP servers, bạn có thể cấu hình UI client để kết nối đến server sử dụng MCP protocol. Cách thiết lập như sau:
|
| 64 |
-
|
| 65 |
-
### Cấu hình cơ bản
|
| 66 |
-
|
| 67 |
-
Tạo file mới tên `config.json` với cấu hình sau:
|
| 68 |
-
|
| 69 |
-
```json
|
| 70 |
-
{
|
| 71 |
-
"mcpServers": {
|
| 72 |
-
"mcp": {
|
| 73 |
-
"url": "http://localhost:7860/gradio_api/mcp/sse"
|
| 74 |
-
}
|
| 75 |
-
}
|
| 76 |
-
}
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
-
Cấu hình này cho phép UI client của bạn giao tiếp với Gradio MCP server sử dụng MCP protocol, giúp tích hợp liền mạch giữa frontend và dịch vụ MCP.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit2/gradio-client.mdx
DELETED
|
@@ -1,144 +0,0 @@
|
|
| 1 |
-
# Gradio với vai trò Máy khách MCP
|
| 2 |
-
|
| 3 |
-
Ở chương trước, chúng ta đã tìm hiểu cách tạo MCP Server bằng Gradio và kết nối đến nó bằng một MCP Client. Trong chương này, chúng ta sẽ khám phá cách sử dụng Gradio như một MCP Client để kết nối đến MCP Server.
|
| 4 |
-
|
| 5 |
-
<Tip>
|
| 6 |
-
|
| 7 |
-
Gradio phù hợp nhất để tạo UI client và MCP server, nhưng cũng có thể dùng nó như MCP Client và hiển thị dưới dạng UI.
|
| 8 |
-
|
| 9 |
-
</Tip>
|
| 10 |
-
|
| 11 |
-
Chúng ta sẽ kết nối đến MCP server đã tạo ở chương trước và dùng nó để trả lời câu hỏi.
|
| 12 |
-
|
| 13 |
-
## MCP Client trong Gradio
|
| 14 |
-
|
| 15 |
-
Đầu tiên, cần cài đặt các thư viện `smolagents`, gradio và mcp-client nếu chưa có:
|
| 16 |
-
|
| 17 |
-
```bash
|
| 18 |
-
pip install smolagents[mcp] gradio[mcp] mcp
|
| 19 |
-
```
|
| 20 |
-
|
| 21 |
-
Giờ chúng ta có thể import các thư viện cần thiết và tạo giao diện Gradio đơn giản sử dụng MCP Client để kết nối đến MCP Server.
|
| 22 |
-
|
| 23 |
-
```python
|
| 24 |
-
import gradio as gr
|
| 25 |
-
|
| 26 |
-
from mcp.client.stdio import StdioServerParameters
|
| 27 |
-
from smolagents import ToolCollection, CodeAgent
|
| 28 |
-
from smolagents import CodeAgent, InferenceClientModel
|
| 29 |
-
from smolagents.mcp_client import MCPClient
|
| 30 |
-
```
|
| 31 |
-
|
| 32 |
-
Tiếp theo, kết nối đến MCP Server và lấy các công cụ có thể dùng để trả lời câu hỏi.
|
| 33 |
-
|
| 34 |
-
```python
|
| 35 |
-
mcp_client = MCPClient(
|
| 36 |
-
{"url": "http://localhost:7860/gradio_api/mcp/sse"}
|
| 37 |
-
)
|
| 38 |
-
tools = mcp_client.get_tools()
|
| 39 |
-
```
|
| 40 |
-
|
| 41 |
-
Sau khi có các công cụ, ta có thể tạo một agent đơn giản sử dụng chúng để trả lời câu hỏi. Hiện tại chúng ta sẽ dùng `InferenceClientModel` và mô hình mặc định từ `smolagents`.
|
| 42 |
-
|
| 43 |
-
```python
|
| 44 |
-
model = InferenceClientModel()
|
| 45 |
-
agent = CodeAgent(tools=[*tools], model=model)
|
| 46 |
-
```
|
| 47 |
-
|
| 48 |
-
Giờ tạo giao diện Gradio đơn giản sử dụng agent để trả lời câu hỏi.
|
| 49 |
-
|
| 50 |
-
```python
|
| 51 |
-
demo = gr.ChatInterface(
|
| 52 |
-
fn=lambda message, history: str(agent.run(message)),
|
| 53 |
-
type="messages",
|
| 54 |
-
examples=["Prime factorization of 68"],
|
| 55 |
-
title="Agent with MCP Tools",
|
| 56 |
-
description="Đây là agent đơn giản sử dụng các công cụ MCP để trả lời câu hỏi.",
|
| 57 |
-
messages=[],
|
| 58 |
-
)
|
| 59 |
-
|
| 60 |
-
demo.launch()
|
| 61 |
-
```
|
| 62 |
-
|
| 63 |
-
Vậy là xong! Chúng ta đã tạo một giao diện Gradio đơn giản dùng MCP Client để kết nối đến MCP Server và trả lời câu hỏi.
|
| 64 |
-
|
| 65 |
-
<iframe
|
| 66 |
-
src="https://mcp-course-unit2-gradio-client.hf.space"
|
| 67 |
-
frameborder="0"
|
| 68 |
-
width="850"
|
| 69 |
-
height="450"
|
| 70 |
-
></iframe>
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
## Ví dụ hoàn chỉnh
|
| 74 |
-
|
| 75 |
-
Dưới đây là ví dụ hoàn chỉnh của MCP Client trong Gradio:
|
| 76 |
-
|
| 77 |
-
```python
|
| 78 |
-
import gradio as gr
|
| 79 |
-
|
| 80 |
-
from mcp.client.stdio import StdioServerParameters
|
| 81 |
-
from smolagents import ToolCollection, CodeAgent
|
| 82 |
-
from smolagents import CodeAgent, InferenceClientModel
|
| 83 |
-
from smolagents.mcp_client import MCPClient
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
try:
|
| 87 |
-
mcp_client = MCPClient(
|
| 88 |
-
# {"url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/sse"}
|
| 89 |
-
{"url": "http://localhost:7860/gradio_api/mcp/sse"}
|
| 90 |
-
)
|
| 91 |
-
tools = mcp_client.get_tools()
|
| 92 |
-
|
| 93 |
-
model = InferenceClientModel()
|
| 94 |
-
agent = CodeAgent(tools=[*tools], model=model)
|
| 95 |
-
|
| 96 |
-
def call_agent(message, history):
|
| 97 |
-
return str(agent.run(message))
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
demo = gr.ChatInterface(
|
| 101 |
-
fn=lambda message, history: str(agent.run(message)),
|
| 102 |
-
type="messages",
|
| 103 |
-
examples=["Prime factorization of 68"],
|
| 104 |
-
title="Agent with MCP Tools",
|
| 105 |
-
description="Đây là agent đơn giản sử dụng các công cụ MCP để trả lời câu hỏi.",
|
| 106 |
-
messages=[],
|
| 107 |
-
)
|
| 108 |
-
|
| 109 |
-
demo.launch()
|
| 110 |
-
finally:
|
| 111 |
-
mcp_client.close()
|
| 112 |
-
```
|
| 113 |
-
|
| 114 |
-
Bạn sẽ thấy chúng ta đóng MCP Client trong khối `finally`. Điều này quan trọng vì MCP Client là đối tượng tồn tại lâu dài cần được đóng khi chương trình kết thúc.
|
| 115 |
-
|
| 116 |
-
## Triển khai lên Hugging Face Spaces
|
| 117 |
-
|
| 118 |
-
Để chia sẻ server của bạn với mọi người, bạn có thể triển khai lên Hugging Face Spaces như đã làm ở chương trước.
|
| 119 |
-
Để triển khai Gradio MCP client lên Hugging Face Spaces:
|
| 120 |
-
|
| 121 |
-
1. Tạo Space mới trên Hugging Face:
|
| 122 |
-
- Truy cập huggingface.co/spaces
|
| 123 |
-
- Click "Create new Space"
|
| 124 |
-
- Chọn "Gradio" làm SDK
|
| 125 |
-
- Đặt tên cho Space (ví dụ: "mcp-client")
|
| 126 |
-
|
| 127 |
-
2. Tạo một tệp `requirements.txt`:
|
| 128 |
-
```txt
|
| 129 |
-
gradio[mcp]
|
| 130 |
-
smolagents[mcp]
|
| 131 |
-
```
|
| 132 |
-
|
| 133 |
-
3. Đẩy code lên Space:
|
| 134 |
-
```bash
|
| 135 |
-
git init
|
| 136 |
-
git add server.py requirements.txt
|
| 137 |
-
git commit -m "Initial commit"
|
| 138 |
-
git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-client
|
| 139 |
-
git push -u origin main
|
| 140 |
-
```
|
| 141 |
-
|
| 142 |
-
## Kết luận
|
| 143 |
-
|
| 144 |
-
Trong phần này, chúng ta đã tìm hiểu cách sử dụng Gradio như một MCP Client để kết nối đến một MCP Server. Chúng ta cũng đã xem qua cách triển khai MCP Client trên Hugging Face Spaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
units/vi/unit2/gradio-server.mdx
DELETED
|
@@ -1,228 +0,0 @@
|
|
| 1 |
-
# Xây dựng Gradio MCP Server
|
| 2 |
-
|
| 3 |
-
Trong phần này, chúng ta sẽ tạo một MCP server phân tích cảm xúc bằng Gradio. Server này sẽ cung cấp công cụ phân tích cảm xúc cho cả người dùng qua giao diện web và các mô hình AI thông qua giao thức MCP.
|
| 4 |
-
|
| 5 |
-
## Giới thiệu tích hợp Gradio MCP
|
| 6 |
-
|
| 7 |
-
Gradio cung cấp cách đơn giản để tạo MCP server bằng việc tự động chuyển đổi các hàm Python thành MCP Tools. Khi bạn đặt `mcp_server=True` trong `launch()`, Gradio sẽ:
|
| 8 |
-
|
| 9 |
-
1. Tự động chuyển đổi các hàm thành MCP Tools
|
| 10 |
-
2. Ánh xạ các thành phần đầu vào sang schema tham số công cụ
|
| 11 |
-
3. Xác định định dạng phản hồi từ các thành phần đầu ra
|
| 12 |
-
4. Thiết lập JSON-RPC qua HTTP+SSE cho giao tiếp client-server
|
| 13 |
-
5. Tạo cả giao diện web và endpoint MCP server
|
| 14 |
-
|
| 15 |
-
## Thiết lập dự án
|
| 16 |
-
|
| 17 |
-
Đầu tiên, hãy tạo thư mục mới cho dự án và cài đặt các phụ thuộc cần thiết:
|
| 18 |
-
|
| 19 |
-
```bash
|
| 20 |
-
mkdir mcp-sentiment
|
| 21 |
-
cd mcp-sentiment
|
| 22 |
-
python -m venv venv
|
| 23 |
-
source venv/bin/activate # Trên Windows: venv\Scripts\activate
|
| 24 |
-
pip install "gradio[mcp]" textblob
|
| 25 |
-
```
|
| 26 |
-
|
| 27 |
-
## Tạo Server
|
| 28 |
-
|
| 29 |
-
Tạo một tệp mới có tên `server.py` với mã sau:
|
| 30 |
-
|
| 31 |
-
<details>
|
| 32 |
-
<summary>Bấm để xem bản dịch tiếng Việt</summary>
|
| 33 |
-
```python
|
| 34 |
-
import gradio as gr
|
| 35 |
-
from textblob import TextBlob
|
| 36 |
-
|
| 37 |
-
def sentiment_analysis(text: str) -> dict:
|
| 38 |
-
"""
|
| 39 |
-
Phân tích cảm xúc của văn bản được cung cấp.
|
| 40 |
-
|
| 41 |
-
Args:
|
| 42 |
-
text (str): Văn bản cần phân tích
|
| 43 |
-
|
| 44 |
-
Returns:
|
| 45 |
-
dict: Từ điển chứa thông tin về độ phân cực, tính chủ quan và đánh giá
|
| 46 |
-
"""
|
| 47 |
-
blob = TextBlob(text)
|
| 48 |
-
sentiment = blob.sentiment
|
| 49 |
-
|
| 50 |
-
return {
|
| 51 |
-
"polarity": round(sentiment.polarity, 2), # -1 (tiêu cực) đến 1 (tích cực)
|
| 52 |
-
"subjectivity": round(sentiment.subjectivity, 2), # 0 (khách quan) đến 1 (chủ quan)
|
| 53 |
-
"assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
# Tạo giao diện Gradio
|
| 57 |
-
demo = gr.Interface(
|
| 58 |
-
fn=sentiment_analysis,
|
| 59 |
-
inputs=gr.Textbox(placeholder="Nhập văn bản để phân tích..."),
|
| 60 |
-
outputs=gr.JSON(),
|
| 61 |
-
title="Phân Tích Cảm Xúc Văn Bản",
|
| 62 |
-
description="Phân tích cảm xúc văn bản sử dụng TextBlob"
|
| 63 |
-
)
|
| 64 |
-
|
| 65 |
-
# Khởi chạy giao diện và Server MCP
|
| 66 |
-
if __name__ == "__main__":
|
| 67 |
-
demo.launch(mcp_server=True)
|
| 68 |
-
```
|
| 69 |
-
</details>
|
| 70 |
-
|
| 71 |
-
```python
|
| 72 |
-
import gradio as gr
|
| 73 |
-
from textblob import TextBlob
|
| 74 |
-
|
| 75 |
-
def sentiment_analysis(text: str) -> dict:
|
| 76 |
-
"""
|
| 77 |
-
Analyze the sentiment of the given text.
|
| 78 |
-
|
| 79 |
-
Args:
|
| 80 |
-
text (str): The text to analyze
|
| 81 |
-
|
| 82 |
-
Returns:
|
| 83 |
-
dict: A dictionary containing polarity, subjectivity, and assessment
|
| 84 |
-
"""
|
| 85 |
-
blob = TextBlob(text)
|
| 86 |
-
sentiment = blob.sentiment
|
| 87 |
-
|
| 88 |
-
return {
|
| 89 |
-
"polarity": round(sentiment.polarity, 2), # -1 (negative) to 1 (positive)
|
| 90 |
-
"subjectivity": round(sentiment.subjectivity, 2), # 0 (objective) to 1 (subjective)
|
| 91 |
-
"assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
|
| 92 |
-
}
|
| 93 |
-
|
| 94 |
-
# Create the Gradio interface
|
| 95 |
-
demo = gr.Interface(
|
| 96 |
-
fn=sentiment_analysis,
|
| 97 |
-
inputs=gr.Textbox(placeholder="Enter text to analyze..."),
|
| 98 |
-
outputs=gr.JSON(),
|
| 99 |
-
title="Text Sentiment Analysis",
|
| 100 |
-
description="Analyze the sentiment of text using TextBlob"
|
| 101 |
-
)
|
| 102 |
-
|
| 103 |
-
# Launch the interface and MCP server
|
| 104 |
-
if __name__ == "__main__":
|
| 105 |
-
demo.launch(mcp_server=True)
|
| 106 |
-
```
|
| 107 |
-
|
| 108 |
-
## Hiểu về Mã
|
| 109 |
-
|
| 110 |
-
Hãy cùng phân tích các thành phần chính:
|
| 111 |
-
|
| 112 |
-
1. **Định nghĩa Hàm**:
|
| 113 |
-
- Hàm `sentiment_analysis` nhận đầu vào là văn bản và trả về một từ điển
|
| 114 |
-
- Sử dụng TextBlob để phân tích cảm xúc
|
| 115 |
-
- Docstring rất quan trọng vì giúp Gradio tạo lược đồ công cụ MCP
|
| 116 |
-
- Gợi ý kiểu dữ liệu (`str` và `dict`) giúp xác định lược đồ đầu vào/đầu ra
|
| 117 |
-
|
| 118 |
-
2. **Giao diện Gradio**:
|
| 119 |
-
- `gr.Interface` tạo cả giao diện web và Server MCP
|
| 120 |
-
- Hàm được hiển thị như một công cụ MCP tự động
|
| 121 |
-
- Các thành phần đầu vào và đầu ra xác định lược đồ công cụ
|
| 122 |
-
- Thành phần đầu ra JSON đảm bảo tuần tự hóa đúng cách
|
| 123 |
-
|
| 124 |
-
3. **Server MCP**:
|
| 125 |
-
- Thiết lập `mcp_server=True` kích hoạt Server MCP
|
| 126 |
-
- Server sẽ có sẵn tại `http://localhost:7860/gradio_api/mcp/sse`
|
| 127 |
-
- Bạn cũng có thể kích hoạt bằng biến môi trường:
|
| 128 |
-
```bash
|
| 129 |
-
export GRADIO_MCP_SERVER=True
|
| 130 |
-
```
|
| 131 |
-
|
| 132 |
-
## Chạy Server
|
| 133 |
-
|
| 134 |
-
Khởi động Server bằng cách chạy:
|
| 135 |
-
|
| 136 |
-
```bash
|
| 137 |
-
python server.py
|
| 138 |
-
```
|
| 139 |
-
|
| 140 |
-
Bạn sẽ thấy đầu ra cho biết cả giao diện web và Server MCP đang chạy. Giao diện web sẽ có sẵn tại `http://localhost:7860`, và Server MCP tại `http://localhost:7860/gradio_api/mcp/sse`.
|
| 141 |
-
|
| 142 |
-
## Kiểm tra Server
|
| 143 |
-
|
| 144 |
-
Bạn có thể kiểm tra Server bằng hai cách:
|
| 145 |
-
|
| 146 |
-
1. **Giao diện Web**:
|
| 147 |
-
- Mở `http://localhost:7860` trong trình duyệt
|
| 148 |
-
- Nhập văn bản và nhấp "Submit"
|
| 149 |
-
- Bạn sẽ thấy kết quả phân tích cảm xúc
|
| 150 |
-
|
| 151 |
-
2. **Lược đồ MCP**:
|
| 152 |
-
- Truy cập `http://localhost:7860/gradio_api/mcp/schema`
|
| 153 |
-
- Hiển thị lược đồ công cụ MCP mà các Client sẽ sử dụng
|
| 154 |
-
- Bạn cũng có thể tìm thấy liên kết này trong phần "View API" ở chân trang ứng dụng Gradio
|
| 155 |
-
|
| 156 |
-
## Mẹo Xử lý Sự cố
|
| 157 |
-
|
| 158 |
-
1. **Gợi ý Kiểu dữ liệu và Docstring**:
|
| 159 |
-
- Luôn cung cấp gợi ý kiểu dữ liệu cho tham số hàm và giá trị trả về
|
| 160 |
-
- Bao gồm docstring với khối "Args:" cho mỗi tham số
|
| 161 |
-
- Điều này giúp Gradio tạo lược đồ công cụ MCP chính xác
|
| 162 |
-
|
| 163 |
-
2. **Đầu vào Chuỗi**:
|
| 164 |
-
- Khi không chắc chắn, hãy chấp nhận đối số đầu vào dưới dạng `str`
|
| 165 |
-
- Chuyển đổi chúng sang kiểu mong muốn bên trong hàm
|
| 166 |
-
- Cung cấp khả năng tương thích tốt hơn với các Client MCP
|
| 167 |
-
|
| 168 |
-
3. **Hỗ trợ SSE**:
|
| 169 |
-
- Một số Client MCP không hỗ trợ Server MCP dựa trên SSE
|
| 170 |
-
- Trong trường hợp đó, sử dụng `mcp-remote`:
|
| 171 |
-
```json
|
| 172 |
-
{
|
| 173 |
-
"mcpServers": {
|
| 174 |
-
"gradio": {
|
| 175 |
-
"command": "npx",
|
| 176 |
-
"args": [
|
| 177 |
-
"mcp-remote",
|
| 178 |
-
"http://localhost:7860/gradio_api/mcp/sse"
|
| 179 |
-
]
|
| 180 |
-
}
|
| 181 |
-
}
|
| 182 |
-
}
|
| 183 |
-
```
|
| 184 |
-
|
| 185 |
-
4. **Sự cố Kết nối**:
|
| 186 |
-
- Nếu gặp vấn đề kết nối, thử khởi động lại cả Client và Server
|
| 187 |
-
- Kiểm tra xem Server đang chạy và có thể truy cập được không
|
| 188 |
-
- Xác nhận rằng lược đồ MCP có sẵn tại URL mong đợi
|
| 189 |
-
|
| 190 |
-
## Triển khai lên Hugging Face Spaces
|
| 191 |
-
|
| 192 |
-
Để làm cho Server của bạn có sẵn cho người khác, bạn có thể triển khai lên Hugging Face Spaces:
|
| 193 |
-
|
| 194 |
-
1. Tạo một Space mới trên Hugging Face:
|
| 195 |
-
- Truy cập huggingface.co/spaces
|
| 196 |
-
- Nhấp "Create new Space"
|
| 197 |
-
- Chọn "Gradio" làm SDK
|
| 198 |
-
- Đặt tên cho Space của bạn (ví dụ: "mcp-sentiment")
|
| 199 |
-
|
| 200 |
-
2. Tạo tệp `requirements.txt`:
|
| 201 |
-
```txt
|
| 202 |
-
gradio[mcp]
|
| 203 |
-
textblob
|
| 204 |
-
```
|
| 205 |
-
|
| 206 |
-
3. Đẩy mã của bạn lên Space:
|
| 207 |
-
```bash
|
| 208 |
-
git init
|
| 209 |
-
git add server.py requirements.txt
|
| 210 |
-
git commit -m "Initial commit"
|
| 211 |
-
git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-sentiment
|
| 212 |
-
git push -u origin main
|
| 213 |
-
```
|
| 214 |
-
|
| 215 |
-
Server MCP của các bạn giờ đã có thể truy cập tại:
|
| 216 |
-
```
|
| 217 |
-
https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse
|
| 218 |
-
```
|
| 219 |
-
|
| 220 |
-
## Bước tiếp theo
|
| 221 |
-
|
| 222 |
-
Giờ khi đã có Server MCP đang chạy, chúng ta sẽ tạo các Client để tương tác với nó. Trong các phần tiếp theo, chúng ta sẽ:
|
| 223 |
-
|
| 224 |
-
1. Tạo một Client dựa trên HuggingFace.js lấy cảm hứng từ Tiny Agents
|
| 225 |
-
2. Triển khai một Client Python dựa trên SmolAgents
|
| 226 |
-
3. Kiểm tra cả hai Client với Server đã triển khai
|
| 227 |
-
|
| 228 |
-
Hãy cùng chuyển sang phần xây dựng Client đầu tiên nào!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|