# Directory Structure
```
├── .gitignore
├── app
│ ├── client
│ │ └── mongo.go
│ ├── configs
│ │ └── config.go
│ ├── mcp.go
│ ├── model
│ │ ├── document.go
│ │ └── index.go
│ └── tools
│ ├── collection.go
│ ├── document.go
│ ├── idgen.go
│ └── index.go
├── config.yml.example
├── Dockerfile
├── go.mod
├── go.sum
├── image
│ ├── img-1.png
│ ├── img-2.png
│ └── img.png
├── README.md
└── server.go
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
# configuration file for Go projects
config.yml
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env
# Local configuration files
*.local
# IDEs and editors
# JetBrains IDEs
.idea/
# Visual Studio Code
.vscode/
# Visual Studio Code workspace
.code-workspace
# MACOS
# macOS Finder directory attributes
.DS_Store
# macOS Finder directory attributes
.AppleDouble
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# MongoDB MCP Server
A Model Context Protocol (MCP) server that enables LLMs to connect MongoDB using [mcp-go](https://github.com/mark3labs/mcp-go). The server acts as a bridge between the LLM and the MongoDB database, allowing you to perform CRUD operations using natural language.
## Features
- **MongoDB action**: Query Collection, Document and Index
- **SSE Support**: Run MCP Server using Server-Sent Events (SSE)
## Available Tools
### Query Tools
- find: Query documents with filtering and projection
- Count: Count documents in a collection
- listCollections: List available collections
- insertOne: Insert a single document
- updateOne: Update a single document
- deleteOne: Delete a single document
### Index Tools
- createIndex: Create a new index
- dropIndex: Remove an index
- indexes: List indexes for a collection
## Configuration
> copy the `config.yml.example` file to `config.yml` and modify it according to your needs.
The server configuration is managed through the `config.yml` file. Below is an example configuration:
```yaml
mongo:
host: mongodb
port: 27017
user: admin
password: 123456
database: db
mcp:
name: mongo-mcp-server
version: 1.0.0
base_url: localhost:8081
address: ":8081"
sse: true
```
- **MongoDB Configuration**:
- `host`: MongoDB server host.
- `port`: MongoDB server port.
- `user`: MongoDB username.
- `password`: MongoDB password.
- `database`: Target MongoDB database.
- **MCP Server Configuration**:
- `name`: Name of the MCP server.
- `version`: Version of the MCP server.
- `base_url`: Base URL for the server.
- `address`: Address and port for the server to listen on.
- `sse`: Enable or disable SSE support, default is `true`.
## Usage
**Start the MCP Server**: Run the server using the following command:
```bash
go run main.go
```
Use in DeepChat

## Example


## References
- [MongoDB Official Documentation](https://www.mongodb.com/zh-cn/docs/languages/go/)
- [mcp-go](https://github.com/mark3labs/mcp-go)
- [mongo-mcp](https://github.com/QuantGeekDev/mongo-mcp)
```
--------------------------------------------------------------------------------
/app/model/index.go:
--------------------------------------------------------------------------------
```go
package model
type CreateIndexRequest struct {
Collection string `mapstructure:"collection" json:"collection"`
IndexSpec map[string]interface{} `mapstructure:"index_spec" json:"index_spec"`
}
type DropIndexRequest struct {
Collection string `mapstructure:"collection" json:"collection"`
IndexName string `mapstructure:"index_name" json:"index_name"`
}
```
--------------------------------------------------------------------------------
/server.go:
--------------------------------------------------------------------------------
```go
package main
import (
"fmt"
"github.com/mark3labs/mcp-go/server"
"mcp/app"
"mcp/app/client"
"mcp/app/configs"
)
func main() {
// Connect mongo client
config := configs.LoadConfig(".", "")
client.ConnectMongo(config.Mongo)
MCPConfig := config.MCP
// Create a new MCP server
s := server.NewMCPServer(
MCPConfig.Name,
MCPConfig.Version,
server.WithResourceCapabilities(true, true),
server.WithLogging(),
server.WithRecovery(),
)
// 添加工具到 MCP 服务器中
app.AddTools(s)
// Start the server
if MCPConfig.SSE {
// SSE server
sse := server.NewSSEServer(s, server.WithBaseURL(MCPConfig.BaseUrl))
if err := sse.Start(MCPConfig.Address); err != nil {
fmt.Printf("Server error: %v\n", err)
}
} else {
// stdio server
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
}
```
--------------------------------------------------------------------------------
/app/client/mongo.go:
--------------------------------------------------------------------------------
```go
package client
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"mcp/app/configs"
)
var (
DB *mongo.Database
MongoClient *mongo.Client
)
// ConnectMongo connects to a MongoDB database using the provided configuration.
func ConnectMongo(config configs.MongoConfig) {
host := config.Host
port := config.Port
user := config.User
password := config.Password
database := config.Database
clientOptions := options.Client().ApplyURI(
fmt.Sprintf("mongodb://%s:%s@%s:%d", user, password, host, port),
)
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatalf("failed to connect to mongodb: %v", err)
}
// Check the connection
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatalf("failed to ping to mongodb: %v", err)
}
log.Println("Connected to MongoDB!")
// if the database does not exist, MongoDB create it
DB = client.Database(database)
MongoClient = client
}
```
--------------------------------------------------------------------------------
/app/tools/collection.go:
--------------------------------------------------------------------------------
```go
package tools
import (
"context"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"go.mongodb.org/mongo-driver/bson"
"mcp/app/client"
"strings"
)
type CollectionTool interface {
// ListCollections get collections in mongodb
ListCollections() (mcp.Tool, server.ToolHandlerFunc)
}
type collectionTool struct{}
func NewCollectionTool() CollectionTool {
return &collectionTool{}
}
// ListCollections List all collections in mongodb
func (c collectionTool) ListCollections() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"ListCollections",
mcp.WithDescription("List all collections in mongodb"),
)
// handler
// request is empty, this tool will return all collections in mongodb
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
collections, err := client.DB.ListCollectionNames(ctx, bson.D{})
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
if len(collections) == 0 {
return mcp.NewToolResultText("No collections found"), nil
}
result := mcp.NewToolResultText("Collections: " + strings.Join(collections, ", "))
return result, nil
}
return
}
```
--------------------------------------------------------------------------------
/app/mcp.go:
--------------------------------------------------------------------------------
```go
package app
import (
"github.com/mark3labs/mcp-go/server"
"mcp/app/tools"
)
func AddTools(s *server.MCPServer) {
// Add Collection tools to MCP server
collTool := tools.NewCollectionTool()
AddCollectionTools(s, collTool)
// Add Document tools to MCP server
docTool := tools.NewDocumentTool()
AddDocumentTools(s, docTool)
// Add Index tools to MCP server
indexTool := tools.NewIndexTool()
AddIndexTools(s, indexTool)
idGenerateTool := tools.NewIdGenerateTool()
AddIdGenerateTools(s, idGenerateTool)
}
// AddCollectionTools adds collection tools to the MCP server
func AddCollectionTools(s *server.MCPServer, collTool tools.CollectionTool) {
s.AddTool(collTool.ListCollections())
}
// AddDocumentTools adds collection tools to the MCP server
func AddDocumentTools(s *server.MCPServer, docTool tools.DocumentTool) {
s.AddTool(docTool.Find())
s.AddTool(docTool.Count())
s.AddTool(docTool.InsertOne())
s.AddTool(docTool.DeleteOne())
s.AddTool(docTool.UpdateOne())
}
// AddIndexTools adds collection tools to the MCP server
func AddIndexTools(s *server.MCPServer, indexTool tools.IndexTool) {
s.AddTool(indexTool.CreateIndex())
s.AddTool(indexTool.ListIndexes())
s.AddTool(indexTool.DropIndex())
}
func AddIdGenerateTools(s *server.MCPServer, idGenerateTool tools.IdGenerateTool) {
s.AddTool(idGenerateTool.Generate())
}
```
--------------------------------------------------------------------------------
/app/model/document.go:
--------------------------------------------------------------------------------
```go
package model
type FindDocumentRequest struct {
Collection string `mapstructure:"collection" json:"collection" bson:"collection"`
Filter map[string]interface{} `mapstructure:"filter" json:"filter" bson:"filter"`
Limit int64 `mapstructure:"limit" json:"limit" bson:"limit"`
Projection map[string]interface{} `mapstructure:"projection" json:"projection" bson:"projection"`
}
type CountDocumentRequest struct {
Collection string `mapstructure:"collection" json:"collection" bson:"collection"`
Filter map[string]interface{} `mapstructure:"filter" json:"filter" bson:"filter"`
Limit int64 `mapstructure:"limit" json:"limit" bson:"limit"`
}
type InsertDocumentRequest struct {
Collection string `mapstructure:"collection" json:"collection" bson:"collection"`
Document string `mapstructure:"document" json:"document" bson:"document"`
}
type DeleteDocumentRequest struct {
Collection string `mapstructure:"collection" json:"collection" bson:"collection"`
Filter map[string]interface{} `mapstructure:"filter" json:"filter" bson:"filter"`
}
type UpdateDocumentRequest struct {
Collection string `mapstructure:"collection" json:"collection"`
Filter map[string]interface{} `mapstructure:"filter" json:"filter" bson:"filter"`
Update map[string]interface{} `mapstructure:"update" json:"update" bson:"update"`
}
```
--------------------------------------------------------------------------------
/app/configs/config.go:
--------------------------------------------------------------------------------
```go
package configs
import (
"github.com/spf13/viper"
"log"
)
type MongoConfig struct {
Host string `mapstructure:"host" json:"host" yaml:"host"`
Port int `mapstructure:"port" json:"port" yaml:"port"`
User string `mapstructure:"user" json:"user" yaml:"user"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
Database string `mapstructure:"database" json:"database" yaml:"database"`
}
type MCPClient struct {
Name string `mapstructure:"name" json:"name" yaml:"name"`
Version string `mapstructure:"version" json:"version" yaml:"version"`
BaseUrl string `mapstructure:"base_url" json:"base_url" yaml:"base_url"`
Address string `mapstructure:"address" json:"address" yaml:"address"`
SSE bool `mapstructure:"sse" json:"sse" yaml:"sse"`
}
type Config struct {
Mongo MongoConfig `mapstructure:"mongo" json:"mongo" yaml:"mongo"`
MCP MCPClient `mapstructure:"mcp" json:"mcp" yaml:"mcp"`
}
func LoadConfig(path string, env string) Config {
var Cfg Config
viper.AddConfigPath(path)
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Read config error: %v", err)
}
if err := viper.Unmarshal(&Cfg); err != nil {
log.Fatalf("Unmarshal config error: %v", err)
}
if env != "" {
viper.SetConfigName("config." + env)
if err := viper.MergeInConfig(); err != nil {
log.Fatalf("Merge config error: %v", err)
}
if err := viper.Unmarshal(&Cfg); err != nil {
log.Fatalf("Unmarshal config error: %v", err)
}
}
log.Println("Config loaded successfully")
return Cfg
}
```
--------------------------------------------------------------------------------
/app/tools/idgen.go:
--------------------------------------------------------------------------------
```go
package tools
import (
"context"
"fmt"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"mcp/app/client"
)
type IdGenerateTool interface {
Generate() (mcp.Tool, server.ToolHandlerFunc)
}
type idGenerateTool struct {
EntityPrefixMap map[string]interface{}
}
func NewIdGenerateTool() IdGenerateTool {
return &idGenerateTool{
EntityPrefixMap: map[string]interface{}{
"task": "TSK",
"lesson": "LSN",
"course": "CRS",
"experiment": "EXP",
},
}
}
func (i idGenerateTool) Generate() (tool mcp.Tool, handler server.ToolHandlerFunc) {
var prefixNameSet []string
for key := range i.EntityPrefixMap {
prefixNameSet = append(prefixNameSet, key)
}
tool = mcp.NewTool(
"entity_id_generator",
mcp.WithDescription("generate id for different type entity"),
mcp.WithString("entity_type",
mcp.Required(),
mcp.Description(fmt.Sprintf("type of entity to generate id, it could be one of %s", prefixNameSet)),
),
)
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
entityType := request.Params.Arguments["entity_type"].(string)
log.Printf("Generate id for entity: %s", entityType)
var entityPrefix string
if value, ok := i.EntityPrefixMap[entityType]; ok {
entityPrefix = value.(string)
//return mcp.NewToolResultText(prefix.(string) + "-" + mcp.GenerateId()), nil
} else {
return mcp.NewToolResultText(fmt.Sprintf("entity type %s not found, please use one of %s", entityType, prefixNameSet)), nil
}
counterID, err := i.getNextSequence(ctx, entityPrefix)
if err != nil {
return mcp.NewToolResultText(fmt.Sprintf("failed to get next sequence: %v", err)), nil
}
return mcp.NewToolResultText(fmt.Sprintf("%s-%04d", entityPrefix, counterID)), nil
}
return
}
func (i idGenerateTool) getNextSequence(ctx context.Context, counterIDType string) (int, error) {
filter := bson.M{"id_type": counterIDType}
update := bson.M{"$inc": bson.M{"sequence": 1}}
opts := options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)
var result struct {
Sequence int `bson:"sequence"`
}
err := client.DB.Collection("counters").FindOneAndUpdate(ctx, filter, update, opts).Decode(&result)
if err != nil {
return 0, err
}
return result.Sequence, nil
}
```
--------------------------------------------------------------------------------
/app/tools/index.go:
--------------------------------------------------------------------------------
```go
package tools
import (
"context"
"fmt"
"github.com/go-viper/mapstructure/v2"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"mcp/app/client"
"mcp/app/model"
)
type IndexTool interface {
// ListIndexes get indexes in mongodb
ListIndexes() (mcp.Tool, server.ToolHandlerFunc)
// CreateIndex create index in mongodb
CreateIndex() (mcp.Tool, server.ToolHandlerFunc)
// DropIndex drop index in mongodb
DropIndex() (mcp.Tool, server.ToolHandlerFunc)
}
type indexTool struct{}
func NewIndexTool() IndexTool {
return &indexTool{}
}
// ListIndexes List all indexes in mongodb
func (c indexTool) ListIndexes() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"ListIndexes",
mcp.WithDescription("List all indexes in mongodb"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
collectionName := request.Params.Arguments["collection"].(string)
cur, err := client.DB.Collection(collectionName).Indexes().List(ctx)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
defer cur.Close(ctx)
var indexes []bson.M
if err = cur.All(ctx, &indexes); err != nil {
return mcp.NewToolResultText(err.Error()), err
}
var result string
for _, doc := range indexes {
result += fmt.Sprintf("%v\n", doc)
}
return mcp.NewToolResultText(result), nil
}
return
}
// CreateIndex create index in mongodb
func (c indexTool) CreateIndex() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"CreateIndex",
mcp.WithDescription("create index in mongodb"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name"),
),
mcp.WithObject("index_spec",
mcp.Required(),
mcp.Description("Index specification (e.g., { field: 1 } for ascending index)"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.CreateIndexRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
res, err := client.DB.Collection(req.Collection).Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: req.IndexSpec,
})
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
return mcp.NewToolResultText(fmt.Sprintf("Index created, Name: %v", res)), nil
}
return
}
// DropIndex drop index in mongodb
func (c indexTool) DropIndex() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"DropIndex",
mcp.WithDescription("drop index in mongodb"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name"),
),
mcp.WithObject("index_name",
mcp.Required(),
mcp.Description("Name of the index to drop"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.DropIndexRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
res, err := client.DB.Collection(req.Collection).Indexes().DropOne(ctx, req.IndexName)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
return mcp.NewToolResultText(fmt.Sprintf("Index dropped Successfully, result: %v", res)), nil
}
return
}
```
--------------------------------------------------------------------------------
/app/tools/document.go:
--------------------------------------------------------------------------------
```go
package tools
import (
"context"
"fmt"
"github.com/go-viper/mapstructure/v2"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"mcp/app/client"
"mcp/app/model"
)
type DocumentTool interface {
// Find get document in collection
Find() (mcp.Tool, server.ToolHandlerFunc)
// Count get documents count in collection
Count() (mcp.Tool, server.ToolHandlerFunc)
// InsertOne insert one document in collection
InsertOne() (mcp.Tool, server.ToolHandlerFunc)
// DeleteOne insert one document in collection
DeleteOne() (mcp.Tool, server.ToolHandlerFunc)
// UpdateOne insert one document in collection
UpdateOne() (mcp.Tool, server.ToolHandlerFunc)
}
type documentTool struct{}
func NewDocumentTool() DocumentTool {
return &documentTool{}
}
// Find get document in collection
func (c documentTool) Find() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"Find",
mcp.WithDescription("Query documents in a collection using MongoDB query syntax"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name to query"),
),
mcp.WithObject("filter",
mcp.Description("MongoDB query filter"),
mcp.DefaultString("{}"),
),
mcp.WithNumber("limit",
mcp.Description("Limit the number of documents to return"),
mcp.DefaultNumber(0),
mcp.Min(0),
mcp.Max(1000),
),
mcp.WithObject("projection",
mcp.Description("MongoDB projection filter"),
mcp.DefaultString("{}"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.FindDocumentRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText("Parse request failed"), err
}
log.Printf(fmt.Sprintf("Find document in collection: %s, filter: %s, limit: %d", req.Collection, req.Filter, req.Limit))
cur, err := client.DB.Collection(req.Collection).Find(ctx, req.Filter, &options.FindOptions{
Limit: &req.Limit,
Projection: req.Projection,
})
defer cur.Close(ctx)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
var documents []bson.M
if err = cur.All(ctx, &documents); err != nil {
return mcp.NewToolResultText(err.Error()), err
}
if len(documents) == 0 {
log.Println("No documents found")
return mcp.NewToolResultText("No documents found"), nil
}
var result string
for _, doc := range documents {
result += fmt.Sprintf("%v\n", doc)
}
log.Println(result)
return mcp.NewToolResultText(result), nil
}
return
}
// Count get documents count in collection
func (c documentTool) Count() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"Count",
mcp.WithDescription("Count documents in a collection using MongoDB query syntax"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name to query"),
),
mcp.WithObject("filter",
mcp.Description("MongoDB query filter"),
mcp.DefaultString("{}"),
),
mcp.WithObject("projection",
mcp.Description("MongoDB projection filter"),
mcp.DefaultString("{}"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.CountDocumentRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText("Parse request failed"), err
}
log.Printf(fmt.Sprintf("Count document in collection: %s, filter: %s", req.Collection, req.Filter))
count, err := client.DB.Collection(req.Collection).CountDocuments(ctx, req.Filter)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
log.Printf(fmt.Sprintf("Count documents success, count: %d", count))
return mcp.NewToolResultText(fmt.Sprintf("Count documents success, count: %d", count)), nil
}
return
}
// InsertOne insert one document in collection
func (c documentTool) InsertOne() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"InertOne",
mcp.WithDescription("Insert a single document into a collection"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name to insert"),
),
mcp.WithString("document",
mcp.Required(),
mcp.Description("document to insert"),
mcp.DefaultString("{}"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.InsertDocumentRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText("Parse request failed"), err
}
log.Printf(fmt.Sprintf("Insert document in collection: %s, document: %s", req.Collection, req.Document))
// Convert the document string to a BSON document
var document bson.M
err = bson.UnmarshalExtJSON([]byte(req.Document), true, &document)
if err != nil {
return mcp.NewToolResultText("Parse document failed"), err
}
res, err := client.DB.Collection(req.Collection).InsertOne(ctx, document)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
if res.InsertedID == nil {
return mcp.NewToolResultText("Insert document failed"), nil
}
return mcp.NewToolResultText(fmt.Sprintf("Insert document success, id: %v", res.InsertedID)), nil
}
return
}
// DeleteOne insert one document in collection
func (c documentTool) DeleteOne() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"DeleteOne",
mcp.WithDescription("Delete a single document into a collection"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name to delete"),
),
mcp.WithObject("filter",
mcp.Required(),
mcp.Description("Filter to identify document"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.DeleteDocumentRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText("Parse request failed"), err
}
log.Printf(fmt.Sprintf("Delete document in collection: %s, filter: %s", req.Collection, req.Filter))
res, err := client.DB.Collection(req.Collection).DeleteOne(ctx, req.Filter)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
if res.DeletedCount == 0 {
return mcp.NewToolResultText("No documents deleted"), nil
}
return mcp.NewToolResultText(fmt.Sprintf("Delete document success, deleted count: %d", res.DeletedCount)), nil
}
return
}
// UpdateOne insert one document in collection
func (c documentTool) UpdateOne() (tool mcp.Tool, handler server.ToolHandlerFunc) {
// MCP Tool
tool = mcp.NewTool(
"UpdateOne",
mcp.WithDescription("update a single document into a collection"),
mcp.WithString("collection",
mcp.Required(),
mcp.Description("Collection name to update"),
),
mcp.WithObject("filter",
mcp.Required(),
mcp.Description("Filter to identify document"),
),
mcp.WithObject("update",
mcp.Required(),
mcp.Description("Update operations to apply"),
),
)
// handler
handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
var req model.UpdateDocumentRequest
err := mapstructure.Decode(request.Params.Arguments, &req)
if err != nil {
return mcp.NewToolResultText("Parse request failed"), err
}
fmt.Println(req)
log.Printf(fmt.Sprintf("Update document in collection: %s, filter: %s", req.Collection, req.Filter))
res, err := client.DB.Collection(req.Collection).UpdateOne(ctx, req.Filter, req.Update)
if err != nil {
return mcp.NewToolResultText(err.Error()), err
}
if res.MatchedCount == 0 {
return mcp.NewToolResultText("No documents matched"), nil
}
if res.ModifiedCount == 0 {
return mcp.NewToolResultText("No documents updated"), nil
}
return mcp.NewToolResultText(
fmt.Sprintf("Update document success, matched count: %d, modified count: %d, upsertedId %d",
res.MatchedCount, res.ModifiedCount, res.UpsertedID,
),
), nil
}
return
}
```