Skip to content

Add the power discovery profile (catalog meta-tools) - #504

Merged
mocha06 merged 1 commit into
devfrom
rc-dev/feat/power-profile
Jul 28, 2026
Merged

Add the power discovery profile (catalog meta-tools)#504
mocha06 merged 1 commit into
devfrom
rc-dev/feat/power-profile

Conversation

@mocha06

@mocha06 mocha06 commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Motivation

Even a curated toolset can be too large for a client that eagerly loads every schema, and some MCP clients cannot defer tool loading at all. Those clients need a model-facing working set that stays small no matter how many tools exist — without losing reach to the rest.

Outcome

--toolsets power (alias architect) hides the curated tools behind four catalog meta-tools — get_tool_categories, search_tools, describe_tool, execute_tool — kept visible alongside the raw-GraphQL tools, so the model-facing set is nine tools regardless of catalog size. The model discovers tools by category or keyword and dispatches by name; execute_tool runs each hidden tool through its own argument validation and error envelope, exactly as a direct call would. The catalog is snapshotted after the remote floor, so execute_tool can never reach a tool the profile withholds. Power is a distinct branch from domain selection and, like it, runs after the floor. The meta-tools are profile-only, so they are not counted in PIPEFY_TOOL_NAMES and do not touch the partition drift-guard or the remote seed.

Part of #308. Completes the two client-independent discovery mechanisms; overlapping persona profiles follow in a later stacked PR.

Stacked on #502; CI fires once the stack merges down to dev.

Live validation (in-process MCP sessions → live API)

execute_tool dispatched through to the live Pipefy API and returned real data (test pipe 303088927):

Scenario Expected Verdict
--toolsets power surface 9 (4 meta + 5 raw-GraphQL)
search_tools("pipe") finds get_pipe (25 hits)
get_tool_categories 8 domain categories
execute_tool → live get_pipe real pipe "000 aqui" returned
execute_tool missing required arg INVALID_ARGUMENTS envelope
execute_tool unknown name TOOL_NOT_FOUND

@adriannoes adriannoes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The power profile lands cleanly as a distinct post-floor branch: nine visible tools, meta-tools outside PIPEFY_TOOL_NAMES, and execute_tool preserving INVALID_ARGUMENTS / TOOL_NOT_FOUND through PipefyValidationTool.run. Unit coverage for the surface and floor withhold path looks solid.

One startup contract needs a fix before merge. When wants_power wins, resolve_selection never runs, so PIPEFY_MCP_TOOLSETS=power,typo starts the server while workflow,typo still raises and --toolsets power,typo still fails in main. That is a fail-open hole relative to the env fail-closed path established for domain selection. Details on the inline.

Also noted (non-blocking):

  • execute_tool's broad except Exception soft-wraps unexpected ToolError raises into a code-less envelope. No catalog tool raises UrlElicitationRequiredError today, so this is polish rather than a live protocol break.
  • --toolsets help and the settings Field still read as domains-only after power/architect ship in docs/config.md. Worth aligning at the operator edge.
  • power (or architect) co-listed with a domain silently becomes full power. Intentional per AGENTS.md; a one-line warning in config.md or --help would help operators.

Comment on lines +84 to +87
if wants_power(toolsets):
registry.apply_power_profile()
else:
registry.apply_toolset_selection(toolsets)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When wants_power(toolsets) is true this branch calls apply_power_profile and never apply_toolset_selection, so resolve_selection never runs. A value like PIPEFY_MCP_TOOLSETS=power,typo therefore starts the server, while workflow,typo still raises and --toolsets power,typo still fails in main.py. That breaks the documented contract that a bad env toolsets value surfaces the same unknown-toolset error at server build.

On the prior stack slice that introduced domain selection, unknown env tokens still fail closed at build (ugly exit 1 vs flag exit 2, but the process does not start). The power short-circuit turns that into silent acceptance of the typo while applying full power.

I would validate tokens before the power/domain branch (for example always call resolve_selection(toolsets) for its ValueError, or fold power into one profile resolver that rejects unknown names first), then keep the existing power XOR domain behavior for valid specs.

Done when:

  • PIPEFY_MCP_TOOLSETS=power,typo (no CLI flag) fails at build with the unknown-toolset message
  • a regression test covers that path
  • power / architect alone still yield the nine-tool surface

