{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/harper-blog/2026-01-06-remote-claude-code-programing-like-it-was-the-early-2000s/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "So so many friends have asked me how I use Claude Code from my phone. I am always a bit surprised, because a lot of this type of work I have been doing for nearly 25 years (or more!) and I always forget that it is partially a lost art. This is how it used to be. We didn’t have fancy IDEs, and fancy magic to deploy stuff. We had to ssh (hah. Telnet!) into a machine and work with it through the terminal. It ruled. It was a total nightmare. It was also a lot of fun.\n\n> One of my favorite parts of the early 2000s was hanging out in IRC channels and just participating in the most ridiculous community of tech workers. A very very fun time. #corporate on efnet!\n\nThere is a lot of nostalgia for that time period - but for the most part the tooling sucked. The new IDEs, and magic deploy systems have made it so that you do not have to deal with a terminal to get shit done. And then… Claude Code sashays into the room and fucks up the vibe.\n\nOr creates a new vibe? Who knows. Anyway. We are all using terminals now and it is hilarious and fun. So let’s vibe.\n\n![Thinking about terminals probably, Leica M11, 12/2025](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/IMG_5743_hu_dfd47be50faeabd5.jpeg)\\\nThinking about terminals probably, Leica M11, 12/2025\n\nThe conversation I have with people about Claude Code start normally, and almost without exception end with “I wish I could do this from my phone.”\n\nWell.. I am here to tell you that it is easy! And accessible!\n\n## The other (easier) way\n\nFirst things first - there are a couple really neat startups that are solving this in a very different way that I work. I think they are awesome. My favorite example of this is [superconductor](https://superconductor.dev) (great name!). They allow you to run and instantiate a bunch of agents (Claude Codex, Amp, Codex, etc) and interact with them remotely. They are also a really great team!\n\nAnother example is [happy coder](https://happy.engineering/). An open source magical app that connects to your Claude Code. It is theoretically pretty good, and I know some people who love it. I couldn’t get it to work reliably.\n\n## My way\n\nOne of my core values is: *I want to just ssh into shit*. That is kind of one of my general hobbies. Can I ssh into this thing? If yes, then I am happy. If no, then how can I make it so I can ssh into it.\n\nWhen it came to figuring out how to use Claude Code on my phone, the obvious answer was: **ssh into my computer from my phone, and run claude**. Turns out this is pretty straight forward.\n\nMy workstation:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal2.png)\n\nMy phone:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal3.png)\n\nLet’s break it down.\n\n*I use an iPhone, so I will be talking about iPhone apps. There are good android apps to do this too!*\n\nThere are maybe 4 things you need to solve for:\n\n- network\n- terminal client\n- workstation\n- tools\n\nAs a form of tldr, here are my personal answers:\n\n- network: [Tailscale](https://en.wikipedia.org/wiki/Tailscale)\n- client: [blink](https://blink.sh/)\n- workstation: Mac with constant power and fast internet\n- tools: [TMUX](https://en.wikipedia.org/wiki/Tmux), some magic scripts, and Claude Code\n\nLet’s break it down:\n\n### Network\n\nYou will need to access your workstation from anywhere. I use a Mac and linux boxes for this.\n\nLinux is easy: Just make sure openssh-server is installed. Test that you can ssh into it - and bam. Typically if you are using a box from a Claude provider, this is built into the program.\n\nMacs are a bit harder. You need to [enable ssh](https://support.apple.com/lt-lt/guide/mac-help/mchlp1066/mac), and then for extra credit you need to [enable screen sharing](https://support.apple.com/lt-lt/guide/mac-help/mh11848/mac). Once this is done you should theoretically be able to remotely connect to your computer.\n\nIt is very important you try to connect to it from another computer that is on the same network. Figure out your local IP (192.168.xxx.yyy), and then *ssh* to your local IP from another machine (or from the same machine). As long as you can connect to it - then the next step will be super easy. If you can’t connect to it, ask chatgpt wtf is going on.\n\nOnce you can reliably SSH into your machine, then it is time to get Tailscale working. There are a few alternatives (zero tier, etc) and I am sure they are good. Tailscale is friends, and they are awesome. Having used them since before they launched, I can promise that it is a life changer.\n\nInstall the Tailscale client on all your machines. Tailscale will magically create a network that only you have access to (or anyone else you add to your network). You can then access any of your machines from any of your machines.\n\nI.e. your phone can instantly connect to your workstation while you workstation is in Chicago, and your phone is in Tokyo. You don’t have to poke a hole in a firewall, do magical networking, or learn how to do magical networking. It just works. It is a beautiful product. There are is a deep bench of Tailscale features that you should check out eventually - but for today, just use it for networking.\n\nSince you were able to ssh into your machine before (I hope!) - now you can test it with your fancy new Tailscale ip address or magic name. And you can do that from any device that is on your Tailscale network. Like.. your phone!\n\nThis means network is solved!\n\n## The terminal client\n\nThis is where some personal preference comes in. You now need to pick a terminal client that you like to use, and feels good to use. Lots of my friends like [prompt](https://panic.com/prompt/), and [termius](https://termius.com/). Both are great choices.\n\nI personally really like [blink](https://blink.sh/). It is a bit nerdier, and when you open it, it just drops you into a shell. Immediately. No interface, no nonsense. Just a shell. It is a wild app. You can use their [blink build](https://docs.blink.sh/build/start) product to host a lil dev server for yourself!\n\n> I wanted to use their build product - but the default and unchangeable user was `root` and I cannot being myself to seriously use a product that drops you into a server as the root user. lol\n\nAnyway, blink is for me!\n\nAnd since you set up Tailscale, and ssh you can just type `ssh <dev-server-ip>` and it will magically connect.\n\n> you can use the `config` command in blink to set up keys, and hosts, etc. highly worthwhile.\n\nNow you are inside of your workstation! Now you can really rip some tokens!\n\n![I checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/L1004804_hu_209da4b88e42b7b8.jpeg)\\\nI checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026\n\n## Tools!\n\nYou could just navigate to the directory that your Claude project live, and run Claude. But then when you phone went to sleep or whatever - your ssh client may disconnect. And you would have to redo the connection, run Claude –continue, and live this life of lots of typing.\n\n**We don’t use AI tools to type more!**\n\nThere are three tools that are super helpful:\n\n- Keys/identity\n- Mosh\n- TMUX\n\n### Keys\n\nIf you are using SSH a lot you need to set up some SSH keys, and then push them around to all your servers. I am not going to tell you how to do that, since you should already have keys somewhere to integrate with source code repositories.\n\nIf you want to generate new, or have questions - the terminal clients may help you. My guess is that you already have some.\n\nCouple tips:\n\n- use a password to unlock your key!\n- use an ssh agent to make that process not horrible\n- on a Mac you can have your key be unlocked by your keychain (which is also where your Claude Code api key is!)\n\n### Mosh\n\n[Mosh](https://mosh.org/) is from a forgotten time (2012!) when the internet was slow, and connections were spotty. What mosh does is allow your “fragile” ssh connection to roam around with you. You use it just like ssh: `mosh <dev-server-ip>`. But now when you shut your laptop, or forget about your phone - the connection will pop back up when you surface it again. It allows the connection to survive a lot of the various environmental things that would normally derail a ssh connection.\n\nThis RULES.\n\nI was on a train the other day and totally lost internet while we were in a tunnel. Then we emerged and internet came back. My ssh (really mosh) session just paused for a moment, and then BAM! Was back and Claude was telling me it had deleted my entire workstation, and was going to the beach!\n\nThere are some gotchas about ssh-agent, keys and mosh that I won’t get into. If things are weird, just google it or as chatgpt.\n\n### TMUX\n\nTbh, I am a [screen](https://en.wikipedia.org/wiki/GNU_Screen) guy. But it is 2026 and [TMUX](https://en.wikipedia.org/wiki/TMUX) is a better choice.\n\nIt allows you to have a long running terminal process that you can reattach to. This is helpful even without a remote connection. It also acts as a multiplexer - allowing for multiple terminal sessions in a single terminal window.\n\nYou can have 7 Claude Codes running simultaneously and just tab through them as needed.\n\nTMUX is what a lot of the “Claude Code orchestration” hacks are built upon.You should [check them out](https://github.com/steveyegge/gastown). I haven’t yet found one that works how I want it - even know there are some good ones! I just want to use regular old TMUX, and a bunch of weird helpers.\n\nMy TMUX config is here: [harperreed/dotfiles/.TMUX.conf](https://github.com/harperreed/dotfiles/blob/master/.TMUX.conf). Be forewarned, that the key combos are wacky!\n\nTMUX is the key that allows me to run a dozen Claude Code instances, and then walk away from my workstation, pick up my phone and continue hacking.\n\n### shell scripts\n\nTo make things consistent, and easier I have a few scripts that really tie the room together.\n\n#### Aliases\n\nFirst, I have my claude code aliases:\n\n`alias cc-start=\"claude --dangerously-skip-permissions\"`\n\n`alias cc-continue=\"claude --dangerously-skip-permissions --continue\"`\n\nThese allow me to start or pick up my last work. You are dangerously skipping permissions, right?\n\n#### unlock.sh\n\nAnother helpful script is this one to help me unlock my keychain:\n\n```\n#!/bin/bash\n\n# Try to show keychain info without password prompt\n# If it times out or fails, the keychain is locked\nif timeout 1 security show-keychain-info &>/dev/null; then\n    echo \"✓ Keychain is already unlocked\"\nelse\n    echo \"✗ Keychain is locked - unlocking...\"\n    security unlock-keychain\n\n    if [ $? -eq 0 ]; then\n        echo \"✓ Keychain unlocked successfully\"\n    else\n        echo \"✗ Failed to unlock keychain\"\n        exit 1\n    fi\nfi\n```\n\nlike so:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal1.png)\n\nOn a Mac, Claude Code stores its api key in your keychain, then it requires you to unlock your keychain to work. This also has the added benefit of unlocking your ssh keys if they are using the keychain for your ssh-agent.\n\n#### tm\n\nMy TMUX starter script is really handy. I just type `tm` and it magically starts a new named session, or attaches to the named session already.\n\nThis script specifically names my sessions based on the workstation I use it from. This allows me to see what computer I am in via the terminal title.\n\n```\n#!/bin/bash\n\n# Machine-specific default emoji\ncase \"$(hostname -s)\" in\n    \"orbit\")     DEFAULT_EMOJI=\"🪐\" ;;\n    \"godzilla\")  DEFAULT_EMOJI=\"🦖\" ;;\n    \"occult\")    DEFAULT_EMOJI=\"🔮\" ;;\n    *)           DEFAULT_EMOJI=\"✨\" ;;\nesac\n\nSESSION_NAME=\"${1:-$DEFAULT_EMOJI}\"\n\n# Check if session exists\nif tmux has-session -t \"$SESSION_NAME\" 2>/dev/null; then\n    # Session exists, attach to it\n    tmux attach-session -t \"$SESSION_NAME\"\nelse\n    # Session doesn't exist, create it\n    tmux new-session -s \"$SESSION_NAME\"\nfi\n```\n\n#### The final workflow\n\nMy workflow is:\n\n- open blink\n- ssh into my workstation\n- type `unlock.sh`\n- type `tm`\n- burn tokens\n\n## Simple, right\n\nNow you can tell Claude to do weird shit from your phone 24 hours a day. It rules. Don’t do it while driving.\n",
  "authors": [
    "Harper Reed"
  ],
  "captured_at": "2026-09-27T19:29:15.293681927+00:00",
  "category": "programming",
  "content_html": "<p>So so many friends have asked me how I use Claude Code from my phone. I am always a bit surprised, because a lot of this type of work I have been doing for nearly 25 years (or more!) and I always forget that it is partially a lost art. This is how it used to be. We didn’t have fancy IDEs, and fancy magic to deploy stuff. We had to ssh (hah. Telnet!) into a machine and work with it through the terminal. It ruled. It was a total nightmare. It was also a lot of fun.</p>\n<blockquote>\n<p>One of my favorite parts of the early 2000s was hanging out in IRC channels and just participating in the most ridiculous community of tech workers. A very very fun time. #corporate on efnet!</p>\n</blockquote>\n<p>There is a lot of nostalgia for that time period - but for the most part the tooling sucked. The new IDEs, and magic deploy systems have made it so that you do not have to deal with a terminal to get shit done. And then… Claude Code sashays into the room and fucks up the vibe.</p>\n<p>Or creates a new vibe? Who knows. Anyway. We are all using terminals now and it is hilarious and fun. So let’s vibe.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/IMG_5743_hu_dfd47be50faeabd5.jpeg\" alt=\"Thinking about terminals probably, Leica M11, 12/2025\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>Thinking about terminals probably, Leica M11, 12/2025</figcaption></figure>\n<p>The conversation I have with people about Claude Code start normally, and almost without exception end with “I wish I could do this from my phone.”</p>\n<p>Well.. I am here to tell you that it is easy! And accessible!</p>\n<h2>The other (easier) way</h2>\n<p>First things first - there are a couple really neat startups that are solving this in a very different way that I work. I think they are awesome. My favorite example of this is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://superconductor.dev\">superconductor</a> (great name!). They allow you to run and instantiate a bunch of agents (Claude Codex, Amp, Codex, etc) and interact with them remotely. They are also a really great team!</p>\n<p>Another example is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://happy.engineering/\">happy coder</a>. An open source magical app that connects to your Claude Code. It is theoretically pretty good, and I know some people who love it. I couldn’t get it to work reliably.</p>\n<h2>My way</h2>\n<p>One of my core values is: <em>I want to just ssh into shit</em>. That is kind of one of my general hobbies. Can I ssh into this thing? If yes, then I am happy. If no, then how can I make it so I can ssh into it.</p>\n<p>When it came to figuring out how to use Claude Code on my phone, the obvious answer was: <strong>ssh into my computer from my phone, and run claude</strong>. Turns out this is pretty straight forward.</p>\n<p>My workstation:</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>My phone:</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal3.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Let’s break it down.</p>\n<p><em>I use an iPhone, so I will be talking about iPhone apps. There are good android apps to do this too!</em></p>\n<p>There are maybe 4 things you need to solve for:</p>\n<ul>\n<li>network</li>\n<li>terminal client</li>\n<li>workstation</li>\n<li>tools</li>\n</ul>\n<p>As a form of tldr, here are my personal answers:</p>\n<ul>\n<li>network: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Tailscale\">Tailscale</a></li>\n<li>client: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://blink.sh/\">blink</a></li>\n<li>workstation: Mac with constant power and fast internet</li>\n<li>tools: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Tmux\">TMUX</a>, some magic scripts, and Claude Code</li>\n</ul>\n<p>Let’s break it down:</p>\n<h3>Network</h3>\n<p>You will need to access your workstation from anywhere. I use a Mac and linux boxes for this.</p>\n<p>Linux is easy: Just make sure openssh-server is installed. Test that you can ssh into it - and bam. Typically if you are using a box from a Claude provider, this is built into the program.</p>\n<p>Macs are a bit harder. You need to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://support.apple.com/lt-lt/guide/mac-help/mchlp1066/mac\">enable ssh</a>, and then for extra credit you need to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://support.apple.com/lt-lt/guide/mac-help/mh11848/mac\">enable screen sharing</a>. Once this is done you should theoretically be able to remotely connect to your computer.</p>\n<p>It is very important you try to connect to it from another computer that is on the same network. Figure out your local IP (192.168.xxx.yyy), and then <em>ssh</em> to your local IP from another machine (or from the same machine). As long as you can connect to it - then the next step will be super easy. If you can’t connect to it, ask chatgpt wtf is going on.</p>\n<p>Once you can reliably SSH into your machine, then it is time to get Tailscale working. There are a few alternatives (zero tier, etc) and I am sure they are good. Tailscale is friends, and they are awesome. Having used them since before they launched, I can promise that it is a life changer.</p>\n<p>Install the Tailscale client on all your machines. Tailscale will magically create a network that only you have access to (or anyone else you add to your network). You can then access any of your machines from any of your machines.</p>\n<p>I.e. your phone can instantly connect to your workstation while you workstation is in Chicago, and your phone is in Tokyo. You don’t have to poke a hole in a firewall, do magical networking, or learn how to do magical networking. It just works. It is a beautiful product. There are is a deep bench of Tailscale features that you should check out eventually - but for today, just use it for networking.</p>\n<p>Since you were able to ssh into your machine before (I hope!) - now you can test it with your fancy new Tailscale ip address or magic name. And you can do that from any device that is on your Tailscale network. Like.. your phone!</p>\n<p>This means network is solved!</p>\n<h2>The terminal client</h2>\n<p>This is where some personal preference comes in. You now need to pick a terminal client that you like to use, and feels good to use. Lots of my friends like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://panic.com/prompt/\">prompt</a>, and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://termius.com/\">termius</a>. Both are great choices.</p>\n<p>I personally really like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://blink.sh/\">blink</a>. It is a bit nerdier, and when you open it, it just drops you into a shell. Immediately. No interface, no nonsense. Just a shell. It is a wild app. You can use their <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.blink.sh/build/start\">blink build</a> product to host a lil dev server for yourself!</p>\n<blockquote>\n<p>I wanted to use their build product - but the default and unchangeable user was <code>root</code> and I cannot being myself to seriously use a product that drops you into a server as the root user. lol</p>\n</blockquote>\n<p>Anyway, blink is for me!</p>\n<p>And since you set up Tailscale, and ssh you can just type <code>ssh &lt;dev-server-ip&gt;</code> and it will magically connect.</p>\n<blockquote>\n<p>you can use the <code>config</code> command in blink to set up keys, and hosts, etc. highly worthwhile.</p>\n</blockquote>\n<p>Now you are inside of your workstation! Now you can really rip some tokens!</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/L1004804_hu_209da4b88e42b7b8.jpeg\" alt=\"I checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>I checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026</figcaption></figure>\n<h2>Tools!</h2>\n<p>You could just navigate to the directory that your Claude project live, and run Claude. But then when you phone went to sleep or whatever - your ssh client may disconnect. And you would have to redo the connection, run Claude –continue, and live this life of lots of typing.</p>\n<p><strong>We don’t use AI tools to type more!</strong></p>\n<p>There are three tools that are super helpful:</p>\n<ul>\n<li>Keys/identity</li>\n<li>Mosh</li>\n<li>TMUX</li>\n</ul>\n<h3>Keys</h3>\n<p>If you are using SSH a lot you need to set up some SSH keys, and then push them around to all your servers. I am not going to tell you how to do that, since you should already have keys somewhere to integrate with source code repositories.</p>\n<p>If you want to generate new, or have questions - the terminal clients may help you. My guess is that you already have some.</p>\n<p>Couple tips:</p>\n<ul>\n<li>use a password to unlock your key!</li>\n<li>use an ssh agent to make that process not horrible</li>\n<li>on a Mac you can have your key be unlocked by your keychain (which is also where your Claude Code api key is!)</li>\n</ul>\n<h3>Mosh</h3>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://mosh.org/\">Mosh</a> is from a forgotten time (2012!) when the internet was slow, and connections were spotty. What mosh does is allow your “fragile” ssh connection to roam around with you. You use it just like ssh: <code>mosh &lt;dev-server-ip&gt;</code>. But now when you shut your laptop, or forget about your phone - the connection will pop back up when you surface it again. It allows the connection to survive a lot of the various environmental things that would normally derail a ssh connection.</p>\n<p>This RULES.</p>\n<p>I was on a train the other day and totally lost internet while we were in a tunnel. Then we emerged and internet came back. My ssh (really mosh) session just paused for a moment, and then BAM! Was back and Claude was telling me it had deleted my entire workstation, and was going to the beach!</p>\n<p>There are some gotchas about ssh-agent, keys and mosh that I won’t get into. If things are weird, just google it or as chatgpt.</p>\n<h3>TMUX</h3>\n<p>Tbh, I am a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/GNU_Screen\">screen</a> guy. But it is 2026 and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/TMUX\">TMUX</a> is a better choice.</p>\n<p>It allows you to have a long running terminal process that you can reattach to. This is helpful even without a remote connection. It also acts as a multiplexer - allowing for multiple terminal sessions in a single terminal window.</p>\n<p>You can have 7 Claude Codes running simultaneously and just tab through them as needed.</p>\n<p>TMUX is what a lot of the “Claude Code orchestration” hacks are built upon.You should <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/steveyegge/gastown\">check them out</a>. I haven’t yet found one that works how I want it - even know there are some good ones! I just want to use regular old TMUX, and a bunch of weird helpers.</p>\n<p>My TMUX config is here: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/harperreed/dotfiles/blob/master/.TMUX.conf\">harperreed/dotfiles/.TMUX.conf</a>. Be forewarned, that the key combos are wacky!</p>\n<p>TMUX is the key that allows me to run a dozen Claude Code instances, and then walk away from my workstation, pick up my phone and continue hacking.</p>\n<h3>shell scripts</h3>\n<p>To make things consistent, and easier I have a few scripts that really tie the room together.</p>\n<h4>Aliases</h4>\n<p>First, I have my claude code aliases:</p>\n<p><code>alias cc-start=&quot;claude --dangerously-skip-permissions&quot;</code></p>\n<p><code>alias cc-continue=&quot;claude --dangerously-skip-permissions --continue&quot;</code></p>\n<p>These allow me to start or pick up my last work. You are dangerously skipping permissions, right?</p>\n<h4>unlock.sh</h4>\n<p>Another helpful script is this one to help me unlock my keychain:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">!/bin/bash</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Try to show keychain info without password prompt</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> If it times out or fails, the keychain is locked</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-keyword syntax-control syntax-if syntax-begin syntax-shell\">if</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">timeout</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 1 security show-keychain-info <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&amp;&gt;</span>/dev/null</span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-if syntax-then syntax-shell\">then</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-echo syntax-shell\">echo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>✓ Keychain is already unlocked<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-keyword syntax-control syntax-if syntax-else syntax-shell\">else</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-echo syntax-shell\">echo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>✗ Keychain is locked - unlocking...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">security</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unlock-keychain</span>\n\n    <span class=\"syntax-keyword syntax-control syntax-if syntax-begin syntax-shell\">if</span> <span class=\"syntax-support syntax-function syntax-test syntax-begin syntax-shell\">[</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-language syntax-shell\">?</span></span> <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>eq</span> 0 <span class=\"syntax-support syntax-function syntax-test syntax-end syntax-shell\">]</span></span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-if syntax-then syntax-shell\">then</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-echo syntax-shell\">echo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>✓ Keychain unlocked successfully<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n    <span class=\"syntax-keyword syntax-control syntax-if syntax-else syntax-shell\">else</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-echo syntax-shell\">echo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>✗ Failed to unlock keychain<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-exit syntax-shell\">exit</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 1</span>\n    <span class=\"syntax-keyword syntax-control syntax-if syntax-end syntax-shell\">fi</span>\n<span class=\"syntax-keyword syntax-control syntax-if syntax-end syntax-shell\">fi</span>\n</span></span></code></pre>\n<p>like so:</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>On a Mac, Claude Code stores its api key in your keychain, then it requires you to unlock your keychain to work. This also has the added benefit of unlocking your ssh keys if they are using the keychain for your ssh-agent.</p>\n<h4>tm</h4>\n<p>My TMUX starter script is really handy. I just type <code>tm</code> and it magically starts a new named session, or attaches to the named session already.</p>\n<p>This script specifically names my sessions based on the workstation I use it from. This allows me to see what computer I am in via the terminal title.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">!/bin/bash</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Machine-specific default emoji</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-keyword syntax-control syntax-case syntax-begin syntax-shell\">case</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-command syntax-parens syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-parens syntax-begin syntax-shell\">(</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">hostname</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>s</span></span><span class=\"syntax-punctuation syntax-section syntax-parens syntax-end syntax-shell\">)</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> <span class=\"syntax-keyword syntax-control syntax-case syntax-in syntax-shell\">in</span>\n    <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>orbit<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span><span class=\"syntax-keyword syntax-control syntax-case syntax-item syntax-shell\">)</span>     <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">DEFAULT_EMOJI</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>🪐<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-terminator syntax-case syntax-shell\">;;</span>\n    <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>godzilla<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span><span class=\"syntax-keyword syntax-control syntax-case syntax-item syntax-shell\">)</span>  <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">DEFAULT_EMOJI</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>🦖<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-terminator syntax-case syntax-shell\">;;</span>\n    <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>occult<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span><span class=\"syntax-keyword syntax-control syntax-case syntax-item syntax-shell\">)</span>    <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">DEFAULT_EMOJI</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>🔮<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-terminator syntax-case syntax-shell\">;;</span>\n    <span class=\"syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell\">*</span><span class=\"syntax-keyword syntax-control syntax-case syntax-item syntax-shell\">)</span>           <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">DEFAULT_EMOJI</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>✨<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-terminator syntax-case syntax-shell\">;;</span>\n<span class=\"syntax-keyword syntax-control syntax-case syntax-end syntax-shell\">esac</span>\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">SESSION_NAME</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-begin syntax-shell\">{</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">1</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">:-</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">DEFAULT_EMOJI</span></span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-end syntax-shell\">}</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Check if session exists</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-keyword syntax-control syntax-if syntax-begin syntax-shell\">if</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tmux</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> has-session<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>t</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">SESSION_NAME</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-file-descriptor syntax-shell\">2</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span>/dev/null</span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-if syntax-then syntax-shell\">then</span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Session exists, attach to it</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span>    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tmux</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> attach-session<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>t</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">SESSION_NAME</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-keyword syntax-control syntax-if syntax-else syntax-shell\">else</span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Session doesn&#39;t exist, create it</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span>    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tmux</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> new-session<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>s</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">SESSION_NAME</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-keyword syntax-control syntax-if syntax-end syntax-shell\">fi</span>\n</span></span></code></pre>\n<h4>The final workflow</h4>\n<p>My workflow is:</p>\n<ul>\n<li>open blink</li>\n<li>ssh into my workstation</li>\n<li>type <code>unlock.sh</code></li>\n<li>type <code>tm</code></li>\n<li>burn tokens</li>\n</ul>\n<h2>Simple, right</h2>\n<p>Now you can tell Claude to do weird shit from your phone 24 hours a day. It rules. Don’t do it while driving.</p>\n",
  "content_markdown": "So so many friends have asked me how I use Claude Code from my phone. I am always a bit surprised, because a lot of this type of work I have been doing for nearly 25 years (or more!) and I always forget that it is partially a lost art. This is how it used to be. We didn’t have fancy IDEs, and fancy magic to deploy stuff. We had to ssh (hah. Telnet!) into a machine and work with it through the terminal. It ruled. It was a total nightmare. It was also a lot of fun.\n\n> One of my favorite parts of the early 2000s was hanging out in IRC channels and just participating in the most ridiculous community of tech workers. A very very fun time. #corporate on efnet!\n\nThere is a lot of nostalgia for that time period - but for the most part the tooling sucked. The new IDEs, and magic deploy systems have made it so that you do not have to deal with a terminal to get shit done. And then… Claude Code sashays into the room and fucks up the vibe.\n\nOr creates a new vibe? Who knows. Anyway. We are all using terminals now and it is hilarious and fun. So let’s vibe.\n\n![Thinking about terminals probably, Leica M11, 12/2025](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/IMG_5743_hu_dfd47be50faeabd5.jpeg)\\\nThinking about terminals probably, Leica M11, 12/2025\n\nThe conversation I have with people about Claude Code start normally, and almost without exception end with “I wish I could do this from my phone.”\n\nWell.. I am here to tell you that it is easy! And accessible!\n\n## The other (easier) way\n\nFirst things first - there are a couple really neat startups that are solving this in a very different way that I work. I think they are awesome. My favorite example of this is [superconductor](https://superconductor.dev) (great name!). They allow you to run and instantiate a bunch of agents (Claude Codex, Amp, Codex, etc) and interact with them remotely. They are also a really great team!\n\nAnother example is [happy coder](https://happy.engineering/). An open source magical app that connects to your Claude Code. It is theoretically pretty good, and I know some people who love it. I couldn’t get it to work reliably.\n\n## My way\n\nOne of my core values is: *I want to just ssh into shit*. That is kind of one of my general hobbies. Can I ssh into this thing? If yes, then I am happy. If no, then how can I make it so I can ssh into it.\n\nWhen it came to figuring out how to use Claude Code on my phone, the obvious answer was: **ssh into my computer from my phone, and run claude**. Turns out this is pretty straight forward.\n\nMy workstation:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal2.png)\n\nMy phone:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal3.png)\n\nLet’s break it down.\n\n*I use an iPhone, so I will be talking about iPhone apps. There are good android apps to do this too!*\n\nThere are maybe 4 things you need to solve for:\n\n- network\n- terminal client\n- workstation\n- tools\n\nAs a form of tldr, here are my personal answers:\n\n- network: [Tailscale](https://en.wikipedia.org/wiki/Tailscale)\n- client: [blink](https://blink.sh/)\n- workstation: Mac with constant power and fast internet\n- tools: [TMUX](https://en.wikipedia.org/wiki/Tmux), some magic scripts, and Claude Code\n\nLet’s break it down:\n\n### Network\n\nYou will need to access your workstation from anywhere. I use a Mac and linux boxes for this.\n\nLinux is easy: Just make sure openssh-server is installed. Test that you can ssh into it - and bam. Typically if you are using a box from a Claude provider, this is built into the program.\n\nMacs are a bit harder. You need to [enable ssh](https://support.apple.com/lt-lt/guide/mac-help/mchlp1066/mac), and then for extra credit you need to [enable screen sharing](https://support.apple.com/lt-lt/guide/mac-help/mh11848/mac). Once this is done you should theoretically be able to remotely connect to your computer.\n\nIt is very important you try to connect to it from another computer that is on the same network. Figure out your local IP (192.168.xxx.yyy), and then *ssh* to your local IP from another machine (or from the same machine). As long as you can connect to it - then the next step will be super easy. If you can’t connect to it, ask chatgpt wtf is going on.\n\nOnce you can reliably SSH into your machine, then it is time to get Tailscale working. There are a few alternatives (zero tier, etc) and I am sure they are good. Tailscale is friends, and they are awesome. Having used them since before they launched, I can promise that it is a life changer.\n\nInstall the Tailscale client on all your machines. Tailscale will magically create a network that only you have access to (or anyone else you add to your network). You can then access any of your machines from any of your machines.\n\nI.e. your phone can instantly connect to your workstation while you workstation is in Chicago, and your phone is in Tokyo. You don’t have to poke a hole in a firewall, do magical networking, or learn how to do magical networking. It just works. It is a beautiful product. There are is a deep bench of Tailscale features that you should check out eventually - but for today, just use it for networking.\n\nSince you were able to ssh into your machine before (I hope!) - now you can test it with your fancy new Tailscale ip address or magic name. And you can do that from any device that is on your Tailscale network. Like.. your phone!\n\nThis means network is solved!\n\n## The terminal client\n\nThis is where some personal preference comes in. You now need to pick a terminal client that you like to use, and feels good to use. Lots of my friends like [prompt](https://panic.com/prompt/), and [termius](https://termius.com/). Both are great choices.\n\nI personally really like [blink](https://blink.sh/). It is a bit nerdier, and when you open it, it just drops you into a shell. Immediately. No interface, no nonsense. Just a shell. It is a wild app. You can use their [blink build](https://docs.blink.sh/build/start) product to host a lil dev server for yourself!\n\n> I wanted to use their build product - but the default and unchangeable user was `root` and I cannot being myself to seriously use a product that drops you into a server as the root user. lol\n\nAnyway, blink is for me!\n\nAnd since you set up Tailscale, and ssh you can just type `ssh <dev-server-ip>` and it will magically connect.\n\n> you can use the `config` command in blink to set up keys, and hosts, etc. highly worthwhile.\n\nNow you are inside of your workstation! Now you can really rip some tokens!\n\n![I checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/L1004804_hu_209da4b88e42b7b8.jpeg)\\\nI checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026\n\n## Tools!\n\nYou could just navigate to the directory that your Claude project live, and run Claude. But then when you phone went to sleep or whatever - your ssh client may disconnect. And you would have to redo the connection, run Claude –continue, and live this life of lots of typing.\n\n**We don’t use AI tools to type more!**\n\nThere are three tools that are super helpful:\n\n- Keys/identity\n- Mosh\n- TMUX\n\n### Keys\n\nIf you are using SSH a lot you need to set up some SSH keys, and then push them around to all your servers. I am not going to tell you how to do that, since you should already have keys somewhere to integrate with source code repositories.\n\nIf you want to generate new, or have questions - the terminal clients may help you. My guess is that you already have some.\n\nCouple tips:\n\n- use a password to unlock your key!\n- use an ssh agent to make that process not horrible\n- on a Mac you can have your key be unlocked by your keychain (which is also where your Claude Code api key is!)\n\n### Mosh\n\n[Mosh](https://mosh.org/) is from a forgotten time (2012!) when the internet was slow, and connections were spotty. What mosh does is allow your “fragile” ssh connection to roam around with you. You use it just like ssh: `mosh <dev-server-ip>`. But now when you shut your laptop, or forget about your phone - the connection will pop back up when you surface it again. It allows the connection to survive a lot of the various environmental things that would normally derail a ssh connection.\n\nThis RULES.\n\nI was on a train the other day and totally lost internet while we were in a tunnel. Then we emerged and internet came back. My ssh (really mosh) session just paused for a moment, and then BAM! Was back and Claude was telling me it had deleted my entire workstation, and was going to the beach!\n\nThere are some gotchas about ssh-agent, keys and mosh that I won’t get into. If things are weird, just google it or as chatgpt.\n\n### TMUX\n\nTbh, I am a [screen](https://en.wikipedia.org/wiki/GNU_Screen) guy. But it is 2026 and [TMUX](https://en.wikipedia.org/wiki/TMUX) is a better choice.\n\nIt allows you to have a long running terminal process that you can reattach to. This is helpful even without a remote connection. It also acts as a multiplexer - allowing for multiple terminal sessions in a single terminal window.\n\nYou can have 7 Claude Codes running simultaneously and just tab through them as needed.\n\nTMUX is what a lot of the “Claude Code orchestration” hacks are built upon.You should [check them out](https://github.com/steveyegge/gastown). I haven’t yet found one that works how I want it - even know there are some good ones! I just want to use regular old TMUX, and a bunch of weird helpers.\n\nMy TMUX config is here: [harperreed/dotfiles/.TMUX.conf](https://github.com/harperreed/dotfiles/blob/master/.TMUX.conf). Be forewarned, that the key combos are wacky!\n\nTMUX is the key that allows me to run a dozen Claude Code instances, and then walk away from my workstation, pick up my phone and continue hacking.\n\n### shell scripts\n\nTo make things consistent, and easier I have a few scripts that really tie the room together.\n\n#### Aliases\n\nFirst, I have my claude code aliases:\n\n`alias cc-start=\"claude --dangerously-skip-permissions\"`\n\n`alias cc-continue=\"claude --dangerously-skip-permissions --continue\"`\n\nThese allow me to start or pick up my last work. You are dangerously skipping permissions, right?\n\n#### unlock.sh\n\nAnother helpful script is this one to help me unlock my keychain:\n\n```\n#!/bin/bash\n\n# Try to show keychain info without password prompt\n# If it times out or fails, the keychain is locked\nif timeout 1 security show-keychain-info &>/dev/null; then\n    echo \"✓ Keychain is already unlocked\"\nelse\n    echo \"✗ Keychain is locked - unlocking...\"\n    security unlock-keychain\n\n    if [ $? -eq 0 ]; then\n        echo \"✓ Keychain unlocked successfully\"\n    else\n        echo \"✗ Failed to unlock keychain\"\n        exit 1\n    fi\nfi\n```\n\nlike so:\n\n![](https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/terminal1.png)\n\nOn a Mac, Claude Code stores its api key in your keychain, then it requires you to unlock your keychain to work. This also has the added benefit of unlocking your ssh keys if they are using the keychain for your ssh-agent.\n\n#### tm\n\nMy TMUX starter script is really handy. I just type `tm` and it magically starts a new named session, or attaches to the named session already.\n\nThis script specifically names my sessions based on the workstation I use it from. This allows me to see what computer I am in via the terminal title.\n\n```\n#!/bin/bash\n\n# Machine-specific default emoji\ncase \"$(hostname -s)\" in\n    \"orbit\")     DEFAULT_EMOJI=\"🪐\" ;;\n    \"godzilla\")  DEFAULT_EMOJI=\"🦖\" ;;\n    \"occult\")    DEFAULT_EMOJI=\"🔮\" ;;\n    *)           DEFAULT_EMOJI=\"✨\" ;;\nesac\n\nSESSION_NAME=\"${1:-$DEFAULT_EMOJI}\"\n\n# Check if session exists\nif tmux has-session -t \"$SESSION_NAME\" 2>/dev/null; then\n    # Session exists, attach to it\n    tmux attach-session -t \"$SESSION_NAME\"\nelse\n    # Session doesn't exist, create it\n    tmux new-session -s \"$SESSION_NAME\"\nfi\n```\n\n#### The final workflow\n\nMy workflow is:\n\n- open blink\n- ssh into my workstation\n- type `unlock.sh`\n- type `tm`\n- burn tokens\n\n## Simple, right\n\nNow you can tell Claude to do weird shit from your phone 24 hours a day. It rules. Don’t do it while driving.\n",
  "dateCreated": "2026-09-27T19:29:15.293681927+00:00",
  "date_created": "2026-01-06T00:10:00+00:00",
  "date_modified": "2026-01-06T00:10:00+00:00",
  "date_published": "2026-01-06T00:10:00+00:00",
  "description": "So so many friends have asked me how I use Claude Code from my phone. I am always a bit surprised, because a lot of this type of work I have been doing for nearly 25 years (or more!) and I always forget that it is partially a lost art.…",
  "external_url": "https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/harper-blog/2026/01/2026-01-06-remote-claude-code-programing-like-it-was-the-early-2000s.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/harper-blog/2026/01/2026-01-06-remote-claude-code-programing-like-it-was-the-early-2000s.md"
  },
  "id": "urn:aggr:item:d5d6a6e5994d4b3f9fd0ec944336a798577b1d31",
  "isBasedOn": {
    "@id": "https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/"
  },
  "mainEntity": {
    "@id": "https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/harper-blog/2026-01-06-remote-claude-code-programing-like-it-was-the-early-2000s/#webpage"
    },
    "author": [
      {
        "@type": "Person",
        "name": "Harper Reed"
      }
    ],
    "dateModified": "2026-01-06T00:10:00+00:00",
    "datePublished": "2026-01-06T00:10:00+00:00",
    "headline": "Remote Claude Code: programing like it was the early 2000s",
    "timeRequired": "PT9M",
    "url": "https://harper.blog/2026/01/05/claude-code-is-better-on-your-phone/",
    "wordCount": 1949
  },
  "name": "Archived snapshot: Remote Claude Code: programing like it was the early 2000s",
  "preview": null,
  "reading_minutes": 9,
  "replicated_at": null,
  "source": "harper-blog",
  "source_name": "Home on Harper Reed's Blog",
  "summary": "So so many friends have asked me how I use Claude Code from my phone. I am always a bit surprised, because a lot of this type of work I have been doing for nearly 25 years (or more!) and I always forget that it is partially a lost art. This is how it used to be. We didn’t have fancy IDEs, and fancy magic to deploy stuff. We had to ssh (hah. Telnet!) into a machine and work with it through the terminal. It ruled. It was a total nightmare. It was also a lot of fun. One of my favorite parts of the early 2000s was hanging out in IRC channels and just participating in the most ridiculous community of tech workers. A very very fun time. #corporate on efnet! There is a lot of nostalgia for that time period - but for the most part the tooling sucked. The new IDEs, and magic deploy systems have made it so that you do not have to deal with a terminal to get shit done. And then… Claude Code sashays into the room and fucks up the vibe. Or creates a new vibe? Who knows. Anyway. We are all using terminals now and it is hilarious and fun. So let’s vibe. Thinking about terminals probably, Leica M11, 12/2025 The conversation I have with people about Claude Code start normally, and almost without exception end with “I wish I could do this from my phone.” Well.. I am here to tell you that it is easy! And accessible! The other (easier) way First things first - there are a couple really neat startups that are solving this in a very different way that I work. I think they are awesome. My favorite example of this is superconductor (great name!). They allow you to run and instantiate a bunch of agents (Claude Codex, Amp, Codex, etc) and interact with them remotely. They are also a really great team! Another example is happy coder. An open source magical app that connects to your Claude Code. It is theoretically pretty good, and I know some people who love it. I couldn’t get it to work reliably. My way One of my core values is: I want to just ssh into shit. That is kind of one of my general hobbies. Can I ssh into this thing? If yes, then I am happy. If no, then how can I make it so I can ssh into it. When it came to figuring out how to use Claude Code on my phone, the obvious answer was: ssh into my computer from my phone, and run claude. Turns out this is pretty straight forward. My workstation: My phone: Let’s break it down. I use an iPhone, so I will be talking about iPhone apps. There are good android apps to do this too! There are maybe 4 things you need to solve for: network terminal client workstation tools As a form of tldr, here are my personal answers: network: Tailscale client: blink workstation: Mac with constant power and fast internet tools: TMUX, some magic scripts, and Claude Code Let’s break it down: Network You will need to access your workstation from anywhere. I use a Mac and linux boxes for this. Linux is easy: Just make sure openssh-server is installed. Test that you can ssh into it - and bam. Typically if you are using a box from a Claude provider, this is built into the program. Macs are a bit harder. You need to enable ssh, and then for extra credit you need to enable screen sharing. Once this is done you should theoretically be able to remotely connect to your computer. It is very important you try to connect to it from another computer that is on the same network. Figure out your local IP (192.168.xxx.yyy), and then ssh to your local IP from another machine (or from the same machine). As long as you can connect to it - then the next step will be super easy. If you can’t connect to it, ask chatgpt wtf is going on. Once you can reliably SSH into your machine, then it is time to get Tailscale working. There are a few alternatives (zero tier, etc) and I am sure they are good. Tailscale is friends, and they are awesome. Having used them since before they launched, I can promise that it is a life changer. Install the Tailscale client on all your machines. Tailscale will magically create a network that only you have access to (or anyone else you add to your network). You can then access any of your machines from any of your machines. I.e. your phone can instantly connect to your workstation while you workstation is in Chicago, and your phone is in Tokyo. You don’t have to poke a hole in a firewall, do magical networking, or learn how to do magical networking. It just works. It is a beautiful product. There are is a deep bench of Tailscale features that you should check out eventually - but for today, just use it for networking. Since you were able to ssh into your machine before (I hope!) - now you can test it with your fancy new Tailscale ip address or magic name. And you can do that from any device that is on your Tailscale network. Like.. your phone! This means network is solved! The terminal client This is where some personal preference comes in. You now need to pick a terminal client that you like to use, and feels good to use. Lots of my friends like prompt, and termius. Both are great choices. I personally really like blink. It is a bit nerdier, and when you open it, it just drops you into a shell. Immediately. No interface, no nonsense. Just a shell. It is a wild app. You can use their blink build product to host a lil dev server for yourself! I wanted to use their build product - but the default and unchangeable user was root and I cannot being myself to seriously use a product that drops you into a server as the root user. lol Anyway, blink is for me! And since you set up Tailscale, and ssh you can just type ssh <dev-server-ip> and it will magically connect. you can use the config command in blink to set up keys, and hosts, etc. highly worthwhile. Now you are inside of your workstation! Now you can really rip some tokens! I checked the build status RIGHT AFTER THIS SHOT, Leica M11, 01/2026 Tools! You could just navigate to the directory that your Claude project live, and run Claude. But then when you phone went to sleep or whatever - your ssh client may disconnect. And you would have to redo the connection, run Claude –continue, and live this life of lots of typing. We don’t use AI tools to type more! There are three tools that are super helpful: Keys/identity Mosh TMUX Keys If you are using SSH a lot you need to set up some SSH keys, and then push them around to all your servers. I am not going to tell you how to do that, since you should already have keys somewhere to integrate with source code repositories. If you want to generate new, or have questions - the terminal clients may help you. My guess is that you already have some. Couple tips: use a password to unlock your key! use an ssh agent to make that process not horrible on a Mac you can have your key be unlocked by your keychain (which is also where your Claude Code api key is!) Mosh Mosh is from a forgotten time (2012!) when the internet was slow, and connections were spotty. What mosh does is allow your “fragile” ssh connection to roam around with you. You use it just like ssh: mosh <dev-server-ip>. But now when you shut your laptop, or forget about your phone - the connection will pop back up when you surface it again. It allows the connection to survive a lot of the various environmental things that would normally derail a ssh connection. This RULES. I was on a train the other day and totally lost internet while we were in a tunnel. Then we emerged and internet came back. My ssh (really mosh) session just paused for a moment, and then BAM! Was back and Claude was telling me it had deleted my entire workstation, and was going to the beach! There are some gotchas about ssh-agent, keys and mosh that I won’t get into. If things are weird, just google it or as chatgpt. TMUX Tbh, I am a screen guy. But it is 2026 and TMUX is a better choice. It allows you to have a long running terminal process that you can reattach to. This is helpful even without a remote connection. It also acts as a multiplexer - allowing for multiple terminal sessions in a single terminal window. You can have 7 Claude Codes running simultaneously and just tab through them as needed. TMUX is what a lot of the “Claude Code orchestration” hacks are built upon.You should check them out. I haven’t yet found one that works how I want it - even know there are some good ones! I just want to use regular old TMUX, and a bunch of weird helpers. My TMUX config is here: harperreed/dotfiles/.TMUX.conf. Be forewarned, that the key combos are wacky! TMUX is the key that allows me to run a dozen Claude Code instances, and then walk away from my workstation, pick up my phone and continue hacking. shell scripts To make things consistent, and easier I have a few scripts that really tie the room together. Aliases First, I have my claude code aliases: alias cc-start=\"claude --dangerously-skip-permissions\" alias cc-continue=\"claude --dangerously-skip-permissions --continue\" These allow me to start or pick up my last work. You are dangerously skipping permissions, right? unlock.sh Another helpful script is this one to help me unlock my keychain: #!/bin/bash # Try to show keychain info without password prompt # If it times out or fails, the keychain is locked if timeout 1 security show-keychain-info &>/dev/null; then echo \"✓ Keychain is already unlocked\" else echo \"✗ Keychain is locked - unlocking...\" security unlock-keychain if [ $? -eq 0 ]; then echo \"✓ Keychain unlocked successfully\" else echo \"✗ Failed to unlock keychain\" exit 1 fi fi like so: On a Mac, Claude Code stores its api key in your keychain, then it requires you to unlock your keychain to work. This also has the added benefit of unlocking your ssh keys if they are using the keychain for your ssh-agent. tm My TMUX starter script is really handy. I just type tm and it magically starts a new named session, or attaches to the named session already. This script specifically names my sessions based on the workstation I use it from. This allows me to see what computer I am in via the terminal title. #!/bin/bash # Machine-specific default emoji case \"$(hostname -s)\" in \"orbit\") DEFAULT_EMOJI=\"🪐\" ;; \"godzilla\") DEFAULT_EMOJI=\"🦖\" ;; \"occult\") DEFAULT_EMOJI=\"🔮\" ;; *) DEFAULT_EMOJI=\"✨\" ;; esac SESSION_NAME=\"${1:-$DEFAULT_EMOJI}\" # Check if session exists if tmux has-session -t \"$SESSION_NAME\" 2>/dev/null; then # Session exists, attach to it tmux attach-session -t \"$SESSION_NAME\" else # Session doesn't exist, create it tmux new-session -s \"$SESSION_NAME\" fi The final workflow My workflow is: open blink ssh into my workstation type unlock.sh type tm burn tokens Simple, right Now you can tell Claude to do weird shit from your phone 24 hours a day. It rules. Don’t do it while driving. Thank you for using RSS. I appreciate you. Email me",
  "tags": [],
  "temporalCoverage": "2026-09-27T19:29:15.293681927+00:00",
  "title": "Remote Claude Code: programing like it was the early 2000s",
  "url": "https://aggr.aymericbeaumet.com/items/harper-blog/2026-01-06-remote-claude-code-programing-like-it-was-the-early-2000s/",
  "word_count": 1949
}