@@ -91,6 +91,22 @@ type serializedCheckResults struct {
9191 NextLevel * serializedLevel
9292}
9393
94+ type serializedCampaign struct {
95+ Id string
96+ Name string
97+ ProjectBrief string
98+ Status string
99+ CheckStats opslevel.Stats
100+ HtmlURL string
101+ ServiceStats opslevel.Stats
102+ Filter * opslevel.FilterId
103+ Owner * opslevel.TeamId
104+ StartDate * iso8601.Time
105+ EndedDate * iso8601.Time
106+ TargetDate * iso8601.Time
107+ Reminder * opslevel.CampaignReminder
108+ }
109+
94110// newToolResult creates a CallToolResult for the passed object handling any json marshaling errors
95111func newToolResult (obj any , err error ) (* mcp.CallToolResult , error ) {
96112 if err != nil {
@@ -513,6 +529,71 @@ var rootCmd = &cobra.Command{
513529 return newToolResult (result , nil )
514530 })
515531
532+ // Register campaigns tool
533+ s .AddTool (
534+ mcp .NewTool (
535+ "campaigns" ,
536+ mcp .WithDescription ("Get all the campaigns in the OpsLevel account. Campaigns are used to track and manage initiatives or projects within OpsLevel." ),
537+ mcp .WithString ("status" , mcp .Description ("Filter campaigns by status, default is 'in_progress'" ), mcp .Enum (opslevel .AllCampaignStatusEnum ... )),
538+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
539+ Title : "Campaigns in OpsLevel" ,
540+ ReadOnlyHint : & trueValue ,
541+ DestructiveHint : & falseValue ,
542+ IdempotentHint : & trueValue ,
543+ OpenWorldHint : & trueValue ,
544+ }),
545+ ),
546+ func (ctx context.Context , req mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
547+ args := & opslevel.ListCampaignsVariables {}
548+ status := req .GetString ("status" , "" )
549+ if status != "" {
550+ status_enum := opslevel .CampaignStatusEnum (status )
551+ args .Status = & status_enum
552+ }
553+
554+ resp , err := client .ListCampaigns (args )
555+ if err != nil {
556+ return mcp .NewToolResultErrorFromErr ("failed to list campaigns" , err ), nil
557+ }
558+ var campaigns []serializedCampaign
559+ for _ , node := range resp .Nodes {
560+ c := serializedCampaign {
561+ Id : string (node .Id ),
562+ Name : node .Name ,
563+ ProjectBrief : node .ProjectBrief ,
564+ Status : string (node .Status ),
565+ HtmlURL : node .HtmlUrl ,
566+ CheckStats : node .CheckStats ,
567+ ServiceStats : node .ServiceStats ,
568+ }
569+ if node .Owner != (opslevel.TeamId {}) {
570+ c .Owner = & node .Owner
571+ }
572+ if node .StartDate != (iso8601.Time {}) {
573+ c .StartDate = & node .StartDate
574+ }
575+ if node .EndedDate != (iso8601.Time {}) {
576+ c .EndedDate = & node .EndedDate
577+ }
578+ if node .TargetDate != (iso8601.Time {}) {
579+ c .TargetDate = & node .TargetDate
580+ }
581+ if len (node .Reminder .Channels ) > 0 {
582+ c .Reminder = & node .Reminder
583+ }
584+ if node .Filter != (opslevel.FilterId {}) {
585+ c .Filter = & node .Filter
586+ }
587+ if node .CheckStats != (opslevel.Stats {}) {
588+ c .CheckStats = node .CheckStats
589+ }
590+
591+ campaigns = append (campaigns , c )
592+ }
593+
594+ return newToolResult (campaigns , err )
595+ })
596+
516597 log .Info ().Msg ("Starting MCP server..." )
517598 if err := server .ServeStdio (s ); err != nil {
518599 if err == context .Canceled {
0 commit comments