Skip to content

feat: add hspt, sfdc, and cr tools; fix gro cask; add CI#7

Open
piekstra wants to merge 1 commit into
mainfrom
feat/new-clis-and-ci
Open

feat: add hspt, sfdc, and cr tools; fix gro cask; add CI#7
piekstra wants to merge 1 commit into
mainfrom
feat/new-clis-and-ci

Conversation

@piekstra

Copy link
Copy Markdown
Contributor

Summary

Brings the MCP server up to date with the current state of the collective:

  • New CLIs: adds hspt (hubspot-cli), sfdc (salesforce-cli), and cr (codereview-cli) to CLI_CONFIG, each with a generic *_cli(args) MCP tool, plus a salesforce_query(soql) convenience wrapper. cr gets a 600s subprocess timeout since live reviews run an LLM loop.
  • Bug fix: gro's cask was configured as open-cli-collective/tap/gro, but the tap has no gro cask — it's google-readonly. install_missing_tools / update_tools / status checks for gro were broken.
  • CI: adds the GitHub Actions workflow proposed in ci: Add GitHub Actions CI workflow #4 (pytest on Python 3.11–3.13). Closes ci: Add GitHub Actions CI workflow #4.
  • Docs: README and CLAUDE.md tool tables synced (CLAUDE.md listed the New Relic binary as newrelic-cli; it's nrq), brew install commands normalized to --cask, and a note that cpm is deliberately excluded because it's an interactive TUI.

Not included

  • cpm — interactive TUI, can't run as a non-interactive MCP subprocess.

Known issue elsewhere

The hubspot-cli cask in the tap is currently broken: its .goreleaser.yml homebrew_casks entry omits binary: hspt, so the generated cask declares binary "hubspot-cli" while the tarball ships hspt. Filing separately against hubspot-cli.

Testing

pytest test_server.py — 10 passed (includes new shlex coverage for the three new tools and the salesforce_query wrapper).

- Add hubspot-cli (hspt), salesforce-cli (sfdc), and codereview-cli (cr)
  to CLI_CONFIG with generic MCP tools and a salesforce_query wrapper
- Fix gro cask name: the tap has no 'gro' cask; it is 'google-readonly',
  so install/update tooling for gro was broken
- Add GitHub Actions CI workflow running pytest on Python 3.11-3.13
  (closes #4)
- Sync README and CLAUDE.md tool tables; normalize brew install
  commands; note cpm is excluded as an interactive TUI
@piekstra
piekstra requested a review from piekstra-dev July 15, 2026 17:31
@piekstra-dev

Copy link
Copy Markdown

⏱️ Automated review timed out after 15 minutes, so no review was posted.

Ways to get this PR reviewed:

  • Add the cr:large label and re-request the review — it routes to a larger model tier with a longer time budget.
  • Split this PR into smaller, focused PRs — large diffs are the usual cause of review timeouts.
  • Re-request the review to retry as-is (occasionally a run is just unlucky).

@piekstra-dev piekstra-dev left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: 3ebf6aa2f834
Profile: reviewer - Posting as: piekstra-dev

Summary

Reviewer Findings
mcp:cli-wrapper-safety 1
automation:ci-release 0
documentation:docs 0
mcp:cli-wrapper-safety (1 finding)

Minor - server.py:420

salesforce_query builds its args via f'query "{soql}" --output json' and then re-parses that string with shlex.split inside salesforce_cli. If the SOQL text contains a double quote (e.g. a string literal like WHERE Name = 'O"Brien' or a caller-supplied value with embedded quotes), shlex.split will mis-tokenize the string, either raising a ValueError or, worse, splitting the query into extra shell-style tokens that get passed as separate argv entries to the sfdc binary — letting query content smuggle in additional CLI flags. This mirrors the pre-existing gmail_search/drive_search/slack_search_messages pattern, but it's the new instance introduced by this PR, so it's a good point to fix instead of propagate. Prefer building the argv list directly (e.g. [config["path"], "query", soql, "--output", "json"]) or shlex.quote the interpolated value before handing it back through shlex.split.

Reviewer Coverage

Reviewer Status Inspected Skipped Constraints
mcp:cli-wrapper-safety complete_broad CLAUDE.md, README.md, server.py, test_server.py unavailable unavailable
automation:ci-release complete_broad .github/workflows/ci.yml unavailable unavailable
documentation:docs complete_broad CLAUDE.md, README.md unavailable unavailable

0 PR discussion threads considered. 0 summarized; 0 resolved.


Completed in 52s | unavailable | claude-sonnet-5 | cr 0.10.257
Field Value
Model claude-sonnet-5
Reviewers mcp:cli-wrapper-safety, automation:ci-release, documentation:docs
Engine claude_cli · claude-sonnet-5
Reviewed by cr · piekstra-dev
Duration 52s wall · 1m 54s compute
Cost unavailable
Tokens 38 in / 6.7k out

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost Duration
orchestrator-selection claude-sonnet-5 6 1.5k 30.4k 18.9k unavailable 20s
mcp:cli-wrapper-safety claude-sonnet-5 10 2.3k 107.0k 64.0k unavailable 35s
automation:ci-release claude-sonnet-5 10 1.2k 94.2k 22.5k unavailable 19s
documentation:docs claude-sonnet-5 8 1.3k 71.9k 25.9k unavailable 26s
orchestrator-rollup claude-sonnet-5 4 366 12.7k 27.7k unavailable 13s

Comment thread server.py
@mcp.tool()
def salesforce_query(soql: str) -> str:
"""Run a SOQL query against Salesforce (e.g., "SELECT Id, Name FROM Account LIMIT 10")."""
return salesforce_cli(f'query "{soql}" --output json')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

salesforce_query builds its args via f'query "{soql}" --output json' and then re-parses that string with shlex.split inside salesforce_cli. If the SOQL text contains a double quote (e.g. a string literal like WHERE Name = 'O"Brien' or a caller-supplied value with embedded quotes), shlex.split will mis-tokenize the string, either raising a ValueError or, worse, splitting the query into extra shell-style tokens that get passed as separate argv entries to the sfdc binary — letting query content smuggle in additional CLI flags. This mirrors the pre-existing gmail_search/drive_search/slack_search_messages pattern, but it's the new instance introduced by this PR, so it's a good point to fix instead of propagate. Prefer building the argv list directly (e.g. [config["path"], "query", soql, "--output", "json"]) or shlex.quote the interpolated value before handing it back through shlex.split.

Reply inline to this comment.

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.

ci: Add GitHub Actions CI workflow

2 participants