RE:NODE

AI context files in your repo: CLAUDE.md, AGENTS.md and the server

By RE:NODE Team
15 min read


An AI coding assistant opened in a repository knows the code and nothing else. It does not know which port the server listens on, that only one directory survives a restart, that there is no root and no systemd, or that a push redeploys within seconds. So it guesses, and the guesses are the defaults from tutorials: port 3000, localhost, a Dockerfile nobody asked for, a password pasted into a config file. The fix is a plain Markdown file in the repository that the assistant reads before it starts - CLAUDE.md for Claude Code, AGENTS.md for Codex, Cursor and a growing list of others. On RE:NODE app servers linked to GitHub, the panel can write that file for you: switch on Keep AI context in the repository on the GitHub tab and it opens a pull request adding .renode/server.md and a short marked block in CLAUDE.md and AGENTS.md. You read it, you merge it, and from then on the assistant knows how the server runs without anyone pasting it in.

This post covers both halves: what a context file is and how to write a good one on any host, and exactly what the panel writes, what it leaves out, and how the pre-flight check feeds into it.

What an AI context file is#

A context file is instructions for an agent, kept next to the code. When an agentic tool starts a session in a repository, it looks for a file with a known name at the root (and sometimes in subdirectories), reads it, and treats it as standing instructions for the whole session. It is not configuration in the strict sense - nothing parses it - it is prose and lists the model reads the same way it reads your prompt, except you only write it once.

What goes in it is the knowledge a new colleague would need on day one and would otherwise have to ask for:

  • how to install, build, test and run the project, as exact commands;
  • where things live, and which directories are generated and must not be edited;
  • the conventions that are not obvious from the code - naming, error handling, which library wins when two would do;
  • the environment the code actually runs in, and its limits;
  • the things that must never happen: secrets in commits, edits to vendored code, force pushes.

The last two items are where most context files are thin, and where most damage comes from. An assistant that does not know the deployment environment writes code for a laptop. Code for a laptop listens on 127.0.0.1, writes uploads to /tmp, and assumes it can apt install whatever it needs. All three fail quietly on a container host. We covered the general failure modes of agents doing server work in AI coding agents for server and DevOps work; a context file is the cheapest guardrail against the "wrong environment" class of mistake.

Which tools read which file#

There is no single standard yet, and the file names are a small mess. The useful summary as of late 2026:

FileRead by
CLAUDE.mdClaude Code
AGENTS.mdOpenAI Codex, Cursor, GitHub Copilot's agent and others
.cursor/rules/Cursor (its own rule files)
.github/copilot-instructions.mdGitHub Copilot

AGENTS.md is the closest thing to a shared format: a plain Markdown file with no required structure, which several vendors agreed to read. CLAUDE.md is Claude Code's own name for the same idea; it also reads CLAUDE.md files in subdirectories when it works in them, and a personal one in your home directory. Tool support moves quickly, so if one of these matters to you, check the tool's own documentation for which names it currently picks up.

Two practical consequences. First, if your team uses more than one assistant, you need the same core instructions in more than one file. Keeping them identical by hand does not last; the usual answer is to keep the shared part short and point both files at one longer document. Second, a chat assistant such as ChatGPT in a browser does not read your repository on its own at all. It only knows what you give it - which is why the panel also has a share link for that case, covered at the end.

What belongs in one, and what does not#

The best context files are short and specific. A model reads every line of the file on every session, and a long file full of general advice dilutes the few lines that matter. A useful test for each line: would an assistant that had never seen this file get this wrong? If not, delete it. "Write clean code" fails that test. "The server listens on the port in SERVER_PORT, not 3000" passes it.

A small Node service might have this:

CLAUDE.md
# Orders API## Commands- Install: npm ci- Test: npm test (needs a local Postgres, see docker-compose.yml)- Start: npm start (runs node dist/server.js; build first with npm run build)## Layout- src/ is the code; dist/ is generated - never edit it.- migrations/ is append-only. Add a new file; never change a merged one.## Rules- Read configuration from environment variables only. See .env.example.- Never commit .env or any key, token or password.- Use the existing logger in src/log.ts, not console.log.

What does not belong in it:

  • Secrets. A context file is committed, so anything in it is in the history for good. Name the variable; never write its value. Environment variables and secrets covers where the values should live instead.
  • Things that change on every deploy. The current commit, the last deploy time, a build number. They go stale immediately and make every diff noisy.
  • Things the code already says. The list of routes, the database schema. The assistant can read those; copying them into prose just creates a second version to drift.
  • Long tutorials. Link to a document in the repository instead, and let the assistant open it when it needs it.

The part most people leave out is the server. They write commands and conventions, then stop, because the server feels like somebody else's problem. It is the part the panel can fill in, because the panel is the one place that knows it exactly.

The AI context switch on the GitHub tab#

On an app server linked to a GitHub repository, the GitHub tab has a switch: Keep AI context in the repository (opens a pull request). It is off until you turn it on, and it applies to that one link. Nothing is ever opened for a repository whose owner has not clicked it.

