Update MCP to handle markdown for all document content tools + fix converter edge case for code fence closing

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-06 15:04:55 +04:00
parent 24a9459fb9
commit 6d2e9dbe19
5 changed files with 140 additions and 23 deletions

View File

@@ -2067,12 +2067,17 @@ func (r *Resolver) AddDocumentTool(ctx context.Context, req *mcp.CallToolRequest
trustCenterVisibility = input.TrustCenterVisibility
}
contentJSON, err := markdownToProseMirrorJSON(input.Content)
if err != nil {
panic(fmt.Errorf("cannot convert markdown to prosemirror: %w", err))
}
document, documentVersion, err := svc.Documents.Create(
ctx,
probo.CreateDocumentRequest{
OrganizationID: input.OrganizationID,
Title: input.Title,
Content: input.Content,
Content: contentJSON,
Classification: input.Classification,
DocumentType: input.DocumentType,
TrustCenterVisibility: trustCenterVisibility,
@@ -2082,7 +2087,12 @@ func (r *Resolver) AddDocumentTool(ctx context.Context, req *mcp.CallToolRequest
panic(fmt.Errorf("cannot create document: %w", err))
}
return nil, types.NewAddDocumentOutput(document, documentVersion), nil
out, err := types.NewAddDocumentOutput(document, documentVersion)
if err != nil {
panic(fmt.Errorf("cannot build add document output: %w", err))
}
return nil, out, nil
}
func (r *Resolver) UpdateDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDocumentInput) (*mcp.CallToolResult, types.UpdateDocumentOutput, error) {
@@ -2129,7 +2139,12 @@ func (r *Resolver) ListDocumentVersionsTool(ctx context.Context, req *mcp.CallTo
panic(fmt.Errorf("cannot list document versions: %w", err))
}
return nil, types.NewListDocumentVersionsOutput(versionPage), nil
out, err := types.NewListDocumentVersionsOutput(versionPage)
if err != nil {
panic(fmt.Errorf("cannot build list document versions output: %w", err))
}
return nil, out, nil
}
func (r *Resolver) GetDocumentVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentVersionInput) (*mcp.CallToolResult, types.GetDocumentVersionOutput, error) {
@@ -2142,8 +2157,13 @@ func (r *Resolver) GetDocumentVersionTool(ctx context.Context, req *mcp.CallTool
panic(fmt.Errorf("cannot get document version: %w", err))
}
dv, err := types.NewDocumentVersion(version)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.GetDocumentVersionOutput{
DocumentVersion: types.NewDocumentVersion(version),
DocumentVersion: dv,
}, nil
}
@@ -2175,8 +2195,13 @@ func (r *Resolver) CreateDraftDocumentVersionTool(ctx context.Context, req *mcp.
}
}
dv, err := types.NewDocumentVersion(draftVersion)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.CreateDraftDocumentVersionOutput{
DocumentVersion: types.NewDocumentVersion(draftVersion),
DocumentVersion: dv,
}, nil
}
@@ -2207,8 +2232,13 @@ func (r *Resolver) UpdateDocumentVersionTool(ctx context.Context, req *mcp.CallT
panic(fmt.Errorf("cannot update document version: %w", err))
}
dv, err := types.NewDocumentVersion(documentVersion)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.UpdateDocumentVersionOutput{
DocumentVersion: types.NewDocumentVersion(documentVersion),
DocumentVersion: dv,
}, nil
}
@@ -3835,8 +3865,13 @@ func (r *Resolver) RequestDocumentVersionApprovalTool(ctx context.Context, req *
panic(fmt.Errorf("cannot get document version: %w", err))
}
dv, err := types.NewDocumentVersion(documentVersion)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.RequestDocumentVersionApprovalOutput{
DocumentVersion: types.NewDocumentVersion(documentVersion),
DocumentVersion: dv,
}, nil
}
@@ -3856,9 +3891,14 @@ func (r *Resolver) PublishMajorDocumentVersionTool(ctx context.Context, req *mcp
panic(fmt.Errorf("cannot publish major document version: %w", err))
}
dv, err := types.NewDocumentVersion(documentVersion)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.PublishMajorDocumentVersionOutput{
Document: types.NewDocument(document),
DocumentVersion: types.NewDocumentVersion(documentVersion),
DocumentVersion: dv,
}, nil
}
@@ -3878,9 +3918,14 @@ func (r *Resolver) PublishMinorDocumentVersionTool(ctx context.Context, req *mcp
panic(fmt.Errorf("cannot publish minor document version: %w", err))
}
dv, err := types.NewDocumentVersion(documentVersion)
if err != nil {
panic(fmt.Errorf("cannot build document version: %w", err))
}
return nil, types.PublishMinorDocumentVersionOutput{
Document: types.NewDocument(document),
DocumentVersion: types.NewDocumentVersion(documentVersion),
DocumentVersion: dv,
}, nil
}

View File

