简单使用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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…