Token导航 LogoToken导航

MCP Server · 搜索检索

Vector Mind

VectorMind 是一个轻量级向量数据库服务,基于 Redis 提供语义搜索能力,支持 REST API 和 MCP 协议。

未说明官方级别未说明来源级核验工具 9
搜索向量数据库GoAPI集成

快速开始

公开资料没有提供安装命令,按仓库或官方文档接入。
作者 / 组织
RecallFlow
提供方
RecallFlow

工具数量

9

来源目录标注

资源数量

0

来源目录标注

提示词数量

0

来源目录标注

GitHub Star

1

仓库热度

收录来源

1 个

MCP World

选型结论

Vector Mind 属于搜索检索类 MCP Server,公开资料标注 9 个工具,通过传输方式未标注接入,客户端适配情况以官方文档为准,没有现成的安装命令;接入前先确认权限范围。

分类

搜索检索

传输方式

未说明

认证方式

无需认证

部署方式

公开资料未说明

安装与配置

公开目录没有给出安装命令,需要按仓库 README安装;下面按同类条目的通用流程说明。

公开命令不是通用的启动方式,拼不出可靠配置示例;请在客户端 MCP 配置里按官方文档填写 command 和 args。

上手步骤

  1. 1

    先确认运行方式

    公开资料没有标注传输方式,先看仓库 README,确认是本地进程还是远程地址。

  2. 2

    获取服务

    公开目录没有给出安装命令,按仓库 README里的步骤安装或获取服务。

  3. 3

    写入客户端配置

    在客户端的 MCP 配置里填启动命令和参数,保存后完全退出客户端再打开,让新配置生效。

  4. 4

    验证是否可用

    连接成功后客户端会列出 9 个工具,随便调一个只读工具确认能返回结果。

接入前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

公开资料仍需确认:安装命令

详细介绍

VectorMind

一个基于Redis的文本RAG(检索增强生成)系统,具有REST API端点和MCP(模型上下文协议)服务器支持。

什么是VectorMind?

VectorMind是一个轻量级的矢量数据库服务,它使用Redis作为后端存储提供语义搜索功能。它从文本内容中创建嵌入,并支持基于相似性的搜索操作。

主要特点

  • 双接口:同时公开REST API(端口8080)和MCP服务器(端口9090)以获得灵活性
  • 向量存储:使用Redis和HNSW(分层导航小世界)索引进行高效的相似性搜索
  • 嵌入支持:例如:使用 ai/mxbai-embed-large 模型
  • 文档管理:使用可选标签和元数据存储文档
  • 文档分块:自动将长文档拆分为重叠的块,以实现更好的语义搜索
  • 相似性搜索:基于具有可配置距离阈值和标签过滤的文本查询查找类似文档

建筑

VectorMind由以下部分组成:

  • Redis服务器:通过RediSearch存储嵌入并提供矢量搜索功能
  • VectorMind服务:Go应用程序,处理嵌入生成并公开API
  • 嵌入模型:例如,它使用 ai/mxbai-embed-large 文本嵌入模型(可配置)
graph TD
    CLIENT1[Client REST API]:::client
    CLIENT2[Client MCP Protocol]:::client

    CLIENT1 -->|HTTP POST
/embeddings
/search
/chunk-and-store| API
    CLIENT2 -->|MCP Protocol| MCP

    subgraph "Docker Compose Environment"
        subgraph "VectorMind Service - Ports: 9090, 8080"
            MCP[MCP Server
Port: 9090]:::mcpserver
            API[REST API
Port: 8080]:::restapi
            VM[VectorMind Container]:::vectormind

            MCP --> VM
            API --> VM
        end

        VM -.->|MODEL_RUNNER_BASE_URL| MODEL

        subgraph "AI Model Layer"
            MODEL[Embedding Model
ai/mxbai-embed-large]:::model
        end

        VM -.->|REDIS_ADDRESS
depends_on| REDIS

        subgraph "Storage Layer"
            REDIS[(Redis Server
Port: 6379)]:::redis
            DATA[(/data Volume)]:::volume

            REDIS --> DATA
        end
    end

    classDef vectormind fill:#4A90E2,stroke:#2E5C8A,stroke-width:2px,color:#fff
    classDef redis fill:#DC382D,stroke:#A72822,stroke-width:2px,color:#fff
    classDef model fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff
    classDef mcpserver fill:#8B5CF6,stroke:#6D28D9,stroke-width:2px,color:#fff
    classDef restapi fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff
    classDef client fill:#6B7280,stroke:#4B5563,stroke-width:2px,color:#fff
    classDef volume fill:#EC4899,stroke:#BE185D,stroke-width:2px,color:#fff