@@ -5327,7 +5327,7 @@ components:
description: Document type
content:
type: string
description: Document content
description: Document body in markdown (converted from stored ProseMirror JSON)
changelog:
type: string
description: Changelog
@@ -5481,7 +5481,7 @@ components:
description: Document title
content:
type: string
description: Document content
description: Document content in markdown format
classification:
$ref: "#/components/schemas/DocumentClassification"
description: Document classification
@@ -5494,6 +5494,7 @@ components:
AddDocumentOutput:
type: object
description: Created document and version; document_version.content is markdown
required:
- document
- document_version
@@ -5580,6 +5581,7 @@ components:
ListDocumentVersionsOutput:
type: object
description: Each document_versions[].content is markdown
required:
- document_versions
properties:
@@ -5602,6 +5604,7 @@ components:
GetDocumentVersionOutput:
type: object
description: document_version.content is markdown
required:
- document_version
properties:
@@ -5622,6 +5625,7 @@ components:
CreateDraftDocumentVersionOutput:
type: object
description: Created draft; document_version.content is markdown
required:
- document_version
properties:
@@ -5648,6 +5652,7 @@ components:
UpdateDocumentVersionOutput:
type: object
description: Updated draft; document_version.content is markdown
required:
- document_version
properties:
@@ -5698,6 +5703,7 @@ components:
PublishDocumentVersionOutput:
type: object
description: document_version.content is markdown
required:
- document
- document_version
@@ -5727,6 +5733,7 @@ components:
RequestDocumentVersionApprovalOutput:
type: object
description: document_version.content is markdown
required:
- document_version
properties:

View File

@@ -15,10 +15,32 @@
package types
import (
"fmt"
"strings"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/page"
"go.probo.inc/probo/pkg/prosemirror"
)
func proseMirrorJSONToMarkdown(pmJSON string) (string, error) {
if strings.TrimSpace(pmJSON) == "" {
return "", nil
}
node, err := prosemirror.Parse(pmJSON)
if err != nil {
return "", fmt.Errorf("cannot parse prosemirror json: %w", err)
}
md, err := prosemirror.RenderMarkdown(node)
if err != nil {
return "", fmt.Errorf("cannot render markdown: %w", err)
}
return md, nil
}
func NewDocument(d *coredata.Document) *Document {
return &Document{
ID: d.ID,
@@ -88,14 +110,24 @@ func NewListDocumentsOutput(documentPage *page.Page[*coredata.Document, coredata
}
}
func NewAddDocumentOutput(doc *coredata.Document, docVersion *coredata.DocumentVersion) AddDocumentOutput {
func NewAddDocumentOutput(doc *coredata.Document, docVersion *coredata.DocumentVersion) (AddDocumentOutput, error) {
dv, err := NewDocumentVersion(docVersion)
if err != nil {
return AddDocumentOutput{}, err
}
return AddDocumentOutput{
Document: NewDocument(doc),
DocumentVersion: NewDocumentVersion(docVersion),
}
DocumentVersion: dv,
}, nil
}
func NewDocumentVersion(dv *coredata.DocumentVersion) *DocumentVersion {
func NewDocumentVersion(dv *coredata.DocumentVersion) (*DocumentVersion, error) {
contentMD, err := proseMirrorJSONToMarkdown(dv.Content)
if err != nil {
return nil, fmt.Errorf("cannot convert document version content to markdown: %w", err)
}
return &DocumentVersion{
ID: dv.ID,
OrganizationID: dv.OrganizationID,
@@ -105,19 +137,23 @@ func NewDocumentVersion(dv *coredata.DocumentVersion) *DocumentVersion {
Minor: dv.Minor,
Classification: dv.Classification,
DocumentType: dv.DocumentType,
Content: dv.Content,
Content: contentMD,
Changelog: dv.Changelog,
Status: dv.Status,
PublishedAt: dv.PublishedAt,
CreatedAt: dv.CreatedAt,
UpdatedAt: dv.UpdatedAt,
}
}, nil
}
func NewListDocumentVersionsOutput(versionPage *page.Page[*coredata.DocumentVersion, coredata.DocumentVersionOrderField]) ListDocumentVersionsOutput {
func NewListDocumentVersionsOutput(versionPage *page.Page[*coredata.DocumentVersion, coredata.DocumentVersionOrderField]) (ListDocumentVersionsOutput, error) {
versions := make([]*DocumentVersion, 0, len(versionPage.Data))
for _, v := range versionPage.Data {
versions = append(versions, NewDocumentVersion(v))
dv, err := NewDocumentVersion(v)
if err != nil {
return ListDocumentVersionsOutput{}, err
}
versions = append(versions, dv)
}
var nextCursor *page.CursorKey
@@ -129,7 +165,7 @@ func NewListDocumentVersionsOutput(versionPage *page.Page[*coredata.DocumentVers
return ListDocumentVersionsOutput{
NextCursor: nextCursor,
DocumentVersions: versions,
}
}, nil
}
func NewDocumentVersionSignature(dvs *coredata.DocumentVersionSignature) *DocumentVersionSignature {