Link Harness is small and mighty

Link Harness is Link's own agent runner: edit its instructions and skills as files, inspect the prompt it sends, and keep your conversations in an event log you control. Choose it when you want a native harness whose behavior follows your agent's spec and whose saved state you can inspect without a separate harness runtime.

lnk agent start       # create or start your agent and choose its model
lnk agent use --harness link    # switch this agent to Link Harness
lnk agent chat send   # try it in this terminal

Link Harness ships as a Rust executable with Link, and installs no separate Node or Python harness runtime. It builds the prompt from your files, calls your chosen model and tools, and saves the conversation between turns. Your model still determines answer quality and much of the response time; Measure shows the time and resources your own workload uses.

What it needs

Use a Mac or a Linux x86-64 computer with bubblewrap, the agent plugins and a model. Agents owns setup and costs. A hosted model bills you through its provider; a model running on your computer uses your computer's resources.

Use a model

Use the same model selection as other Link agents. Link Harness accepts local runtimes discovered by Link and hosted models through Link's proxy. A model must support tool calls to use tools, memory and skills through memory.

The trade-offs

You get visible prompt sections, file-based instructions and skills, configurable conversation storage and a hosted fallback. You also take on choosing an appropriate model and setting its limits. Another harness may suit an established workflow that depends on its own prompt, extensions or native state. Compare Harnesses and Switch Harnesses explain the alternatives and transfer boundaries.

Switch to it, and back

Link keeps your model, files and connections while switching. Link Harness imports and exports conversations through the Agent State Protocol, so conversations can continue when the other harness supports the matching transfer. Link names anything the destination cannot carry before switching: what comes along.

lnk agent use --harness link
lnk agent use --harness hermes

Make it yours

The agent owns its editable instruction and skill files; Link Harness reads them to build each turn's prompt. Its spec controls the sources and size limits, which you can inspect alongside the resulting prompt.

Tell it who to be

Edit standing instructions, persona and owner information in the agent's instructions folder. Link Harness reads the files at each message, so you can change them without restarting it. Inspect the assembled prompt to verify the change.

echo "Answer in French, in one sentence." > ~/Link/Agents/main/Agent/instructions/instruction.md
echo "You are Ada: dry, warm, and never in a hurry." > ~/Link/Agents/main/Agent/instructions/persona.md
echo "Sam Okafor, a night-shift nurse in Leeds; sister Maya, cat Biscuit." > ~/Link/Agents/main/Agent/instructions/owner.md
lnk agent show --instructions --json

Its prompt's sections

Its prompt is made of sections, in the order of how often each changes, least first, so the provider's cache holds up to the first that changed:

  1. Base: Link's (a personal agent who answers briefly), a file of yours, or none. It changes with a release.
  2. Model: yours for the model it runs on, instructions/models/<maker>/<model>/instruction.md in its files, the model named as OpenRouter names it. It changes when you edit it, or it runs another model.
  3. Tools: what each tool it's offered says of itself as it starts (MCP's instructions), under the tool's name. It changes at a start.
  4. Environment: where its files are, which of their folders it may change, its teams and teammates, the connections it's reached on, and, with no run, that it can't run programs. It changes at a start.
  5. Repository: in the repository it works in, each folder's AGENTS.md, else its CLAUDE.md, from Home up to the repository's root, the nearest first. It changes when one is edited.
  6. Skills: each skill's name and what it's for, from skills/<name>/SKILL.md. It changes when one is added.
  7. Persona: instructions/persona.md, who it is whatever the task: its name, its voice, its character. It changes when you edit it.
  8. Owner: instructions/owner.md, who you are: your name, your work, the people in your life, how you like things. It changes when you edit it.
  9. Standing: instructions/instruction.md, what you tell it to do. It changes when you edit it.
  10. Notes: memory/notes.md, what it noted for itself. It changes when it notes something.
  11. Now: the date, local time, connection and speaker, attached to each message rather than the system prompt.

Who wrote each file

Persona, owner and standing are files in its own folder, each headed with who wrote it: you, or you or it where it may write instructions/.

Now

Now is never in the prompt: each message starts with it ([Thursday 8 October 2026, 14:03 (UTC+02:00), on Telegram, from your owner]), kept with the message so it reads the same at every turn after.

A message from anyone else

A message from anyone else says who on the line after, each of its lines quoted (> ) so none reads as yours: a schedule, a subagent, another agent, or someone in a chat you shared it with, by their name there and their connection ((from "Alice Ng" on Slack, in a chat your owner shared you with, not your owner:)).

Where each section comes from

Your spec's [instructions] says where each section comes from, Link's or a file of yours, or leaves it out, and [instructions.max] how large each may be, cutting what's past it. lnk agent show --instructions --json shows each section, where it came from and its size.

The repository's files

The repository's root is the nearest folder holding .git: outside a repository, or where its sandbox hides the root, Home's file alone is read, and a file its sandbox doesn't let it read, or a link, is left out.

A model's file

A model's file is named as OpenRouter names the model, its maker then its name: instructions/models/anthropic/claude-opus-5-5/instruction.md for claude-opus-5-5 on Anthropic, instructions/models/openai/gpt-6-luna/instruction.md on OpenAI. A model through OpenRouter is named so already (anthropic/claude-opus-5.5), so its folder is its name.

A model on a runtime here

One on a runtime here goes under the runtime's (instructions/models/ollama/qwen3:8b/instruction.md). lnk agent show --instructions --json says the path for the model it runs now. A turn its fallback answers is sent the fallback's file in its place. No spec key names it: the folder is the only place.

Its folder

The agent's configuration defines Home/ for your documents and Agent/ for instructions, skills, conversations, notes and schedules. Edit instructions and skills there as plain files. The file permissions decide what the agent itself may change; its tools cannot rewrite its conversation log.