入门指南

先决条件

  • Docker、Docker模型运行器和Docker代理编写

启动VectorMind

  1. 使用Docker Compose (推荐):

创建 一 compose.yml 包含以下内容的文件:

services:

  redis-server:
    image: redis:8.2.3-alpine3.22
    environment: 
      - REDIS_ARGS=--save 30 1
    ports:
      - 6379:6379
    volumes:
      - ./data:/data

  vectormind-tests:
    image: k33g/vectormind:0.0.3
    ports:
      - 9090:9090
      - 8080:8080
    environment:
      REDIS_INDEX_NAME: vectormind_index
      REDIS_ADDRESS: redis-server:6379
      REDIS_PASSWORD: ""

      MCP_HTTP_PORT: 9090
      API_REST_PORT: 8080

    models:
      embedding-model:
        endpoint_var: MODEL_RUNNER_BASE_URL
        model_var: EMBEDDING_MODEL

    depends_on:
      redis-server:
        condition: service_started

models:

  embedding-model:
    model: ai/mxbai-embed-large

跑 以下命令启动 VectorMind:

docker compose up -d

这将开始:

  • 端口上的Redis服务器 6379
  • 端口上的VectorMind MCP服务器 9090
  • 端口上的VectorMind REST API 8080
  1. 环境变量:

撰写文件会自动配置:

  • REDIS_INDEX_NAME:vectormind_index
  • REDIS_ADDRESS:redis服务器:6379
  • MCP_HTTP_PORT: 9090
  • API_REST_PORT: 8080
  • MODEL_RUNNER_BASE_URL:通过模型配置设置
  • EMBEDDING_MODEL:ai/mxbai嵌入大

验证安装

检查VectorMind是否正在运行:

curl http://localhost:8080/health

预期响应:

{
  "status": "healthy",
  "server": "mcp-vectormind-server"
}

如何使用VectorMind

REST API使用

1.获取嵌入模型信息

获取有关正在使用的嵌入模型的信息:

curl http://localhost:8080/embedding-model-info

答复:

{
  "success": true,
  "model_id": "ai/mxbai-embed-large",
  "dimension": 1024
}

此终结点返回:

  • success:布尔值,指示请求是否成功
  • model_id:正在使用的嵌入模型的标识符
  • dimension:嵌入向量的维度
2.创建嵌入

使用可选标签和元数据存储文本内容:

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Squirrels run in the forest",
        "label": "animals",
        "metadata": "id=animals_1"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Birds fly in the sky",
        "label": "animals",
        "metadata": "id=animals_2"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Frogs swim in the pond",
        "label": "animals",
        "metadata": "id=animals_3"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Fishes swim in the sea",
        "label": "animals",
        "metadata": "id=animals_4"
    }'

答复:

{"id":"doc:b1c36710-9d94-41cb-abfc-aa404b896d1f","content":"Squirrels run in the forest","label":"animals","metadata":"id=animals_1","created_at":"2025-11-09T08:36:01.962629337Z","success":true}
{"id":"doc:fbc259cc-eb8d-425e-a444-d4f5b26400cb","content":"Birds fly in the sky","label":"animals","metadata":"id=animals_2","created_at":"2025-11-09T08:36:02.093359462Z","success":true}
{"id":"doc:0154fc6d-887b-4af2-a5a7-c8b37183554f","content":"Frogs swim in the pond","label":"animals","metadata":"id=animals_3","created_at":"2025-11-09T08:36:02.247079753Z","success":true}
{"id":"doc:3953dfdd-2a92-48de-b61b-0119c9d106fc","content":"Fishes swim in the sea","label":"animals","metadata":"id=animals_4","created_at":"2025-11-09T08:36:02.367855295Z","success":true}
3.搜索类似文档

查找与查询文本类似的文档:

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Which animals swim?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Where are the squirrels?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What can be found in the pond?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

答复:

{"results":[{"id":"doc:050c7cee-5891-4052-a3c9-40f2bd3abff7","content":"Fishes swim in the sea","distance":0.5175167322158813},{"id":"doc:efe2868d-3330-452c-ac2a-0e835caecdc9","content":"Frogs swim in the pond","distance":0.6700224280357361}],"success":true}
{"results":[{"id":"doc:14e7a8fb-78e5-4fe7-8969-7559b7cd9752","content":"Squirrels run in the forest","distance":0.48874980211257935}],"success":true}
{"results":[{"id":"doc:efe2868d-3330-452c-ac2a-0e835caecdc9","content":"Frogs swim in the pond","distance":0.6417693495750427}],"success":true}

参数:

  • text (必填):搜索查询
  • max_count (可选):最大结果数(默认值:5)
  • distance_threshold (可选):过滤结果的最大距离(越低=越相似)
4.搜索按标签筛选的类似文档
curl -X POST http://localhost:8080/search_with_label \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What lives in the forest?",
    "label": "animals",
    "max_count": 5,
    "distance_threshold": 0.8
  }'

参数:

  • text (必填):搜索查询
  • label (必填):用于筛选结果的标签
  • max_count (可选):最大结果数(默认值:5)
  • distance_threshold (可选):过滤结果的最大距离(更低=更相似)
5.压缩和存储文档

将一个长文档分割成重叠的小块,并使用相同的标签和元数据存储所有块:

# Read the document content and escape it for JSON
DOCUMENT_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/chunk-and-store \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${DOCUMENT_CONTENT},
    \"label\": \"my-label\",
    \"metadata\": \"category=documentation\",
    \"chunk_size\": 1024,
    \"overlap\": 256
  }"

参数:

  • document (必填):要分块和存储的文档内容
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据
  • chunk_size (必填):每个块的字符大小(必须≤嵌入维度)
  • overlap (必需):块之间重叠的字符数(必须小于chunk_size)

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

此端点可用于:

  • 处理超过嵌入模型限制的长文档
  • 创建重叠块以更好地保存上下文
  • 使用一致的标签批量存储多个块
6.拆分和存储Markdown部分

将markdown文档按节(标题如#、##、###)拆分,并用嵌入存储所有节。大于嵌入维度的部分会自动细分,同时保留部分标题:

# Read the markdown document and escape it for JSON
MARKDOWN_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-markdown-sections \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${MARKDOWN_CONTENT},
    \"label\": \"documentation\",
    \"metadata\": \"project=vectormind\"
  }"

