Claude Code
The setup most people want, because the agent is already in the repository where the app lives. One command connects it, and a line in your .env means every session in that repo works on the right app without being told.
Add the server
claude mcp add --env HELMDESK_API_KEY=sk_live_your_key_here --transport stdio helmdesk -- npx -y @helmdesk/mcpWhy --transport stdio is in there
It is the default transport, so it looks redundant — but --env takes repeated KEY=value pairs, and if the server name comes straight after an --env the CLI reads helmdesk as another pair and rejects the command. Any other option between the two fixes it. This one is the least surprising.
Add more variables the same way, each with its own flag:
claude mcp add \
--env HELMDESK_API_KEY=sk_live_your_key_here \
--env HELMDESK_PROJECT=ledgerly \
--env HELMDESK_ENVIRONMENT=sandbox \
--transport stdio helmdesk -- npx -y @helmdesk/mcpHELMDESK_ENVIRONMENT takes live or sandboxand nothing else — anything unrecognised is ignored and the key's own plane wins. Starting on sandbox is a good idea for the first few days.
Pick a scope
Pass --scope to decide who gets the server and where the config is written.
| Scope | Written to | Use it when |
|---|---|---|
| local | ~/.claude.json | The default. Just you, just this repository. Fine for a personal key. |
| user | ~/.claude.json | Just you, every repository. Right for an all-projects key you use across all your apps. |
| project | .mcp.json | Everyone who clones the repo. Convenient for a team — but the file is committed, so do not put a raw key in it. |
Do not commit a key
--scope project writes .mcp.json into the repository. If you use it, reference the variable rather than the secret and let each developer supply their own:
{
"mcpServers": {
"helmdesk": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@helmdesk/mcp"],
"env": {
"HELMDESK_API_KEY": "${HELMDESK_API_KEY}",
"HELMDESK_PROJECT": "ledgerly"
}
}
}
}The project slug is not a secret, so pinning it here is exactly right: everyone who clones the repo gets an agent already pointed at the correct app.
Check it connected
claude mcp list # every server and whether it connected
claude mcp get helmdesk # this server's command, env, and any error
claude mcp remove helmdeskInside a session, /mcp opens a panel showing connection status and the tools each server exposes. Helmdesk should report 73 tools. The panel also shows the server's own instructions, which is where the project-selection rules and the "never guess before emailing a customer" policy come from.
Let reads run, make sends ask
This is the setting that makes the whole thing pleasant. Reading your support queue should never interrupt you; emailing a customer always should. Claude Code matches MCP tools as mcp__<server>__<tool>, and allow rules accept a glob after the server prefix — so the naming convention does the work:
{
"permissions": {
"allow": [
"mcp__helmdesk__list_*",
"mcp__helmdesk__get_*",
"mcp__helmdesk__search_*",
"mcp__helmdesk__query_*",
"mcp__helmdesk__preview_*"
],
"ask": [
"mcp__helmdesk__reply_to_ticket",
"mcp__helmdesk__send_email",
"mcp__helmdesk__send_email_batch",
"mcp__helmdesk__send_custom_email",
"mcp__helmdesk__resend_email",
"mcp__helmdesk__reply_to_feedback",
"mcp__helmdesk__request_feedback",
"mcp__helmdesk__approve_agent_item",
"mcp__helmdesk__update_ticket",
"mcp__helmdesk__bulk_update_tickets"
]
}
}The five allow patterns cover every read-only tool, because the catalog is named consistently. The ask list is the ten tools that reach a real person — including update_ticket and bulk_update_tickets, which email a satisfaction survey when they resolve something, and approve_agent_item, where approving a drafted reply is what sends it.
To take them off the table entirely rather than prompt, put the same names under deny. Stronger still, issue a key without emails:send — settings are a convenience, scopes are enforcement. See Safety & approvals.
Pin the project per repository
If you run several apps on one account, put the slug in the repo rather than in your global config:
HELMDESK_PROJECT=ledgerlyNow the agent works on Ledgerly in the Ledgerly repo and on Nightjar in the Nightjar repo, with one user-scoped key and nothing to remember. Without a default, an all-projects key makes the API refuse and list your projects rather than guess — safe, but you will be answering that question a lot.
A first session
> What needs my attention in Helmdesk today?
> Read ticket 41 and tell me whether we have an article that answers it.
> Draft a reply to it citing that article. Do not send it — show me first.The third one is worth noticing: there is no "draft" tool. The agent writes the reply into the conversation for you to read, and only calls reply_to_ticket when you say go. Asking to see things first is a habit worth keeping. More in the prompt cookbook.