From d069201899f727dfb0e6f8811cd0ba6f70eee103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Wed, 1 Apr 2026 21:33:12 +0400 Subject: [PATCH] MCP takes markdown input for document version content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Émile Ré --- pkg/server/api/mcp/v1/resolver.go | 17 +++++++++++++ pkg/server/api/mcp/v1/schema.resolvers.go | 29 ++++++++++++++++++++++- pkg/server/api/mcp/v1/specification.yaml | 5 +++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/pkg/server/api/mcp/v1/resolver.go b/pkg/server/api/mcp/v1/resolver.go index 1c4ba2048..0e7552ddf 100644 --- a/pkg/server/api/mcp/v1/resolver.go +++ b/pkg/server/api/mcp/v1/resolver.go @@ -18,11 +18,14 @@ package mcp_v1 import ( "context" + "encoding/json" + "fmt" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/probo" + "go.probo.inc/probo/pkg/prosemirror" "go.probo.inc/probo/pkg/server/api/authn" ) @@ -32,6 +35,20 @@ type Resolver struct { logger *log.Logger } +func markdownToProseMirrorJSON(markdown string) (string, error) { + node, err := prosemirror.ParseMarkdown(markdown) + if err != nil { + return "", fmt.Errorf("cannot parse markdown: %w", err) + } + + out, err := json.Marshal(node) + if err != nil { + return "", fmt.Errorf("cannot marshal prosemirror node: %w", err) + } + + return string(out), nil +} + func (r *Resolver) MustAuthorize(ctx context.Context, entityID gid.GID, action iam.Action) { identity := authn.IdentityFromContext(ctx) diff --git a/pkg/server/api/mcp/v1/schema.resolvers.go b/pkg/server/api/mcp/v1/schema.resolvers.go index 2e0253989..d6c8ffa1d 100644 --- a/pkg/server/api/mcp/v1/schema.resolvers.go +++ b/pkg/server/api/mcp/v1/schema.resolvers.go @@ -2170,6 +2170,24 @@ func (r *Resolver) CreateDraftDocumentVersionTool(ctx context.Context, req *mcp. panic(fmt.Errorf("cannot create draft document version: %w", err)) } + if input.Content != nil { + content, err := markdownToProseMirrorJSON(*input.Content) + if err != nil { + panic(fmt.Errorf("cannot convert markdown to prosemirror: %w", err)) + } + + draftVersion, err = svc.Documents.UpdateVersion( + ctx, + probo.UpdateDocumentVersionRequest{ + ID: draftVersion.ID, + Content: &content, + }, + ) + if err != nil { + panic(fmt.Errorf("cannot update draft document version content: %w", err)) + } + } + return nil, types.CreateDraftDocumentVersionOutput{ DocumentVersion: types.NewDocumentVersion(draftVersion), }, nil @@ -2180,11 +2198,20 @@ func (r *Resolver) UpdateDocumentVersionTool(ctx context.Context, req *mcp.CallT svc := r.ProboService(ctx, input.DocumentVersionID) + var content *string + if input.Content != nil { + c, err := markdownToProseMirrorJSON(*input.Content) + if err != nil { + panic(fmt.Errorf("cannot convert markdown to prosemirror: %w", err)) + } + content = &c + } + documentVersion, err := svc.Documents.UpdateVersion( ctx, probo.UpdateDocumentVersionRequest{ ID: input.DocumentVersionID, - Content: input.Content, + Content: content, Classification: input.Classification, }, ) diff --git a/pkg/server/api/mcp/v1/specification.yaml b/pkg/server/api/mcp/v1/specification.yaml index 93557d4ff..8fe07d97c 100644 --- a/pkg/server/api/mcp/v1/specification.yaml +++ b/pkg/server/api/mcp/v1/specification.yaml @@ -5565,6 +5565,9 @@ components: document_id: $ref: "#/components/schemas/GID" description: Document ID + content: + type: string + description: Document content in markdown format CreateDraftDocumentVersionOutput: type: object @@ -5584,7 +5587,7 @@ components: description: Document version ID content: type: string - description: Document content + description: Document content in markdown format classification: $ref: "#/components/schemas/DocumentClassification" description: Document classification