参数:

  • document (必填):要拆分和存储的降价文档内容
  • label (可选):标签适用于所有部分/块
  • metadata (可选):应用于所有节/块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 按标题(#######等)拆分markdown文档
  • 每个部分都存储为单独的块
  • 如果截面超过嵌入尺寸,则会自动细分
  • 重要:细分时,每个子块(第一个子块除外)都将添加节头以保留上下文
  • 所有块共享相同的标签和元数据

示例:如果“##矢量简介”一节的长度为3000个字符,并且超过了嵌入维度(1024),它将被拆分为3个子块:

  1. ## Introduction to Vectors\n\n[first 1024 chars of content]
  2. ## Introduction to Vectors\n\n[next 1024 chars of content]
  3. ## Introduction to Vectors\n\n[remaining content]

此端点可用于:

  • 处理结构化降价文档
  • 通过节标题保留语义上下文
  • 无需手动分块即可自动处理大块
7.使用自定义分隔符拆分和存储

用自定义分隔符拆分文档,并使用嵌入存储所有块。大于嵌入维度的块会自动细分,同时保留前2行非空行作为上下文:

# Read the document and escape it for JSON
DOCUMENT_CONTENT=$(cat startrek.txt | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-with-delimiter \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${DOCUMENT_CONTENT},
    \"delimiter\": \"-----\",
    \"label\": \"star-trek-diseases\",
    \"metadata\": \"source=federation-medical-database\"
  }"

参数:

  • document (必填):要拆分和存储的文档内容
  • delimiter (必填):用于分割文档的分隔符(例如,“-----”、“###”等)
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 按指定的分隔符拆分文档
  • 每个块都存储为单独的文档
  • 如果块超过嵌入维度,则会自动细分
  • 重要:细分时,原始块的前2行非空行将添加到每个子块(第一行除外)之前,以保留上下文
  • 所有块共享相同的标签和元数据

示例:如果一个块以以下开头:

Disease: Andorian Ice Plague
Provenance: Andoria, Andorian Empire

并且超过嵌入维度,它将被拆分为子块,其中每个子块(第一个子块除外)将以以下开头:

Disease: Andorian Ice Plague
Provenance: Andoria, Andorian Empire

[remaining content]

此端点可用于:

  • 使用自定义分隔符处理结构化数据
  • 通过关键标识行维护文档上下文
  • 使用一致分隔符的数据集(类似CSV、日志文件等)
  • 自动处理大型记录,无需手动分块
8.使用层次结构拆分和存储Markdown(🧪 实验)

按标题拆分markdown文档,同时保留层次结构上下文。每个块都包括带有标题、层次和内容字段的结构化元数据。大于嵌入维度的块会自动细分:

# Read the markdown document and escape it for JSON
MARKDOWN_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-markdown-with-hierarchy \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${MARKDOWN_CONTENT},
    \"label\": \"documentation\",
    \"metadata\": \"project=vectormind\"
  }"

参数:

  • document (必填):要拆分和存储的降价文档内容
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 解析markdown文档并提取标题及其层次关系
  • 每个块的格式如下:

- TITLE: 报头前缀(例如。, ##)和标题 - HIERARCHY: 完整的分层路径(例如。, Introduction > Getting Started > Installation) - CONTENT: 本节内容

  • 如果块超过嵌入维度,则会自动细分
  • 所有块共享相同的标签和元数据

块格式示例:

TITLE: ## Installation
HIERARCHY: Getting Started > Installation
CONTENT: To install VectorMind, follow these steps...

用例:

  • 处理具有深层层次结构的文档
  • 通过父子关系维护语义上下文
  • 在特定文档层次结构中搜索
  • 在矢量数据库中保留文档导航结构

备注:此功能是实验性的,块格式可能会在未来的版本中发生变化。

MCP使用

VectorMind公开了以下MCP工具:

1. about_vectormind

提供有关VectorMind MCP服务器的信息。

参数:无

2. create_embedding

使用可选标签和元数据从文本内容创建和存储嵌入。

参数:

  • content (必填):用于创建嵌入的文本内容
  • label (可选):文档的标签/标记
  • metadata (可选):文档的元数据

退货:具有文档ID、内容、标签、元数据和创建时间戳的JSON对象

3. similarity_search

基于文本查询搜索类似文档。返回按相似性排序的文档(最接近的第一个)。

参数:

  • text (必填):搜索类似文档的文本查询
  • max_count (可选):返回的最大结果数(默认值:1)
  • distance_threshold (可选):仅返回距离\ Getting Started > Installation`)

- CONTENT: 本节内容

  • 如果块超过嵌入维度,则会自动细分
  • 所有块共享相同的标签和元数据

块格式示例:

TITLE: ## Installation
HIERARCHY: Getting Started > Installation
CONTENT: To install VectorMind, follow these steps...

用例:

  • 处理具有深层层次结构的文档
  • 通过父子关系维护语义上下文
  • 在特定文档层次结构中搜索
  • 在矢量数据库中保留文档导航结构

备注:此功能是实验性的,块格式可能会在未来的版本中发生变化。

例子

将VectorMind与OpenAI JS SDK结合使用

看 示例/openai js sdk
import OpenAI from "openai";

// OpenAI Client
const openai = new OpenAI({
	baseURL: "http://localhost:12434/engines/v1",
	apiKey: "i-love-docker-model-runner",
});

const VECTORMIND_API = "http://localhost:8080";

const chunks = [
	`# Orcs
	Orcs are savage, brutish humanoids with dark green skin and prominent tusks. 
	These fierce warriors inhabit dense forests where they hunt in packs, 
	using crude but effective weapons forged from scavenged metal and bone. 
	Their tribal society revolves around strength and combat prowess, 
	making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

	`# Dragons
	Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings. 
	These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks. 
	Known for their vast hoards of treasure and centuries of accumulated knowledge, 
	dragons command both fear and respect throughout the realm. 
	Their aerial dominance makes them nearly untouchable in their celestial domain.`,

	`# Goblins
	Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears. 
	Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands. 
	These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers. 
	They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

	`# Krakens
	Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease. 
	These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed. 
	Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet. 
	Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools 
	and tidal waves that reshape entire coastlines.`,
];

// Function to create embeddings
async function createEmbedding(content, label = "", metadata = "") {
	const response = await fetch(`${VECTORMIND_API}/embeddings`, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
		},
		body: JSON.stringify({
			content,
			label,
			metadata,
		}),
	});

	return await response.json();
}

// Function to search for similar documents
async function searchSimilar(text, maxCount = 5, distanceThreshold = 0.7) {
	const response = await fetch(`${VECTORMIND_API}/search`, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
		},
		body: JSON.stringify({
			text,
			max_count: maxCount,
			distance_threshold: distanceThreshold,
		}),
	});

	return await response.json();
}

let userInput = "Tell me something about the dragons";

try {
	// Create embeddings from chunks
	console.log("Creating embeddings...\n");

	for (const chunk of chunks) {
		const result = await createEmbedding(chunk, "fantasy-creatures", "");
		console.log("Created embedding:", result);
	}

	// Search for similar documents
	console.log("\n\nSearching for similar documents...\n");

	const searchResult = await searchSimilar(userInput, 1, 0.7);
	console.log("Search results:\n", JSON.stringify(searchResult, null, 2));

	const documents = searchResult.results.map(r => r.content).join("\n");

	const completion = await openai.chat.completions.create({
		model: "hf.co/menlo/jan-nano-gguf:q4_k_m",
		messages: [
      { role: "system", content: "Using the following documents:" },
      { role: "system", content: "documents:\n"+ documents },
      { role: "user", content: "userInput" }
    ],
		stream: true,
	});

  console.log("=".repeat);

	for await (const chunk of completion) {
		process.stdout.write(chunk.choices[0].delta.content || "");
	}
} catch (error) {
	console.error("Error:", error);
}

将VectorMind与OpenAI Golang SDK结合使用

看 样品/openai go sdk
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
)

const VECTORMIND_API = "http://localhost:8080"

// EmbeddingRequest représente la requête pour créer un embedding
type EmbeddingRequest struct {
	Content  string `json:"content"`
	Label    string `json:"label,omitempty"`
	Metadata string `json:"metadata,omitempty"`
}

// EmbeddingResponse représente la réponse de création d'embedding
type EmbeddingResponse struct {
	ID        string `json:"id"`
	Content   string `json:"content"`
	Label     string `json:"label"`
	Metadata  string `json:"metadata"`
	CreatedAt string `json:"created_at"`
	Success   bool   `json:"success"`
}

// SearchRequest représente la requête de recherche
type SearchRequest struct {
	Text              string  `json:"text"`
	MaxCount          int     `json:"max_count,omitempty"`
	DistanceThreshold float64 `json:"distance_threshold,omitempty"`
}

// SearchResult représente un résultat de recherche
type SearchResult struct {
	ID       string  `json:"id"`
	Content  string  `json:"content"`
	Distance float64 `json:"distance"`
}

// SearchResponse représente la réponse de recherche
type SearchResponse struct {
	Results []SearchResult `json:"results"`
	Success bool           `json:"success"`
}

// CreateEmbedding crée un embedding dans VectorMind
func CreateEmbedding(content, label, metadata string) (*EmbeddingResponse, error) {
	reqBody := EmbeddingRequest{
		Content:  content,
		Label:    label,
		Metadata: metadata,
	}

	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("erreur marshaling: %w", err)
	}

	resp, err := http.Post(VECTORMIND_API+"/embeddings", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("erreur requête: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("erreur lecture réponse: %w", err)
	}

	var result EmbeddingResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, fmt.Errorf("erreur unmarshaling: %w", err)
	}

	return &result, nil
}

// SearchSimilar recherche des documents similaires
func SearchSimilar(text string, maxCount int, distanceThreshold float64) (*SearchResponse, error) {
	reqBody := SearchRequest{
		Text:              text,
		MaxCount:          maxCount,
		DistanceThreshold: distanceThreshold,
	}

	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("erreur marshaling: %w", err)
	}

	resp, err := http.Post(VECTORMIND_API+"/search", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("erreur requête: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("erreur lecture réponse: %w", err)
	}

	var result SearchResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, fmt.Errorf("erreur unmarshaling: %w", err)
	}

	return &result, nil
}

func main() {

	baseURL := "http://localhost:12434/engines/llama.cpp/v1/"
	model := "hf.co/menlo/jan-nano-gguf:q4_k_m"

	client := openai.NewClient(
		option.WithBaseURL(baseURL),
		option.WithAPIKey(""),
	)

	ctx := context.Background()

	chunks := []string{
		`# Orcs
		Orcs are savage, brutish humanoids with dark green skin and prominent tusks.
		These fierce warriors inhabit dense forests where they hunt in packs,
		using crude but effective weapons forged from scavenged metal and bone.
		Their tribal society revolves around strength and combat prowess,
		making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

		`# Dragons
		Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings.
		These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks.
		Known for their vast hoards of treasure and centuries of accumulated knowledge,
		dragons command both fear and respect throughout the realm.
		Their aerial dominance makes them nearly untouchable in their celestial domain.`,

		`# Goblins
		Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears.
		Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands.
		These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers.
		They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

		`# Krakens
		Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease.
		These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed.
		Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet.
		Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools
		and tidal waves that reshape entire coastlines.`,
	}

	// Creation of embeddings
	fmt.Println("Creation of embeddings...")
	for _, chunk := range chunks {
		result, err := CreateEmbedding(chunk, "fantasy-creatures", "")
		if err != nil {
			fmt.Printf("Error when embedding: %v\n", err)
			continue
		}
		fmt.Printf("Embedding created: ID=%s, Success=%v\n", result.ID, result.Success)
	}

	// Search for similar documents
	fmt.Println("\n\nSearch for similar documents...")

	userInput := "Tell me something about the dragons"

	searchResult, err := SearchSimilar(userInput, 2, 0.7)
	if err != nil {
		fmt.Printf("Error search: %v\n", err)
	}

	fmt.Printf("Found: %d\n", len(searchResult.Results))

	var documents string

	for i, result := range searchResult.Results {
		fmt.Printf("  %d. Distance: %.4f\n", i+1, result.Distance)
		fmt.Printf("     ID: %s\n", result.ID)
		fmt.Printf("     Content: %s...\n", result.Content[:50])
		documents += result.Content + "\n"
	}

	fmt.Println(strings.Repeat("-", 50))
	fmt.Println("Chat Completion with retrieved documents as context:")

	messages := []openai.ChatCompletionMessageParamUnion{
		openai.SystemMessage("Using the following documents:"),
		openai.SystemMessage("documents:\n" + documents),
		openai.UserMessage(userInput),
	}

	param := openai.ChatCompletionNewParams{
		Messages:    messages,
		Model:       model,
		Temperature: openai.Opt(0.0),
	}

	stream := client.Chat.Completions.NewStreaming(ctx, param)

	for stream.Next() {
		chunk := stream.Current()
		// Stream each chunk as it arrives
		if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
			fmt.Print(chunk.Choices[0].Delta.Content)
		}
	}

	if err := stream.Err(); err != nil {
		log.Fatalln("Error with the completion:", err)
	}
}

将VectorMind与Golang MCP客户端结合使用

看 示例/与go-mcp客户端一起使用
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"strings"

	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/client/transport"
	"github.com/mark3labs/mcp-go/mcp"
)

type SearchResult struct {
	ID       string  `json:"id"`
	Content  string  `json:"content"`
	Distance float64 `json:"distance"`
}

type SearchResponse struct {
	Results []SearchResult `json:"results"`
	Success bool           `json:"success"`
}

var chunks = []string{
	`# Orcs
		Orcs are savage, brutish humanoids with dark green skin and prominent tusks.
		These fierce warriors inhabit dense forests where they hunt in packs,
		using crude but effective weapons forged from scavenged metal and bone.
		Their tribal society revolves around strength and combat prowess,
		making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

	`# Dragons
		Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings.
		These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks.
		Known for their vast hoards of treasure and centuries of accumulated knowledge,
		dragons command both fear and respect throughout the realm.
		Their aerial dominance makes them nearly untouchable in their celestial domain.`,

	`# Goblins
		Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears.
		Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands.
		These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers.
		They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

	`# Krakens
		Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease.
		These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed.
		Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet.
		Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools
		and tidal waves that reshape entire coastlines.`,
}

func main() {

	ctx := context.Background()

	// MCP client initialization
	fmt.Println("🚀 Initializing MCP StreamableHTTP client...")
	// Create HTTP transport
	httpURL := "http://localhost:9090/mcp"
	httpTransport, err := transport.NewStreamableHTTP(httpURL)
	if err != nil {
		log.Fatalf("Failed to create HTTP transport: %v", err)
	}
	// Create client with the transport
	mcpClient := client.NewClient(httpTransport)
	// Start the client
	if err := mcpClient.Start(ctx); err != nil {
		log.Fatalf("Failed to start client: %v", err)
	}

	initRequest := mcp.InitializeRequest{}
	initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
	initRequest.Params.ClientInfo = mcp.Implementation{
		Name:    "MCP-Go Simple Client Example",
		Version: "1.0.0",
	}
	initRequest.Params.Capabilities = mcp.ClientCapabilities{}

	_, err = mcpClient.Initialize(ctx, initRequest)
	if err != nil {
		log.Fatalf("Failed to initialize: %v", err)
	}

	// Tools listing
	toolsRequest := mcp.ListToolsRequest{}
	// Get the list of tools
	toolsResult, err := mcpClient.ListTools(ctx, toolsRequest)
	if err != nil {
		log.Fatalf("Failed to list tools: %v", err)
	}
	fmt.Println("🛠️  Available tools:")
	for _, tool := range toolsResult.Tools {
		fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
	}

	// Create Embeddings with `create_embedding` MCP tool
	fmt.Println("\n\nCreation of embeddings...")
	for _, chunk := range chunks {
		request := mcp.CallToolRequest{
			Params: mcp.CallToolParams{
				Name: "create_embedding",
				Arguments: map[string]any{
					"content":  chunk,
					"label":    "fantasy-creatures",
					"metadata": "",
				},
			},
		}
		toolResponse, err := mcpClient.CallTool(ctx, request)
		if err != nil {
			fmt.Printf("Error when embedding: %v\n", err)
			continue
		}
		if toolResponse == nil || len(toolResponse.Content) == 0 {
			fmt.Printf("No response from embedding tool\n")
			continue
		}
		fmt.Println("🛠️  Tool response:", toolResponse.Content[0].(mcp.TextContent).Text)

	}

	fmt.Println(strings.Repeat("=", 50))
	fmt.Println("Search for similar documents...")

	userInput := "Tell me something about the dragons"

	searchRequest := mcp.CallToolRequest{
		Params: mcp.CallToolParams{
			Name: "similarity_search",
			Arguments: map[string]any{
				"text":               userInput,
				"max_count":          2,
				"distance_threshold": 0.7,
			},
		},
	}
	searchResponse, err := mcpClient.CallTool(ctx, searchRequest)
	if err != nil {
		log.Fatalf("Error search: %v", err)
	}
	if searchResponse == nil || len(searchResponse.Content) == 0 {
		log.Fatalf("No response from search tool")
	}

	searchResult := searchResponse.Content[0].(mcp.TextContent).Text

	// Parse the JSON response
	var response SearchResponse
	err = json.Unmarshal([]byte(searchResult), &response)
	if err != nil {
		log.Fatalf("Error parsing search result: %v", err)
	}

	// Loop through results
	fmt.Println("\n📋 Search Results:")
	for _, result := range response.Results {
		fmt.Printf("\nID: %s\n", result.ID)
		fmt.Printf("Distance: %f\n", result.Distance)
		fmt.Printf("Content: %s\n", result.Content)
		fmt.Println(strings.Repeat("-", 50))
	}
}

开发和测试

VectorMind 使用基于以下内容的本地CI管道 Docker Compose 包含以下文件:

  • 主管道: compose.ci.yml
  • compose.ci.redis-test-server.yml
  • compose.ci.unit-tests.yml
  • compose.ci.multi-arch-build.yml
  • compose.ci.start-vectormind.yml
  • compose.ci.get-model-info.yml
  • compose.ci.create-embeddings.yml
  • compose.ci.search-embeddings.yml
  • compose.ci.stop-vectormind.yml
  • compose.ci.stop-redis.yml

启动CI管道:

docker compose -f compose.ci.yml up --remove-orphans --build

停止CI管道(以干净的方式):

docker compose -f compose.ci.yml down

本地CI管道

本地CI管道使用Docker Compose进行编排,并遵循以下工作流程:

graph TD
    Start([Start CI Pipeline]):::startNode

    Start --> Redis[redis-test-server
Redis Server]:::service
    Start --> UnitTests[unit-tests
Run Unit Tests]:::test

    UnitTests -->|success| MultiBuild[multi-arch-build
Multi-Architecture Build]:::build

    MultiBuild -->|success| StartVM[start-vectormind
Start VectorMind Service]:::service
    Redis --> StartVM

    StartVM -->|healthy| GetModelInfo[get-model-info
Get Embedding Model Info]:::test

    GetModelInfo -->|success| CreateEmb[create-embeddings
Create Test Embeddings]:::test

    StartVM -->|healthy| SearchEmb[search-embeddings
Search Embeddings]:::test

    CreateEmb -->|success| SearchEmb

    SearchEmb -->|success| StopVM[stop-vectormind
Stop VectorMind]:::cleanup

    StopVM -->|success| StopRedis[stop-redis
Stop Redis Server]:::cleanup

    StopRedis --> Complete([Pipeline Complete]):::endNode

    classDef startNode fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff
    classDef service fill:#3B82F6,stroke:#2563EB,stroke-width:2px,color:#fff
    classDef test fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff
    classDef build fill:#8B5CF6,stroke:#7C3AED,stroke-width:2px,color:#fff
    classDef cleanup fill:#EF4444,stroke:#DC2626,stroke-width:2px,color:#fff
    classDef endNode fill:#6B7280,stroke:#4B5563,stroke-width:2px,color:#fff

管道阶段

  1. redis测试服务器:启动Redis服务器进行测试
  2. 单元测试:在短模式下运行单元测试
  3. 连拱结构:构建多架构Docker镜像(取决于单元测试的成功)
  4. 启动矢量风暴:启动VectorMind服务(取决于多拱形构建成功和redis测试服务器)
  5. 获取模型信息:获取嵌入模型信息(取决于start vectormind是否正常)
  6. 创建嵌入:创建测试嵌入(取决于启动vectormind是否正常并成功获取模型信息)
  7. 搜索嵌入:测试嵌入搜索功能(取决于创建嵌入成功和启动vectormind健康)
  8. 停止矢量风暴:停止VectorMind服务(取决于搜索嵌入是否成功)
  9. 停止redis:停止Redis服务器(取决于停止vectormind的成功)

工具与能力

工具数量

9

资源数量

0

提示词数量

0

能力标签

语义搜索Go本地部署向量数据库RedisRESTAPIMCP协议

数量来自来源目录的标注,具体工具清单以官方文档为准。

典型使用场景

查资料带出处

把网页、论文和文档的检索结果连同链接一起带回对话。

站内知识检索

在自己的文档库里做语义搜索,比关键词更贴题。

事实核对

交叉多个来源确认一条信息,减少模型凭记忆作答。

选择建议

值得选的地方

  • 只提供 9 个工具,职责集中,接入后不容易误操作。
  • 公开说明写得比较完整,接入前能看清能力边界。

先想清楚的地方

  • 公开资料没有可直接复制的安装命令,第一次接入要自己找入口。
  • 第三方目录整理,版本更新和行为细节以官方仓库为准。

更适合

  • 需要在搜索检索场景里让模型直接调用外部能力的人。
  • 愿意照着官方文档一步步配环境的人。

不太适合

  • 希望一条命令就装好、不想看文档的人。
  • 需要厂商级 SLA 和技术支持的生产环境。

同类对比

5 个同类
MCP Server工具数传输方式安装命令收录来源最后核验
Vector Mind

MCP World · 本页

9未说明未标注1 个2026-05-17
Baidu Netdisk

MCP World

未标注未说明未标注1 个2026-05-17
Sequentialthinking

MCP.so

1SSE有2 个2026-05-17
Brave Search 433812ff

MCP World

2未说明未标注1 个2026-05-17
mindsdb (430e18)

MCP World

0未说明有1 个2026-05-17

按同分类和工具数量挑出最接近的几条,字段以各自详情页为准。

常见问题

5 条

Vector Mind 怎么安装?

公开目录没有给出可以直接复制的安装命令,需要按仓库 README里的步骤安装;装好后写进客户端的 MCP 配置再重启。

Vector Mind 怎么在 Claude Desktop、Cursor 里配置?

它是传输方式未标注,客户端配置里要写启动命令和参数,运行环境是 未标注;保存后完全退出客户端再打开,配置才会生效。

Vector Mind 收费吗?

本站只整理公开资料,不代收费用,也没有标注具体价格。是否收费取决于服务本身和背后的接口额度,正式使用前按官方说明确认。

Vector Mind 需要 API Key 吗?

公开资料标注为无需认证,装好就能连;如果实际调用时报鉴权错误,按官方文档补上凭据。

Vector Mind 支持哪些客户端?

公开资料没有标注具体客户端;能配置本地 MCP 命令的客户端都能接,配置方式参照官方文档。

来源信息

继续浏览同类 MCP