Access via AI Agents
AI coding agents running on your local machine, such as Claude Code, OpenCode, and Codex CLI, can execute remote commands over SSH. If they connect directly to login.ncshare.org, those commands run on the shared login node.
As with Access via VS Code, an SSH host alias backed by the auto-provisioning proxy directs those commands to a Slurm compute node instead.
Prerequisites
- An NCShare account with SSH key access already configured. See Access via SSH if you haven't set this up yet.
- A coding agent installed locally, e.g., OpenCode, Codex CLI, or Claude Code.
Step 1: Add a Dedicated SSH Host for Agent Sessions
Create a local SSH control-socket directory once,
mkdir -p ~/.ssh/sockets
Then add a Host block to ~/.ssh/config, using its own --name agent and a longer idle timeout than the interactive VS Code profiles. Replace NCSHARE_UID with your NCShare UID.
Host ncshare-agent
User NCSHARE_UID
ProxyCommand ssh -o ConnectTimeout=300 NCSHARE_UID@login.ncshare.org 'bash /usr/local/bin/ncshare-ssh-proxy.sh --name agent --partition common --idle-min 30'
ConnectTimeout 300
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
ServerAliveInterval 30
ControlMaster auto
ControlPersist 30m
ControlPath ~/.ssh/sockets/%r@%h-%p
If your agent requires GPU access, add a second alias,
Host ncshare-agent-gpu
User NCSHARE_UID
ProxyCommand ssh -o ConnectTimeout=300 NCSHARE_UID@login.ncshare.org 'bash /usr/local/bin/ncshare-ssh-proxy.sh --name agent-gpu --partition gpu --gres gpu:h200:1 --idle-min 30'
ConnectTimeout 300
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
ServerAliveInterval 30
ControlMaster auto
ControlPersist 30m
ControlPath ~/.ssh/sockets/%r@%h-%p
Step 2: Point your Agent at the Alias
All remote commands issued by the agent must target ncshare-agent or ncshare-agent-gpu, not login.ncshare.org. For example,
ssh ncshare-agent 'hostname'
and for a GPU command,
ssh ncshare-agent-gpu 'hostname && nvidia-smi'
Tell the agent to use these aliases through its project-level instruction file, as described below.
Add an Agent Instruction File
Many coding agents support a project-level instruction file such as AGENTS.md. Add the following content to the file in your project root.
# Remote Execution Policy: NCShare
- Never run commands directly on `login.ncshare.org`. It is a shared login node, not meant for computation.
- For any command that needs to run on NCShare, use:
ssh ncshare-agent '<command>'
- For any command that needs to run on NCShare that requires GPUs, use:
ssh ncshare-agent-gpu '<command>'
This transparently provisions (or reuses) a Slurm compute job and proxies the connection to it -- you don't need to run `sbatch`/`salloc`/`srun` yourself.
- The first command after a period of inactivity may take several minutes while a new job is provisioned. This is expected; do not treat it as a failure.
- Do not run `scancel` on these jobs unless explicitly asked to. An idle watchdog ends the job automatically once nobody has run a command through `ncshare-agent` or `ncshare-agent-gpu` for a while.
Tool-specific filenames
The filename of the agent instruction file varies by tool. For example, Claude Code uses CLAUDE.md instead of AGENTS.md. Consult your agent's documentation and use the filename it expects.
Customizing the Agent Profile
Set these options as flags in the ProxyCommand in ~/.ssh/config.
| Flag | Default | Meaning |
|---|---|---|
--partition |
common |
Slurm partition(s) to submit to (comma-separated list) |
--account |
(none) | Slurm account, if required by your partition |
--qos |
(none) | Slurm QoS, if required |
--gres |
none |
GPU request, e.g. gpu:1, gpu:h200:1; none = CPU-only |
--cpus |
4 |
CPUs to allocate |
--mem |
16G |
Memory to allocate |
--time |
8:00:00 |
Hard wall-time cap on the job |
--idle-min |
15 |
Minutes of no connection before idle cleanup (0 disables idle cleanup); use 30 for agentic workflows |
--wait |
240 |
Seconds to wait for a new job to start |
--name |
vscode |
Use agent or agent-gpu to keep agentic workflows separate from other sessions |
--log |
/dev/null |
Where to send Slurm job stdout/stderr (set a path to debug) |
For example, add --mem 128G to the GPU profile's ProxyCommand to request 128 GB of memory.
--idle-min 0 disables idle-based cleanup
Setting --idle-min 0 prevents the watchdog from ending an idle job. The allocation remains active until you cancel it or it reaches the --time wall-time limit (8 hours by default).
Ending Sessions
After the shared SSH connection closes, the watchdog ends the job when its heartbeat has been stale for --idle-min minutes. With the configuration above, ControlPersist keeps that connection open for 30 minutes after the last command. You don't need to run scancel manually in normal use.
How it Works
Without this configuration, an agent that sends commands to login.ncshare.org runs them on the shared login node. Login nodes are intended for file management, job submission, and other lightweight tasks; computational workloads should run on compute nodes.
The required scripts, ncshare-ssh-proxy.sh and ncshare-session-watchdog.sh, are installed centrally in /usr/local/bin. When an agent connects through ncshare-agent or ncshare-agent-gpu,
- SSH connects to the login node and runs
ncshare-ssh-proxy.shthrough the configuredProxyCommand. - The proxy reuses a running Slurm job for that profile or submits a new job and waits for its allocation.
- The proxy carries the SSH connection to port 22 on the allocated compute node.
- Commands sent through the alias therefore execute on the compute node rather than the login node.
The Slurm job runs ncshare-session-watchdog.sh. While the proxy connection remains open, the proxy updates a heartbeat file. After the connection closes and the heartbeat becomes stale, the watchdog ends the job after the configured --idle-min period. Setting --idle-min 0 disables idle-based cleanup. The job then runs until it is cancelled or reaches its wall-time limit.
Reusing SSH Connections
Agents commonly start a new ssh process for each remote command. The following options let those processes share one underlying SSH connection,
ControlMaster autoreuses an existing shared connection when one is available. The first connection creates it and later connections to the same host alias use it instead of reconnecting.ControlPersist 30mkeeps the shared connection open in the background for 30 minutes after the last command finishes.ControlPath ~/.ssh/sockets/%r@%h-%pspecifies the local socket used to find the shared connection.%r,%h, and%pexpand to the remote username, host, and port, keeping connections for different aliases separate.
The first command must authenticate, run the proxy, and possibly wait for a Slurm allocation. Commands issued while the shared connection remains open reuse it immediately and do not rerun the proxy.
Connection persistence and idle cleanup
ControlPersist keeps the proxy connection and its heartbeat active. The --idle-min countdown effectively begins after the shared connection closes. With ControlPersist 30m and --idle-min 30, the allocation may remain active for approximately 60 minutes after the last command. Use a shorter ControlPersist value if faster cleanup is more important than connection reuse.
Troubleshooting
Every command seems to re-provision a new job
Check that each command uses the same host alias and --name, and that the gap between commands does not exceed the combined connection-persistence and idle periods. ControlMaster improves connection speed, but the proxy can still reuse a running Slurm job without it.
How do I confirm the agent isn't running on the login node?
Ask the agent to run ssh ncshare-agent hostname. It should print a compute node name (e.g., compute-11), never a login node name.
Acknowledgements
This guide was adapted from PSC's Launching Remote IDEs on Bridges-2 Compute Nodes documentation and was enhanced with the help of Joe Shamblin at Duke University.