Wire
A memory MCP server for Claude Code, Codex, Cursor and GitHub Copilot.
Connect any agent you already use. Harbor is an MCP server, so any client that speaks MCP can search your team’s knowledge and write back what it learns. Installing the CLI adds hooks, which a pull-only connection cannot have, and this page is honest about which is which.
How do I add a memory MCP server to Claude Code?
Once your workspace exists (the quickstart gets you there), run npx harborloop init in your repo. It signs you in once in the browser, adds Harbor’s MCP server to ~/.claude.json, installs its hooks in ~/.claude/settings.json, and turns Harbor on in that repo (in a workspace with teammates in it, it asks first). The same command wires Codex, Cursor and GitHub Copilot if they are on the machine.
npx harborloop initThat is the whole setup. Your team’s rules reach the agent in its next session, and what it learns comes back to the team. The harborloop CLI reference lists every file it changes.
From inside the agent, as a plugin
Claude Code and Codex can install the same thing as a plugin, from the public gethrbr/harbor-plugins repo:
claude plugin marketplace add gethrbr/harbor-plugins
claude plugin install harbor@harborcodex plugin marketplace add gethrbr/harbor-plugins
codex plugin add harbor@harborThen run /harbor:login in Claude Code, or $harbor:login in Codex. It runs the same sign-in and puts the same hooks in place. If you already ran npx harborloop init, you do not need the plugin.
Pull only, in one command
claude mcp add --transport http harbor https://mcp.gethrbr.com/mcpThe server answers 401 until it has a credential. In Claude Code, open /mcp, pick harbor and sign in in the browser. On a hosted client that supports it, adding the same URL as a connector runs the same sign-in. There is nothing to paste and nothing to install, and you get the tools without the hooks. A connection made this way counts as a third-party connection.
MCP or hooks: what is the difference?
MCP gives your agent tools it can choose to call. Hooks are commands the agent app runs on its own at fixed moments, whether or not the model thinks to ask. Harbor uses both: the MCP server is how an agent searches and writes back, and the hooks are how your team’s rules arrive without anyone asking, how a forbidden command is stopped before it runs, and how a session gets counted at all.
| Installed | Pull only | |
|---|---|---|
| How | npx harborloop init | claude mcp add |
| Search and cite your team’s knowledge | Yes | Yes |
| Knowledge pushed in before each prompt | Yes | No |
| Captures what the session decided | Yes | No |
| Guardrails refuse a command before it runs | Yes | No |
| A session key, so any of it can be counted | Yes | No |
| What harbor doctor can tell you | Recall, Fit, Attribution, Contributed | Nothing |
In Claude Code, harbor init registers seven hook events:
| Event | What Harbor does there |
|---|---|
UserPromptSubmit | Puts the team rules that fit this prompt in front of the model, before it answers. |
PreToolUse | Checks a shell command, a file edit or an MCP call against your team’s guardrails, and refuses it before it runs. |
PostToolUse | After a read, an edit, a search or a command, adds the rules about the file it just touched. |
Stop | At the end of each turn, asks the agent to record what was settled, and prints the ⚓ line naming the team rules the answer used. |
SessionStart | After a compaction, makes sure the rules come back on the next prompt. |
SubagentStart | Hands a subagent what its parent was given. |
SessionEnd | Closes the session’s count, so harbor doctor and Insights include it. |
A CLAUDE.md or AGENTS.md file is context the model may or may not follow. A PreToolUse hook is not: it runs before the tool and can say no. That is why the guardrails live there. See block risky agent commands with Claude Code hooks.
Pull only is a real option and it takes one command. It is the right answer for a client Harbor cannot install into, and for anybody trying Harbor before wiring a machine up. It is the wrong answer if you want to know whether Harbor is working, because nothing in it produces the evidence.
The four tools
One to read, one to record a finding, one to take a finding back, and one to save how a job is done. A connection harbor init made gets all four. A browser sign-in gets three: everything but taking a finding back. There is no separate deep search: when a search scoped to this repo’s Space finds little, harbor_get_knowledge widens to your other Spaces by itself and numbers those results too.
| Tool | What it does | Reaches |
|---|---|---|
harbor_get_knowledge | Search your team’s knowledge. An agent calls it before a task and again whenever it meets a name, a file or a decision it does not know. What comes back is numbered, so an answer can cite it. | Every connection |
harbor_record_learning | Write one finding back: a rule, a pattern, a gotcha, a fact about the team, or a preference of yours. It returns a short id to take the finding back by. | Every connection |
harbor_revoke_learning | Take back something recorded in error, by that id or, once the id has scrolled away, by a phrase from the text. A phrase that matches more than one is refused, with the candidates listed. | Local only |
harbor_save_how_to | Save the steps of a job your team repeats, one page per job. Teammates’ agents see its title at the start of a session and can open it. A save that adds a link, an install step, a risky shell command or something that looks like a secret, or that changes a page someone else wrote, waits for a person first. | Every connection |
harbor_get_knowledge
Every argument is optional. The server’s instructions tell the agent to call it before starting work, then again for every unfamiliar name, file or decision, and to check a team fact from its own memory files against Harbor first, because those are older copies. Where Harbor disagrees with a rules file or with you, the agent is told to say so and ask rather than choose.
| Argument | What it takes |
|---|---|
taskContext | What you are working on, in a sentence. This is the search query. Up to 500 characters. |
projectId | A Space id, to search one Space. Omit it and the repo’s binding decides. |
originUrl | The repo’s git remote, so the server can find its Space when no projectId is given. |
howTo | The exact title of a how-to, to open the whole page instead of searching. |
applied | The numbers from the last answer whose facts the agent actually used, such as [3, 7]. Claude Code only. |
noise | The numbers it did not need. Claude Code only. |
wrong | Facts that are out of date, each with a line on why: [{ "n": 5, "why": "deploys moved to the release workflow" }]. Harbor marks the fact disputed for your team. Claude Code only. |
Skills are not served here. They stay where your agent keeps them, in its own skills folder.
harbor_record_learning
kind and content are required. Before it records, the agent is told to check the finding against the repo’s own rules files (CLAUDE.md, AGENTS.md, Cursor rules). If it contradicts a line there, it quotes the line to you and asks which is right instead of recording. The reply says whether the finding went live or is waiting in Review, and why.
| Argument | What it takes |
|---|---|
kind | CONVENTION (a team rule, or a decision with its reason), PATTERN, GOTCHA, PREFERENCE (how you like to work, kept private to you) or TEAM_MEMORY (a durable fact about the team rather than a rule). |
content | One fact, in as few words as it takes: when it applies, what to do, why. Aim for 500 characters. Up to 8,000 are kept, and recall serves about the first 800. |
domain | ENGINEERING or NON_ENGINEERING. Left out when the agent cannot tell. |
evidence | Optional files, snippets and ids of related results, shown to whoever reviews it. |
statedBy | Your exact words, when you said the rule yourself. Shown beside the rule as who said it. |
scope | Left out by default: the server finds the Space from the repo. Named only for a fact that is deliberately not about this repo. |
until | For a fact with an end date, such as “staging is read-only until Thursday”: the day it stops being true, as "2026-10-09", "Q3 2027" or a weekday. Harbor archives it after that day. |
replaces | For a correction: the id of the rule it corrects, or a phrase of at least 12 characters and 2 words from its text. The new one takes that rule’s place in one call, the old one is archived with a Restore button, and its author is told. A phrase that matches nothing, or several rules, records the learning on its own and says so. |
applied, noise, wrong | The same three as on harbor_get_knowledge. Claude Code only. |
A replaces takes the old rule’s place on its own only when you could have retired that rule yourself. Otherwise the pair waits for a person. The rule is the same one that governs any capture that reverses a live rule, written out on what happens when a capture reverses a live rule.
harbor_revoke_learning
Pass id or contentMatch. Revoking reaches what you recorded in this session or an earlier one (after a resume or a compaction) and rules you wrote, never a teammate’s. A learning that is already live is removed for everyone when you may publish knowledge in its Space. One a person approved, or one you may not publish, is not removed: with a reason it is marked disputed instead, and every agent is handed it flagged until an owner settles it.
| Argument | What it takes |
|---|---|
id | The lrn_ id that harbor_record_learning returned. |
contentMatch | A phrase from the text, when the id is gone. To reach a learning from an earlier session it needs at least 12 characters and 2 words. |
reason | What is true instead, in one sentence. Used only when the learning cannot be removed: it is then marked disputed, and an owner settles it on Review with these words. |
harbor_save_how_to
title, whenToUse and body are required. Saving under a title that already exists replaces that page with a new version, and every version is kept, so the agent is told to open the current page first and keep what still holds. Most saves go live at once. A held one leaves teammates on the previous version until a person approves it in Review.
| Argument | What it takes |
|---|---|
title | The job, as a short name, such as “Release the CLI to npm”. The same title opens and replaces the same page. |
whenToUse | One line on when an agent should open it. |
body | The numbered steps with the exact commands, links and traps. The whole page, because it replaces the current version. Up to 8,000 characters. |
projectId | The Space to save it in. Omit it and the repo decides. |
originUrl | The repo’s git remote, as on harbor_get_knowledge. |
Browser sign-in connections are treated as third-party
A connection made by signing in through the browser (a hosted connector, ChatGPT, or claude mcp add followed by /mcp) gets three of the four tools, and Harbor holds it to a stricter line than a connection harbor init made on your machine:
harbor_revoke_learningis not offered, and the route behind it refuses the token anyway. A wrong rule is archived on the Knowledge page instead, by someone who may curate its Space.- A capture never retires a live rule, whether it names one in
replacesor reverses one without naming it. The pair waits in Review for a person. - Every
harbor_save_how_towaits for a person: “It was saved from a third-party chat app, and those always wait for a person before agents get them.” - There are no hooks, so none of the session is counted.
The three citation arguments, applied, noise and wrong, follow the client rather than the sign-in: Claude Code is offered them either way, and other clients are not.
Harbor’s tools are off outside your team’s repos
On an installed machine, Harbor runs only in repos your team bound. In a repo nobody bound, a folder with no git remote, or a repo paused with harbor off, the hooks send nothing, and the agent’s calls to Harbor’s own tools are refused on the machine before they leave. The agent is told:
Folders outside any repo can be turned on by an admin, under Settings, Spaces, “Work outside a repo”. See scope agent memory by repo and team.
Per-agent notes
harbor init configures every agent it finds on the machine and skips the ones it does not. Each gets an MCP entry and a set of hooks; the hooks are what make a session measurable.
| Agent | MCP config | Hook events |
|---|---|---|
| Claude Code | ~/.claude.json | 7 |
| Codex | ~/.codex/config.toml | 6 |
| Cursor | ~/.cursor/mcp.json | 7 |
| GitHub Copilot | ~/.copilot/mcp-config.json | 7 |
Harbor sits beside each agent’s own files, and does not replace them. How each one loads them: does Claude Code read AGENTS.md, why Codex ignores AGENTS.md, Cursor rules and copilot-instructions.md. What each remembers on its own is in Claude Code memory vs Codex, Cursor and Copilot.
Copilot: the CLI and VS Code’s agent mode
init writes one hook file, ~/.copilot/hooks/harbor.json, and both Copilot CLI and VS Code’s agent mode run it. Rules reach the agent on every prompt and after each file it touches, guardrails refuse before a tool runs, and the session’s learnings are captured, the same as the other three.
Copilot shows no ⚓ line, because its hooks have no channel to the person, so harbor doctor is how you see it working. And VS Code starts the harbor MCP server only when you do: once, from MCP: List Servers, harbor, Start Server. Until then the hooks run, but the agent has no Harbor tools. If VS Code’s "chat.useHooks" setting is false, nothing runs there, and doctor warns. Copilot’s cloud agent is not supported yet.
Cursor recalls on every prompt, in a current app
Knowledge reaches Cursor when the session starts and again on every prompt, the same as Claude Code and Codex, and it comes back after a compaction. An older Cursor app ignores context on its prompt event, so there knowledge lands only at the start of a session.
harbor doctor says which you have. Its Cursor line reads recall at session start and on every prompt when it is healthy, and it names the app version when the app is too old.
Devin runs Harbor through Claude Code’s hooks
Devin, the CLI and Devin Desktop’s local agent, runs the hooks in Claude Code’s settings by default, so a machine with Harbor’s Claude Code hooks has Harbor in Devin too. There harbor doctor prints runs Harbor through Claude Code’s hooks, guardrails included. If Devin is set not to read Claude Code’s config, doctor warns and tells you to set read_config_from.claude to true. Gemini CLI and OpenCode run none of these hooks, and doctor says so when it finds one.
Each agent speaks its own tool names
Cursor’s tool vocabulary is not Claude’s: Bash is Shell, Edit is Write. VS Code’s agent mode has its own again, such as run_in_terminal and replace_string_in_file. A hook registered with the wrong matcher is not an error, it is simply a hook that never fires, which is why init translates rather than copies and why doctor checks the set of events rather than trusting the file.
What a session looks like
- Recall. Before each prompt, and again when the work moves to a different file, the relevant conventions and past decisions are put in front of the model without anyone typing a command.
- Work. Nothing to do differently. The agent can also call the tools directly when it wants more than it was given.
- Capture. When something worth keeping is settled, the agent records it. One finding per record, with the reason it was decided, because a rule without its why gets reverted.
- Review. One workspace setting decides which captures go live and which wait for a person. On the default setting most go live on their own, on trial. A secret, an install step or a risky shell command waits in every setting, and so does a capture that reverses a live rule its recorder could not retire. See what coding agents remember, and who approves it.
Everything on this page needs a terminal. The next surface needs none: ask your team’s knowledge from Slack, for the people on your team who will never run an agent.