Add mcp control links

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-02-26 16:44:10 +01:00
parent 35914fc1c3
commit f7f65567a2
9 changed files with 590 additions and 306 deletions

View File

@@ -1578,108 +1578,215 @@ func (r *Resolver) UpdateControlTool(ctx context.Context, req *mcp.CallToolReque
}, nil
}
func (r *Resolver) LinkControlMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlMeasureInput) (*mcp.CallToolResult, types.LinkControlMeasureOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate)
func (r *Resolver) LinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlInput) (*mcp.CallToolResult, types.LinkControlOutput, error) {
svc := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.CreateMeasureMapping(ctx, input.ControlID, input.MeasureID)
if err != nil {
return nil, types.LinkControlMeasureOutput{}, fmt.Errorf("failed to link control measure: %w", err)
switch input.ResourceID.EntityType() {
case coredata.MeasureEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate)
if _, _, err := svc.Controls.CreateMeasureMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to measure: %w", err)
}
case coredata.DocumentEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate)
if _, _, err := svc.Controls.CreateDocumentMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to document: %w", err)
}
case coredata.AuditEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate)
if _, _, err := svc.Controls.CreateAuditMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to audit: %w", err)
}
case coredata.SnapshotEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingCreate)
if _, _, err := svc.Controls.CreateSnapshotMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to snapshot: %w", err)
}
case coredata.ObligationEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlObligationMappingCreate)
if _, _, err := svc.Controls.CreateObligationMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to obligation: %w", err)
}
default:
return nil, types.LinkControlOutput{}, fmt.Errorf("unsupported resource type for control linking: entity type %d", input.ResourceID.EntityType())
}
return nil, types.LinkControlMeasureOutput{}, nil
return nil, types.LinkControlOutput{}, nil
}
func (r *Resolver) UnlinkControlMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlMeasureInput) (*mcp.CallToolResult, types.UnlinkControlMeasureOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete)
func (r *Resolver) UnlinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlInput) (*mcp.CallToolResult, types.UnlinkControlOutput, error) {
svc := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.DeleteMeasureMapping(ctx, input.ControlID, input.MeasureID)
if err != nil {
return nil, types.UnlinkControlMeasureOutput{}, fmt.Errorf("failed to unlink control measure: %w", err)
switch input.ResourceID.EntityType() {
case coredata.MeasureEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete)
if _, _, err := svc.Controls.DeleteMeasureMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from measure: %w", err)
}
case coredata.DocumentEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete)
if _, _, err := svc.Controls.DeleteDocumentMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from document: %w", err)
}
case coredata.AuditEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete)
if _, _, err := svc.Controls.DeleteAuditMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from audit: %w", err)
}
case coredata.SnapshotEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingDelete)
if _, _, err := svc.Controls.DeleteSnapshotMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from snapshot: %w", err)
}
case coredata.ObligationEntityType:
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlObligationMappingDelete)
if _, _, err := svc.Controls.DeleteObligationMapping(ctx, input.ControlID, input.ResourceID); err != nil {
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from obligation: %w", err)
}
default:
return nil, types.UnlinkControlOutput{}, fmt.Errorf("unsupported resource type for control unlinking: entity type %d", input.ResourceID.EntityType())
}
return nil, types.UnlinkControlMeasureOutput{}, nil
return nil, types.UnlinkControlOutput{}, nil
}
func (r *Resolver) LinkControlDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlDocumentInput) (*mcp.CallToolResult, types.LinkControlDocumentOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate)
func (r *Resolver) ListControlObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlObligationsInput) (*mcp.CallToolResult, types.ListControlObligationsOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlGet)
svc := r.ProboService(ctx, input.ControlID)
prb := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID)
if err != nil {
return nil, types.LinkControlDocumentOutput{}, fmt.Errorf("failed to link control document: %w", err)
pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{
Field: coredata.ObligationOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if input.OrderBy != nil {
pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{
Field: input.OrderBy.Field,
Direction: input.OrderBy.Direction,
}
}
return nil, types.LinkControlDocumentOutput{}, nil
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
obligationPage, err := prb.Obligations.ListForControlID(ctx, input.ControlID, cursor, coredata.NewObligationFilter(nil))
if err != nil {
return nil, types.ListControlObligationsOutput{}, fmt.Errorf("failed to list control obligations: %w", err)
}
return nil, types.NewListControlObligationsOutput(obligationPage), nil
}
func (r *Resolver) UnlinkControlDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlDocumentInput) (*mcp.CallToolResult, types.UnlinkControlDocumentOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete)
func (r *Resolver) ListControlMeasuresTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlMeasuresInput) (*mcp.CallToolResult, types.ListControlMeasuresOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlGet)
svc := r.ProboService(ctx, input.ControlID)
prb := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.DeleteDocumentMapping(ctx, input.ControlID, input.DocumentID)
if err != nil {
return nil, types.UnlinkControlDocumentOutput{}, fmt.Errorf("failed to unlink control document: %w", err)
pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{
Field: coredata.MeasureOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if input.OrderBy != nil {
pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{
Field: input.OrderBy.Field,
Direction: input.OrderBy.Direction,
}
}
return nil, types.UnlinkControlDocumentOutput{}, nil
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
measurePage, err := prb.Measures.ListForControlID(ctx, input.ControlID, cursor, coredata.NewMeasureFilter(nil, nil))
if err != nil {
return nil, types.ListControlMeasuresOutput{}, fmt.Errorf("failed to list control measures: %w", err)
}
return nil, types.NewListControlMeasuresOutput(measurePage), nil
}
func (r *Resolver) LinkControlAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlAuditInput) (*mcp.CallToolResult, types.LinkControlAuditOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate)
func (r *Resolver) ListControlDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlDocumentsInput) (*mcp.CallToolResult, types.ListControlDocumentsOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlGet)
svc := r.ProboService(ctx, input.ControlID)
prb := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.CreateAuditMapping(ctx, input.ControlID, input.AuditID)
if err != nil {
return nil, types.LinkControlAuditOutput{}, fmt.Errorf("failed to link control audit: %w", err)
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
Field: coredata.DocumentOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if input.OrderBy != nil {
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
Field: input.OrderBy.Field,
Direction: input.OrderBy.Direction,
}
}
return nil, types.LinkControlAuditOutput{}, nil
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
docPage, err := prb.Documents.ListForControlID(ctx, input.ControlID, cursor, coredata.NewDocumentFilter(nil))
if err != nil {
return nil, types.ListControlDocumentsOutput{}, fmt.Errorf("failed to list control documents: %w", err)
}
approverIDsMap := make(map[gid.GID][]gid.GID)
for _, d := range docPage.Data {
approverPage, err := prb.Documents.ListApprovers(ctx, d.ID, allApproversCursor())
if err != nil {
return nil, types.ListControlDocumentsOutput{}, fmt.Errorf("failed to list document approvers: %w", err)
}
approverIDsMap[d.ID] = profileIDs(approverPage)
}
return nil, types.NewListControlDocumentsOutput(docPage, approverIDsMap), nil
}
func (r *Resolver) UnlinkControlAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlAuditInput) (*mcp.CallToolResult, types.UnlinkControlAuditOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete)
func (r *Resolver) ListControlAuditsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlAuditsInput) (*mcp.CallToolResult, types.ListControlAuditsOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlGet)
svc := r.ProboService(ctx, input.ControlID)
prb := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.DeleteAuditMapping(ctx, input.ControlID, input.AuditID)
if err != nil {
return nil, types.UnlinkControlAuditOutput{}, fmt.Errorf("failed to unlink control audit: %w", err)
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
Field: coredata.AuditOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if input.OrderBy != nil {
pageOrderBy = page.OrderBy[coredata.AuditOrderField]{
Field: input.OrderBy.Field,
Direction: input.OrderBy.Direction,
}
}
return nil, types.UnlinkControlAuditOutput{}, nil
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
auditPage, err := prb.Audits.ListForControlID(ctx, input.ControlID, cursor)
if err != nil {
return nil, types.ListControlAuditsOutput{}, fmt.Errorf("failed to list control audits: %w", err)
}
return nil, types.NewListControlAuditsOutput(auditPage), nil
}
func (r *Resolver) LinkControlSnapshotTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlSnapshotInput) (*mcp.CallToolResult, types.LinkControlSnapshotOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingCreate)
func (r *Resolver) ListControlSnapshotsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlSnapshotsInput) (*mcp.CallToolResult, types.ListControlSnapshotsOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlGet)
svc := r.ProboService(ctx, input.ControlID)
prb := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.CreateSnapshotMapping(ctx, input.ControlID, input.SnapshotID)
if err != nil {
return nil, types.LinkControlSnapshotOutput{}, fmt.Errorf("failed to link control snapshot: %w", err)
pageOrderBy := page.OrderBy[coredata.SnapshotOrderField]{
Field: coredata.SnapshotOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if input.OrderBy != nil {
pageOrderBy = page.OrderBy[coredata.SnapshotOrderField]{
Field: input.OrderBy.Field,
Direction: input.OrderBy.Direction,
}
}
return nil, types.LinkControlSnapshotOutput{}, nil
}
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
func (r *Resolver) UnlinkControlSnapshotTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlSnapshotInput) (*mcp.CallToolResult, types.UnlinkControlSnapshotOutput, error) {
r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingDelete)
svc := r.ProboService(ctx, input.ControlID)
_, _, err := svc.Controls.DeleteSnapshotMapping(ctx, input.ControlID, input.SnapshotID)
snapshotPage, err := prb.Snapshots.ListForControlID(ctx, input.ControlID, cursor)
if err != nil {
return nil, types.UnlinkControlSnapshotOutput{}, fmt.Errorf("failed to unlink control snapshot: %w", err)
return nil, types.ListControlSnapshotsOutput{}, fmt.Errorf("failed to list control snapshots: %w", err)
}
return nil, types.UnlinkControlSnapshotOutput{}, nil
return nil, types.NewListControlSnapshotsOutput(snapshotPage), nil
}
func (r *Resolver) ListRiskObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskObligationsInput) (*mcp.CallToolResult, types.ListRiskObligationsOutput, error) {

View File

@@ -4,6 +4,7 @@ package server
import (
"context"
"github.com/modelcontextprotocol/go-sdk/mcp"
"go.probo.inc/probo/pkg/server/api/mcp/v1/types"
)
@@ -86,14 +87,13 @@ type ResolverInterface interface {
GetControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetControlInput) (*mcp.CallToolResult, types.GetControlOutput, error)
AddControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddControlInput) (*mcp.CallToolResult, types.AddControlOutput, error)
UpdateControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateControlInput) (*mcp.CallToolResult, types.UpdateControlOutput, error)
LinkControlMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlMeasureInput) (*mcp.CallToolResult, types.LinkControlMeasureOutput, error)
UnlinkControlMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlMeasureInput) (*mcp.CallToolResult, types.UnlinkControlMeasureOutput, error)
LinkControlDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlDocumentInput) (*mcp.CallToolResult, types.LinkControlDocumentOutput, error)
UnlinkControlDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlDocumentInput) (*mcp.CallToolResult, types.UnlinkControlDocumentOutput, error)
LinkControlAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlAuditInput) (*mcp.CallToolResult, types.LinkControlAuditOutput, error)
UnlinkControlAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlAuditInput) (*mcp.CallToolResult, types.UnlinkControlAuditOutput, error)
LinkControlSnapshotTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlSnapshotInput) (*mcp.CallToolResult, types.LinkControlSnapshotOutput, error)
UnlinkControlSnapshotTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlSnapshotInput) (*mcp.CallToolResult, types.UnlinkControlSnapshotOutput, error)
LinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlInput) (*mcp.CallToolResult, types.LinkControlOutput, error)
UnlinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlInput) (*mcp.CallToolResult, types.UnlinkControlOutput, error)
ListControlObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlObligationsInput) (*mcp.CallToolResult, types.ListControlObligationsOutput, error)
ListControlMeasuresTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlMeasuresInput) (*mcp.CallToolResult, types.ListControlMeasuresOutput, error)
ListControlDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlDocumentsInput) (*mcp.CallToolResult, types.ListControlDocumentsOutput, error)
ListControlAuditsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlAuditsInput) (*mcp.CallToolResult, types.ListControlAuditsOutput, error)
ListControlSnapshotsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlSnapshotsInput) (*mcp.CallToolResult, types.ListControlSnapshotsOutput, error)
ListRiskObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskObligationsInput) (*mcp.CallToolResult, types.ListRiskObligationsOutput, error)
LinkRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkRiskInput) (*mcp.CallToolResult, types.LinkRiskOutput, error)
UnlinkRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkRiskInput) (*mcp.CallToolResult, types.UnlinkRiskOutput, error)
@@ -1067,82 +1067,92 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) {
mcp.AddTool(
server,
&mcp.Tool{
Name: "linkControlMeasure",
Description: "Link a measure to a control",
InputSchema: types.LinkControlMeasureToolInputSchema,
OutputSchema: types.LinkControlMeasureToolOutputSchema,
Name: "linkControl",
Description: "Link a resource to a control (measure, document, audit, snapshot, or obligation). The resource type is determined from the resource_id GID.",
InputSchema: types.LinkControlToolInputSchema,
OutputSchema: types.LinkControlToolOutputSchema,
},
resolver.LinkControlMeasureTool,
resolver.LinkControlTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "unlinkControlMeasure",
Description: "Unlink a measure from a control",
InputSchema: types.UnlinkControlMeasureToolInputSchema,
OutputSchema: types.UnlinkControlMeasureToolOutputSchema,
Name: "unlinkControl",
Description: "Unlink a resource from a control (measure, document, audit, snapshot, or obligation). The resource type is determined from the resource_id GID.",
InputSchema: types.UnlinkControlToolInputSchema,
OutputSchema: types.UnlinkControlToolOutputSchema,
},
resolver.UnlinkControlMeasureTool,
resolver.UnlinkControlTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "linkControlDocument",
Description: "Link a document to a control",
InputSchema: types.LinkControlDocumentToolInputSchema,
OutputSchema: types.LinkControlDocumentToolOutputSchema,
Name: "listControlObligations",
Description: "List obligations linked to a control",
InputSchema: types.ListControlObligationsToolInputSchema,
OutputSchema: types.ListControlObligationsToolOutputSchema,
Annotations: &mcp.ToolAnnotations{
ReadOnlyHint: true,
IdempotentHint: true,
},
},
resolver.LinkControlDocumentTool,
resolver.ListControlObligationsTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "unlinkControlDocument",
Description: "Unlink a document from a control",
InputSchema: types.UnlinkControlDocumentToolInputSchema,
OutputSchema: types.UnlinkControlDocumentToolOutputSchema,
Name: "listControlMeasures",
Description: "List measures linked to a control",
InputSchema: types.ListControlMeasuresToolInputSchema,
OutputSchema: types.ListControlMeasuresToolOutputSchema,
Annotations: &mcp.ToolAnnotations{
ReadOnlyHint: true,
IdempotentHint: true,
},
},
resolver.UnlinkControlDocumentTool,
resolver.ListControlMeasuresTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "linkControlAudit",
Description: "Link an audit to a control",
InputSchema: types.LinkControlAuditToolInputSchema,
OutputSchema: types.LinkControlAuditToolOutputSchema,
Name: "listControlDocuments",
Description: "List documents linked to a control",
InputSchema: types.ListControlDocumentsToolInputSchema,
OutputSchema: types.ListControlDocumentsToolOutputSchema,
Annotations: &mcp.ToolAnnotations{
ReadOnlyHint: true,
IdempotentHint: true,
},
},
resolver.LinkControlAuditTool,
resolver.ListControlDocumentsTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "unlinkControlAudit",
Description: "Unlink an audit from a control",
InputSchema: types.UnlinkControlAuditToolInputSchema,
OutputSchema: types.UnlinkControlAuditToolOutputSchema,
Name: "listControlAudits",
Description: "List audits linked to a control",
InputSchema: types.ListControlAuditsToolInputSchema,
OutputSchema: types.ListControlAuditsToolOutputSchema,
Annotations: &mcp.ToolAnnotations{
ReadOnlyHint: true,
IdempotentHint: true,
},
},
resolver.UnlinkControlAuditTool,
resolver.ListControlAuditsTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "linkControlSnapshot",
Description: "Link a snapshot to a control",
InputSchema: types.LinkControlSnapshotToolInputSchema,
OutputSchema: types.LinkControlSnapshotToolOutputSchema,
Name: "listControlSnapshots",
Description: "List snapshots linked to a control",
InputSchema: types.ListControlSnapshotsToolInputSchema,
OutputSchema: types.ListControlSnapshotsToolOutputSchema,
Annotations: &mcp.ToolAnnotations{
ReadOnlyHint: true,
IdempotentHint: true,
},
},
resolver.LinkControlSnapshotTool,
)
mcp.AddTool(
server,
&mcp.Tool{
Name: "unlinkControlSnapshot",
Description: "Unlink a snapshot from a control",
InputSchema: types.UnlinkControlSnapshotToolInputSchema,
OutputSchema: types.UnlinkControlSnapshotToolOutputSchema,
},
resolver.UnlinkControlSnapshotTool,
resolver.ListControlSnapshotsTool,
)
mcp.AddTool(
server,

View File

@@ -4317,133 +4317,192 @@ components:
control:
$ref: "#/components/schemas/Control"
LinkControlMeasureInput:
LinkControlInput:
type: object
required:
- control_id
- measure_id
- resource_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
measure_id:
resource_id:
$ref: "#/components/schemas/GID"
description: Measure ID
description: ID of the resource to link (measure, document, audit, snapshot, or obligation)
LinkControlMeasureOutput:
LinkControlOutput:
type: object
UnlinkControlMeasureInput:
UnlinkControlInput:
type: object
required:
- control_id
- measure_id
- resource_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
measure_id:
resource_id:
$ref: "#/components/schemas/GID"
description: Measure ID
description: ID of the resource to unlink (measure, document, audit, snapshot, or obligation)
UnlinkControlMeasureOutput:
UnlinkControlOutput:
type: object
LinkControlDocumentInput:
ListControlObligationsInput:
type: object
required:
- control_id
- document_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
document_id:
$ref: "#/components/schemas/GID"
description: Document ID
cursor:
$ref: "#/components/schemas/CursorKey"
description: Page cursor
size:
type: integer
description: Page size
order_by:
$ref: "#/components/schemas/ObligationOrderBy"
description: Obligation order by
LinkControlDocumentOutput:
ListControlObligationsOutput:
type: object
required:
- obligations
properties:
next_cursor:
$ref: "#/components/schemas/CursorKey"
description: Next cursor
obligations:
type: array
items:
$ref: "#/components/schemas/Obligation"
UnlinkControlDocumentInput:
ListControlMeasuresInput:
type: object
required:
- control_id
- document_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
document_id:
$ref: "#/components/schemas/GID"
description: Document ID
cursor:
$ref: "#/components/schemas/CursorKey"
description: Page cursor
size:
type: integer
description: Page size
order_by:
$ref: "#/components/schemas/MeasureOrderBy"
description: Measure order by
UnlinkControlDocumentOutput:
ListControlMeasuresOutput:
type: object
required:
- measures
properties:
next_cursor:
$ref: "#/components/schemas/CursorKey"
description: Next cursor
measures:
type: array
items:
$ref: "#/components/schemas/Measure"
LinkControlAuditInput:
ListControlDocumentsInput:
type: object
required:
- control_id
- audit_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
audit_id:
$ref: "#/components/schemas/GID"
description: Audit ID
cursor:
$ref: "#/components/schemas/CursorKey"
description: Page cursor
size:
type: integer
description: Page size
order_by:
$ref: "#/components/schemas/DocumentOrderBy"
description: Document order by
LinkControlAuditOutput:
ListControlDocumentsOutput:
type: object
required:
- documents
properties:
next_cursor:
$ref: "#/components/schemas/CursorKey"
description: Next cursor
documents:
type: array
items:
$ref: "#/components/schemas/Document"
UnlinkControlAuditInput:
ListControlAuditsInput:
type: object
required:
- control_id
- audit_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
audit_id:
$ref: "#/components/schemas/GID"
description: Audit ID
cursor:
$ref: "#/components/schemas/CursorKey"
description: Page cursor
size:
type: integer
description: Page size
order_by:
$ref: "#/components/schemas/AuditOrderBy"
description: Audit order by
UnlinkControlAuditOutput:
ListControlAuditsOutput:
type: object
required:
- audits
properties:
next_cursor:
$ref: "#/components/schemas/CursorKey"
description: Next cursor
audits:
type: array
items:
$ref: "#/components/schemas/Audit"
LinkControlSnapshotInput:
ListControlSnapshotsInput:
type: object
required:
- control_id
- snapshot_id
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
snapshot_id:
$ref: "#/components/schemas/GID"
description: Snapshot ID
cursor:
$ref: "#/components/schemas/CursorKey"
description: Page cursor
size:
type: integer
description: Page size
order_by:
$ref: "#/components/schemas/SnapshotOrderBy"
description: Snapshot order by
LinkControlSnapshotOutput:
type: object
UnlinkControlSnapshotInput:
ListControlSnapshotsOutput:
type: object
required:
- control_id
- snapshot_id
- snapshots
properties:
control_id:
$ref: "#/components/schemas/GID"
description: Control ID
snapshot_id:
$ref: "#/components/schemas/GID"
description: Snapshot ID
UnlinkControlSnapshotOutput:
type: object
next_cursor:
$ref: "#/components/schemas/CursorKey"
description: Next cursor
snapshots:
type: array
items:
$ref: "#/components/schemas/Snapshot"
ListRiskObligationsInput:
type: object
@@ -6839,70 +6898,67 @@ tools:
$ref: "#/components/schemas/UpdateControlInput"
outputSchema:
$ref: "#/components/schemas/UpdateControlOutput"
- name: linkControlMeasure
description: Link a measure to a control
- name: linkControl
description: Link a resource to a control (measure, document, audit, snapshot, or obligation). The resource type is determined from the resource_id GID.
hints:
readonly: false
inputSchema:
$ref: "#/components/schemas/LinkControlMeasureInput"
$ref: "#/components/schemas/LinkControlInput"
outputSchema:
$ref: "#/components/schemas/LinkControlMeasureOutput"
- name: unlinkControlMeasure
description: Unlink a measure from a control
$ref: "#/components/schemas/LinkControlOutput"
- name: unlinkControl
description: Unlink a resource from a control (measure, document, audit, snapshot, or obligation). The resource type is determined from the resource_id GID.
hints:
readonly: false
inputSchema:
$ref: "#/components/schemas/UnlinkControlMeasureInput"
$ref: "#/components/schemas/UnlinkControlInput"
outputSchema:
$ref: "#/components/schemas/UnlinkControlMeasureOutput"
- name: linkControlDocument
description: Link a document to a control
$ref: "#/components/schemas/UnlinkControlOutput"
- name: listControlObligations
description: List obligations linked to a control
hints:
readonly: false
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/LinkControlDocumentInput"
$ref: "#/components/schemas/ListControlObligationsInput"
outputSchema:
$ref: "#/components/schemas/LinkControlDocumentOutput"
- name: unlinkControlDocument
description: Unlink a document from a control
$ref: "#/components/schemas/ListControlObligationsOutput"
- name: listControlMeasures
description: List measures linked to a control
hints:
readonly: false
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/UnlinkControlDocumentInput"
$ref: "#/components/schemas/ListControlMeasuresInput"
outputSchema:
$ref: "#/components/schemas/UnlinkControlDocumentOutput"
- name: linkControlAudit
description: Link an audit to a control
$ref: "#/components/schemas/ListControlMeasuresOutput"
- name: listControlDocuments
description: List documents linked to a control
hints:
readonly: false
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/LinkControlAuditInput"
$ref: "#/components/schemas/ListControlDocumentsInput"
outputSchema:
$ref: "#/components/schemas/LinkControlAuditOutput"
- name: unlinkControlAudit
description: Unlink an audit from a control
$ref: "#/components/schemas/ListControlDocumentsOutput"
- name: listControlAudits
description: List audits linked to a control
hints:
readonly: false
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/UnlinkControlAuditInput"
$ref: "#/components/schemas/ListControlAuditsInput"
outputSchema:
$ref: "#/components/schemas/UnlinkControlAuditOutput"
- name: linkControlSnapshot
description: Link a snapshot to a control
$ref: "#/components/schemas/ListControlAuditsOutput"
- name: listControlSnapshots
description: List snapshots linked to a control
hints:
readonly: false
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/LinkControlSnapshotInput"
$ref: "#/components/schemas/ListControlSnapshotsInput"
outputSchema:
$ref: "#/components/schemas/LinkControlSnapshotOutput"
- name: unlinkControlSnapshot
description: Unlink a snapshot from a control
hints:
readonly: false
inputSchema:
$ref: "#/components/schemas/UnlinkControlSnapshotInput"
outputSchema:
$ref: "#/components/schemas/UnlinkControlSnapshotOutput"
$ref: "#/components/schemas/ListControlSnapshotsOutput"
- name: listRiskObligations
description: List obligations linked to a risk
hints:

View File

@@ -34,6 +34,24 @@ func NewAudit(a *coredata.Audit) *Audit {
}
}
func NewListControlAuditsOutput(auditPage *page.Page[*coredata.Audit, coredata.AuditOrderField]) ListControlAuditsOutput {
audits := make([]*Audit, 0, len(auditPage.Data))
for _, v := range auditPage.Data {
audits = append(audits, NewAudit(v))
}
var nextCursor *page.CursorKey
if len(auditPage.Data) > 0 {
cursorKey := auditPage.Data[len(auditPage.Data)-1].CursorKey(auditPage.Cursor.OrderBy.Field)
nextCursor = &cursorKey
}
return ListControlAuditsOutput{
NextCursor: nextCursor,
Audits: audits,
}
}
func NewListAuditsOutput(auditPage *page.Page[*coredata.Audit, coredata.AuditOrderField]) ListAuditsOutput {
audits := make([]*Audit, 0, len(auditPage.Data))
for _, v := range auditPage.Data {

View File

@@ -35,6 +35,24 @@ func NewDocument(d *coredata.Document, approverIDs []gid.GID) *Document {
}
}
func NewListControlDocumentsOutput(documentPage *page.Page[*coredata.Document, coredata.DocumentOrderField], approverIDsMap map[gid.GID][]gid.GID) ListControlDocumentsOutput {
documents := make([]*Document, 0, len(documentPage.Data))
for _, d := range documentPage.Data {
documents = append(documents, NewDocument(d, approverIDsMap[d.ID]))
}
var nextCursor *page.CursorKey
if len(documentPage.Data) > 0 {
cursorKey := documentPage.Data[len(documentPage.Data)-1].CursorKey(documentPage.Cursor.OrderBy.Field)
nextCursor = &cursorKey
}
return ListControlDocumentsOutput{
NextCursor: nextCursor,
Documents: documents,
}
}
func NewListDocumentsOutput(documentPage *page.Page[*coredata.Document, coredata.DocumentOrderField], approverIDsMap map[gid.GID][]gid.GID) ListDocumentsOutput {
documents := make([]*Document, 0, len(documentPage.Data))
for _, d := range documentPage.Data {

View File

@@ -31,6 +31,24 @@ func NewMeasure(m *coredata.Measure) *Measure {
}
}
func NewListControlMeasuresOutput(measurePage *page.Page[*coredata.Measure, coredata.MeasureOrderField]) ListControlMeasuresOutput {
measures := make([]*Measure, 0, len(measurePage.Data))
for _, v := range measurePage.Data {
measures = append(measures, NewMeasure(v))
}
var nextCursor *page.CursorKey
if len(measurePage.Data) > 0 {
cursorKey := measurePage.Data[len(measurePage.Data)-1].CursorKey(measurePage.Cursor.OrderBy.Field)
nextCursor = &cursorKey
}
return ListControlMeasuresOutput{
NextCursor: nextCursor,
Measures: measures,
}
}
func NewListMeasuresOutput(measurePage *page.Page[*coredata.Measure, coredata.MeasureOrderField]) ListMeasuresOutput {
measures := make([]*Measure, 0, len(measurePage.Data))
for _, v := range measurePage.Data {

View File

@@ -57,6 +57,24 @@ func NewListObligationsOutput(obligationPage *page.Page[*coredata.Obligation, co
}
}
func NewListControlObligationsOutput(obligationPage *page.Page[*coredata.Obligation, coredata.ObligationOrderField]) ListControlObligationsOutput {
obligations := make([]*Obligation, 0, len(obligationPage.Data))
for _, v := range obligationPage.Data {
obligations = append(obligations, NewObligation(v))
}
var nextCursor *page.CursorKey
if len(obligationPage.Data) > 0 {
cursorKey := obligationPage.Data[len(obligationPage.Data)-1].CursorKey(obligationPage.Cursor.OrderBy.Field)
nextCursor = &cursorKey
}
return ListControlObligationsOutput{
NextCursor: nextCursor,
Obligations: obligations,
}
}
func NewListRiskObligationsOutput(obligationPage *page.Page[*coredata.Obligation, coredata.ObligationOrderField]) ListRiskObligationsOutput {
obligations := make([]*Obligation, 0, len(obligationPage.Data))
for _, v := range obligationPage.Data {

View File

@@ -29,6 +29,24 @@ func NewSnapshot(s *coredata.Snapshot) *Snapshot {
}
}
func NewListControlSnapshotsOutput(snapshotPage *page.Page[*coredata.Snapshot, coredata.SnapshotOrderField]) ListControlSnapshotsOutput {
snapshots := make([]*Snapshot, 0, len(snapshotPage.Data))
for _, s := range snapshotPage.Data {
snapshots = append(snapshots, NewSnapshot(s))
}
var nextCursor *page.CursorKey
if len(snapshotPage.Data) > 0 {
cursorKey := snapshotPage.Data[len(snapshotPage.Data)-1].CursorKey(snapshotPage.Cursor.OrderBy.Field)
nextCursor = &cursorKey
}
return ListControlSnapshotsOutput{
NextCursor: nextCursor,
Snapshots: snapshots,
}
}
func NewListSnapshotsOutput(snapshotPage *page.Page[*coredata.Snapshot, coredata.SnapshotOrderField]) ListSnapshotsOutput {
snapshots := make([]*Snapshot, 0, len(snapshotPage.Data))
for _, s := range snapshotPage.Data {

View File

@@ -133,14 +133,8 @@ var (
GetUserToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"user":{"type":"object","properties":{"additional_email_addresses":{"type":"array","items":{"type":"string","format":"string"},"description":"Additional email addresses"},"contract_end_date":{"type":["string","null"],"description":"Contract end date","format":"date-time"},"contract_start_date":{"type":["string","null"],"description":"Contract start date","format":"date-time"},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"email_address":{"type":"string","format":"string"},"full_name":{"type":"string","description":"Full name"},"id":{"type":"string","format":"string"},"kind":{"type":"string","enum":["EMPLOYEE","CONTRACTOR","SERVICE_ACCOUNT"]},"organization_id":{"type":"string","format":"string"},"position":{"type":["string","null"],"description":"Position"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","full_name","email_address","additional_email_addresses","kind","created_at","updated_at"]}},"required":["user"]}`)
InviteUserToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"organization_id":{"type":"string","format":"string"},"profile_id":{"type":"string","format":"string"}},"required":["organization_id","profile_id"]}`)
InviteUserToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"invitation_id":{"type":"string","format":"string"}},"required":["invitation_id"]}`)
LinkControlAuditToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audit_id":{"type":"string","format":"string"},"control_id":{"type":"string","format":"string"}},"required":["control_id","audit_id"]}`)
LinkControlAuditToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkControlDocumentToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"document_id":{"type":"string","format":"string"}},"required":["control_id","document_id"]}`)
LinkControlDocumentToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkControlMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"measure_id":{"type":"string","format":"string"}},"required":["control_id","measure_id"]}`)
LinkControlMeasureToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkControlSnapshotToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"snapshot_id":{"type":"string","format":"string"}},"required":["control_id","snapshot_id"]}`)
LinkControlSnapshotToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"resource_id":{"type":"string","format":"string"}},"required":["control_id","resource_id"]}`)
LinkControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"measure_id":{"type":"string","format":"string"},"resource_id":{"type":"string","format":"string"}},"required":["measure_id","resource_id"]}`)
LinkMeasureToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
LinkRiskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"resource_id":{"type":"string","format":"string"},"risk_id":{"type":"string","format":"string"}},"required":["risk_id","resource_id"]}`)
@@ -153,6 +147,16 @@ var (
ListAuditsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audits":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":["string","null"],"description":"Audit name"},"organization_id":{"type":"string","format":"string"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED","REJECTED","OUTDATED"]},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"},"valid_from":{"type":["string","null"],"description":"Valid from date","format":"date-time"},"valid_until":{"type":["string","null"],"description":"Valid until date","format":"date-time"}},"required":["id","organization_id","framework_id","state","trust_center_visibility","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["audits"]}`)
ListContinualImprovementsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","REFERENCE_ID","TARGET_DATE","STATUS","PRIORITY"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}},"required":["organization_id"]}`)
ListContinualImprovementsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"continual_improvements":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"type":["string","null"],"description":"Description"},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"reference_id":{"type":"string","description":"Reference ID"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"type":["string","null"],"description":"Source"},"source_id":{"type":["string","null"],"description":"Source ID"},"status":{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},"target_date":{"type":["string","null"],"description":"Target date","format":"date-time"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","reference_id","owner_id","status","priority","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["continual_improvements"]}`)
ListControlAuditsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","VALID_FROM","VALID_UNTIL","STATE"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["control_id"]}`)
ListControlAuditsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audits":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":["string","null"],"description":"Audit name"},"organization_id":{"type":"string","format":"string"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED","REJECTED","OUTDATED"]},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"},"valid_from":{"type":["string","null"],"description":"Valid from date","format":"date-time"},"valid_until":{"type":["string","null"],"description":"Valid until date","format":"date-time"}},"required":["id","organization_id","framework_id","state","trust_center_visibility","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["audits"]}`)
ListControlDocumentsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","TITLE","DOCUMENT_TYPE"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["control_id"]}`)
ListControlDocumentsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"documents":{"type":"array","items":{"type":"object","properties":{"approver_ids":{"type":"array","items":{"type":"string","format":"string"},"description":"Approver IDs"},"classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"current_published_version":{"type":["integer","null"],"description":"Current published version number"},"document_type":{"type":"string","enum":["OTHER","ISMS","POLICY","PROCEDURE"]},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"title":{"type":"string","description":"Document title"},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","approver_ids","title","document_type","classification","trust_center_visibility","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["documents"]}`)
ListControlMeasuresToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","NAME"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["control_id"]}`)
ListControlMeasuresToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"measures":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string","description":"Measure category"},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"type":["string","null"],"description":"Measure description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Measure name"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","NOT_APPLICABLE","IMPLEMENTED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","category","name","state","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["measures"]}`)
ListControlObligationsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","LAST_REVIEW_DATE","DUE_DATE","STATUS"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["control_id"]}`)
ListControlObligationsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"next_cursor":{"type":"string","format":"string"},"obligations":{"type":"array","items":{"type":"object","properties":{"actions_to_be_implemented":{"type":["string","null"],"description":"Actions to be implemented"},"area":{"type":["string","null"],"description":"Area"},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"due_date":{"type":["string","null"],"description":"Due date","format":"date-time"},"id":{"type":"string","format":"string"},"last_review_date":{"type":["string","null"],"description":"Last review date","format":"date-time"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"regulator":{"type":["string","null"],"description":"Regulator"},"requirement":{"type":["string","null"],"description":"Requirement"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"type":["string","null"],"description":"Source"},"source_id":{"type":["string","null"],"description":"Source ID"},"status":{"type":"string","enum":["NON_COMPLIANT","PARTIALLY_COMPLIANT","COMPLIANT"]},"type":{"type":"string","enum":["LEGAL","CONTRACTUAL"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","owner_id","status","type","created_at","updated_at"]}}},"required":["obligations"]}`)
ListControlSnapshotsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","NAME","TYPE"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["control_id"]}`)
ListControlSnapshotsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"next_cursor":{"type":"string","format":"string"},"snapshots":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Snapshot description","anyOf":[{"type":"string","description":"Snapshot description"},{"type":"null","description":"No description"}]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Snapshot name"},"organization_id":{"type":"string","format":"string"},"type":{"type":"string","enum":["RISKS","VENDORS","ASSETS","DATA","NONCONFORMITIES","OBLIGATIONS","CONTINUAL_IMPROVEMENTS","PROCESSING_ACTIVITIES","STATES_OF_APPLICABILITY"]}},"required":["id","organization_id","name","type","created_at"]}}},"required":["snapshots"]}`)
ListControlsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"query":{"type":"string","description":"Search query"}}},"framework_id":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","SECTION_TITLE"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}},"required":["organization_id"]}`)
ListControlsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"controls":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"type":["string","null"],"description":"Control description"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["controls"]}`)
ListDataProtectionImpactAssessmentsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer"}},"required":["organization_id"]}`)
@@ -217,14 +221,8 @@ var (
TakeSnapshotToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"snapshot":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Snapshot description","anyOf":[{"type":"string","description":"Snapshot description"},{"type":"null","description":"No description"}]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Snapshot name"},"organization_id":{"type":"string","format":"string"},"type":{"type":"string","enum":["RISKS","VENDORS","ASSETS","DATA","NONCONFORMITIES","OBLIGATIONS","CONTINUAL_IMPROVEMENTS","PROCESSING_ACTIVITIES","STATES_OF_APPLICABILITY"]}},"required":["id","organization_id","name","type","created_at"]}},"required":["snapshot"]}`)
UnassignTaskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
UnassignTaskToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"task":{"type":"object","properties":{"assigned_to_id":{"description":"Assigned to person ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"Not assigned"}]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"deadline":{"description":"Deadline","anyOf":[{"type":"string","description":"Deadline","format":"date-time"},{"type":"null","description":"No deadline"}]},"description":{"description":"Task description","anyOf":[{"type":"string","description":"Task description"},{"type":"null","description":"No description"}]},"id":{"type":"string","format":"string"},"measure_id":{"description":"Measure ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No measure"}]},"name":{"type":"string","description":"Task name"},"organization_id":{"type":"string","format":"string"},"state":{"type":"string","enum":["TODO","DONE"]},"time_estimate":{"description":"Time estimate","anyOf":[{"type":"string","description":"A duration"},{"type":"null","description":"No time estimate"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","state","created_at","updated_at"]}},"required":["task"]}`)
UnlinkControlAuditToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audit_id":{"type":"string","format":"string"},"control_id":{"type":"string","format":"string"}},"required":["control_id","audit_id"]}`)
UnlinkControlAuditToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkControlDocumentToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"document_id":{"type":"string","format":"string"}},"required":["control_id","document_id"]}`)
UnlinkControlDocumentToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkControlMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"measure_id":{"type":"string","format":"string"}},"required":["control_id","measure_id"]}`)
UnlinkControlMeasureToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkControlSnapshotToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"snapshot_id":{"type":"string","format":"string"}},"required":["control_id","snapshot_id"]}`)
UnlinkControlSnapshotToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control_id":{"type":"string","format":"string"},"resource_id":{"type":"string","format":"string"}},"required":["control_id","resource_id"]}`)
UnlinkControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"measure_id":{"type":"string","format":"string"},"resource_id":{"type":"string","format":"string"}},"required":["measure_id","resource_id"]}`)
UnlinkMeasureToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object"}`)
UnlinkRiskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"resource_id":{"type":"string","format":"string"},"risk_id":{"type":"string","format":"string"}},"required":["risk_id","resource_id"]}`)
@@ -1957,52 +1955,16 @@ type InviteUserOutput struct {
InvitationID gid.GID `json:"invitation_id"`
}
// LinkControlAuditInput represents the schema
type LinkControlAuditInput struct {
// Audit ID
AuditID gid.GID `json:"audit_id"`
// LinkControlInput represents the schema
type LinkControlInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// ID of the resource to link (measure, document, audit, snapshot, or obligation)
ResourceID gid.GID `json:"resource_id"`
}
// LinkControlAuditOutput represents the schema
type LinkControlAuditOutput struct {
}
// LinkControlDocumentInput represents the schema
type LinkControlDocumentInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Document ID
DocumentID gid.GID `json:"document_id"`
}
// LinkControlDocumentOutput represents the schema
type LinkControlDocumentOutput struct {
}
// LinkControlMeasureInput represents the schema
type LinkControlMeasureInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Measure ID
MeasureID gid.GID `json:"measure_id"`
}
// LinkControlMeasureOutput represents the schema
type LinkControlMeasureOutput struct {
}
// LinkControlSnapshotInput represents the schema
type LinkControlSnapshotInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Snapshot ID
SnapshotID gid.GID `json:"snapshot_id"`
}
// LinkControlSnapshotOutput represents the schema
type LinkControlSnapshotOutput struct {
// LinkControlOutput represents the schema
type LinkControlOutput struct {
}
// LinkMeasureInput represents the schema
@@ -2107,6 +2069,101 @@ type ListContinualImprovementsOutput struct {
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
}
// ListControlAuditsInput represents the schema
type ListControlAuditsInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Page cursor
Cursor *page.CursorKey `json:"cursor,omitempty"`
// Audit order by
OrderBy *AuditOrderBy `json:"order_by,omitempty"`
// Page size
Size *int `json:"size,omitempty"`
}
// ListControlAuditsOutput represents the schema
type ListControlAuditsOutput struct {
Audits []*Audit `json:"audits"`
// Next cursor
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
}
// ListControlDocumentsInput represents the schema
type ListControlDocumentsInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Page cursor
Cursor *page.CursorKey `json:"cursor,omitempty"`
// Document order by
OrderBy *DocumentOrderBy `json:"order_by,omitempty"`
// Page size
Size *int `json:"size,omitempty"`
}
// ListControlDocumentsOutput represents the schema
type ListControlDocumentsOutput struct {
Documents []*Document `json:"documents"`
// Next cursor
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
}
// ListControlMeasuresInput represents the schema
type ListControlMeasuresInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Page cursor
Cursor *page.CursorKey `json:"cursor,omitempty"`
// Measure order by
OrderBy *MeasureOrderBy `json:"order_by,omitempty"`
// Page size
Size *int `json:"size,omitempty"`
}
// ListControlMeasuresOutput represents the schema
type ListControlMeasuresOutput struct {
Measures []*Measure `json:"measures"`
// Next cursor
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
}
// ListControlObligationsInput represents the schema
type ListControlObligationsInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Page cursor
Cursor *page.CursorKey `json:"cursor,omitempty"`
// Obligation order by
OrderBy *ObligationOrderBy `json:"order_by,omitempty"`
// Page size
Size *int `json:"size,omitempty"`
}
// ListControlObligationsOutput represents the schema
type ListControlObligationsOutput struct {
// Next cursor
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
Obligations []*Obligation `json:"obligations"`
}
// ListControlSnapshotsInput represents the schema
type ListControlSnapshotsInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Page cursor
Cursor *page.CursorKey `json:"cursor,omitempty"`
// Snapshot order by
OrderBy *SnapshotOrderBy `json:"order_by,omitempty"`
// Page size
Size *int `json:"size,omitempty"`
}
// ListControlSnapshotsOutput represents the schema
type ListControlSnapshotsOutput struct {
// Next cursor
NextCursor *page.CursorKey `json:"next_cursor,omitempty"`
Snapshots []*Snapshot `json:"snapshots"`
}
// ListControlsInput represents the schema
type ListControlsInput struct {
// Page cursor
@@ -3083,52 +3140,16 @@ type UnassignTaskOutput struct {
Task *Task `json:"task"`
}
// UnlinkControlAuditInput represents the schema
type UnlinkControlAuditInput struct {
// Audit ID
AuditID gid.GID `json:"audit_id"`
// UnlinkControlInput represents the schema
type UnlinkControlInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// ID of the resource to unlink (measure, document, audit, snapshot, or obligation)
ResourceID gid.GID `json:"resource_id"`
}
// UnlinkControlAuditOutput represents the schema
type UnlinkControlAuditOutput struct {
}
// UnlinkControlDocumentInput represents the schema
type UnlinkControlDocumentInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Document ID
DocumentID gid.GID `json:"document_id"`
}
// UnlinkControlDocumentOutput represents the schema
type UnlinkControlDocumentOutput struct {
}
// UnlinkControlMeasureInput represents the schema
type UnlinkControlMeasureInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Measure ID
MeasureID gid.GID `json:"measure_id"`
}
// UnlinkControlMeasureOutput represents the schema
type UnlinkControlMeasureOutput struct {
}
// UnlinkControlSnapshotInput represents the schema
type UnlinkControlSnapshotInput struct {
// Control ID
ControlID gid.GID `json:"control_id"`
// Snapshot ID
SnapshotID gid.GID `json:"snapshot_id"`
}
// UnlinkControlSnapshotOutput represents the schema
type UnlinkControlSnapshotOutput struct {
// UnlinkControlOutput represents the schema
type UnlinkControlOutput struct {
}
// UnlinkMeasureInput represents the schema