Skip to content

Commit 22f6c35

Browse files
committed
feat: 新增MCP Server功能,支持文档全局检索工具
1 parent b85ae2d commit 22f6c35

File tree

9 files changed

+174
-6
lines changed

9 files changed

+174
-6
lines changed

commands/daemon/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package daemon
33
import (
44
"fmt"
55
"os"
6-
76
"path/filepath"
87

98
"github.com/beego/beego/v2/core/logs"
109
"github.com/beego/beego/v2/server/web"
1110
"github.com/kardianos/service"
11+
1212
"github.com/mindoc-org/mindoc/commands"
1313
"github.com/mindoc-org/mindoc/conf"
1414
"github.com/mindoc-org/mindoc/controllers"

conf/app.conf.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,7 @@ workweixin_secret="${MINDOC_WORKWEIXIN_SECRET}"
248248
# i18n config
249249
i18n_list=zh-cn:简体中文|en-us:English|ru-ru:Русский
250250
default_lang="zh-cn"
251+
252+
# MCP Server 功能
253+
enable_mcp_server="${MINDOC_ENABLE_MCP_SERVER||false}"
254+
mcp_api_key="${MINDOC_MCP_API_KEY||demo-mcp-api-key}"

go.mod

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/mindoc-org/mindoc
22

3-
go 1.18
3+
go 1.23
44

55
require (
66
github.com/PuerkitoBio/goquery v1.8.0
@@ -12,6 +12,7 @@ require (
1212
github.com/kardianos/service v1.2.1
1313
github.com/lib/pq v1.10.5
1414
github.com/lifei6671/gocaptcha v0.2.0
15+
github.com/mark3labs/mcp-go v0.38.0
1516
github.com/mattn/go-runewidth v0.0.13
1617
github.com/mattn/go-sqlite3 v1.14.17
1718
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
@@ -22,16 +23,21 @@ require (
2223
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
2324
github.com/Unknwon/goconfig v1.0.0 // indirect
2425
github.com/andybalholm/cascadia v1.3.1 // indirect
26+
github.com/bahlo/generic-list-go v0.2.0 // indirect
2527
github.com/beorn7/perks v1.0.1 // indirect
2628
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
29+
github.com/buger/jsonparser v1.1.1 // indirect
2730
github.com/cespare/xxhash/v2 v2.1.2 // indirect
2831
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
2932
github.com/go-redis/redis/v7 v7.4.1 // indirect
3033
github.com/go-sql-driver/mysql v1.6.0 // indirect
3134
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
3235
github.com/golang/protobuf v1.5.2 // indirect
3336
github.com/gomodule/redigo v2.0.0+incompatible // indirect
37+
github.com/google/uuid v1.6.0 // indirect
3438
github.com/hashicorp/golang-lru v0.5.4 // indirect
39+
github.com/invopop/jsonschema v0.13.0 // indirect
40+
github.com/mailru/easyjson v0.7.7 // indirect
3541
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
3642
github.com/mitchellh/mapstructure v1.5.0 // indirect
3743
github.com/pkg/errors v0.9.1 // indirect
@@ -42,6 +48,9 @@ require (
4248
github.com/rivo/uniseg v0.3.4 // indirect
4349
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
4450
github.com/smartystreets/goconvey v1.7.2 // indirect
51+
github.com/spf13/cast v1.7.1 // indirect
52+
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
53+
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
4554
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
4655
golang.org/x/image v0.5.0 // indirect
4756
golang.org/x/net v0.7.0 // indirect

go.sum

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
4646
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
4747
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
4848
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
49+
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
50+
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
4951
github.com/beego/beego/v2 v2.0.5 h1:fa2TBWfKGDs35Ck9an9SVnpS0zM8sRTXlW8rFjpeYlE=
5052
github.com/beego/beego/v2 v2.0.5/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
5153
github.com/beego/i18n v0.0.0-20161101132742-e9308947f407 h1:WtJfx5HqASTQp7HfiZldnin8KQV2futplF3duGp5PGc=
@@ -58,6 +60,8 @@ github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyX
5860
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
5961
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
6062
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
63+
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
64+
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
6165
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
6266
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
6367
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
@@ -71,10 +75,13 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
7175
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
7276
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7377
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
78+
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
7479
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
7580
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
7681
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
7782
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
83+
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
84+
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
7885
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
7986
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
8087
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
@@ -140,7 +147,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
140147
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
141148
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
142149
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
143-
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
150+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
151+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
144152
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
145153
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
146154
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -152,6 +160,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
152160
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
153161
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
154162
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
163+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
164+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
155165
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
156166
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
157167
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@@ -165,6 +175,9 @@ github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1O
165175
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
166176
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
167177
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
178+
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
179+
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
180+
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
168181
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
169182
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
170183
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -182,15 +195,21 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
182195
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
183196
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
184197
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
185-
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
186198
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
199+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
200+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
187201
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
188-
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
189202
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
203+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
204+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
190205
github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
191206
github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
192207
github.com/lifei6671/gocaptcha v0.2.0 h1:CwMjGitq5MsYtWODQhlphdl7WhDdD243y1O2d3l8yFU=
193208
github.com/lifei6671/gocaptcha v0.2.0/go.mod h1:mcUWn1eB+kHOBHLQdmWAQ83bhEGrFTnGMqRCY7sFgUc=
209+
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
210+
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
211+
github.com/mark3labs/mcp-go v0.38.0 h1:E5tmJiIXkhwlV0pLAwAT0O5ZjUZSISE/2Jxg+6vpq4I=
212+
github.com/mark3labs/mcp-go v0.38.0/go.mod h1:T7tUa2jO6MavG+3P25Oy/jR7iCeJPHImCZHRymCn39g=
194213
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
195214
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
196215
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
@@ -248,6 +267,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
248267
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
249268
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
250269
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
270+
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
271+
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
251272
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
252273
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
253274
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
@@ -259,13 +280,20 @@ github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N
259280
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
260281
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
261282
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
283+
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
284+
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
262285
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
263286
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
264287
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
265288
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
266289
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
267290
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
268-
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
291+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
292+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
293+
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
294+
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
295+
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
296+
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
269297
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
270298
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
271299
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

mcp/handler.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package mcp
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
"github.com/mark3labs/mcp-go/mcp"
8+
"github.com/mindoc-org/mindoc/conf"
9+
"github.com/mindoc-org/mindoc/models"
10+
"github.com/mindoc-org/mindoc/utils/sqltil"
11+
)
12+
13+
// GetGlobalSearchMcpTool 获取全局搜索的mcp工具
14+
func GetGlobalSearchMcpTool() mcp.Tool {
15+
return mcp.NewTool("MinDocGlobalSearch",
16+
mcp.WithDescription("MinDoc全局文档内容搜索"),
17+
mcp.WithString("keyword",
18+
mcp.Required(),
19+
mcp.Description("要执行全局搜索的关键词,多个搜索关键词请用空格分割,请使用最少的关键词来检索,结果中只会出现包含全部关键词的结果,过多的无关词会导致更少的检索结果"),
20+
),
21+
mcp.WithNumber("pageIndex",
22+
mcp.Required(),
23+
mcp.Description("全局搜索时指定分页的顺序下标,每页最多有10条结果,建议只查看1-10页文档内容的搜索结果"),
24+
mcp.Enum("1", "2", "3", "4", "5", "6", "7", "8", "9", "10"),
25+
),
26+
)
27+
}
28+
29+
// GlobalSearchMcpHandler 全局搜索的mcp处理函数
30+
func GlobalSearchMcpHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
31+
paramMap := request.Params.Arguments.(map[string]any)
32+
pageIndex, _ := paramMap["pageIndex"].(int)
33+
totalCount, result := globalSearchFunction(paramMap["keyword"].(string), pageIndex)
34+
jsonContent, err := json.Marshal(result)
35+
if err != nil {
36+
return mcp.NewToolResultStructuredOnly(map[string]any{
37+
"totalCount": 0,
38+
"result": make([]map[string]any, 0),
39+
}), err
40+
}
41+
42+
structContent := make([]map[string]any, 0)
43+
err = json.Unmarshal(jsonContent, &structContent)
44+
if err != nil {
45+
return mcp.NewToolResultStructuredOnly(map[string]any{
46+
"totalCount": 0,
47+
"result": make([]map[string]any, 0),
48+
}), err
49+
}
50+
51+
return mcp.NewToolResultStructuredOnly(map[string]any{
52+
"totalCount": totalCount,
53+
"result": structContent,
54+
}), nil
55+
}
56+
57+
func globalSearchFunction(keyword string, pageIndex int) (int, []*models.DocumentSearchResult) {
58+
memberId := 0
59+
searchResult, totalCount, err := models.NewDocumentSearchResult().FindToPager(sqltil.EscapeLike(keyword),
60+
pageIndex, conf.PageSize, memberId)
61+
if err != nil {
62+
return 0, make([]*models.DocumentSearchResult, 0)
63+
}
64+
return totalCount, searchResult
65+
}

mcp/mcp.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package mcp
2+
3+
import (
4+
"github.com/mark3labs/mcp-go/server"
5+
)
6+
7+
// MCPServer MinDoc MCP Server
8+
type MCPServer struct {
9+
server *server.MCPServer
10+
}
11+
12+
// NewMCPServer creates a new MinDoc MCP Server
13+
func NewMCPServer() *MCPServer {
14+
mcpServer := server.NewMCPServer(
15+
"MinDoc MCP Server",
16+
"1.0.0",
17+
server.WithRecovery(),
18+
)
19+
20+
mcpServer.AddTool(GetGlobalSearchMcpTool(), GlobalSearchMcpHandler)
21+
22+
return &MCPServer{
23+
server: mcpServer,
24+
}
25+
}
26+
27+
// ServeHTTP Run starts the server
28+
func (s *MCPServer) ServeHTTP() *server.StreamableHTTPServer {
29+
return server.NewStreamableHTTPServer(s.server)
30+
}

mcp/middleware.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package mcp
2+
3+
import (
4+
"context"
5+
"net/http"
6+
7+
"github.com/beego/beego/v2/server/web"
8+
beegoContext "github.com/beego/beego/v2/server/web/context"
9+
)
10+
11+
// AuthMiddleware 返回一个中间件函数,用于验证MCP请求中的认证令牌
12+
func AuthMiddleware(ctx *beegoContext.Context) {
13+
presetMcpApiKey := web.AppConfig.DefaultString("mcp_api_key", "")
14+
mcpApiKeyParamValue := ctx.Request.URL.Query().Get("api_key")
15+
if presetMcpApiKey != mcpApiKeyParamValue {
16+
http.Error(ctx.ResponseWriter, "Missing or invalid mcp authorization key", http.StatusUnauthorized)
17+
return
18+
}
19+
20+
// Add mcp_api_key to request context
21+
ctx.Request.WithContext(context.WithValue(ctx.Request.Context(), "mcp_api_key", mcpApiKeyParamValue))
22+
}

routers/filter.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77

88
"github.com/beego/beego/v2/server/web"
99
"github.com/beego/beego/v2/server/web/context"
10+
1011
"github.com/mindoc-org/mindoc/conf"
12+
"github.com/mindoc-org/mindoc/mcp"
1113
"github.com/mindoc-org/mindoc/models"
1214
)
1315

@@ -38,6 +40,7 @@ func init() {
3840
web.InsertFilter("/book/*", web.BeforeRouter, FilterUser)
3941
web.InsertFilter("/api/*", web.BeforeRouter, FilterUser)
4042
web.InsertFilter("/manage/*", web.BeforeRouter, FilterUser)
43+
web.InsertFilter("/mcp/*", web.BeforeRouter, mcp.AuthMiddleware)
4144

4245
var FinishRouter = func(ctx *context.Context) {
4346
ctx.ResponseWriter.Header().Add("MinDoc-Version", conf.VERSION)

routers/router.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
// "github.com/mindoc-org/mindoc/conf"
1616
"github.com/mindoc-org/mindoc/controllers"
17+
"github.com/mindoc-org/mindoc/mcp"
1718
)
1819

1920
type CorsTransport struct {
@@ -268,4 +269,10 @@ func init() {
268269
web.Router("/items", &controllers.ItemsetsController{}, "get:Index")
269270
web.Router("/items/:key", &controllers.ItemsetsController{}, "get:List")
270271

272+
if web.AppConfig.DefaultBool("enable_mcp_server", false) {
273+
mcpServer := mcp.NewMCPServer()
274+
web.Any("/mcp/*", func(ctx *context.Context) {
275+
mcpServer.ServeHTTP().ServeHTTP(ctx.ResponseWriter, ctx.Request)
276+
})
277+
}
271278
}

0 commit comments

Comments
 (0)