Change its opinions

Inspect lnk agent show --opinions to see the context window, reasoning effort, round limits and tool-result limits Link Harness reads. Their types, defaults and values live in the Agent Spec, so the harness and your configuration share one source of settings.

Make it a personal or a coding agent

Choose a profile for shared personal or coding defaults, then override individual keys. Link Harness reads the resulting feature settings at each message, including whether repository instructions, persona and group-chat features are included.

Give it memory and tools

Add tools through Agents. Link Harness receives them as MCP tools through Link's proxy and offers their descriptions to the model. Their own pages explain memory, web access, programs and files.

What a tool says of itself

The prompt includes each offered server's MCP instructions, under its name, at most 2 KB per tool server by default. When a conversation narrows its tools, a server with none offered contributes no instructions. The model's calls and the tools' replies become conversation events.

Its notes

Link Memory's remember changes memory/notes.md, which Link Harness reads into every conversation's prompt. The file is editable by you; its size limit and write permissions are documented with Memory. This gives every conversation the same current notes while its own message history stays separate.

Its limits

A busy tool bridge is retried within the tool's startup deadline. Transient HTTP 503 responses do not hide a tool for five minutes; if it remains busy, the next turn can try again. Other startup failures retain their bounded cooldown. An operation that has started is never repeated by this startup retry.

Turn and call limits

A message makes at most eight rounds of calls by default, then answers with what it has. A call taking more than five minutes, including waiting for your approval, is cancelled and the model is told. Both limits are configurable in the spec. A long program can run in the background through Link Run, which sends its completion back into the conversation.

Give it skills

Add, edit and remove skills through the agent's Skills page. Link Harness lists each skill's name and description in the prompt, then the model reads the full SKILL.md through Link Memory when needed. Start memory for that reading path.

lnk agent memory start

How it uses one

The list is rebuilt from skill metadata at each turn, sorted by name. It holds the names and descriptions rather than the full instructions, so installing a skill does not put all its text into every prompt. The model reads the chosen skill and follows its links when the task needs them.

Room in the prompt

The default [instructions.max] skills allows 8 KB for the list. Skills that do not fit are omitted whole, rather than cut mid-description, and lnk agent show --instructions --json shows the section as cut. A skill with missing or mismatched metadata is omitted. Its scripts run under the same permissions as other programs.

How it answers

A turn reads its current instructions and saved history, builds the model's context, calls the model and tools, and appends the results. Only one turn runs at a time per conversation. Conversations explains context limits, summaries, forks and crash recovery in detail.

Fall back to a hosted model

Link Harness can use a hosted fallback for a turn its primary model cannot answer. Configure it through Switch Models, which owns model selection, credentials and provider restrictions.

lnk agent start --model qwen3 --fallback qwen/qwen3-32b

When it falls back

For one turn at a time, the fallback answers when your model's runtime is unreachable or sends nothing back within 60 seconds, its provider answers busy or overloaded, or its prompt still exceeds the model window after older turns leave it. The turn's later rounds stay with the fallback, whose model-specific instructions replace the primary model's instructions.

A model found off

A model found off is left alone for 3 minutes, its turns going to the fallback at once, and the turn after tries it again. Summaries of what leaves the window are asked the same way.

What it says of it

Each answer says which model wrote it, and the turn's measures count it (link.fallbacks.off.sum, link.fallbacks.window.sum in lnk measure).

Talk to it

Connect and share your agent through Connections, which owns chat routing, replies, streaming and who may speak to it. Those messages reach Link Harness through the same Agent Client Protocol interface as a terminal client.

Its commands and ACP

Send /help for harness commands, /chat:create for a fresh conversation and /model:set to change its model: Commands. The Agent Client Protocol page documents its client interface, sessions, cancellation and steering.

Send it images and documents

Link Harness reads message photos and documents according to the agent's feature settings, and stores the attachments with the conversation: Images and documents explains supported content, size limits and how each provider receives it.

Its conversations

Conversations persist independently of the harness process. The default append-only log keeps model messages, tool calls and replies, with a Markdown copy to read. Compact files and store drivers are alternatives with different storage and reading costs. Conversations explains their formats, migration, context window and recovery behavior.

On a machine that packs agents

A machine that runs each agent only while it answers can start Link Harness ahead, blank: lnk-link-harness serve --blank <control> holds nothing of anyone's and answers on no port, only on the Unix socket <control>, the user's alone.

Bound to one agent

One line binds it to one agent (its name, ID and owner, a key made for that binding, its settings, and its bridges' sockets), and from then on it answers that agent alone, on its usual port, with that key; it keeps the settings in memory and writes none. It's bound once: a second binding is refused, and the process ends when the agent sleeps. Why.

More about it

The pages beside this one, and those on Link's agents that set Link Harness among the rest:

Docs

  • Agent Client Protocol: Link Harness is an ACP agent: a client of the Agent Client Protocol opens a session on one of its conversations, prompts it, and is streamed the answer as it's written, its tool calls beside it
  • Commands: A command is an owner's slash message that Link Harness handles
  • Images, documents and voice notes: Link Harness reads the images, documents and voice notes a message holds, from ACP, the Agent Client Protocol, or from any of Link's connections, and keeps each as a file in the conversation's folder
  • Developing: lnk-link-harness is Link Harness, the harness a Link agent runs by default: a small router in Rust that answers you, keeps the thread, and calls the tools Link runs for it
  • Decisions: Why Link Harness works the way it does
  • Conversations: Every conversation of Link Harness is a folder in your agent's files, so it moves with your agent (lnk agent move) and stays when you switch harness
  • Troubleshooting: What to do when Link Harness doesn't answer, or answers wrong