簡單使用MCP

1、說明

# 測試環境服務器
CPU數量:2核
內存:4GB
磁盤:50GB# 補充
如果不想使用Docker進行操作,只需要跳過Docker相關命令操作
即:使用Ollama運行模型,使用Python來創建MCP

2、安裝Docker

# 安裝Docker
https://docs.docker.com/get-docker/# 安裝Docker Compose
https://docs.docker.com/compose/install/# CentOS安裝Docker
https://mp.weixin.qq.com/s/nHNPbCmdQs3E5x1QBP-ueA

3、安裝Ollama、Python

創建docker-compose.yaml文件:

services:ollama:image: ollama/ollamacontainer_name: mcp-ollamaports:- "11434:11434"python:image: python:3.11-alpinecontainer_name: mcp-pythontty: true

創建并啟動容器:

docker-compose up -d

查看容器列表:

docker ps

停止并銷毀容器:

docker-compose down

刪除鏡像:

docker rmi ollama/ollama python:3.11-alpine

3.1、ollama容器

詳見:
https://ollama.com/
https://github.com/ollama/ollama/blob/main/docs/docker.md
# 進入容器:
docker exec -it mcp-ollama bash# 運行模型:
ollama run qwen3:0.6b

3.2、python容器

詳見:
https://developer.aliyun.com/mirror/alpine
https://developer.aliyun.com/mirror/pypi
# 進入容器:
docker exec -it mcp-python sh# 備份:
cp /etc/apk/repositories /etc/apk/repositories-bak# 修改鏡像源:
sed -i  's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories# 創建~/.pip目錄
mkdir ~/.pip# 編輯~/.pip/pip.conf文件
cat << EOF > ~/.pip/pip.conf
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/[install]
trusted-host=mirrors.aliyun.com
EOF

4、測試

詳見:
https://modelcontextprotocol.io/quickstart/server
https://modelcontextprotocol.io/quickstart/client
https://mcp-docs.cn/quickstart/server
https://mcp-docs.cn/quickstart/client
https://github.com/modelcontextprotocol/quickstart-resources/blob/main/weather-server-python/weather.py
https://github.com/modelcontextprotocol/quickstart-resources/blob/main/mcp-client-python/client.py
https://github.com/ollama/ollama-python

進入容器:

# 進入容器:
docker exec -it mcp-python sh# 切換目錄
cd /root

安裝uv:

pip install uv

創建項目:

# 為我們的項目創建一個新 directory
uv init weather
cd weather# 創建 virtual environment 并激活它
uv venv
source .venv/bin/activate# 安裝 dependencies
uv add "mcp[cli]" httpx python-dotenv anthropic ollama# 創建我們的 server file、client file
touch server.py client.py

創建server.py文件:

詳見:https://github.com/modelcontextprotocol/quickstart-resources/blob/main/weather-server-python/weather.py
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP# Initialize FastMCP server
mcp = FastMCP("weather")# Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"async def make_nws_request(url: str) -> dict[str, Any] | None:"""Make a request to the NWS API with proper error handling."""headers = {"User-Agent": USER_AGENT,"Accept": "application/geo+json"}async with httpx.AsyncClient() as client:try:response = await client.get(url, headers=headers, timeout=30.0)response.raise_for_status()return response.json()except Exception:return Nonedef format_alert(feature: dict) -> str:"""Format an alert feature into a readable string."""props = feature["properties"]return f"""
Event: {props.get('event', 'Unknown')}
Area: {props.get('areaDesc', 'Unknown')}
Severity: {props.get('severity', 'Unknown')}
Description: {props.get('description', 'No description available')}
Instructions: {props.get('instruction', 'No specific instructions provided')}
"""@mcp.tool()
async def get_alerts(state: str) -> str:"""Get weather alerts for a US state.Args:state: Two-letter US state code (e.g. CA, NY)"""url = f"{NWS_API_BASE}/alerts/active/area/{state}"data = await make_nws_request(url)if not data or "features" not in data:return "Unable to fetch alerts or no alerts found."if not data["features"]:return "No active alerts for this state."alerts = [format_alert(feature) for feature in data["features"]]return "\n---\n".join(alerts)@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:"""Get weather forecast for a location.Args:latitude: Latitude of the locationlongitude: Longitude of the location"""# First get the forecast grid endpointpoints_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"points_data = await make_nws_request(points_url)if not points_data:return "Unable to fetch forecast data for this location."# Get the forecast URL from the points responseforecast_url = points_data["properties"]["forecast"]forecast_data = await make_nws_request(forecast_url)if not forecast_data:return "Unable to fetch detailed forecast."# Format the periods into a readable forecastperiods = forecast_data["properties"]["periods"]forecasts = []for period in periods[:5]:  # Only show next 5 periodsforecast = f"""
{period['name']}:
Temperature: {period['temperature']}°{period['temperatureUnit']}
Wind: {period['windSpeed']} {period['windDirection']}
Forecast: {period['detailedForecast']}
"""forecasts.append(forecast)return "\n---\n".join(forecasts)if __name__ == "__main__":# Initialize and run the servermcp.run(transport='stdio')

創建client.py文件:

詳見:https://github.com/modelcontextprotocol/quickstart-resources/blob/main/mcp-client-python/client.py
說明:"需要增加process_query_modify、process_tools方法""根據實際情況修改下面代碼中的host的值"
self.ollama = AsyncClient(host="http://localhost:11434")
import asyncio
from typing import Optional
from contextlib import AsyncExitStackfrom mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_clientfrom anthropic import Anthropic
from dotenv import load_dotenvfrom ollama import AsyncClientload_dotenv()  # load environment variables from .envclass MCPClient:def __init__(self):# Initialize session and client objectsself.session: Optional[ClientSession] = Noneself.exit_stack = AsyncExitStack()# self.anthropic = Anthropic()#self.ollama = AsyncClient(host="http://localhost:11434")self.ollama = AsyncClient(host="http://ollama:11434")async def connect_to_server(self, server_script_path: str):"""Connect to an MCP serverArgs:server_script_path: Path to the server script (.py or .js)"""is_python = server_script_path.endswith('.py')is_js = server_script_path.endswith('.js')if not (is_python or is_js):raise ValueError("Server script must be a .py or .js file")command = "python" if is_python else "node"server_params = StdioServerParameters(command=command,args=[server_script_path],env=None)stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))self.stdio, self.write = stdio_transportself.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))await self.session.initialize()# List available toolsresponse = await self.session.list_tools()tools = response.toolsprint("\nConnected to server with tools:", [tool.name for tool in tools])async def process_query(self, query: str) -> str:"""Process a query using Claude and available tools"""messages = [{"role": "user","content": query}]response = await self.session.list_tools()available_tools = [{ "name": tool.name,"description": tool.description,"input_schema": tool.inputSchema} for tool in response.tools]# Initial Claude API callresponse = self.anthropic.messages.create(model="claude-3-5-sonnet-20241022",max_tokens=1000,messages=messages,tools=available_tools)# Process response and handle tool callsfinal_text = []for content in response.content:if content.type == 'text':final_text.append(content.text)elif content.type == 'tool_use':tool_name = content.nametool_args = content.input# Execute tool callresult = await self.session.call_tool(tool_name, tool_args)final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")# Continue conversation with tool resultsif hasattr(content, 'text') and content.text:messages.append({"role": "assistant","content": content.text})messages.append({"role": "user", "content": result.content})# Get next response from Clauderesponse = self.anthropic.messages.create(model="claude-3-5-sonnet-20241022",max_tokens=1000,messages=messages,)final_text.append(response.content[0].text)return "\n".join(final_text)async def process_query_modify(self, query: str) -> str:"""Process a query using Claude and available tools"""messages = [{"role": "user","content": query}]response = await self.session.list_tools()available_tools = [{ "name": tool.name,"description": tool.description,"input_schema": tool.inputSchema} for tool in response.tools]print("------1------\n",response)tools = self.process_tools(response.tools)model_name = "qwen3:0.6b"# Initial Claude API callresponse = await self.ollama.chat(model=model_name,messages=messages,tools=tools)# Process response and handle tool callsfinal_text = []print("------2------\n",response)if response.message.tool_calls:function = response.message.tool_calls[0].get("function")tool_name = function.get("name")tool_args = function.get("arguments")result = await self.session.call_tool(tool_name, tool_args)final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")print("------3------\n",result)messages.append({"role": "user","content": result.content[0].text})response = await self.ollama.chat(model=model_name,messages=messages,)final_text.append(response.message.content)return "\n".join(final_text)# https://github.com/ollama/ollama-python/blob/main/examples/tools.pydef process_tools(self, response_tools) -> []:tools = []for tool in response_tools:item = {'type': 'function','function': {'name': tool.name,'description': tool.description,'parameters': {'type': tool.inputSchema.get('type'),'required': tool.inputSchema.get('required'),'properties': tool.inputSchema.get('properties'),},},}tools.append(item)return toolsasync def chat_loop(self):"""Run an interactive chat loop"""print("\nMCP Client Started!")print("Type your queries or 'quit' to exit.")while True:try:query = input("\nQuery: ").strip()if query.lower() == 'quit':breakresponse = await self.process_query_modify(query)print("\n" + response)except Exception as e:print(f"\nError: {str(e)}")async def cleanup(self):"""Clean up resources"""await self.exit_stack.aclose()async def main():if len(sys.argv) < 2:print("Usage: python client.py <path_to_server_script>")sys.exit(1)client = MCPClient()try:await client.connect_to_server(sys.argv[1])await client.chat_loop()finally:await client.cleanup()if __name__ == "__main__":import sysasyncio.run(main())

執行腳本:

uv run client.py server.py

對話內容:

# 示例1:加利福尼亞州天氣
What are the weather alerts in California# 示例2:紐約州天氣
What are the weather alerts in New York# 示例3:俄亥俄州天氣
What are the weather alerts in Ohio# 示例4:
使用go語言寫一段冒泡排序

5、詳見

https://modelcontextprotocol.io/quickstart
https://mcp-docs.cn/quickstart
https://github.com/modelcontextprotocol/quickstart-resources
https://github.com/ollama/ollama-python
https://github.com/fufankeji/LLMs-Technology-Community-Beyondata
https://blog.csdn.net/u012894975/article/details/147828391
https://gitee.com/MarsBighead/hawthorn
https://mp.weixin.qq.com/s/i36MBzaO6obseW_Zln0rUA

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915082.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915082.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915082.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電腦裝機軟件一鍵安裝管理器

軟件使用 現在的裝機軟件很多&#xff0c;主要幾種類型就是辦公、看圖、影音、下載等&#xff0c;如果每次裝機之后&#xff0c;手動一個一個去安裝&#xff0c;費時費力還容易安裝到全家桶。 就有人整理了網絡上常用的一系列裝機軟件純凈和諧版本&#xff0c;并打包到一起&a…

深度學習入門-深度學習簡介

深度學習是加深了層的深度神經網絡。只需通過疊加層&#xff0c;就可以創建深度網絡。1、 加深網絡將深度學習中的重要技術&#xff08;構成神經網絡的各種層、學習時的有效技巧、對圖像特別有效的CNN、參數的最優化方法等&#xff09;匯總起來&#xff0c;創建一個深度網絡&am…

Linux 下安裝DM8數據庫詳細教程

Linux 下安裝DM8數據庫詳細教程 一、環境準備 1.操作系統要求 DM 數據庫支持多種操作系統,如 Windows、Linux 等。對于 Linux 系統,確保內核版本符合要求,例如 CentOS 7 或更高版本。同時,要保證系統有足夠的磁盤空間(建議至少 10GB 以上)和內存(至少 1GB 以上)。 對…

搭建基于Gitee文檔筆記自動發布

搭建基于Gitee文檔筆記自動發布由于現在gitee不支持代理靜態頁面&#xff0c;并且github.io需要VPN&#xff0c;實際使用的話gitee更為方便。一、為服務器和個人PC添加免密push和pull 參考鏈接&#xff1a;https://help.gitee.com/base/account/SSH%E5%85%AC%E9%92%A5%E8%AE%BE…

【Lua】閉包可能會導致的變量問題

先思考下面這個問題&#xff1a;local function counter()local count 0return function()count count 1return countend endlocal a counter() local b counter()print(a()) --> ? print(a()) --> ? print(b()) --> ? print(a()) --> ?輸出結果&#xff…

可觀測性、OpenTracing、OpenCensus、OpenTelemetry、Jaeger

監控與觀測 隨著軟件應用從單片架構向分布式微服務體系轉變&#xff0c;應用監控(Monitoring)和觀測(Observability)的需求也隨之提升。兩者存在相同的定義&#xff0c;目的都是為了發現應用程序中的問題。但還是有差別&#xff1a; 監控&#xff1a;目的是為了捕獲已知的問題…

Linux下使用原始socket收發數據包

在Linux系統中&#xff0c;使用非原始的socket&#xff0c;可以收發TCP或者UDP等網絡層數據包。如果要處理網絡層以下的數據包&#xff0c;比如ICMP、ARP等&#xff0c;或者更底層&#xff0c;比如鏈路層數據包&#xff0c;就得使用原始socket了。 創建socket 創建socket要使用…

暑期自學嵌入式——Day05補充(C語言階段)

接續上文&#xff1a;暑期自學嵌入式——Day05&#xff08;C語言階段&#xff09;-CSDN博客 主頁點關注不迷路喲。你的點贊、收藏&#xff0c;一鍵三連&#xff0c;是我持續更新的動力喲&#xff01;&#xff01;&#xff01; 主頁&#xff1a; 一位搞嵌入式的 genius-CSDN博…

.NET Core EFCore零基礎快速入門簡單使用

一、什么是 Entity Framework (EF) Core Entity Framework (EF) Core 是輕量化、可擴展和跨平臺版的對象關系映射程序 (O/RM)數據訪問技術&#xff0c;。 它將開發人員從編寫大量 SQL 語句中解放出來。 二、EF的相關程序包 Microsoft.EntityFrameworkCore 核心程序包&#x…

AAC音頻格式

目錄 AAC音頻格式介紹 主要特點 技術優勢 常見文件擴展名 應用領域 AAC與PCM的區別與優勢對比 基本概念差異 主要技術區別 各自優勢 PCM的優勢 AAC的優勢 應用場景選擇 AAC音頻數據格式解析 1. AAC 文件格式 (1) ADIF (Audio Data Interchange Format) (2) ADT…

pom.xml文件中的${}變量從哪里傳值

在 Maven 的 pom.xml 文件中&#xff0c;${} 格式的變量&#xff08;稱為屬性占位符&#xff09;的值來源主要有以下幾種途徑&#xff1a; 1. ?內置屬性&#xff08;Maven 預定義&#xff09;?? ${project.basedir}&#xff1a;項目根目錄${project.version}&#xff1a;項…

【人工智能】項目案例分析:使用TensorFlow進行大規模對象檢測

????歡迎大家來到我們的天空???? ?? 作者簡介:我們的天空 ??《頭銜》:大廠高級軟件測試工程師,阿里云開發者社區專家博主,CSDN人工智能領域新星創作者。 ??《博客》:人工智能,深度學習,機器學習,python,自然語言處理,AIGC等分享。 所屬的專欄:TensorF…

C++---cout、cerr、clog

在C編程里&#xff0c;cout、cerr和clog是標準庫提供的重要輸出流對象&#xff0c;在數據輸出方面發揮著關鍵作用。 一、cout&#xff1a;標準輸出流 cout 是 std::ostream 類的對象&#xff0c;其作用是向標準輸出設備&#xff08;一般是控制臺&#xff09;輸出數據。它和 C 語…

脈沖神經網絡(Spiking Neural Network, SNN)與知識蒸餾(Knowledge Distillation, KD)

目錄 脈沖神經網絡&#xff08;Spiking Neural Network, SNN&#xff09; 知識蒸餾&#xff08;Knowledge Distillation, KD&#xff09; 三種類別 三種變體 脈沖神經網絡&#xff08;Spiking Neural Network, SNN&#xff09; 收到生物神經系統的啟發&#xff0c;設計的&a…

使用Java完成下面項目

第一題&#xff1a;從控制臺輸入十個學生的成績&#xff0c;使用list集合來保存數據&#xff0c; 遍歷并打印其中成績不及格的成績&#xff0c;打印最高成績&#xff0c;最低成績&#xff0c;并計算及格率代碼如下public class Home1 {public static void main(String[] args) …

龍虎榜——20250718

上證指數今天上漲收陽線&#xff0c;繼續在5天均線保持強勢上漲&#xff0c;個股下跌稍多&#xff0c;大盤股上漲為主。深證指數收小陽線&#xff0c;繼續在5天均線上&#xff0c;總體保持強勢&#xff0c;調整更多是小票。2025年7月18日龍虎榜行業方向分析1. 醫藥醫療? 代表標…

2025年華為認證之HCIE-云計算方向的報考流程

一、先搞明白&#xff1a;HCIE - 云計算認證到底是啥&#xff1f; HCIE - 云計算&#xff08;華為認證 ICT 專家 - 云計算&#xff09;是華為體系里云計算領域的頂級認證&#xff0c;說白了&#xff0c;就是證明你有能力搞定大型企業的云平臺設計、部署和運維。現在政企、金融…

什么是私有化部署企業即時通訊?吱吱企業即時通訊安全嗎?

在企業數字化轉型加速的今天&#xff0c;溝通工具的選擇已經從滿足簡單溝通&#xff0c;升級為“安全、高效、可控”。其中&#xff0c;“私有化部署企業即時通訊”成為許多中小型企業、跨國企業以及數據敏感型企業的核心需求。 那么&#xff0c;究竟什么是私有化部署&#xff…

Vue3 中使用 Element Plus 實現自定義按鈕的 ElNotification 提示框

在 Vue3 項目中&#xff0c;我們經常會用到 ElNotification 作為消息提醒組件&#xff0c;尤其是在異步操作、任務完成或用戶需要交互確認時。然而&#xff0c;Element Plus 默認的 Notification 是非交互式的&#xff0c;不能直接嵌入按鈕或事件。 今天我們來實現一個帶自定義…

下載webrtc M114版本源碼只能使用外網googlesource源-命令版

聲網、國內源都不行&#xff0c;只能外網googlesource源&#xff01;&#xff01;&#xff01; 二、創建 Ubuntu 容器&#xff08;帶目錄掛載&#xff09; 拉取Ubuntu鏡像 docker pull ubuntu:22.04創建并啟動容器&#xff08;掛載Windows目錄到容器&#xff09; docker run -i…