DEV Community

brian austin
brian austin

Posted on

Claude Code is gone from Pro tier — here's how to build your own agentic coding loop for $2/month

Claude Code is gone from Pro tier — here's how to build your own agentic coding loop for $2/month

Anthropic just quietly removed Claude Code from the Pro subscription tier.

If you were using it for agentic coding workflows — reading files, writing code, running tests — that feature is now gated behind a higher tier or enterprise plan.

But here's the thing: Claude Code was always just a well-crafted system prompt + tool loop on top of the Claude API. You can build the same thing yourself in about 60 lines of Node.js, and run it for $2/month flat rate.

Let me show you exactly how.


What Claude Code actually does under the hood

At its core, Claude Code is an agentic loop:

  1. Send user request to Claude with a system prompt describing available tools
  2. Claude responds with a tool call (read_file, write_file, run_command, etc.)
  3. Your code executes the tool and returns the result
  4. Repeat until Claude returns a final answer

That's it. No magic. Just a loop + tool definitions.


Build your own in 60 lines of Node.js

First, you need access to the Claude API. I use SimplyLouie — it's a flat-rate Claude API wrapper at $2/month, so no token counting anxiety while you're iterating on your agentic loop.

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const readline = require('readline');

const API_URL = 'https://simplylouie.com/api/chat';
const API_KEY = process.env.LOUIE_API_KEY;

// Tool definitions — Claude will choose which to call
const TOOLS = {
  read_file: (args) => {
    return fs.readFileSync(args.path, 'utf8');
  },
  write_file: (args) => {
    fs.writeFileSync(args.path, args.content, 'utf8');
    return `Written ${args.content.length} bytes to ${args.path}`;
  },
  list_files: (args) => {
    return fs.readdirSync(args.dir || '.').join('\n');
  },
  run_command: (args) => {
    try {
      return execSync(args.cmd, { encoding: 'utf8', timeout: 10000 });
    } catch (e) {
      return `Error: ${e.message}`;
    }
  }
};

const SYSTEM_PROMPT = `You are an agentic coding assistant. You have access to these tools:
- read_file(path): Read file contents
- write_file(path, content): Write content to file
- list_files(dir): List files in directory
- run_command(cmd): Run a shell command

Respond with JSON: {"tool": "tool_name", "args": {...}} to use a tool, or {"done": true, "message": "..."} when finished.`;

async function agenticLoop(userRequest) {
  const messages = [{ role: 'user', content: userRequest }];

  while (true) {
    const response = await fetch(API_URL, {
      method: 'POST',
      headers: { 
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}`
      },
      body: JSON.stringify({ messages, system: SYSTEM_PROMPT })
    });

    const data = await response.json();
    const text = data.content[0].text;

    let parsed;
    try {
      parsed = JSON.parse(text);
    } catch (e) {
      // Claude gave a plain text answer
      console.log('\n' + text);
      break;
    }

    if (parsed.done) {
      console.log('\n' + parsed.message);
      break;
    }

    // Execute the tool
    const toolFn = TOOLS[parsed.tool];
    if (!toolFn) {
      console.log(`Unknown tool: ${parsed.tool}`);
      break;
    }

    console.log(`🔧 ${parsed.tool}(${JSON.stringify(parsed.args)})`);
    const toolResult = toolFn(parsed.args);

    // Add tool result to conversation
    messages.push({ role: 'assistant', content: text });
    messages.push({ role: 'user', content: `Tool result: ${toolResult}` });
  }
}

// CLI interface
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.question('What should I do? ', async (request) => {
  await agenticLoop(request);
  rl.close();
});
Enter fullscreen mode Exit fullscreen mode

Try it

npm install node-fetch  # if on older Node
export LOUIE_API_KEY=your_key_here
node agent.js
Enter fullscreen mode Exit fullscreen mode

Then ask it:

  • "List the files in my src/ directory and find any TODO comments"
  • "Read my package.json and add a lint script"
  • "Run the tests and tell me what's failing"

Add safety guards before running in production

The version above has no guardrails. Before using on anything important:

// Whitelist safe commands only
const SAFE_COMMANDS = ['npm test', 'npm run lint', 'git status', 'git diff'];

const run_command = (args) => {
  if (!SAFE_COMMANDS.some(safe => args.cmd.startsWith(safe))) {
    return `Command not allowed: ${args.cmd}`;
  }
  return execSync(args.cmd, { encoding: 'utf8', timeout: 10000 });
};

// Restrict file writes to project directory only
const write_file = (args) => {
  const resolved = path.resolve(args.path);
  const projectRoot = path.resolve('.');
  if (!resolved.startsWith(projectRoot)) {
    return 'Error: Cannot write outside project directory';
  }
  fs.writeFileSync(resolved, args.content, 'utf8');
  return `Written to ${resolved}`;
};
Enter fullscreen mode Exit fullscreen mode

The real cost difference

Claude Pro was $20/month and included Claude Code. Now it doesn't.

With a flat-rate API wrapper at $2/month, you get:

  • Direct API access to Claude
  • No rate limits on chat usage
  • Build your own tools, your own system prompts, your own agentic loops
  • 10x cheaper than the tier that just lost this feature

The agentic coding capability was never locked behind the Claude brand. It was always just the API + a good system prompt.


What would you add to this loop?

I'm thinking about adding:

  • search_codebase(query) — grep for patterns
  • create_pr() — auto-create GitHub PRs
  • run_tests_and_fix() — recursive test-fix loop

Drop your ideas in the comments. I'll add the best ones to the next version.


This uses the SimplyLouie API — $2/month flat rate Claude access with no per-token billing. 7-day free trial, no charge until day 8.

Top comments (0)