@mocha06
mocha06 force-pushed the rc-dev/feat/toolset-selection branch from 255f803 to d46d07c Compare July 28, 2026 02:37
@mocha06
mocha06 force-pushed the rc-dev/feat/power-profile branch from f0af312 to 2ed1f2a Compare July 28, 2026 02:37
@adriannoes
adriannoes self-requested a review July 28, 2026 10:58
@mocha06
mocha06 force-pushed the rc-dev/feat/toolset-selection branch from d46d07c to edfcb82 Compare July 28, 2026 12:53
@mocha06
mocha06 force-pushed the rc-dev/feat/power-profile branch from 2ed1f2a to a44fe38 Compare July 28, 2026 12:53

@adriannoes adriannoes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks Roberto. The power,typo fail-closed path is in place now: resolve_selection runs before apply_power_profile, with a regression test on the build path, and the help/settings copy calls out power/architect.

The power profile itself still looks right: nine-tool surface, post-floor catalog snapshot, meta-tools outside PIPEFY_TOOL_NAMES, and execute_tool keeping the validation envelopes. Happy to approve on a44fe38.

Optional polish only (non-blocking): narrow execute_tool's broad except Exception for unexpected ToolError raises, and a one-line operator note that power co-listed with a domain still means full power.

Add --toolsets power (alias architect): hide the curated tools behind four catalog
meta-tools in tools/meta_tools.py — get_tool_categories, search_tools,
describe_tool, execute_tool — kept visible alongside the raw-GraphQL tools
(POWER_GRAPHQL_TOOLS), so the model-facing set is nine tools regardless of catalog
size. ToolRegistry.apply_power_profile snapshots the curated tools that survived
the floor, removes them from tools/list, and registers the meta-tools over that
snapshot; server.py routes to this branch via wants_power before the domain path.

execute_tool dispatches through each hidden tool's own PipefyValidationTool.run,
so argument validation and the error envelope apply exactly as a direct call.
Because the snapshot is taken after apply_remote_profile, execute_tool can never
reach a floor-withheld tool. The meta-tools are profile-only and not in
PIPEFY_TOOL_NAMES, so the partition drift-guard and remote seed are unaffected.

Part of #308.
@mocha06
mocha06 force-pushed the rc-dev/feat/power-profile branch from a44fe38 to f499ec4 Compare July 28, 2026 13:19
@mocha06

mocha06 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator Author

Applied both optional items on f499ec4:

  • Narrowed execute_tool. It's now a transparent pass-through — dropped the broad except Exception, so a genuine execution failure propagates as a protocol error (isError) exactly like a direct call, instead of being soft-wrapped into a {success: false} business envelope. Argument-validation errors still come back as the standard envelope (they're returned by PipefyValidationTool.run, not raised), so the existing meta-tool tests hold unchanged.
  • Power-wins operator note. Added to the PIPEFY_MCP_TOOLSETS row in docs/config.md: co-listing power/architect with a domain or profile applies the full power profile (power wins).

Thanks for the thorough pass.

adriannoes
adriannoes previously approved these changes Jul 28, 2026

@adriannoes adriannoes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-checked on f499ec4. Still good to merge.

The power,typo fail-closed path remains in place, and the latest push tightens two follow-ups: execute_tool now dispatches transparently (raises propagate like a direct call; validation envelopes still return from PipefyValidationTool), and docs/config.md spells out that co-listing power with a domain applies the full power profile.

Approving again on the current head.

Base automatically changed from rc-dev/feat/toolset-selection to dev July 28, 2026 13:38
@mocha06
mocha06 dismissed adriannoes’s stale review July 28, 2026 13:38

The base branch was changed.

@mocha06 mocha06 closed this Jul 28, 2026
@mocha06 mocha06 reopened this Jul 28, 2026
@adriannoes
adriannoes self-requested a review July 28, 2026 13:39

@adriannoes adriannoes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, little robert.

@mocha06
mocha06 merged commit fce55e8 into dev Jul 28, 2026
5 checks passed
@mocha06
mocha06 deleted the rc-dev/feat/power-profile branch July 28, 2026 13:42
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