From 947b621eb52e6596a3419e627762140a1aac7848 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Sun, 23 Nov 2025 21:31:04 +0100 Subject: [PATCH] Add data tools Signed-off-by: Bryan Frimin --- pkg/server/api/mcp/v1/schema.resolvers.go | 94 +++++++++ pkg/server/api/mcp/v1/server/server.go | 44 +++++ pkg/server/api/mcp/v1/specification.yaml | 222 ++++++++++++++++++++++ pkg/server/api/mcp/v1/types/datum.go | 50 +++++ pkg/server/api/mcp/v1/types/types.go | 111 +++++++++++ 5 files changed, 521 insertions(+) create mode 100644 pkg/server/api/mcp/v1/types/datum.go diff --git a/pkg/server/api/mcp/v1/schema.resolvers.go b/pkg/server/api/mcp/v1/schema.resolvers.go index 2ee3ca339..d41d4930d 100644 --- a/pkg/server/api/mcp/v1/schema.resolvers.go +++ b/pkg/server/api/mcp/v1/schema.resolvers.go @@ -571,3 +571,97 @@ func (r *Resolver) UpdateAssetTool(ctx context.Context, req *mcp.CallToolRequest Asset: types.NewAsset(asset), }, nil } + +func (r *Resolver) ListDataTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDataInput) (*mcp.CallToolResult, types.ListDataOutput, error) { + r.MustBeAuthorized(ctx, input.OrganizationID, authz.ActionListData) + + prb := r.ProboService(ctx, input.OrganizationID) + + pageOrderBy := page.OrderBy[coredata.DatumOrderField]{ + Field: coredata.DatumOrderFieldCreatedAt, + Direction: page.OrderDirectionDesc, + } + if input.OrderBy != nil { + pageOrderBy = page.OrderBy[coredata.DatumOrderField]{ + Field: input.OrderBy.Field, + Direction: input.OrderBy.Direction, + } + } + + cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy) + + var datumFilter = coredata.NewDatumFilter(nil) + if input.Filter != nil { + datumFilter = coredata.NewDatumFilter(&input.Filter.SnapshotID) + } + + page, err := prb.Data.ListForOrganizationID(ctx, input.OrganizationID, cursor, datumFilter) + if err != nil { + panic(fmt.Errorf("cannot list organization data: %w", err)) + } + + return nil, types.NewListDataOutput(page), nil +} + +func (r *Resolver) GetDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDatumInput) (*mcp.CallToolResult, types.GetDatumOutput, error) { + r.MustBeAuthorized(ctx, input.ID, authz.ActionGet) + + prb := r.ProboService(ctx, input.ID) + + datum, err := prb.Data.Get(ctx, input.ID) + if err != nil { + return nil, types.GetDatumOutput{}, fmt.Errorf("failed to get datum: %w", err) + } + + return nil, types.GetDatumOutput{ + Datum: types.NewDatum(datum), + }, nil +} + +func (r *Resolver) AddDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddDatumInput) (*mcp.CallToolResult, types.AddDatumOutput, error) { + r.MustBeAuthorized(ctx, input.OrganizationID, authz.ActionCreateDatum) + + svc := r.ProboService(ctx, input.OrganizationID) + + datum, err := svc.Data.Create( + ctx, + probo.CreateDatumRequest{ + OrganizationID: input.OrganizationID, + Name: input.Name, + DataClassification: input.DataClassification, + OwnerID: input.OwnerID, + VendorIDs: input.VendorIds, + }, + ) + if err != nil { + return nil, types.AddDatumOutput{}, fmt.Errorf("failed to create datum: %w", err) + } + + return nil, types.AddDatumOutput{ + Datum: types.NewDatum(datum), + }, nil +} + +func (r *Resolver) UpdateDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDatumInput) (*mcp.CallToolResult, types.UpdateDatumOutput, error) { + r.MustBeAuthorized(ctx, input.ID, authz.ActionUpdateDatum) + + svc := r.ProboService(ctx, input.ID) + + datum, err := svc.Data.Update( + ctx, + probo.UpdateDatumRequest{ + ID: input.ID, + Name: input.Name, + DataClassification: input.DataClassification, + OwnerID: input.OwnerID, + VendorIDs: input.VendorIds, + }, + ) + if err != nil { + return nil, types.UpdateDatumOutput{}, fmt.Errorf("failed to update datum: %w", err) + } + + return nil, types.UpdateDatumOutput{ + Datum: types.NewDatum(datum), + }, nil +} diff --git a/pkg/server/api/mcp/v1/server/server.go b/pkg/server/api/mcp/v1/server/server.go index 6d9e32a06..c36aefd69 100644 --- a/pkg/server/api/mcp/v1/server/server.go +++ b/pkg/server/api/mcp/v1/server/server.go @@ -33,6 +33,10 @@ type ResolverInterface interface { GetAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAssetInput) (*mcp.CallToolResult, types.GetAssetOutput, error) AddAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddAssetInput) (*mcp.CallToolResult, types.AddAssetOutput, error) UpdateAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateAssetInput) (*mcp.CallToolResult, types.UpdateAssetOutput, error) + ListDataTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDataInput) (*mcp.CallToolResult, types.ListDataOutput, error) + GetDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDatumInput) (*mcp.CallToolResult, types.GetDatumOutput, error) + AddDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddDatumInput) (*mcp.CallToolResult, types.AddDatumOutput, error) + UpdateDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDatumInput) (*mcp.CallToolResult, types.UpdateDatumOutput, error) } // New creates a new MCP server instance with all handlers registered. @@ -282,4 +286,44 @@ func registerToolHandlers(server *mcp.Server, resolver ResolverInterface) { }, resolver.UpdateAssetTool, ) + mcp.AddTool( + server, + &mcp.Tool{ + Name: "listData", + Description: "List all data for the organization", + InputSchema: types.ListDataToolInputSchema, + OutputSchema: types.ListDataToolOutputSchema, + }, + resolver.ListDataTool, + ) + mcp.AddTool( + server, + &mcp.Tool{ + Name: "getDatum", + Description: "Get a datum by ID", + InputSchema: types.GetDatumToolInputSchema, + OutputSchema: types.GetDatumToolOutputSchema, + }, + resolver.GetDatumTool, + ) + mcp.AddTool( + server, + &mcp.Tool{ + Name: "addDatum", + Description: "Add a new datum to the organization", + InputSchema: types.AddDatumToolInputSchema, + OutputSchema: types.AddDatumToolOutputSchema, + }, + resolver.AddDatumTool, + ) + mcp.AddTool( + server, + &mcp.Tool{ + Name: "updateDatum", + Description: "Update an existing datum", + InputSchema: types.UpdateDatumToolInputSchema, + OutputSchema: types.UpdateDatumToolOutputSchema, + }, + resolver.UpdateDatumTool, + ) } diff --git a/pkg/server/api/mcp/v1/specification.yaml b/pkg/server/api/mcp/v1/specification.yaml index 66dda021e..0b560aa2c 100644 --- a/pkg/server/api/mcp/v1/specification.yaml +++ b/pkg/server/api/mcp/v1/specification.yaml @@ -1209,6 +1209,200 @@ components: asset: $ref: "#/components/schemas/Asset" + DataClassification: + type: string + enum: + - PUBLIC + - INTERNAL + - CONFIDENTIAL + - SECRET + go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.DataClassification + + DatumOrderField: + type: string + enum: + - CREATED_AT + - NAME + - DATA_CLASSIFICATION + go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.DatumOrderField + + DatumOrderBy: + type: object + required: + - field + - direction + properties: + field: + $ref: "#/components/schemas/DatumOrderField" + description: Datum order field + direction: + $ref: "#/components/schemas/OrderDirection" + description: Datum order direction + + Datum: + type: object + required: + - id + - organization_id + - name + - data_classification + - owner_id + - created_at + - updated_at + properties: + id: + $ref: "#/components/schemas/GID" + description: Datum ID + organization_id: + $ref: "#/components/schemas/GID" + description: Organization ID + snapshot_id: + anyOf: + - $ref: "#/components/schemas/GID" + description: Snapshot ID + - type: "null" + description: No snapshot + description: Snapshot ID + name: + type: string + description: Datum name + data_classification: + $ref: "#/components/schemas/DataClassification" + description: Data classification + owner_id: + $ref: "#/components/schemas/GID" + description: Owner ID + created_at: + type: string + format: date-time + description: Creation timestamp + updated_at: + type: string + format: date-time + description: Update timestamp + + ListDataInput: + type: object + required: + - organization_id + properties: + organization_id: + $ref: "#/components/schemas/GID" + description: Organization ID + order_by: + $ref: "#/components/schemas/DatumOrderBy" + description: Datum order by + size: + type: integer + description: Page size + cursor: + $ref: "#/components/schemas/CursorKey" + description: Page cursor + filter: + type: object + properties: + snapshot_id: + $ref: "#/components/schemas/GID" + description: Snapshot ID + + ListDataOutput: + type: object + required: + - data + properties: + next_cursor: + $ref: "#/components/schemas/CursorKey" + description: Next cursor + data: + type: array + items: + $ref: "#/components/schemas/Datum" + + GetDatumInput: + type: object + required: + - id + properties: + id: + $ref: "#/components/schemas/GID" + description: Datum ID + + GetDatumOutput: + type: object + required: + - datum + properties: + datum: + $ref: "#/components/schemas/Datum" + + AddDatumInput: + type: object + required: + - organization_id + - name + - data_classification + - owner_id + properties: + organization_id: + $ref: "#/components/schemas/GID" + description: Organization ID + name: + type: string + description: Datum name + data_classification: + $ref: "#/components/schemas/DataClassification" + description: Data classification + owner_id: + $ref: "#/components/schemas/GID" + description: Owner ID + vendor_ids: + type: array + items: + $ref: "#/components/schemas/GID" + description: Vendor IDs + + AddDatumOutput: + type: object + required: + - datum + properties: + datum: + $ref: "#/components/schemas/Datum" + + UpdateDatumInput: + type: object + required: + - id + properties: + id: + $ref: "#/components/schemas/GID" + description: Datum ID + name: + type: string + description: Datum name + data_classification: + $ref: "#/components/schemas/DataClassification" + description: Data classification + owner_id: + anyOf: + - type: string + $ref: "#/components/schemas/GID" + - type: "null" + description: Owner ID + vendor_ids: + type: array + items: + $ref: "#/components/schemas/GID" + description: Vendor IDs + + UpdateDatumOutput: + type: object + required: + - datum + properties: + datum: + $ref: "#/components/schemas/Datum" + tools: - name: listOrganizations description: List all organizations the user has access to @@ -1371,3 +1565,31 @@ tools: $ref: "#/components/schemas/UpdateAssetInput" outputSchema: $ref: "#/components/schemas/UpdateAssetOutput" + - name: listData + description: List all data for the organization + readonly: true + inputSchema: + $ref: "#/components/schemas/ListDataInput" + outputSchema: + $ref: "#/components/schemas/ListDataOutput" + - name: getDatum + description: Get a datum by ID + readonly: true + inputSchema: + $ref: "#/components/schemas/GetDatumInput" + outputSchema: + $ref: "#/components/schemas/GetDatumOutput" + - name: addDatum + description: Add a new datum to the organization + readonly: false + inputSchema: + $ref: "#/components/schemas/AddDatumInput" + outputSchema: + $ref: "#/components/schemas/AddDatumOutput" + - name: updateDatum + description: Update an existing datum + readonly: false + inputSchema: + $ref: "#/components/schemas/UpdateDatumInput" + outputSchema: + $ref: "#/components/schemas/UpdateDatumOutput" diff --git a/pkg/server/api/mcp/v1/types/datum.go b/pkg/server/api/mcp/v1/types/datum.go new file mode 100644 index 000000000..6cf461e5b --- /dev/null +++ b/pkg/server/api/mcp/v1/types/datum.go @@ -0,0 +1,50 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/page" +) + +func NewDatum(d *coredata.Datum) *Datum { + return &Datum{ + ID: d.ID, + Name: d.Name, + OrganizationID: d.OrganizationID, + SnapshotID: d.SnapshotID, + DataClassification: d.DataClassification, + CreatedAt: d.CreatedAt, + UpdatedAt: d.UpdatedAt, + } +} + +func NewListDataOutput(datumPage *page.Page[*coredata.Datum, coredata.DatumOrderField]) ListDataOutput { + data := make([]*Datum, 0, len(datumPage.Data)) + for _, v := range datumPage.Data { + data = append(data, NewDatum(v)) + } + + var nextCursor *page.CursorKey + if len(datumPage.Data) > 0 { + cursorKey := datumPage.Data[len(datumPage.Data)-1].CursorKey(datumPage.Cursor.OrderBy.Field) + nextCursor = &cursorKey + } + + return ListDataOutput{ + NextCursor: nextCursor, + Data: data, + } +} diff --git a/pkg/server/api/mcp/v1/types/types.go b/pkg/server/api/mcp/v1/types/types.go index 8859c50a6..26c7c458e 100644 --- a/pkg/server/api/mcp/v1/types/types.go +++ b/pkg/server/api/mcp/v1/types/types.go @@ -14,6 +14,8 @@ import ( var ( AddAssetToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id","name","amount","owner_id","asset_type","data_types_stored"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"data_types_stored":{"type":"string","description":"Data types stored"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"vendor_ids":{"type":"array","description":"Vendor IDs","items":{"type":"string","format":"string"}}}}`) AddAssetToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["asset"],"properties":{"asset":{"type":"object","required":["id","organization_id","name","amount","owner_id","asset_type","data_types_stored","created_at","updated_at"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) + AddDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id","name","data_classification","owner_id"],"properties":{"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"vendor_ids":{"type":"array","description":"Vendor IDs","items":{"type":"string","format":"string"}}}}`) + AddDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["datum"],"properties":{"datum":{"type":"object","required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) AddFrameworkToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id","name"],"properties":{"description":{"type":"string","description":"Framework description"},"name":{"type":"string","description":"Framework name"},"organization_id":{"type":"string","format":"string"}}}`) AddFrameworkToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["framework"],"properties":{"framework":{"type":"object","required":["id","organization_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Framework description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Framework name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) AddMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id","name","category"],"properties":{"category":{"type":"string","description":"Measure category"},"description":{"type":"string","description":"Measure description"},"name":{"type":"string","description":"Measure name"},"organization_id":{"type":"string","format":"string"}}}`) @@ -26,6 +28,8 @@ var ( AddVendorToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["vendor"],"properties":{"vendor":{"type":"object","required":["id","name","organization_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Vendor description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Vendor name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) GetAssetToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"string"}}}`) GetAssetToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["asset"],"properties":{"asset":{"type":"object","required":["id","organization_id","name","amount","owner_id","asset_type","data_types_stored","created_at","updated_at"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) + GetDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"string"}}}`) + GetDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["datum"],"properties":{"datum":{"type":"object","required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) GetFrameworkToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"string"}}}`) GetFrameworkToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["framework"],"properties":{"framework":{"type":"object","required":["id","organization_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Framework description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Framework name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) GetMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"string"}}}`) @@ -36,6 +40,8 @@ var ( GetRiskToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["risk"],"properties":{"risk":{"type":"object","required":["id","organization_id","name","category","treatment","inherent_likelihood","inherent_impact","inherent_risk_score","residual_likelihood","residual_impact","residual_risk_score","note","created_at","updated_at"],"properties":{"category":{"type":"string","description":"Risk category"},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Risk description"},"id":{"type":"string","format":"string"},"inherent_impact":{"type":"integer","description":"Inherent impact"},"inherent_likelihood":{"type":"integer","description":"Inherent likelihood"},"inherent_risk_score":{"type":"integer","description":"Inherent risk score"},"name":{"type":"string","description":"Risk name"},"note":{"type":"string","description":"Risk note"},"organization_id":{"type":"string","format":"string"},"owner_id":{"description":"Owner ID"},"residual_impact":{"type":"integer","description":"Residual impact"},"residual_likelihood":{"type":"integer","description":"Residual likelihood"},"residual_risk_score":{"type":"integer","description":"Residual risk score"},"snapshot_id":{"description":"Snapshot ID"},"treatment":{"type":"string","enum":["MITIGATED","ACCEPTED","AVOIDED","TRANSFERRED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) ListAssetsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id"],"properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","required":["field","direction"],"properties":{"direction":{"type":"string","enum":["asc","desc"]},"field":{"type":"string","enum":["CREATED_AT","AMOUNT"]}}},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}}}`) ListAssetsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"type":"object","required":["id","organization_id","name","amount","owner_id","asset_type","data_types_stored","created_at","updated_at"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}},"next_cursor":{"type":"string","format":"string"}}}`) + ListDataToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id"],"properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","required":["field","direction"],"properties":{"direction":{"type":"string","enum":["asc","desc"]},"field":{"type":"string","enum":["CREATED_AT","NAME","DATA_CLASSIFICATION"]}}},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}}}`) + ListDataToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}},"next_cursor":{"type":"string","format":"string"}}}`) ListFrameworksToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id"],"properties":{"cursor":{"type":"string","format":"string"},"order_by":{"type":"object","required":["field","direction"],"properties":{"direction":{"type":"string","enum":["asc","desc"]},"field":{"type":"string","enum":["CREATED_AT"]}}},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}}}`) ListFrameworksToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["frameworks"],"properties":{"frameworks":{"type":"array","items":{"type":"object","required":["id","organization_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Framework description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Framework name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}},"next_cursor":{"type":"string","format":"string"}}}`) ListMeasuresToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["organization_id"],"properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"query":{"type":"string","description":"Search query"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","NOT_APPLICABLE","IMPLEMENTED"]}}},"order_by":{"type":"object","required":["field","direction"],"properties":{"direction":{"type":"string","enum":["asc","desc"]},"field":{"type":"string","enum":["CREATED_AT","NAME"]}}},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}}}`) @@ -50,6 +56,8 @@ var ( ListVendorsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["vendors"],"properties":{"next_cursor":{"type":"string","format":"string"},"vendors":{"type":"array","items":{"type":"object","required":["id","name","organization_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Vendor description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Vendor name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}}`) UpdateAssetToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"owner_id":{"description":"Owner ID","anyOf":[{"type":"string","format":"string"},{"type":"null"}]},"vendor_ids":{"type":"array","description":"Vendor IDs","items":{"type":"string","format":"string"}}}}`) UpdateAssetToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["asset"],"properties":{"asset":{"type":"object","required":["id","organization_id","name","amount","owner_id","asset_type","data_types_stored","created_at","updated_at"],"properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) + UpdateDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"owner_id":{"description":"Owner ID","anyOf":[{"type":"string","format":"string"},{"type":"null"}]},"vendor_ids":{"type":"array","description":"Vendor IDs","items":{"type":"string","format":"string"}}}}`) + UpdateDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["datum"],"properties":{"datum":{"type":"object","required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) UpdateFrameworkToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"description":{"description":"Framework description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Framework name"}}}`) UpdateFrameworkToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["framework"],"properties":{"framework":{"type":"object","required":["id","organization_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Framework description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Framework name"},"organization_id":{"type":"string","format":"string"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}}}}}`) UpdateMeasureToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","required":["id"],"properties":{"category":{"type":"string","description":"Measure category"},"description":{"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"]}}}`) @@ -83,6 +91,25 @@ type AddAssetOutput struct { Asset *Asset `json:"asset"` } +// AddDatumInput represents the schema +type AddDatumInput struct { + // Data classification + DataClassification coredata.DataClassification `json:"data_classification"` + // Datum name + Name string `json:"name"` + // Organization ID + OrganizationID gid.GID `json:"organization_id"` + // Owner ID + OwnerID gid.GID `json:"owner_id"` + // Vendor IDs + VendorIds []gid.GID `json:"vendor_ids,omitempty"` +} + +// AddDatumOutput represents the schema +type AddDatumOutput struct { + Datum *Datum `json:"datum"` +} + // AddFrameworkInput represents the schema type AddFrameworkInput struct { // Framework description @@ -222,6 +249,34 @@ type AssetOrderBy struct { Field coredata.AssetOrderField `json:"field"` } +// Datum represents the schema +type Datum struct { + // Creation timestamp + CreatedAt time.Time `json:"created_at"` + // Data classification + DataClassification coredata.DataClassification `json:"data_classification"` + // Datum ID + ID gid.GID `json:"id"` + // Datum name + Name string `json:"name"` + // Organization ID + OrganizationID gid.GID `json:"organization_id"` + // Owner ID + OwnerID gid.GID `json:"owner_id"` + // Snapshot ID + SnapshotID *gid.GID `json:"snapshot_id,omitempty"` + // Update timestamp + UpdatedAt time.Time `json:"updated_at"` +} + +// DatumOrderBy represents the schema +type DatumOrderBy struct { + // Datum order direction + Direction page.OrderDirection `json:"direction"` + // Datum order field + Field coredata.DatumOrderField `json:"field"` +} + // Framework represents the schema type Framework struct { // Creation timestamp @@ -257,6 +312,17 @@ type GetAssetOutput struct { Asset *Asset `json:"asset"` } +// GetDatumInput represents the schema +type GetDatumInput struct { + // Datum ID + ID gid.GID `json:"id"` +} + +// GetDatumOutput represents the schema +type GetDatumOutput struct { + Datum *Datum `json:"datum"` +} + // GetFrameworkInput represents the schema type GetFrameworkInput struct { // Framework ID @@ -321,6 +387,26 @@ type ListAssetsOutput struct { NextCursor *page.CursorKey `json:"next_cursor,omitempty"` } +// ListDataInput represents the schema +type ListDataInput struct { + // Page cursor + Cursor *page.CursorKey `json:"cursor,omitempty"` + Filter *ListDataInputFilter `json:"filter,omitempty"` + // Datum order by + OrderBy *DatumOrderBy `json:"order_by,omitempty"` + // Organization ID + OrganizationID gid.GID `json:"organization_id"` + // Page size + Size *int `json:"size,omitempty"` +} + +// ListDataOutput represents the schema +type ListDataOutput struct { + Data []*Datum `json:"data"` + // Next cursor + NextCursor *page.CursorKey `json:"next_cursor,omitempty"` +} + // ListFrameworksInput represents the schema type ListFrameworksInput struct { // Page cursor @@ -574,6 +660,25 @@ type UpdateAssetOutput struct { Asset *Asset `json:"asset"` } +// UpdateDatumInput represents the schema +type UpdateDatumInput struct { + // Data classification + DataClassification *coredata.DataClassification `json:"data_classification,omitempty"` + // Datum ID + ID gid.GID `json:"id"` + // Datum name + Name *string `json:"name,omitempty"` + // Owner ID + OwnerID *gid.GID `json:"owner_id,omitempty"` + // Vendor IDs + VendorIds []gid.GID `json:"vendor_ids,omitempty"` +} + +// UpdateDatumOutput represents the schema +type UpdateDatumOutput struct { + Datum *Datum `json:"datum"` +} + // UpdateFrameworkInput represents the schema type UpdateFrameworkInput struct { // Framework description @@ -684,6 +789,12 @@ type ListAssetsInputFilter struct { SnapshotID *gid.GID `json:"snapshot_id,omitempty"` } +// ListDataInputFilter represents the schema +type ListDataInputFilter struct { + // Snapshot ID + SnapshotID *gid.GID `json:"snapshot_id,omitempty"` +} + // ListMeasuresInputFilter represents the schema type ListMeasuresInputFilter struct { // Search query