Skip to content

Add tags and team membership to users tool, bump SDK to v2026.5.6#113

Open
saditya370 wants to merge 1 commit intomainfrom
feat/users-tool-tags-teams
Open

Add tags and team membership to users tool, bump SDK to v2026.5.6#113
saditya370 wants to merge 1 commit intomainfrom
feat/users-tool-tags-teams

Conversation

@saditya370
Copy link
Copy Markdown
Contributor

Summary

The users MCP tool returned name, email, contacts, and role but omitted tags and team memberships — both populated in OpsLevel and required for incident-routing and on-call queries (OLX use case: "which users are tagged as on-call leads?", "which team does this user belong to?"). This PR wires the now-available User.Tags and User.TeamsConnection fields (added in opslevel-go v2026.5.6) into the tool response, and bumps the SDK from v2025 to v2026.

Changes

src/cmd/root.go

Users tool (the actual feature)

  • New serializedUser and serializedTeamRef types — keeps the JSON output tight: tags as []string of "key:value", teams as []{Id, Alias}.
  • users handler now maps client.ListUsers(...) results through serializedUser instead of returning raw SDK nodes. Tags and teams are pulled from node.Tags.Nodes and node.TeamsConnection.Nodes.
  • Tool description updated to mention tags and team memberships, with example questions ("which team does this user belong to?", "which users are tagged as on-call leads?") so the model picks the right tool.

v2026 bump fallout

  • Import path: github.com/opslevel/opslevel-go/v2025/v2026.
  • convertToServiceFilterInput updated for v2026's ServiceFilterInput shape change:
    • Key is now *ServiceFilterEnum (was PredicateKeyEnum value).
    • Type is now *TypeEnum (was PredicateTypeEnum value).
    • Predicates is now []ServiceFilterInput (was *[]ServiceFilterInput).
      Wire behavior of the components tool is unchanged.

src/cmd/client.go

  • Import path bump: v2025v2026.

src/go.mod / src/go.sum

  • Bumped github.com/opslevel/opslevel-go/v2025 v2025.7.28github.com/opslevel/opslevel-go/v2026 v2026.5.6.
  • Pulled in transitive bumps from go mod tidy: iso8601 v1.6.0v1.7.0, hasura/go-graphql-client v0.14.4v0.15.1, cobra v1.9.1v1.10.1, plus minor golang.org/x/* updates.

Test plan

  • go build ./... passes
  • go vet ./... clean
  • Smoke test: hit the users tool against a real account, verify tags and teams populate
  • Verify tool description renders cleanly in MCP clients (Claude Desktop, etc.)
  • Sanity-check components tool (filter conversion was rewritten for v2026's pointer-typed filter shape)

@saditya370 saditya370 self-assigned this May 6, 2026
@saditya370 saditya370 force-pushed the feat/users-tool-tags-teams branch 2 times, most recently from 1120b41 to 103ff7e Compare May 6, 2026 20:07
@saditya370 saditya370 requested a review from andrewstillv15 May 6, 2026 20:13
@saditya370 saditya370 force-pushed the feat/users-tool-tags-teams branch from 103ff7e to 6a3d0ea Compare May 6, 2026 20:21
Comment thread src/cmd/root.go Outdated
func convertToServiceFilterInput(filter componentFilter) (opslevel.ServiceFilterInput, error) {
// Handle simple filter
if filter.Key != "" && filter.Type != "" {
key := opslevel.ServiceFilterEnum(filter.Key)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this assignment necessary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

replaced the named-variable pattern with a small local ptr[T any](v T) *T helper for convertToServiceFilterInput. The SDK's RefOf returns *Nullable[T] which doesn't fit ServiceFilterInput's *ServiceFilterEnum/*TypeEnum/*ConnectiveEnum fields, so a custom helper was the cleanest way to keep the struct literals inline without the named vars

Comment thread src/cmd/root.go Outdated
mcp.NewTool(
"users",
mcp.WithDescription("Get all the user names, e-mail addresses and metadata for the OpsLevel account. Users are the people in OpsLevel. Only use this if you need to search all users."),
mcp.WithDescription("Get all users in the OpsLevel account along with their tags and team memberships. Users are the people in OpsLevel. Each user includes their tags (as 'key:value' strings) and the teams they belong to (id and alias), which is useful for answering questions like 'which team does this user belong to?' or 'which users are tagged as on-call leads?'. Only use this if you need to search all users."),
Copy link
Copy Markdown
Contributor

@andrewstillv15 andrewstillv15 May 7, 2026

Choose a reason for hiding this comment

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

Was this prompt tested/compared to any other prompts? I'm curious about how this would perform against something a little less verbose.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tried both versions in Claude Desktop with 6 test queries — 4 that should hit users and 2 that shouldn't. Both scored 6/6, so going with the shorter one to match the style of the other tool descriptions here.

Heads up: not a real benchmark — queries shared context within each run, so this is more of a sanity check than rigorous testing. If we care about prompt changes going forward, reviving mcp-eval/ or scripting against the API directly would be the way.

@saditya370 saditya370 force-pushed the feat/users-tool-tags-teams branch from 6a3d0ea to c22aebf Compare May 8, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants