Skip to content

Commit 2fde982

Browse files
David-KreinerHarness
authored andcommitted
feat: [ML-1256]: Add support for custom ui from mcp (#84)
* Merge branch 'master' into ML-1256 * Merge branch 'master' into ML-1256 * Merge branch 'master' into ML-1256 * feat: [ML-1256]: Fix format of tabledata and prompt json * feat: [ML-1256]: add some consts and comments * feat: [ML-1256]: ai review fixes * feat: [ML-1256]: Remove extra param * feat: [ML-1256]: Refactor from review * feat: [ML-1256]: fix from ai review * feat: [ML-1256]: Add priority order and improve DTOs * feat: [ML-1256]: Add priority order and improve DTOs * feat: [ML-1256]: Add Continue option to base component * feat: [ML-1256]:fix code smells * feat: [ML-1256]: fix error handling and param management * feat: [ML-1256]: fix from rebase * feat: [ML-1256]: rebase * feat: [ML-1256]: Add better error handling * Merge branch 'master' into ML-1256 * feat: [ML-1256]: Fix from review * feat: [ML-1256]: Add terminate and fix formatting * feat: [ML-1256]: Remove extra resource * feat: [ML-1256]: Add support for custom ui from mcp
1 parent 476253f commit 2fde982

File tree

9 files changed

+409
-356
lines changed

9 files changed

+409
-356
lines changed

pkg/harness/event/builder.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

pkg/harness/event/common/builder.go

Lines changed: 0 additions & 164 deletions
This file was deleted.

pkg/harness/event/event.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package event
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"github.com/mark3labs/mcp-go/mcp"
8+
)
9+
10+
const (
11+
CustomEventURI = "harness:custom-event"
12+
CustomEventMIMEType = "application/vnd.harness.custom-event+json"
13+
)
14+
15+
// CustomEvent represents a custom event sent back to a client as embedded resource
16+
type CustomEvent struct {
17+
Type string `json:"type"`
18+
Continue bool `json:"continue,omitempty"` // wether the agent should continue or stop processing
19+
DisplayOrder int `json:"display_order,omitempty"` // default will be the order that the items are added
20+
Content any `json:"content,omitempty"`
21+
}
22+
23+
// CustomEventOption configures a CustomEvent
24+
type CustomEventOption func(*CustomEvent)
25+
26+
// NewCustomEvent creates a new custom event with provided type and content
27+
func NewCustomEvent(eventType string, content any, opts ...CustomEventOption) CustomEvent {
28+
ce := CustomEvent{
29+
Type: eventType,
30+
Content: content,
31+
Continue: true,
32+
}
33+
for _, opt := range opts {
34+
opt(&ce)
35+
}
36+
return ce
37+
}
38+
39+
// WithContinue sets whether the event allows continuation
40+
func WithContinue(continueFlag bool) CustomEventOption {
41+
return func(ce *CustomEvent) {
42+
ce.Continue = continueFlag
43+
}
44+
}
45+
46+
// WithDisplayOrder sets the display order for the event
47+
func WithDisplayOrder(order int) CustomEventOption {
48+
return func(ce *CustomEvent) {
49+
ce.DisplayOrder = order
50+
}
51+
}
52+
53+
// CreateResource creates a resource from this event
54+
func (e CustomEvent) CreateCustomResource() (*mcp.TextResourceContents, error) {
55+
jsonData, err := json.Marshal(e)
56+
if err != nil {
57+
return nil, fmt.Errorf("failed to marshal custom event: %w", err)
58+
}
59+
60+
return &mcp.TextResourceContents{
61+
URI: CustomEventURI,
62+
MIMEType: CustomEventMIMEType,
63+
Text: string(jsonData),
64+
}, nil
65+
}
66+
67+
// CreateEmbeddedResource creates an embedded resource from this event
68+
func (e CustomEvent) CreateEmbeddedResource() (mcp.Content, error) {
69+
resource, err := e.CreateCustomResource()
70+
if err != nil {
71+
return nil, err
72+
}
73+
return mcp.NewEmbeddedResource(resource), nil
74+
}

pkg/harness/event/response/utility.go

Lines changed: 0 additions & 74 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Package types provides specific event type implementations
2+
package types
3+
4+
import "github.com/harness/harness-mcp/pkg/harness/event"
5+
6+
const (
7+
ActionDisplayOrder = 100
8+
)
9+
10+
type ActionWrapper struct {
11+
Prompts []string `json:"prompts"`
12+
}
13+
14+
// NewActionEvent uses strings and makes simple selectable actions in the UI (always displayed last)
15+
func NewActionEvent(actions []string, opts ...event.CustomEventOption) event.CustomEvent {
16+
allOpts := append([]event.CustomEventOption{event.WithDisplayOrder(ActionDisplayOrder)}, opts...)
17+
wrapper := ActionWrapper{Prompts: actions}
18+
return event.NewCustomEvent("prompt", wrapper, allOpts...)
19+
}

0 commit comments

Comments
 (0)