When it is on, the panel's GitHub App - the same one that handles deploys from GitHub - does the following:

  1. It creates a branch called renode/ai-context from the head of the branch your server deploys from.
  2. It commits .renode/server.md and the marked blocks in CLAUDE.md and AGENTS.md to that branch, through GitHub's API. Nothing is cloned.
  3. It opens a pull request from renode/ai-context into your deploy branch.
  4. You review it and merge it, or close it.

The panel never pushes to the branch your server deploys from. Every commit goes to its own renode/ai-context branch, and merging is your decision. Pushes to renode/ branches are also ignored by the deploy-on-push hook, so refreshing the context never restarts the server.

The status line under the switch tells you where things stand: off, working on it, waiting for permission, a pull request open against your branch, up to date, the last pull request closed without merging, or an error. Every refusal from GitHub - a rate limit, a protected branch, an archived repository, a missing permission - shows up as one of those lines rather than a failure page. The general steps for linking a repository in the first place are in the deploys guide.

What the panel writes into the repository#

Two kinds of content, with different ownership.

The block in CLAUDE.md and AGENTS.md

In CLAUDE.md and AGENTS.md the panel owns only the text between two HTML comments, <!-- renode:start --> and <!-- renode:end -->. If the file does not exist, it is created holding just the block. If it exists without the markers, the block is appended at the end. If it has the markers, only what is between them is replaced. Everything you wrote outside them survives byte for byte, so your own commands and conventions sit above or below the panel's part without being touched. HTML comments do not render on GitHub, so the markers are invisible when someone reads the file there.

The block is deliberately short - the handful of rules that break a deploy when ignored, and a pointer to the full file. For a Node.js server with deploy on push it reads roughly like this:

CLAUDE.md (the panel's block)
<!-- renode:start -->## Renode serverThis repository is deployed to a Renode server (Node.js) from the mainbranch. Read .renode/server.md before changing how it builds, starts orconnects to anything.- Listen on 0.0.0.0 on the port in the SERVER_PORT environment variable.  No other port is reachable from outside.- Only /home/container persists. No root, no apt, no systemd, no Docker.- The panel starts it in a fixed order. Keep the entry file and start  script it expects.- Never commit secrets. They go in a .env uploaded through the Files tab,  or in Startup variables, and are read from the environment.- A push to main redeploys and restarts the server within seconds.- Fix the code, not the startup command or the Docker image.<!-- renode:end -->

The exact wording depends on the server: the runtime name, the branch, the number of boot steps, and whether deploy on push is on. With it off, the push line instead tells the assistant to restart the server from the panel after pushing.

The server file

.renode/server.md belongs to the panel entirely, says so in a comment at the top, and is overwritten whenever the server's settings change. Put your own notes in CLAUDE.md or AGENTS.md, outside the markers, not here. It has these sections:

SectionWhat it holds
Runtimethe kind of server and its Docker image
Networkthe port, plus address and domains (private repos)
Codethe path in the container, repo, branch, deploy switches
How this server bootsthe numbered steps the panel runs on start
Variableseach environment variable, its name, whether it is secret
Databasesattached databases (details only in private repos)
Limitsmemory, CPU and disk
Pre-flight checkwhat the panel found wrong in the repository
Rulesthe full list the short block summarises

The boot order is the most useful part, and the one nobody writes by hand. An assistant asked "why does my app not start" can read that the server installs dependencies, then runs a particular start command, and reason from there instead of inventing a Procfile. The limits section matters for the same reason: knowing the process is killed at its memory ceiling with no error message - the console just stops - turns a mysterious crash into an obvious diagnosis. Node memory limits explained goes into that one in detail.

What the file leaves out on purpose: the deployed commit and its time. Including them would turn every push into a pull request update, which is exactly the noise you do not want.

Public and private repositories#

The panel asks GitHub whether the repository is private every time it writes, and treats anything other than an explicit "private" as public. The two get different files.

DetailPrivate repoPublic repo
Rules, boot steps, limitsyesyes
Server address and portyesport variable only
Domains, node, server IDyesno
Variable namesyesyes
Variable valuesnon-secret onesno
Database host, name, useryescount only

Secret values are never written to either kind. A variable marked secret appears as a placeholder that says it is set on the server and not shown, and database passwords are never included - the file says the password is on the Databases tab and belongs in .env. Both versions also pass through the same redactor the panel's other AI features use, which scrubs anything shaped like a key or token and the server's own known secrets. We describe that as a net, not a promise: it catches what it was built to catch, and you should still read the pull request before you merge it, as you would any other.

How pre-flight findings feed the context#

The GitHub tab also runs a pre-flight check: it reads the repository - one tree listing and a few small files, never a clone - and lists what will break when the server starts, worst first, each with a fix to paste. It looks for a missing start script or entry file, binding port 3000 or localhost instead of the server's port on 0.0.0.0, a framework that is never built (no .next, say), a runtime version pinned in .nvmrc or go.mod, Python requirements and the entry file, a Go main package, Bun and Deno start tasks, an index file on web hosting, and a committed .env, which is reported by name and never opened.

When the AI context switch is on, those findings go into .renode/server.md under Pre-flight check, introduced with "What the panel found when it read this repository. Fix every FAIL first." Each finding is one line, tagged with its level in capitals, followed by the detail and the fix:

.renode/server.md (excerpt)
## Pre-flight checkWhat the panel found when it read this repository. Fix every FAIL first.- [FAIL] No start script and no entry file - The server runs npm run start,  and package.json has no start script. ... Fix: Add "start": "node <your  main file>" to the scripts in package.json.

This is the part that changes how an assistant behaves. Without it, you open Claude Code or Cursor and type "the deploy is broken, fix it", and the assistant starts by guessing. With it, the assistant opens the repository, reads the context file, and finds a list of concrete faults with their fixes already written. The usual first move is then to work down that list. The panel did the diagnosis; the assistant does the edit; you review the diff.

It also closes a loop. You fix a FAIL, push, and the next refresh reads the repository again. The finding is gone, the file content changes, and the open pull request gets a new commit without it. A clean repository ends up with no Pre-flight check section at all.

Keeping it current#

The context is refreshed, not regenerated on a whim. A background task runs every ten minutes and notices when variables, ports, databases or domains change; saving settings on the GitHub tab queues a refresh too, held to at most one per link per ten minutes. Each time, the content is hashed, and if the hash matches the last one, nothing is written. A server that does not change produces no commits.

What happens to the pull request depends on its state:

  • Open: it gets a new commit on renode/ai-context with the changes.
  • Merged: a new pull request opens only when the content differs from what is on your branch.
  • Closed without merging: the status says so, and a new one opens only when the content changes again.

Update now skips the wait and runs a refresh immediately - useful after approving the App's permissions or right after a settings change you want in the file today.

The link follows the server's deploy settings. Switching the deploy branch closes the pull request and opens one against the new branch. Switching to a different repository turns the feature off, because agreeing to pull requests in one repository is not agreeing to them in another. Unlinking turns it off as well. Turning the switch off yourself closes the open pull request with a comment and deletes the renode/ai-context branch. It never touches what you already merged: the files stay in your repository until you remove them.

Troubleshooting#

The status says it is waiting for permission. The GitHub App has not been granted Contents and Pull requests write access on your installation. Follow the link on the tab to the installation's settings, accept the new permissions, then press Update now. Until you do, the panel writes nothing.

It says it could not update the repository. Read the status line and the reason with it. The common ones: the repository is archived (GitHub refuses all writes), you have hit GitHub's rate limit (wait and press Update now), or a branch protection rule covers renode/*. Protection on your main branch does not matter - the panel never writes there - but a wildcard rule that also matches renode/ai-context will block it.

My CLAUDE.md has a start marker but no end marker. The panel refuses to guess where its block ends and writes nothing. This usually happens after a hand edit or a bad merge. Delete the stray marker, or add the missing one, and press Update now.

The assistant still binds to port 3000. Check the pull request was merged into the branch you have checked out. The files only work once they are in the working copy the assistant opens. Then check the tool reads the file you think it reads - Claude Code reads CLAUDE.md, Codex and Cursor read AGENTS.md. Some tools only read context at the start of a session, so start a new one.

I do not want the panel touching CLAUDE.md at all. Close the pull request, or turn the switch off. If you want the information without the pull request, the "Work on this server with AI" bar on the Console tab gives you a link with the same server context to hand to an assistant directly.

FAQ#

Does the panel ever push to my main branch?

No. Every write goes to renode/ai-context and reaches your branch only through a pull request that you merge. The code that moves branches refuses any branch outside renode/, and pushes to those branches never trigger a deploy.

Will merging the pull request restart my server?

If deploy on push is on, merging puts a new commit on your deploy branch, so yes, it redeploys and restarts like any other push. The context files themselves change nothing about how the code runs.

Can I edit the generated files?

Edit CLAUDE.md and AGENTS.md freely outside the markers; the panel leaves that text alone. Do not edit .renode/server.md or the text between the markers - the next refresh will overwrite it. Change the server's settings instead and the file follows.

Does this work with ChatGPT?

Not through the repository. ChatGPT in a browser does not read files from your GitHub on its own. For a chat assistant, use the Connect AI button on the Console tab, which makes a share link with the server's context that you paste into the conversation. Claude Code, Cursor, Copilot and Codex are the tools that pick up the repository files by themselves.

Is my database password in the file?

No, in neither public nor private repositories. A private repository gets the database name, host, port and user, with a note that the password is on the Databases tab and belongs in .env. A public one gets only the number of databases attached.

What if my repository is not linked to a server?

Then there is nothing for the panel to describe, and the switch is not offered. You can still write CLAUDE.md and AGENTS.md by hand using the advice above - the server section is the part to take most care over.

Was this helpful?