Skip to content

feat: add committee & committee-member search/fetch tools (ARCH-329)#8

Merged
emsearcy merged 4 commits into
mainfrom
feat/arch-329-committee-tools
Mar 4, 2026
Merged

feat: add committee & committee-member search/fetch tools (ARCH-329)#8
emsearcy merged 4 commits into
mainfrom
feat/arch-329-committee-tools

Conversation

@emsearcy

@emsearcy emsearcy commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds committee and committee member search/fetch MCP tools using the lfx-v2-committee-service and lfx-v2-query-service Goa SDKs.

New Tools

  • search_committees — queries the query service with type=committee; supports optional name typeahead, project_uid filter (formatted as project:<uid> for the Parent field), and pagination.
  • get_committee — fetches CommitteeBase and CommitteeSettings; settings are omitted gracefully if the caller lacks permissions.
  • get_committee_member — fetches a single member by committee UID and member UID.
  • search_committee_members — queries the query service with type=committee_member and a committee_uid:<uid> tag filter (the tag format the committee service uses when indexing members); supports optional name typeahead and pagination. committee_uid is required.

Changes

  • internal/tools/committee.go — new file with all four tools following the same config/registration pattern as project.go.
  • internal/lfxv2/client.go — adds Committee *committeeservice.Client to Clients and wires up the lfx-v2-committee-service v0.2.19 HTTP client.
  • cmd/lfx-mcp-server/main.go — calls SetCommitteeConfig alongside SetProjectConfig, registers all four tools, extends the default enabled tools list.
  • go.mod / go.sum — adds github.com/linuxfoundation/lfx-v2-committee-service v0.2.19.

Jira

ARCH-329

emsearcy added 3 commits March 4, 2026 11:36
Add three new MCP tools for committee operations:
- search_committees: queries the LFX query service with type=committee,
  supports name typeahead, optional project_uid filter, and pagination.
- get_committee: fetches CommitteeBase and CommitteeSettings (settings
  are omitted gracefully when the caller lacks permissions).
- get_committee_member: fetches a single committee member by committee
  UID and member UID.

Wire up lfx-v2-committee-service v0.2.19 HTTP client in lfxv2.Clients
alongside the existing project and query service clients. Committee
tools share the same CommitteeConfig/SetCommitteeConfig pattern as
project tools and reuse the token exchange client.

Default enabled tools list extended to include all five tools:
search_projects, get_project, search_committees, get_committee,
get_committee_member.

🤖 Generated with [GitHub Copilot](https://github.com/features/copilot) (via Zed)

Signed-off-by: Eric Searcy <eric@linuxfoundation.org>
Add search_committee_members MCP tool that queries the LFX query
service with type=committee_member and a committee_uid:<uid> tag filter.
Members are indexed with this tag by the committee service, so it is
the correct way to scope a member search to a specific committee.

Supports optional name typeahead and pagination. committee_uid is a
required parameter. Adds the tool to the default enabled list.

🤖 Generated with [GitHub Copilot](https://github.com/features/copilot) (via Zed)

Signed-off-by: Eric Searcy <eric@linuxfoundation.org>
The query service Parent parameter requires a typed reference in the
form "<type>:<id>" (validated by regexp ^[a-zA-Z]+:[a-zA-Z0-9_-]+$).
Passing a bare UUID causes a 400 BadRequest.

Also update the project_uid arg description to clarify it takes a
plain UID (the tool handles the prefix internally).

🤖 Generated with [GitHub Copilot](https://github.com/features/copilot) (via Zed)

Signed-off-by: Eric Searcy <eric@linuxfoundation.org>
Copilot AI review requested due to automatic review settings March 4, 2026 20:25
Comment thread go.mod
🤖 Generated with [GitHub Copilot](https://github.com/features/copilot) (via Zed)

Signed-off-by: Eric Searcy <eric@linuxfoundation.org>

Copilot AI left a comment

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.

Pull request overview

Adds MCP tools for discovering and fetching LFX committees and committee members, backed by the existing LFX v2 client infrastructure and new lfx-v2-committee-service SDK wiring.

Changes:

  • Introduces new committee-related MCP tools: search_committees, get_committee, get_committee_member, search_committee_members.
  • Extends the LFX v2 client wrapper to initialize a committee service client.
  • Updates server wiring to configure/register the new tools and enables them by default.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
internal/tools/committee.go Implements and registers the 4 new committee/committee-member MCP tools.
internal/lfxv2/client.go Adds Clients.Committee and wires up the committee-service HTTP client.
cmd/lfx-mcp-server/main.go Configures committee tools, registers them, and expands default enabled tools list.
go.mod Adds lfx-v2-committee-service dependency and makes query-service a direct dependency.
go.sum Updates module sums for added/updated dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if err != nil {
logger.Error("failed to create LFX v2 clients", "error", err)
return &mcp.CallToolResult{
Content: []mcp.Content{

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

lfxv2.ErrorMessage is referenced here, but there is no ErrorMessage helper defined in the internal/lfxv2 package in this repo (only client.go and token_exchange.go). This will not compile unless the helper is added or these calls are replaced (e.g., with err.Error() or another existing formatter).

Suggested change
Content: []mcp.Content{
&mcp.TextContent{Text: fmt.Sprintf("Error: failed to connect to LFX API: %s", err.Error())},

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +149

pageSize := args.PageSize
if pageSize <= 0 {
pageSize = 10
}

resourceType := committeeResourceType
payload := &querysvc.QueryResourcesPayload{
Version: "1",
Type: &resourceType,
PageSize: pageSize,

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

The page_size schema says "max 100", but the implementation only defaults when <= 0 and does not clamp values above 100. This can lead to unexpected API errors or overly large responses; consider capping pageSize to 100 (or returning a validation error) when the caller provides a larger value.

Copilot uses AI. Check for mistakes.
Comment on lines +276 to +285

// Settings may be unavailable due to insufficient permissions; treat that
// as a partial result rather than a hard failure so callers still get the
// base data they are authorised to see.
var committeeSettings *committeeservice.CommitteeSettingsWithReadonlyAttributes
settingsResult, err := clients.Committee.GetCommitteeSettings(ctx, &committeeservice.GetCommitteeSettingsPayload{
UID: &args.UID,
})
if err != nil {
logger.Warn("getting privileged committee settings failed, returning base only", "error", lfxv2.ErrorMessage(err), "uid", args.UID)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This treats any error from GetCommitteeSettings as a permissions issue and returns base-only results, which can hide real failures (timeouts, 5xx, misconfig) and also diverges from the intent described in the comment/PR text. Consider only suppressing known authz errors (e.g., 401/403) and returning an error (or including a settings error field) for other failures.

Copilot uses AI. Check for mistakes.
Comment on lines +467 to +481

pageSize := args.PageSize
if pageSize <= 0 {
pageSize = 10
}

resourceType := committeeMemberResourceType
// Members are tagged with committee_uid:<uid> by the committee service indexer.
committeeTag := fmt.Sprintf("committee_uid:%s", args.CommitteeUID)
payload := &querysvc.QueryResourcesPayload{
Version: "1",
Type: &resourceType,
Tags: []string{committeeTag},
PageSize: pageSize,
Sort: "name_asc",

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

Same as search_committees: the page_size schema advertises a max of 100, but values above 100 are currently passed through unmodified. Consider clamping or validating pageSize before calling the query service.

Copilot uses AI. Check for mistakes.
@emsearcy emsearcy merged commit 4427f0f into main Mar 4, 2026
3 checks passed
@emsearcy emsearcy deleted the feat/arch-329-committee-tools branch March 4, 2026 20:30
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