chore: add /sdk-proxy slash command for hitting the API via the SDK app proxy#1991
Open
serikjensen wants to merge 3 commits into
Open
chore: add /sdk-proxy slash command for hitting the API via the SDK app proxy#1991serikjensen wants to merge 3 commits into
serikjensen wants to merge 3 commits into
Conversation
…pp proxy
Drops in a Claude/Cursor slash command at .claude/commands/sdk-proxy.md that
lets the agent run real curl requests against the demo company you already
have running in the SDK Dev App, without re-provisioning or reading the env
file directly.
The command teaches the agent to:
- Discover the SDK app's port robustly via lsof + cwd match (works across
auto-incremented ports 5200/5201/... and multiple sibling-repo SDK apps
running in parallel)
- Route curl through the running Vite proxy at http://localhost:<port>/api
so the in-memory FLOW_TOKEN is always the source of truth (the on-disk
env file lags when "Set Manual Token" or "Refresh Token" is used in the
Settings panel)
- Discover the live company UUID by hitting /v1/companies, never by
reading sdk-app/env/.env.demo (which can be stale)
- Look up endpoints via the gusto-payroll MCP (find_endpoint /
generate_curl / check_scopes / validate_workflow) instead of guessing
paths from memory
- Use a temp-file pattern (curl -o ... -w "HTTP %{http_code}" && jq < ...)
so status code and JSON body never collide in jq's parse stream
- Cache the discovered port + company UUID in $TMPDIR with a 120s TTL and
a single verify probe, so repeat invocations skip discovery entirely
Includes author notes on two subtle footguns: (1) Cursor's slash-command
renderer interpolates dollar-digit tokens as positional args from the
user's invocation, so awk positional fields cannot be used here -- the
discovery snippet uses lsof -F field records + grep/sed instead; (2) the
cache hygiene relies on unset-before-source plus rm+unset on every
failure path to prevent stale shell state from leaking into rediscovery.
No source code changes; only the new .claude/commands/sdk-proxy.md file.
Co-authored-by: Cursor <cursoragent@cursor.com>
…prompt install
The previous draft of this command referenced the `gusto-payroll` MCP at
the internal staging URL (gusto-partner-api.staging.zp-int.com), which
isn't installable by partners or by anyone outside Gusto's network. The
Embedded Dev Assistant MCP is the documented, public, partner-facing
equivalent -- this commit migrates the command to point at it and adds a
project-level config so teammates get auto-prompted to install on first
workspace open.
Changes:
- Add `.cursor/mcp.json` at the repo root with the public
`embedded-payroll` entry from docs.gusto.com. Cursor auto-detects
project-level MCP configs and prompts the user to enable them, so
teammates opening the workspace see a one-click install instead of
hitting "MCP not loaded" errors when they run /sdk-proxy.
- Rename all MCP references in .claude/commands/sdk-proxy.md from
`gusto-payroll` -> `embedded-payroll` to match the docs canonical
server name.
- Replace Step 3's hardcoded tool-name table (find_endpoint /
generate_curl / check_scopes / validate_workflow / generate_typescript)
with a capability-keyed one. The public MCP's docs describe its
surface as "API reference access, documentation search, code/snippet
generation" without naming individual tools, and tool names are
subject to change as the MCP evolves. Describing what we need by
capability lets the agent introspect the live tool surface and pick
the right one, rather than failing on a renamed tool.
- Add a Prerequisites section at the top of the command linking the
official Dev Assistant MCP docs, with the canonical install snippet
and a verification step ("ask the agent what MCP tools it has").
- Update the worked example and the discovery-only escape hatch to
match the new capability-based phrasing.
Net effect: a partner who clones this repo, opens it in Cursor, and
clicks "Enable" on the prompt can run /sdk-proxy with no further setup.
Co-authored-by: Cursor <cursoragent@cursor.com>
On first install of the `embedded-payroll` MCP -- either via the project-level `.cursor/mcp.json` prompt or a manual edit to `~/.cursor/mcp.json` -- Cursor shows the server as enabled but doesn't actually load its tools until the user manually toggles it off and back on in settings. Before this commit, /sdk-proxy would simply bail with "MCP not loaded; see Prerequisites", leaving the user to guess what to do next. Two changes: - Add a "First-install gotcha" subsection to Prerequisites that names the toggle dance up front (Cmd+, -> Tools & MCP -> embedded-payroll -> off/on), with fallbacks for the older "MCP" / "Integrations" settings labels. This makes the workaround discoverable to anyone reading the docs ahead of time. - Replace Step 3's terse "stop and link the user to Prerequisites" with a verbatim user-facing message the agent should emit when it can't see embedded-payroll tools. The message branches on "never installed" vs "just installed", walks through the exact toggle steps, and asks the user to reply when done so the agent can retry the original request without needing them to re-issue /sdk-proxy. Net effect: a first-time user who hits the toggle bug gets a one-screen fix from the agent itself, instead of a docs link they have to dig through. Co-authored-by: Cursor <cursoragent@cursor.com>
mariechatfield
approved these changes
Jun 2, 2026
Contributor
mariechatfield
left a comment
There was a problem hiding this comment.
Ah this is so cool! loved using it to update some data live
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Claude/Cursor slash command at .claude/commands/sdk-proxy.md that lets the agent run real curl requests against whatever demo company you already have running in the SDK Dev App. No re-provisioning, no env-file reads, no port hardcoding.
Invocation pattern:
What the command teaches the agent
lsof -iTCP:5200-5299+cwd-match againstgit rev-parse --show-toplevel. Robust against auto-incremented ports (5201/5202/...) and multiple sibling-repo SDK apps running in parallel; verified with/sdk-app/api/validate-tokensignature endpoint as a fallback diagnostic.http://localhost:<port>/api/...), never the gws-flows host directly. The proxy's in-memoryFLOW_TOKENis the source of truth; the on-disk env file lags when "Set Manual Token" / "Refresh Token" is used in the Settings panel./v1/companies, never by readingsdk-app/env/.env.demo.gusto-payrollMCP (find_endpoint/generate_curl/check_scopes/validate_workflow) instead of guessing paths from memory.curl -o $OUT -w "HTTP %{http_code}" && jq < $OUT) so the status code and JSON body never collide in jq's parse stream.$TMPDIR(120s TTL + single verify probe) so repeat invocations skip discovery entirely — first call ~1.2s, subsequent calls ~150ms.Two subtle footguns captured as inline author-notes
$0–$9) as positional args from the user's invocation, before the agent sees the prompt. Anawk '{print $2}'literal becomesawk '{print <second word of user message>}'. The discovery snippet useslsof -Ffield records +grep/sedinstead ofawkpositional fields, and a verified-grep guard keeps it that way.unset→source→<rm + unset>on every failure path. Without the pre-sourceunset, a missing key in a partial cache file inherits prior shell state. Without the post-failureunset, a staleCOMPANY_IDlingers in the shell environment and silently leaks into rediscovery in Step 1.Files touched
Just one new file:
.claude/commands/sdk-proxy.md(+262 lines)No source code changes. Cache file lives in
$TMPDIR, outside the repo — no.gitignoreupdate needed.Test plan
SDK_APP_PORT=5200against this repo's running SDK app (verified end-to-end during development).HTTP 200(verified).CACHE_HIT/ file / unset state.curl -o $OUT -w "HTTP %{http_code}" && jq < $OUTpattern produces clean output (nojq: parse errornoise).\$<digit>matches remain in the file (verified-grep guard)./sdk-proxy list employees for the current companyagainst a running SDK app to confirm the end-to-end flow works in your environment.Screen.Recording.2026-06-02.at.4.05.51.PM.mov
Made with Cursor