Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ Toolset Name: `fme`

- `list_fme_workspaces`: List all FME workspaces
- `list_fme_environments`: List environments for a specific workspace
- `list_fme_feature_flags`: List feature flags for a specific workspace
- `list_fme_feature_flags`: List feature flags for a specific workspace (supports pagination via `offset` and `count`; default count: 20, max count: 50)
- `get_fme_feature_flag_definition`: Get the definition of a specific feature flag in an environment

#### SEI Toolset
Expand Down
13 changes: 10 additions & 3 deletions common/client/fme.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"context"
"fmt"
"strconv"

"github.com/harness/mcp-server/common/client/dto"
)
Expand Down Expand Up @@ -39,13 +40,19 @@ func (f *FMEService) ListEnvironments(ctx context.Context, wsID string) (*dto.FM
return &response, nil
}

// ListFeatureFlags retrieves all feature flags for a specific workspace
// ListFeatureFlags retrieves feature flags for a specific workspace with pagination support.
// GET https://api.split.io/internal/api/v2/splits/ws/{wsId}
func (f *FMEService) ListFeatureFlags(ctx context.Context, wsID string) (*dto.FMEFeatureFlagsResponse, error) {
// offset specifies the number of items to skip; limit controls how many items to return (max 100).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment says max 100, but it looks like a max of 50 is actually used

func (f *FMEService) ListFeatureFlags(ctx context.Context, wsID string, offset, limit int) (*dto.FMEFeatureFlagsResponse, error) {
var response dto.FMEFeatureFlagsResponse

params := map[string]string{
"offset": strconv.Itoa(offset),
"limit": strconv.Itoa(limit),
}

path := fmt.Sprintf("internal/api/v2/splits/ws/%s", wsID)
err := f.Client.Get(ctx, path, nil, nil, &response)
err := f.Client.Get(ctx, path, params, nil, &response)
if err != nil {
return nil, fmt.Errorf("failed to list feature flags: %w", err)
}
Expand Down
26 changes: 25 additions & 1 deletion common/pkg/tools/fme.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func ListFMEEnvironmentsTool(config *config.McpServerConfig, fmeService *client.
}
}

const (
fmeFeatureFlagsDefaultCount = 20
fmeFeatureFlagsMaxCount = 50
)

// ListFMEFeatureFlagsTool creates a tool for listing FME feature flags for a specific workspace
func ListFMEFeatureFlagsTool(config *config.McpServerConfig, fmeService *client.FMEService) (mcp.Tool, server.ToolHandlerFunc) {
return mcp.NewTool("list_fme_feature_flags",
Expand All @@ -68,14 +73,33 @@ func ListFMEFeatureFlagsTool(config *config.McpServerConfig, fmeService *client.
mcp.Required(),
mcp.Description("The workspace ID to list feature flags for"),
),
mcp.WithNumber("offset",
mcp.Description("The number of feature flags to skip for pagination (default: 0)"),
),
mcp.WithNumber("count",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We could use "limit" to keep naming consistent with the API

mcp.Description(fmt.Sprintf("The number of feature flags to return (default: %d, max: %d)", fmeFeatureFlagsDefaultCount, fmeFeatureFlagsMaxCount)),
),
),
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
wsID, err := RequiredParam[string](request, "ws_id")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}

featureFlags, err := fmeService.ListFeatureFlags(ctx, wsID)
offset, err := OptionalIntParam(request, "offset")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: check for offset < 0

if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}

count, err := OptionalIntParamWithDefault(request, "count", fmeFeatureFlagsDefaultCount)
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
if count > fmeFeatureFlagsMaxCount {
count = fmeFeatureFlagsMaxCount
}

featureFlags, err := fmeService.ListFeatureFlags(ctx, wsID, offset, count)
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("failed to list FME feature flags: %v", err)), nil
}
Expand Down