From b1e1127392e13330545633d901d29990d3a07db2 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Tue, 25 Nov 2025 11:27:52 +0100 Subject: [PATCH] Add mcp hint support Signed-off-by: Bryan Frimin --- go.mod | 2 +- go.sum | 4 +- pkg/server/api/mcp/v1/server/server.go | 116 ++++++++++++ pkg/server/api/mcp/v1/specification.yaml | 220 ++++++++++++++++------- 4 files changed, 275 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 0e414c823..8e2186bfb 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( go.gearno.de/x/ref v0.0.0-20240502200927-d74926fcb14c go.opentelemetry.io/otel v1.38.0 go.opentelemetry.io/otel/trace v1.38.0 - go.probo.inc/mcpgen v0.0.0-20251123193256-f77e7775c058 + go.probo.inc/mcpgen v0.0.0-20251124210642-41a5174eb92f golang.org/x/crypto v0.45.0 golang.org/x/image v0.33.0 golang.org/x/sync v0.18.0 diff --git a/go.sum b/go.sum index c3bd0da35..679922c87 100644 --- a/go.sum +++ b/go.sum @@ -245,8 +245,8 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= -go.probo.inc/mcpgen v0.0.0-20251123193256-f77e7775c058 h1:zRiWKVVJZCDDolmVedKm0xdQlJQXvLzgFEDu/s20jYs= -go.probo.inc/mcpgen v0.0.0-20251123193256-f77e7775c058/go.mod h1:HunWQGqLdMocExJh4tWaX7p+uRZ9GlKvBvOXHaFW6vM= +go.probo.inc/mcpgen v0.0.0-20251124210642-41a5174eb92f h1:+DQYe30MBnbGitWf/2BlAMmqYCxzSEwmJtUOnWsfQNc= +go.probo.inc/mcpgen v0.0.0-20251124210642-41a5174eb92f/go.mod h1:HunWQGqLdMocExJh4tWaX7p+uRZ9GlKvBvOXHaFW6vM= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= diff --git a/pkg/server/api/mcp/v1/server/server.go b/pkg/server/api/mcp/v1/server/server.go index 523ac1a2c..16cbbec77 100644 --- a/pkg/server/api/mcp/v1/server/server.go +++ b/pkg/server/api/mcp/v1/server/server.go @@ -100,6 +100,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all organizations the user has access to", InputSchema: types.ListOrganizationsToolInputSchema, OutputSchema: types.ListOrganizationsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListOrganizationsTool, ) @@ -110,6 +114,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all vendors for the organization", InputSchema: types.ListVendorsToolInputSchema, OutputSchema: types.ListVendorsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListVendorsTool, ) @@ -120,6 +128,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all people for the organization", InputSchema: types.ListPeopleToolInputSchema, OutputSchema: types.ListPeopleToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListPeopleTool, ) @@ -150,6 +162,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a people by ID", InputSchema: types.GetPeopleToolInputSchema, OutputSchema: types.GetPeopleToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetPeopleTool, ) @@ -170,6 +186,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all risks for the organization", InputSchema: types.ListRisksToolInputSchema, OutputSchema: types.ListRisksToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListRisksTool, ) @@ -180,6 +200,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a risk by ID", InputSchema: types.GetRiskToolInputSchema, OutputSchema: types.GetRiskToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetRiskTool, ) @@ -210,6 +234,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all measures for the organization", InputSchema: types.ListMeasuresToolInputSchema, OutputSchema: types.ListMeasuresToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListMeasuresTool, ) @@ -220,6 +248,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a measure by ID", InputSchema: types.GetMeasureToolInputSchema, OutputSchema: types.GetMeasureToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetMeasureTool, ) @@ -250,6 +282,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all frameworks for the organization", InputSchema: types.ListFrameworksToolInputSchema, OutputSchema: types.ListFrameworksToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListFrameworksTool, ) @@ -260,6 +296,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a framework by ID", InputSchema: types.GetFrameworkToolInputSchema, OutputSchema: types.GetFrameworkToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetFrameworkTool, ) @@ -290,6 +330,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all assets for the organization", InputSchema: types.ListAssetsToolInputSchema, OutputSchema: types.ListAssetsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListAssetsTool, ) @@ -300,6 +344,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get an asset by ID", InputSchema: types.GetAssetToolInputSchema, OutputSchema: types.GetAssetToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetAssetTool, ) @@ -330,6 +378,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all data for the organization", InputSchema: types.ListDataToolInputSchema, OutputSchema: types.ListDataToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListDataTool, ) @@ -340,6 +392,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a datum by ID", InputSchema: types.GetDatumToolInputSchema, OutputSchema: types.GetDatumToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetDatumTool, ) @@ -370,6 +426,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all nonconformities for the organization", InputSchema: types.ListNonconformitiesToolInputSchema, OutputSchema: types.ListNonconformitiesToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListNonconformitiesTool, ) @@ -380,6 +440,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a nonconformity by ID", InputSchema: types.GetNonconformityToolInputSchema, OutputSchema: types.GetNonconformityToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetNonconformityTool, ) @@ -410,6 +474,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all obligations for the organization", InputSchema: types.ListObligationsToolInputSchema, OutputSchema: types.ListObligationsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListObligationsTool, ) @@ -420,6 +488,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get an obligation by ID", InputSchema: types.GetObligationToolInputSchema, OutputSchema: types.GetObligationToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetObligationTool, ) @@ -450,6 +522,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all continual improvements for the organization", InputSchema: types.ListContinualImprovementsToolInputSchema, OutputSchema: types.ListContinualImprovementsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListContinualImprovementsTool, ) @@ -460,6 +536,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a continual improvement by ID", InputSchema: types.GetContinualImprovementToolInputSchema, OutputSchema: types.GetContinualImprovementToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetContinualImprovementTool, ) @@ -490,6 +570,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all audits for the organization", InputSchema: types.ListAuditsToolInputSchema, OutputSchema: types.ListAuditsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListAuditsTool, ) @@ -500,6 +584,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get an audit by ID", InputSchema: types.GetAuditToolInputSchema, OutputSchema: types.GetAuditToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetAuditTool, ) @@ -530,6 +618,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all controls for the organization or framework", InputSchema: types.ListControlsToolInputSchema, OutputSchema: types.ListControlsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListControlsTool, ) @@ -540,6 +632,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a control by ID", InputSchema: types.GetControlToolInputSchema, OutputSchema: types.GetControlToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetControlTool, ) @@ -650,6 +746,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all tasks for the organization or measure", InputSchema: types.ListTasksToolInputSchema, OutputSchema: types.ListTasksToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListTasksTool, ) @@ -660,6 +760,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a task by ID", InputSchema: types.GetTaskToolInputSchema, OutputSchema: types.GetTaskToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetTaskTool, ) @@ -710,6 +814,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "List all snapshots for the organization", InputSchema: types.ListSnapshotsToolInputSchema, OutputSchema: types.ListSnapshotsToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.ListSnapshotsTool, ) @@ -720,6 +828,10 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { Description: "Get a snapshot by ID", InputSchema: types.GetSnapshotToolInputSchema, OutputSchema: types.GetSnapshotToolOutputSchema, + Annotations: &mcp.ToolAnnotations{ + ReadOnlyHint: true, + IdempotentHint: true, + }, }, resolver.GetSnapshotTool, ) @@ -734,3 +846,7 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { resolver.TakeSnapshotTool, ) } + +func boolPtr(b bool) *bool { + return &b +} diff --git a/pkg/server/api/mcp/v1/specification.yaml b/pkg/server/api/mcp/v1/specification.yaml index b111bfcc5..523e68b20 100644 --- a/pkg/server/api/mcp/v1/specification.yaml +++ b/pkg/server/api/mcp/v1/specification.yaml @@ -3212,448 +3212,540 @@ components: tools: - name: listOrganizations description: List all organizations the user has access to - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListOrganizationsInput" outputSchema: $ref: "#/components/schemas/ListOrganizationsOutput" - name: listVendors description: List all vendors for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListVendorsInput" outputSchema: $ref: "#/components/schemas/ListVendorsOutput" - name: listPeople description: List all people for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListPeopleInput" outputSchema: $ref: "#/components/schemas/ListPeopleOutput" - name: addVendor description: Add a new vendor to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddVendorInput" outputSchema: $ref: "#/components/schemas/AddVendorOutput" - name: updateVendor description: Update an existing vendor - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateVendorInput" outputSchema: $ref: "#/components/schemas/UpdateVendorOutput" - name: getPeople description: Get a people by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetPeopleInput" outputSchema: $ref: "#/components/schemas/GetPeopleOutput" - name: addPeople description: Add a new people to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddPeopleInput" outputSchema: $ref: "#/components/schemas/AddPeopleOutput" - name: listRisks description: List all risks for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListRisksInput" outputSchema: $ref: "#/components/schemas/ListRisksOutput" - name: getRisk description: Get a risk by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetRiskInput" outputSchema: $ref: "#/components/schemas/GetRiskOutput" - name: addRisk description: Add a new risk to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddRiskInput" outputSchema: $ref: "#/components/schemas/AddRiskOutput" - name: updateRisk description: Update an existing risk - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateRiskInput" outputSchema: $ref: "#/components/schemas/UpdateRiskOutput" - name: listMeasures description: List all measures for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListMeasuresInput" outputSchema: $ref: "#/components/schemas/ListMeasuresOutput" - name: getMeasure description: Get a measure by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetMeasureInput" outputSchema: $ref: "#/components/schemas/GetMeasureOutput" - name: addMeasure description: Add a new measure to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddMeasureInput" outputSchema: $ref: "#/components/schemas/AddMeasureOutput" - name: updateMeasure description: Update an existing measure - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateMeasureInput" outputSchema: $ref: "#/components/schemas/UpdateMeasureOutput" - name: listFrameworks description: List all frameworks for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListFrameworksInput" outputSchema: $ref: "#/components/schemas/ListFrameworksOutput" - name: getFramework description: Get a framework by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetFrameworkInput" outputSchema: $ref: "#/components/schemas/GetFrameworkOutput" - name: addFramework description: Add a new framework to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddFrameworkInput" outputSchema: $ref: "#/components/schemas/AddFrameworkOutput" - name: updateFramework description: Update an existing framework - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateFrameworkInput" outputSchema: $ref: "#/components/schemas/UpdateFrameworkOutput" - name: listAssets description: List all assets for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListAssetsInput" outputSchema: $ref: "#/components/schemas/ListAssetsOutput" - name: getAsset description: Get an asset by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetAssetInput" outputSchema: $ref: "#/components/schemas/GetAssetOutput" - name: addAsset description: Add a new asset to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddAssetInput" outputSchema: $ref: "#/components/schemas/AddAssetOutput" - name: updateAsset description: Update an existing asset - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateAssetInput" outputSchema: $ref: "#/components/schemas/UpdateAssetOutput" - name: listData description: List all data for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListDataInput" outputSchema: $ref: "#/components/schemas/ListDataOutput" - name: getDatum description: Get a datum by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetDatumInput" outputSchema: $ref: "#/components/schemas/GetDatumOutput" - name: addDatum description: Add a new datum to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddDatumInput" outputSchema: $ref: "#/components/schemas/AddDatumOutput" - name: updateDatum description: Update an existing datum - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateDatumInput" outputSchema: $ref: "#/components/schemas/UpdateDatumOutput" - name: listNonconformities description: List all nonconformities for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListNonconformitiesInput" outputSchema: $ref: "#/components/schemas/ListNonconformitiesOutput" - name: getNonconformity description: Get a nonconformity by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetNonconformityInput" outputSchema: $ref: "#/components/schemas/GetNonconformityOutput" - name: addNonconformity description: Add a new nonconformity to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddNonconformityInput" outputSchema: $ref: "#/components/schemas/AddNonconformityOutput" - name: updateNonconformity description: Update an existing nonconformity - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateNonconformityInput" outputSchema: $ref: "#/components/schemas/UpdateNonconformityOutput" - name: listObligations description: List all obligations for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListObligationsInput" outputSchema: $ref: "#/components/schemas/ListObligationsOutput" - name: getObligation description: Get an obligation by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetObligationInput" outputSchema: $ref: "#/components/schemas/GetObligationOutput" - name: addObligation description: Add a new obligation to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddObligationInput" outputSchema: $ref: "#/components/schemas/AddObligationOutput" - name: updateObligation description: Update an existing obligation - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateObligationInput" outputSchema: $ref: "#/components/schemas/UpdateObligationOutput" - name: listContinualImprovements description: List all continual improvements for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListContinualImprovementsInput" outputSchema: $ref: "#/components/schemas/ListContinualImprovementsOutput" - name: getContinualImprovement description: Get a continual improvement by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetContinualImprovementInput" outputSchema: $ref: "#/components/schemas/GetContinualImprovementOutput" - name: addContinualImprovement description: Add a new continual improvement to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddContinualImprovementInput" outputSchema: $ref: "#/components/schemas/AddContinualImprovementOutput" - name: updateContinualImprovement description: Update an existing continual improvement - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateContinualImprovementInput" outputSchema: $ref: "#/components/schemas/UpdateContinualImprovementOutput" - name: listAudits description: List all audits for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListAuditsInput" outputSchema: $ref: "#/components/schemas/ListAuditsOutput" - name: getAudit description: Get an audit by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetAuditInput" outputSchema: $ref: "#/components/schemas/GetAuditOutput" - name: addAudit description: Add a new audit to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddAuditInput" outputSchema: $ref: "#/components/schemas/AddAuditOutput" - name: updateAudit description: Update an existing audit - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateAuditInput" outputSchema: $ref: "#/components/schemas/UpdateAuditOutput" - name: listControls description: List all controls for the organization or framework - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListControlsInput" outputSchema: $ref: "#/components/schemas/ListControlsOutput" - name: getControl description: Get a control by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetControlInput" outputSchema: $ref: "#/components/schemas/GetControlOutput" - name: addControl description: Add a new control to a framework - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddControlInput" outputSchema: $ref: "#/components/schemas/AddControlOutput" - name: updateControl description: Update an existing control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateControlInput" outputSchema: $ref: "#/components/schemas/UpdateControlOutput" - name: linkControlMeasure description: Link a measure to a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/LinkControlMeasureInput" outputSchema: $ref: "#/components/schemas/LinkControlMeasureOutput" - name: unlinkControlMeasure description: Unlink a measure from a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UnlinkControlMeasureInput" outputSchema: $ref: "#/components/schemas/UnlinkControlMeasureOutput" - name: linkControlDocument description: Link a document to a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/LinkControlDocumentInput" outputSchema: $ref: "#/components/schemas/LinkControlDocumentOutput" - name: unlinkControlDocument description: Unlink a document from a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UnlinkControlDocumentInput" outputSchema: $ref: "#/components/schemas/UnlinkControlDocumentOutput" - name: linkControlAudit description: Link an audit to a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/LinkControlAuditInput" outputSchema: $ref: "#/components/schemas/LinkControlAuditOutput" - name: unlinkControlAudit description: Unlink an audit from a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UnlinkControlAuditInput" outputSchema: $ref: "#/components/schemas/UnlinkControlAuditOutput" - name: linkControlSnapshot description: Link a snapshot to a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/LinkControlSnapshotInput" outputSchema: $ref: "#/components/schemas/LinkControlSnapshotOutput" - name: unlinkControlSnapshot description: Unlink a snapshot from a control - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UnlinkControlSnapshotInput" outputSchema: $ref: "#/components/schemas/UnlinkControlSnapshotOutput" - name: listTasks description: List all tasks for the organization or measure - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListTasksInput" outputSchema: $ref: "#/components/schemas/ListTasksOutput" - name: getTask description: Get a task by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetTaskInput" outputSchema: $ref: "#/components/schemas/GetTaskOutput" - name: addTask description: Add a new task to the organization - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AddTaskInput" outputSchema: $ref: "#/components/schemas/AddTaskOutput" - name: updateTask description: Update an existing task - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UpdateTaskInput" outputSchema: $ref: "#/components/schemas/UpdateTaskOutput" - name: assignTask description: Assign a task to a person - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/AssignTaskInput" outputSchema: $ref: "#/components/schemas/AssignTaskOutput" - name: unassignTask description: Unassign a task from a person - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/UnassignTaskInput" outputSchema: $ref: "#/components/schemas/UnassignTaskOutput" - name: listSnapshots description: List all snapshots for the organization - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/ListSnapshotsInput" outputSchema: $ref: "#/components/schemas/ListSnapshotsOutput" - name: getSnapshot description: Get a snapshot by ID - readonly: true + hints: + readonly: true + idempotent: true inputSchema: $ref: "#/components/schemas/GetSnapshotInput" outputSchema: $ref: "#/components/schemas/GetSnapshotOutput" - name: takeSnapshot description: Take a snapshot of a collection of objects (risks, vendors, assets, data, nonconformities, obligations, continual improvements, or processing activities) - readonly: false + hints: + readonly: false inputSchema: $ref: "#/components/schemas/TakeSnapshotInput" outputSchema: