How do we give our in-house background coding agent company context through an API instead of hoping the model calls a tool?
Fetch the context in the harness, not in the model. Before the agent's first turn, call a context API with the task text and the files it touches, then put the synthesized answer (decisions, related PRs, incidents, owners, conventions) in the prompt. Keep a research tool exposed for follow-ups, run the agent as a scoped service identity, and compare PRs with and without the packet.
Have your harness fetch the context and write it into the prompt before the model's first turn, then keep a tool available for follow-ups. A background coding agent runs from ticket to pull request with nobody watching, so "the model may call a tool" is not a plan. Context injection is the pattern where the harness calls a context API with what it knows about the task and puts the synthesized answer in the prompt. The same capability stays exposed as a tool for follow-ups. The model just never starts cold.
| Tool-calling only | Context injection | |
|---|---|---|
| Who decides the fetch happens | The model, each turn | The harness, in code |
| When | If and when the model asks | Before the first turn, after planning, before the PR |
| What the model receives | A tool result mid-task | A packet in the prompt, plus the tool |
| Failure mode unattended | A skipped call nobody sees | A bad packet you can diff and fix |
| Identity | The tool's credential | A scoped service token |
Why tool-calling alone is not enough when nobody is watching#
With the default tool_choice of auto, "Claude determines on each turn whether to call a tool or respond directly" (Anthropic tool use docs). A common first attempt is a system prompt line: "Always check Unblocked before you write code." Interactively that works; a person sees the skipped step. In a background loop nobody sees the skip until a reviewer opens the PR and finds a helper the team retired 3 months ago.
Anthropic's answer for the interactive case is hooks. Claude Code runs them "at specific points in its lifecycle, which gives you deterministic control: certain actions always happen rather than relying on the LLM to choose to run them" (Claude Code hooks guide). A UserPromptSubmit hook can return additionalContext, which "is injected as a system reminder that Claude reads as plain text". Your in-house harness should do the same one level up: run the fetch in code, so the model never has to decide. The harness is the product makes the general case.
What to fetch, and at which three points#
You already have the task text and the files it touches. What you want back is what a senior engineer gathers first: decisions about this area and why, related and rejected PRs, incidents the code was in, who owns it, and the conventions the repo does not state. Raphael Bres, CTO at Tradeshift, puts it plainly: "You cannot make coding agents work without domain and functional context. We connected and trained Unblocked on our Code repos, Atlassian tools, Internal docs, Product Documentation, KB from Support and Slack history. When an agent asks a question, it gets the full picture — not just the code analysis, but also why decisions were made and what the constraints are."
Unblocked exposes that as a REST call. POST /context/research takes a query, an optional instruction for focus and format, and an effort of low, medium or high. It returns a Markdown summary plus the sources behind it, each typed as code, pull request, issue, message or documentation (Unblocked API reference). It is available on plans that include the Context API; the reference lists a 403 otherwise. The context_research MCP tool returns the same summary-plus-sources shape. Fetch at 3 points:
- Before the first prompt, with the ticket text and a grep of the files, so the plan starts from history.
- After planning, with the plan as the query, because it names components the ticket did not.
- Before the PR opens, with the diff summary, to catch the convention or owner the agent missed.
The full packet is in context for background coding agents.
Keep it small: an answer with citations, not the documents#
The context packet is the synthesized summary plus a source list that the harness writes into the prompt. Do not inject the raw design doc, PR thread and incident timeline. A March 2026 paper opens from the finding that LLMs show "significant performance degradation as context length increases" (Cao et al., 2026). Inject the summary, keep the sources as titles and URLs, and let the agent pull a full source through context_get_urls on demand. We measured the gap in one run on one production repository, same prompt and model, with and without Unblocked attached: 42 percent fewer tokens and 64 percent fewer tool calls (same prompt, same model, different context).
The "API instead of a tool" framing is a false choice. MCP is a client-server protocol over JSON-RPC. Your harness can be the MCP client, call tools/call from code, and never show the model a tool definition. Its Streamable HTTP transport "supports standard HTTP authentication methods including bearer tokens, API keys, and custom headers" (MCP architecture). The Claude Agent SDK gives you "the same tools, agent loop, and context management that power Claude Code" in Python and TypeScript, with hooks and MCP set in code (Agent SDK overview).
Permissions: the agent is a service identity, so scope what it can read#
A service identity is a credential that belongs to the agent rather than to the engineer who filed the ticket. Unblocked issues two kinds of token. Personal Access Tokens are "scoped to your individual account", and the research endpoint attributes their requests "to the key's user". Team Access Tokens "can access every document in the data sources selected when the token is created". The docs say to select only the sources an integration needs, keep the token in a secret manager, and rotate it (Unblocked API quickstart). For example, an agent that opens PRs across the company gets a team token limited to the repos, trackers and channels it may learn from. A personal token copied from whoever set it up carries that person's access instead.
Keep the token out of the sandbox; Claude Code's cloud sessions show how. GitHub credentials "stay encrypted on Anthropic's servers and never enter a session's VM", and network secrets are "attached to matching requests after they leave the session" (Claude Code cloud sessions). A proxy in front of the context API does the same in your harness. Then log the calls. Unblocked's agent access log records the actor ("the person or API key that invoked the tool") and the tool name, for SIEM ingestion (agent access logs).
Evaluate: the same tickets with and without the packet#
Take 20 closed tickets, run the agent on each twice from the same commit, once with injected context and once without, and compare the PRs. Count what a reviewer would catch: a convention violated, an owner not tagged, a retired helper reintroduced, a fix an incident thread already ruled out. Then check that the injected PR names its citations.
One repository will not generalize; you are testing whether the fetch belongs in the harness. If the injected runs are not cleaner, the context API is the problem, not the pattern. The AI software factory post covers running a fleet of these agents.


