| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- // Package server builds the MCP server and registers the WikiJS tools.
- package server
- import (
- "log/slog"
- "gogs.netdome.biz/paul/go-wikijs-mcp/internal/wikijs"
- "github.com/modelcontextprotocol/go-sdk/mcp"
- )
- const instructions = `This server exposes a WikiJS knowledge base.
- Use search_pages to find pages by full-text query, get_page_by_id or
- get_page_by_path to read a page, and get_all_pages to browse the wiki.
- Page results include absolute URLs that can be shared with the user.
- Assets are managed store-wide, not per page: list_asset_folders and
- list_assets browse the central asset store, and when the write tools are
- enabled upload_asset adds files and create_asset_folder adds folders.
- Reference uploaded assets from pages with the returned markdown snippet.`
- // Options configures the MCP server.
- type Options struct {
- // Version is reported to MCP clients.
- Version string
- // EnableEdit exposes the create_page and edit_page tools.
- EnableEdit bool
- // Logger receives MCP protocol logs. It must write to stderr when the
- // stdio transport is used.
- Logger *slog.Logger
- }
- // New creates an MCP server with all WikiJS tools registered.
- func New(client *wikijs.Client, opts Options) *mcp.Server {
- logger := opts.Logger
- if logger == nil {
- logger = slog.New(slog.DiscardHandler)
- }
- s := mcp.NewServer(&mcp.Implementation{
- Name: "wikijs-mcp-server",
- Title: "WikiJS MCP Server",
- Version: opts.Version,
- Description: "Search, read, and optionally edit pages in a WikiJS instance.",
- }, &mcp.ServerOptions{
- Instructions: instructions,
- Logger: logger,
- })
- h := &handlers{wiki: client}
- readOnly := &mcp.ToolAnnotations{ReadOnlyHint: true}
- mcp.AddTool(s, &mcp.Tool{
- Name: "search_pages",
- Title: "Search pages",
- Description: "Search for pages in WikiJS by query string.",
- Annotations: readOnly,
- }, h.searchPages)
- mcp.AddTool(s, &mcp.Tool{
- Name: "get_page_by_id",
- Title: "Get page by ID",
- Description: "Get a WikiJS page by its numeric ID.",
- Annotations: readOnly,
- }, h.pageByID)
- mcp.AddTool(s, &mcp.Tool{
- Name: "get_page_by_path",
- Title: "Get page by path",
- Description: "Get a WikiJS page by its path and locale.",
- Annotations: readOnly,
- }, h.pageByPath)
- mcp.AddTool(s, &mcp.Tool{
- Name: "get_all_pages",
- Title: "List pages",
- Description: "List pages in WikiJS, optionally filtered by limit, locale, and tags.",
- Annotations: readOnly,
- }, h.listPages)
- mcp.AddTool(s, &mcp.Tool{
- Name: "list_asset_folders",
- Title: "List asset folders",
- Description: "List the child folders of a WikiJS asset folder (root by default).",
- Annotations: readOnly,
- }, h.listAssetFolders)
- mcp.AddTool(s, &mcp.Tool{
- Name: "list_assets",
- Title: "List assets",
- Description: "List the files uploaded to a WikiJS asset folder (root by default), optionally filtered by kind.",
- Annotations: readOnly,
- }, h.listAssets)
- if opts.EnableEdit {
- notDestructive := false
- mcp.AddTool(s, &mcp.Tool{
- Name: "create_page",
- Title: "Create page",
- Description: "Create a new WikiJS page.",
- Annotations: &mcp.ToolAnnotations{DestructiveHint: ¬Destructive},
- }, h.createPage)
- // edit_page advertises IdempotentHint: editing the same page twice
- // with the same content converges to the same state, unlike
- // create_page and upload_asset, which would duplicate work.
- mcp.AddTool(s, &mcp.Tool{
- Name: "edit_page",
- Title: "Edit page",
- Description: "Edit an existing WikiJS page by its numeric ID.",
- Annotations: &mcp.ToolAnnotations{IdempotentHint: true},
- }, h.editPage)
- mcp.AddTool(s, &mcp.Tool{
- Name: "upload_asset",
- Title: "Upload asset",
- Description: "Upload a file to a WikiJS asset folder so it can be referenced from pages.",
- Annotations: &mcp.ToolAnnotations{DestructiveHint: ¬Destructive},
- }, h.uploadAsset)
- mcp.AddTool(s, &mcp.Tool{
- Name: "create_asset_folder",
- Title: "Create asset folder",
- Description: "Create a new WikiJS asset folder.",
- Annotations: &mcp.ToolAnnotations{DestructiveHint: ¬Destructive},
- }, h.createAssetFolder)
- }
- return s
- }
|