Umami增强分析服务器添加福利群:解决AI开发者的「MCP实战痛点」这是一个模型上下文协议(MCP)服务器,通过提供来自 Umami 的网站分析数据来增强 Claude 的功能。该服务器允许 Claude 分析用户行为、跟踪网站性能并提供基于数据的洞察。
代码库从头到尾都是使用 Claude Sonnet 3.5 和 Cursor 生成的。

此服务器将 Claude 连接到您的 Umami 分析平台,使其能够:
服务器为 Claude 提供了以下工具来分析网站数据:
每个工具都有描述和可以传递给它的参数列表。这些用于提供上下文和信息,以使 Claude 能够有效地选择合适的工具,并提供正确的参数。
大多数这些工具直接从 Umami API 中拉取数据到 Claude Desktop,但 get_docs 添加了一个语义搜索步骤,以避免 Claude 的上下文窗口问题以及节省令牌使用。所有给定事件的用户旅程都通过 Umami API 检索,然后这些数据被分割成更小的部分,并使用 Hugging Face 的开源句子转换器模型进行嵌入。然后,根据问题,检索出最相关的片段并返回给 Claude,这使得对用户在网站上执行的具体操作和行为进行分析成为可能,这是传统数据可视化工具难以复制的。这种嵌入和语义搜索的实现位于 src/analytics_service/embeddings.py 文件中。
此外,get_screenshot 和 get_html 工具使用开源的 Crawl4AI 网络爬虫来获取给定网站的 HTML 源代码和截图。为了防止 Claude 的上下文窗口出现问题,这些截图需要进行降采样以减小其大小。这使您能够向 Claude 提供有关网站结构和外观的信息,从而提供更准确和相关的性能改进建议。网络爬虫的实现在 src/analytics_service/crawler.py 文件中。

pip install uvClaude Desktop 配置
在您的 Claude Desktop 配置文件中添加以下内容:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%/Claude/claude_desktop_config.json{
"mcpServers": {
"analytics_service": {
"command": "uv",
"args": [
"--directory",
"/path/to/analytics_service",
"run",
"analytics-service"
],
"env": {
"UMAMI_API_URL": "https://example.com",
"UMAMI_USERNAME": "yourUmamiUsername",
"UMAMI_PASSWORD": "yourUmamiPassword",
"UMAMI_TEAM_ID": "yourUmamiTeamId"
}
}
}
}

将 /path/to/analytics_service 替换为实际的 analytics_service 目录路径。
对于 UMAMI_API_URL,将 https://example.com 替换为您正在使用的 Umami 版本的 URL(无论是自托管还是托管在 Umami Cloud 上)。
对于 UMAMI_USERNAME 和 UMAMI_PASSWORD,将 yourUmamiUsername 和 yourUmamiPassword 替换为您的 Umami 账户凭据。
对于 UMAMI_TEAM_ID,将 yourUmamiTeamId 替换为您想要分析的团队 ID。
打开 Claude Desktop
当您打开 Claude Desktop 时,它会自动开始连接到 analytics_service MCP 服务器。初始化服务器并安装正确的包可能需要几分钟时间。当服务器准备好后,您将在聊天窗口右下角看到 10 个可用的 MCP 工具。这由一个小锤子图标及其旁边的数字 10 表示。

此外,如果您还没有这样做,强烈建议您在 Claude Desktop 中启用“功能预览”中的“分析工具”。这将允许 Claude 为您构建仪表板以及其他数据可视化。为此,在左侧边栏中找到“功能预览”选项卡,并在其中启用“分析工具”。在同一部分中也可以启用 LaTeX 渲染。

最简单的方法是使用服务器提供的创建仪表板提示。这可以通过点击聊天窗口左下角的“从MCP附加”附件按钮来选择,然后选择实现方式,最后选择创建仪表板提示。

这将引导您完成为您的网站创建仪表板的过程,并询问:
提供这些信息后,服务器将生成一个txt文件,指示Claude如何构建仪表板。 在聊天窗口中按回车键,Claude将会完成剩余工作。之后,您可以要求Claude对仪表板进行任何修改或添加其他可视化内容。

对于更加定制化的体验,您可以直接与Claude交谈并指定自己的需求,比如希望在仪表板上看到哪些数据以及想使用的可视化方式。此外,您还可以分析用户旅程以确定特定的痛点,并从您的站点添加屏幕截图,以便为Claude提供更多上下文信息。
完成您的请求所需的工具将由Claude自动使用。只需用自然语言提出您的请求,Claude会决定使用哪些工具。如果您想查看所有可用工具的列表,可以要求Claude列出它们,或者点击聊天窗口右下角的锤子图标。

您还可以为自己经常使用的流程创建自定义提示。要做到这一点,您需要:
Define Your Prompt Structure Create a prompt definition that includes:
name: A unique identifier for your promptdescription: A clear explanation of what the prompt doesarguments: List of input parameters your prompt needsAdd this to the list_prompts() function in src/analytics_service/server.py:
Example structure:
@app.list_prompts()
async def list_prompts():
return [
# ... existing prompts ...
{
"name": "Your Prompt Name",
"description": "Your prompt description",
"arguments": [
{
"name": "Parameter Name 1",
"description": "Parameter description",
"required": True/False
},
{
"name": "Parameter Name 2",
"description": "Parameter description",
"required": True/False
}
]
}
]

Implement the Prompt
Add your prompt handling logic in the get_prompt() function in src/analytics_service/server.py:
@app.get_prompt()
async def get_prompt(name: str, arguments: Any):
# ... existing prompts ...
if name == "Your Prompt Name":
return {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": f"Your prompt template with {arguments['Parameter Name']}"
}
}
]
}

When defining messages in your prompt, the role field is crucial for structuring the conversation:
"role": "user" for messages that simulate user input or questions"role": "assistant" for messages that represent Claude's responses or instructions"role": "system" for messages that set context or provide high-level instructionsThe content field in each message must specify a type. Available types are:
"type": "text" - For plain text content"type": "resource" - For including external resources like files, logs, or other data. Must include a resource object with:
uri: The resource identifiertext: The actual contentmimeType: The MIME type of the content (e.g., "text/plain", "text/x-python")While resources do include their content in the text field, using the resource type provides several important benefits:
mimeType field tells Claude how to interpret the content (e.g., as Python code, plain text, or other formats)uri field maintains a reference to where the content came from, which can be useful for:
Here's an example showing different roles and content types:
"messages": [
{
"role": "system",
"content": {
"type": "text",
"text": "Analyze the following log file and code for potential issues."
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "logs://recent",
"text": "[2024-03-14 15:32:11] ERROR: Connection timeout",
"mimeType": "text/plain"
}
}
},
{
"role": "assistant",
"content": {
"type": "text",
"text": "I notice a connection timeout error. Let me examine the related code."
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "file:///code.py",
"text": "def example():\n pass",
"mimeType": "text/x-python"
}
}
}
]

For most prompts, the text type with user role is more than sufficient and allows Claude more control and creativity in its responses. For more complex workflows however, multiple messages with different roles and types allow for a more structured conversation flow and more user control over the response.
Best Practices for Creating Prompts