---
title: "Load Product Knowledge and Offers From Claude Code"
description: "Load product knowledge, offers and testimonials into FirstSales from Claude Code with the CLI, then test what your agent can safely say."
date: "2026-09-09"
tags: "knowledge-base, claude-code, offerings, cli, ai-sdr, cold-email"
readTime: "26 min read"
author: "FirstSales Team"
slug: "knowledge-base-offers-claude-code"
canonical: "https://firstsales.io/blog/knowledge-base-offers-claude-code/"
---

# Load Product Knowledge and Offers From Claude Code

**TL;DR:** Your outbound agent should not learn your product from a pasted prompt. Put approved facts in a FirstSales knowledge base, put sellable packages in offerings, put real customer proof in testimonials, and let Claude Code load, query and update all three through the `firstsales` CLI.

---

## Table of contents

- [The point of view: a knowledge base is a claims register](#the-point-of-view-a-knowledge-base-is-a-claims-register)
- [Why prompts are the wrong home for product facts](#why-prompts-are-the-wrong-home-for-product-facts)
- [What goes where: knowledge base, offerings, testimonials, skill file](#what-goes-where-knowledge-base-offerings-testimonials-skill-file)
- [Before you touch anything: confirm identity and scope](#before-you-touch-anything-confirm-identity-and-scope)
- [Step 1: read the current state](#step-1-read-the-current-state)
- [Step 2: write the source documents locally](#step-2-write-the-source-documents-locally)
- [Step 3: create the knowledge base and add sources](#step-3-create-the-knowledge-base-and-add-sources)
- [Step 4: query it like a skeptical buyer would](#step-4-query-it-like-a-skeptical-buyer-would)
- [Step 5: create offerings](#step-5-create-offerings)
- [Step 6: add testimonials without inventing proof](#step-6-add-testimonials-without-inventing-proof)
- [Step 7: keep it current](#step-7-keep-it-current)
- [Retrieval quality: why your questions return weak answers](#retrieval-quality-why-your-questions-return-weak-answers)
- [Where MCP fits and where it does not](#where-mcp-fits-and-where-it-does-not)
- [Mistakes that put false claims in emails](#mistakes-that-put-false-claims-in-emails)
- [FAQ](#faq)
- [Conclusion](#conclusion)

## The point of view: a knowledge base is a claims register

Most teams treat a knowledge base as a library. Load every document, hope the agent finds the right paragraph.

We treat it as a **claims register**. Every sentence in it is something you are willing to see in a cold email with your name on it, and anything else stays out.

That one decision changes how you load it, how you test it and how you update it. A library rewards volume.

A claims register rewards restraint.

Claude Code is a good tool for this job because it can read your files, run the CLI, compare the result and show you a diff before anything changes. It is a bad tool for deciding what is true about your product.

That part stays with a human.

This post walks through the full loop with real `firstsales` commands: read state, write sources, load them, interrogate them, create offerings, add proof and keep it all fresh. For a wider picture of where this sits in an agent setup, see [the five layers of an AI outbound agent stack](/blog/ai-outbound-agent-stack).

## Why prompts are the wrong home for product facts

Pasting your positioning into a prompt feels fast. It also copies your facts into every place you paste them, and each copy ages on its own schedule.

Gartner's sales practice has a direct warning about this. In a June 2025 release about its survey of 632 B2B buyers, VP Analyst Robert Blaisdell said that when sellers provide information that does not match the organization's messaging elsewhere, "it can create mistrust, potentially putting the transaction at risk" ([Demand Gen Report, summarizing Gartner](https://www.demandgenreport.com/industry-news/news-brief/3-out-of-5-b2b-buyers-prefer-a-rep-free-buying-experience-gartner/49802)).

A prompt that says your price starts at one number while the pricing page says another is exactly that mismatch. The buyer sees both within a minute.

Buyers also check you out before they answer. Gartner's March 2026 release on a survey of 646 buyers found that 45% used generative AI during a recent purchase, mostly to gather information on vendors and products ([Gartner press release](https://www.gartner.com/en/newsroom/press-releases/2026-03-09-gartner-sales-survey-finds-67-percent-of-b2b-buyers-prefer-a-rep-free-experience)).

Your cold email is compared against whatever the open web and your own site say.

So the job is not "give the agent more context." The job is "give the agent one version of the truth and make every other surface agree with it." Our post on [cold email offer clarity](/blog/cold-email-offer-clarity) covers the writing side of that. This post covers the storage side.

### Three failure patterns we see when facts live in prompts

The first is drift. Someone edits the pricing page and forgets the prompt file, so the agent keeps quoting last quarter.

The second is overreach. A prompt that says "we help teams grow pipeline" gives a model room to invent specifics, such as connectors you do not have or results you never measured.

The third is invisibility. Nobody can audit what an agent was told, because the instruction lives in a chat history or a local note that three people edited.

A knowledge base fixes all three in the same way. It is a named object in your workspace, with sources you can list and a query endpoint you can test.

## What goes where: knowledge base, offerings, testimonials, skill file

FirstSales gives you separate places for different kinds of fact. The README for `@firstsales.io/cli` describes the knowledge base and offerings as the way "to keep sales context current and to let agents retrieve approved positioning before writing or replying."

Use the split below. Mixing these is the most common reason answers come back vague.

| Kind of fact | Where it belongs | CLI group | Why |
|---|---|---|---|
| What the product does, who it is for, how it works | Knowledge base | `kb` | Long-form, queryable, changes slowly |
| What you sell, in packages a buyer can say yes to | Offerings | `offerings` | Short, structured, one clear ask each |
| Real customer proof with permission | Testimonials | `testimonials` | Tied to a campaign, must be genuine |
| How Claude should behave in your repo | Skill file or project notes | none | Instructions, not claims |
| Secrets, API keys, passwords | Nowhere in any of the above | `api-keys` | Never paste into a prompt or doc |

The table above is the whole architecture. If a fact does not fit a row, it probably is not a fact yet.

### A skill file is not a knowledge base

Claude Code supports skills, which are folders with a `SKILL.md` that teach Claude a procedure. The [Claude Code skills documentation](https://code.claude.com/docs/en/skills) describes them as an extension mechanism, and Claude Code watches skill directories for changes during a session.

That makes a skill the right home for "how we load the knowledge base" and the wrong home for "what the product costs." Procedures belong in the skill. Claims belong in the register.

The FirstSales package ships three Claude Code skills named `firstsales-cli`, `firstsales-product-mcp` and `firstsales-developer-api`. The first one tells an agent to verify identity, read state before mutating and re-read after, and that is the loop this post follows.

### Where the offer sits relative to the pitch

An offering is the thing a buyer could say yes to. A knowledge base article explains how the product works, and an offering says what you are asking them to do next, at what scope.

If you cannot write the offering in one sentence a stranger would understand, no amount of retrieval will rescue the email. We go deeper on this in [custom pain points](/blog/custom-pain-points), which shows how a specific pain turns a generic pitch into a reason to reply.

## Before you touch anything: confirm identity and scope

Every command below assumes the CLI is installed and configured. If it is not, `npm i -g @firstsales.io/cli` installs the `firstsales` binary, and the keys go in environment variables, never in a prompt.

```bash
export FIRSTSALES_API_KEY="<YOUR_FIRSTSALES_API_KEY>"
export FIRSTSALES_BASE_URL="https://api.app.firstsales.io"
firstsales whoami --json
firstsales doctor --pretty
```

`whoami` validates the active key and prints the user, key, organization and workspace context without exposing raw or hashed keys. Run it first every time.

If the workspace it reports is not the one you meant, stop.

Then find the identifiers you will pass to every later command.

```bash
firstsales orgs list --json
firstsales workspaces list --org org_123 --json
```

Create a dedicated key for this job. The reasoning is in [API keys for outbound agents](/blog/api-keys-for-outbound-agents): an agent that edits product knowledge does not need to start campaigns or touch billing.

```bash
firstsales api-keys create --org org_123 \
  --data '{"name":"kb-editor","scopes":["<scopes from your org>"],"accessLevel":"workspace"}' \
  --json
```

The README example uses scope strings like `campaigns:read` and `contacts:write`. We are not listing the knowledge base scope names here, because the live API is the authority.

Read the scope list in your own organization, grant the narrowest set that covers `kb`, `offerings` and `testimonials`, and note that `api-keys create` prints the raw key once and never again.

Two details matter. Do not pass `--idempotency-key` to `api-keys create`, because raw keys are reveal-once.

And never paste the key into a chat with Claude.

## Step 1: read the current state

Read before you write. This is the first rule in the `firstsales-cli` skill, and it saves you from creating a second knowledge base next to a forgotten first one.

```bash
firstsales kb list --org org_123 --workspace ws_123 --json
firstsales offerings list --org org_123 --workspace ws_123 --json
```

For testimonials, the README says to use `testimonials list` with `--campaign`, so the proof is tied to a campaign rather than floating at workspace level.

```bash
firstsales testimonials list --org org_123 --workspace ws_123 --campaign camp_123 --json
```

Ask Claude Code to summarize what it finds as a table: object name, id, last update, number of sources. Do not ask it to "clean up." You want an inventory first and a plan second.

### What the inventory usually shows

Teams that have used the app for a while often find a knowledge base created during onboarding and never touched again. That old object is the first thing to decide on: update it or replace it.

If its sources are out of date, replacing is cleaner. Deleting is permanent, though.

`kb delete` is one of the destructive commands and requires `--confirm`, so make the replacement first, test it, and only then consider removing the old one.

## Step 2: write the source documents locally

Do the writing in plain files in a git repository. A repository gives you history, review and rollback, three things a chat box never gives you.

A layout that works:

```text
sales-knowledge/
  product/what-it-does.md
  product/how-it-works.md
  pricing/current-pricing.md
  proof/approved-results.md
  limits/what-we-do-not-do.md
  claims.md
```

The last two files matter most and are the ones people skip.

### The "what we do not do" file

Language models fill gaps with plausible things. If your knowledge base says nothing about a capability, a draft can imply it exists.

So write down the edges. List connectors you do not have, regions you do not serve, company sizes you are a bad fit for and promises you will not make.

A short, blunt document of limits does more to prevent false claims than another page of features.

### The claims file

`claims.md` is the register itself. Each line is one claim, with a source and an owner and a review date.

| Claim | Source | Owner | Review by | Allowed in cold email |
|---|---|---|---|---|
| Starts at a stated price | Pricing page, current | Founder | 2026-12-01 | ✓ |
| Works with a named system | Docs page | Product lead | 2026-12-01 | ✓ |
| Customer X saw a specific lift | Signed case study | Marketing | 2027-01-15 | ✓ with permission |
| "Best in the market" | None | None | None | ✗ |
| Guarantees inbox placement | None | None | None | ✗ |

The ✗ rows are the point. Writing down what you may not say is how the agent learns where the fence is.

Our post on [pricing in cold email](/blog/pricing-in-cold-email) is a good companion for deciding which numbers belong in a first message.

### Write for retrieval, not for display

A knowledge base is read in chunks. A model asks a question, a retrieval step finds a few passages and the answer is built from those passages alone.

So each passage should stand by itself. Name the product and the subject in the first sentence of each section, put the number next to its unit and date, and avoid "as mentioned above."

Anthropic's engineering team made this point about chunking in its [Contextual Retrieval write-up](https://www.anthropic.com/engineering/contextual-retrieval): a chunk that loses its surrounding context becomes hard to retrieve. Their method of adding context to each chunk reduced failed retrievals by 49%, and by 67% when combined with reranking, on their test set.

Writing self-contained sections gives you part of that benefit for free.

## Step 3: create the knowledge base and add sources

Now load it. The CLI has `kb create`, `kb add-sources`, `kb get` and `kb update`, and mutating commands take their body from `--data` or `--data-file`.

We are deliberately not printing a JSON body here. The field names for a knowledge base are defined by the public OpenAPI contract, and `firstsales commands --json` is the local registry authority.

Invented field names are how a blog post ends up teaching people a broken command.

What we can show is the shape of a safe load, using the flags the README documents:

```bash
firstsales kb create --org org_123 --workspace ws_123 \
  --data-file kb-create.json --dry-run

firstsales kb create --org org_123 --workspace ws_123 \
  --data-file kb-create.json --idempotency-key kb-create-2026-10-08 --json
```

The first call uses `--dry-run`, which prints the method, URL, redacted headers and body without sending anything and without needing the key. The second sends it, with an idempotency key so a retry cannot create two knowledge bases.

Then read it back to get the id:

```bash
firstsales kb list --org org_123 --workspace ws_123 --json
firstsales kb get --org org_123 --workspace ws_123 --kb kb_123 --json
```

### Adding sources

Sources go in with `kb add-sources`. Treat each batch like a deploy.

```bash
firstsales kb add-sources --org org_123 --workspace ws_123 --kb kb_123 \
  --data-file sources-batch-1.json --dry-run
```

Check the dry-run output with Claude Code before you remove the flag. Ask it to confirm three things: the target knowledge base id is the one you intended, the document count matches your folder and no file in the batch is something you would not publish.

That last check matters. If a draft pricing sheet, an internal roadmap or a customer list sits in the folder, it will be retrieved and quoted.

Claude Code can scan the batch for obvious risk, such as names of customers without permission, "internal only" markers and numbers that do not appear on any public page.

### A note on web sources

Some teams point a knowledge base at their own website rather than uploading files. That is fine for pages you control, with one catch: the page and the register must agree.

If the page says one thing and `claims.md` says another, fix the page first.

Do not point a knowledge base at third-party pages you do not control. Those pages can change, and the change lands in your agent without anyone reviewing it.

The risk is the same one described in [MCP security for outbound](/blog/mcp-security-outbound), applied to content instead of tools.

## Step 4: query it like a skeptical buyer would

Loading is not done until you have asked it hard questions. The CLI gives you `kb query`, and the README shows the body shape for a query: a JSON object with a `query` field.

```bash
firstsales kb query --org org_123 --workspace ws_123 --kb kb_123 \
  --data '{"query":"What problems do we solve?"}'
```

One question proves nothing. Build a test set.

### The 20-question test set

Write twenty questions in a file, in four groups of five.

1. **Positioning:** who is it for, who is it not for, what does it replace.
2. **Specifics:** pricing, limits, supported systems, setup time.
3. **Proof:** what results can you cite, from whom, with what permission.
4. **Traps:** things the product does not do, phrased as if it does.

The fourth group is where you learn the most. Ask "Does it guarantee inbox placement?" and "Can it send from a personal phone number?" A good knowledge base answers no, or returns nothing, and does not invent a way.

Have Claude Code run each query, save the raw answers to a file and mark each one as supported, unsupported or wrong. A wrong answer means a source is missing, ambiguous or contradicted by another source.

```bash
while read -r q; do
  printf '%s\n' "$q" | jq -R '{query: .}' > /tmp/q.json
  firstsales kb query --org org_123 --workspace ws_123 --kb kb_123 \
    --data-file /tmp/q.json >> kb-answers.jsonl
done < questions.txt
```

The loop uses only commands and flags from the README. Keep the answers file in the repository next to the sources, so a later change can be compared to it.

### How to grade the answers

Use three grades and no more.

A **supported** answer matches a line in `claims.md` and does not add anything. An **unsupported** answer sounds right but cites nothing in your sources.

A **wrong** answer contradicts the register.

Unsupported answers are the dangerous ones, because they pass a casual read. If more than a few of the twenty come back unsupported, the knowledge base is too thin or too vague, and adding more documents will not help.

Rewrite the sections that failed.

Our post on [AI email quality at scale](/blog/ai-email-quality-at-scale) describes the same grading idea applied to drafts, and [the outbound AI eval set](/blog/outbound-ai-eval-set) shows how to keep a fixed test set over time.

## Step 5: create offerings

An offering is a package a buyer can accept. Create one per thing you would sell in a first conversation, and keep the list short.

```bash
firstsales offerings list --org org_123 --workspace ws_123 --json
firstsales offerings create --org org_123 --workspace ws_123 \
  --data-file offering-1.json --dry-run
```

As with the knowledge base, the body fields come from the public contract, so read the schema before you write the file.

### What makes a good offering

Write it from the buyer's side. "A 30 minute teardown of your current outbound setup" is something a person can say yes to.

"Our platform" is not.

Each offering should have one outcome, one scope and one next step. If you find yourself writing "and" three times, split it into two offerings.

Keep pricing out of offerings unless you want it quoted. Anything in an offering is fair game for a draft, so every number should also be in `claims.md` with an owner.

### Offerings and campaigns

Offerings give a campaign something specific to ask for. A campaign without one tends to end in "let me know if you are interested," which is the weakest ask in cold email.

If you are building the campaign itself, create it with `firstsales campaigns create` and edit it afterwards. The walkthrough is in [building a cold email campaign from Claude Code](/blog/claude-code-cold-email-campaign), and the writing workflow is in [writing with a Claude Code skill, launching with FirstSales](/blog/cold-email-skill-to-launch).

## Step 6: add testimonials without inventing proof

Testimonials are the fastest way to get a false claim into an email, because they feel safe. They are quotes, after all.

The README documents `testimonials list`, `testimonials add` and `testimonials update`, each tied to a campaign with `--campaign`, with updates also needing `--testimonial`. Mutations take `--data` or `--data-file`.

```bash
firstsales testimonials add --org org_123 --workspace ws_123 \
  --campaign camp_123 --data-file testimonial-1.json --dry-run
```

### Rules for proof

Only add a testimonial when three things are true. The person said it, you have written permission to use it, and you can show the source if challenged.

Never ask Claude to "write a testimonial" or "make this sound better." Light edits for length are fine if the person approves the edited text. Anything else is fabricated proof, and in the United States it can also create trouble under the FTC's rules on deceptive advertising, which the agency flags alongside its [CAN-SPAM guidance for business](https://www.ftc.gov/business-guidance/resources/can-spam-act-compliance-guide-business).

Put the permission record in your repository: the date, the person, the channel and the approved wording. Then the testimonial in FirstSales is a copy of a record you can point to.

### Matching proof to the reader

A testimonial from a company of a different size or industry can hurt more than help. Tag each one in your register with who it is from, and let campaigns pick the closest match.

For a deeper look at how proof works in a first email, read [case study cold email](/blog/case-study-cold-email).

## Step 7: keep it current

A knowledge base that was right in October is wrong by March. The fix is a routine, not a heroic cleanup.

### A monthly diff routine

Once a month, ask Claude Code to do this in order:

1. Pull the live pricing page, docs index and changelog and compare them to `claims.md`.
2. List every claim whose review date has passed.
3. For each changed claim, propose an edit to the source file and show the diff.
4. After you approve the diff, update the knowledge base and re-run the 20-question test.

Step four is the one that closes the loop. Compare the new answers file to the old one, and look for answers that changed when you did not expect them to.

```bash
firstsales kb update --org org_123 --workspace ws_123 --kb kb_123 \
  --data-file kb-update.json --dry-run
firstsales kb get --org org_123 --workspace ws_123 --kb kb_123 --json
```

The README recommends the same shape for every mutation: inspect, plan the smallest change, preview with `--dry-run`, mutate, then re-read and verify.

### Retire things on purpose

When a product changes, remove the old claim and add the new one. A knowledge base holding both "supports feature A" and "feature A was removed" will answer either way.

Deletion is final. `kb delete` and `offerings delete` both need `--confirm`, and there is no undo.

Keep the removed text in git so you can restore it by loading it again.

### Tie updates to launches

Add a line to your release checklist: "Did a claim change?" If yes, the register changes in the same pull request as the product change.

It costs one minute at release time and saves a week of wrong emails afterward. Teams that run outbound as an engineering function, a role we describe in [the GTM engineer role](/blog/gtm-engineer-role), tend to adopt this habit first.

## Retrieval quality: why your questions return weak answers

When a query returns something vague, resist the urge to add more documents. Work through these causes in order.

| Symptom | Likely cause | Fix |
|---|---|---|
| Right topic, wrong detail | Passage lacks its subject | Rewrite so each section names the product and topic |
| Contradictory answers | Two sources disagree | Delete or fix one source, re-load |
| Confident answer, no source | Register has a gap | Add the claim or add it to the limits file |
| Answer mixes old and new | Stale source still loaded | Remove the old source, re-run the test set |
| Nothing returned | Question phrased unlike the docs | Add a short Q and A section using buyer wording |

The last row deserves a note. Buyers do not use your internal vocabulary.

If your docs say "workflow orchestration" and the buyer asks "can it send follow ups automatically," the match is weak.

Add a plain section titled with real buyer questions and short answers. This is cheap, and it helps both retrieval and the humans reading the same documents.

### Small knowledge bases need less machinery

Anthropic notes in the same Contextual Retrieval post that if a knowledge base is smaller than about 200,000 tokens, roughly 500 pages, you can include the whole thing in the prompt and skip retrieval. We do not recommend that for outbound, because it brings back the copy-and-drift problem and removes your ability to audit what was retrieved.

The better lesson is the opposite. A tight knowledge base of a few dozen well-written pages beats a sprawling one, and it is easier to keep true.

## Where MCP fits and where it does not

The Model Context Protocol is an open standard for connecting AI tools to external systems, and the [Claude Code MCP documentation](https://code.claude.com/docs/en/mcp) describes how to attach servers. FirstSales has a product MCP server at `https://api.app.firstsales.io/mcp`, which uses the `streamable-http` transport and OAuth.

The tool list depends on your tenant and your grant. The `firstsales-product-mcp` skill tells agents to treat the live `tools/list` response as the authority, and says the released catalog is read-only today.

For this workflow, that means one thing: do not assume you can create or edit a knowledge base through MCP. Use the CLI for writes.

Use MCP, if you have it connected, for reading context while you draft.

If you are weighing the two, [CLI, MCP or the app: which for which job](/blog/cli-vs-mcp-vs-app-outbound) lays out the decision, and [what MCP is for sales teams](/blog/what-is-mcp-for-sales) is the starting point if the protocol is new to you. The connection steps are in [connecting FirstSales MCP to Claude Code](/blog/firstsales-mcp-claude-code-setup).

### What we did not verify

We did not verify how every drafting surface inside the app consumes the knowledge base. The CLI README says agents can retrieve approved positioning through it, and this post treats the knowledge base as the store your agent queries.

Check your own drafts after a load, using the test set.

## Mistakes that put false claims in emails

Most bad claims trace back to a handful of habits. Each is easy to catch if you know where to look.

**Loading everything.** Folders of old decks, drafts and internal notes end up in retrieval. Load only what you would publish.

**Skipping the limits file.** The agent fills silence with plausible features. Write the edges down.

**Testing once.** A single good answer says nothing about the other nineteen. Keep the test set and re-run it after every change.

**Letting Claude write proof.** Claude can format a testimonial. It cannot grant permission for one.

**Putting keys in prompts.** A key in a chat is a key in a log. Use environment variables and a narrow key.

**Never expiring claims.** Every claim gets a review date. When the date passes, it is checked or it is gone.

### Review before send

None of this removes the need for a person on the send path. The knowledge base lowers the chance of a bad claim, and it does not drop it to zero.

Before any campaign goes live, run the readiness check and send yourself a test, as covered in [the campaign readiness check](/blog/campaign-readiness-check-cli) and [sending a test email from Claude Code](/blog/send-test-email-claude-code).

The CLI commands for that are `firstsales campaigns readiness` and `firstsales campaigns send-test-email`, and both run before `firstsales campaigns start`. Our guardrails post, [guardrails for email-sending agents](/blog/email-agent-guardrails), explains why an approval step belongs in the loop, and [human in the loop cold email](/blog/human-in-the-loop-cold-email) covers how to staff it.

Unsupervised sending is the failure that makes every other mistake expensive. We cover its costs in [unsupervised AI outbound](/blog/unsupervised-ai-outbound).

## A worked example of the full loop

Here is the order of operations as one checklist, written so Claude Code can follow it and a human can audit it. The people, products and numbers in this sketch are placeholders, not a customer story.

1. Run `firstsales whoami --json` and confirm the workspace.
2. Run `kb list`, `offerings list` and `testimonials list` and save the output.
3. Write or update the source files and `claims.md` in git.
4. Run `kb create` or `kb update` with `--dry-run`, review, then run it for real with an idempotency key.
5. Run `kb add-sources` with `--dry-run`, review, then run it for real.
6. Run the 20-question test with `kb query` and save the answers.
7. Grade the answers and fix any wrong or unsupported ones at the source.
8. Create or update offerings, one clear ask each.
9. Add only permissioned testimonials to the right campaign.
10. Commit the sources, the answers file and the grading notes.

The diagram below shows the same flow with the human gates marked.

```mermaid
graph TD
    A[Write sources and claims in git] --> B[Dry run the load]
    B --> C{Human reviews dry run}
    C -->|Approve| D[Load knowledge base]
    C -->|Reject| A
    D --> E[Run 20 question test]
    E --> F{Any wrong or unsupported answers}
    F -->|Yes| A
    F -->|No| G[Create offerings]
    G --> H[Add permissioned testimonials]
    H --> I[Readiness check and test email]
    I --> J[Human starts campaign]
```

Notice that the loop returns to the source files, never to the knowledge base itself. Fix the cause, not the symptom.

## Working with the rest of the stack

A knowledge base feeds the writing step. The upstream and downstream steps still need their own care.

Upstream, your lists and research decide who reads the claims. Our guides on [importing leads from the terminal](/blog/import-leads-from-terminal) and [the research agent versus the writing agent](/blog/ai-research-agent-vs-writing-agent) explain why research and writing should be separate jobs with separate checks.

Downstream, the campaign workflow decides what is sent. [Editing a campaign workflow by chatting with Claude](/blog/edit-campaign-workflow-with-claude) shows how to change steps safely once the claims are in place.

If you want the whole terminal picture in one read, start with [running outbound from the terminal](/blog/outbound-from-the-terminal). And if you are still deciding where a tool like FirstSales fits next to what you already run, [where FirstSales fits in the outbound stack](/blog/where-firstsales-fits-outbound-stack) answers that.

### Learn from wins

Once campaigns run, feed real outcomes back into the register. [Training AI on won deals](/blog/train-ai-on-won-deals) explains which signals to trust.

The rule that carries over: a claim earns a place in the register because it was true and useful, not because it sounded good.

## FAQ

### What is a knowledge base in FirstSales?

It is a named object in your workspace that holds the documents your agent can retrieve when it needs approved facts about your product. You manage it with the `kb` command group: `list`, `create`, `get`, `update`, `delete`, `query` and `add-sources`.

### How do I load a knowledge base from Claude Code?

Install the CLI, set your API key in an environment variable, confirm the workspace with `firstsales whoami`, then run `firstsales kb create` and `firstsales kb add-sources` with a `--data-file` body. Preview each step with `--dry-run` first.

### Can Claude Code create a knowledge base through MCP?

Do not assume so. The product MCP skill says the released catalog is read-only today and that the live `tools/list` response is the authority.

Use the CLI for creating and editing.

### What is the difference between a knowledge base and an offering?

A knowledge base holds explanatory facts, such as what the product does and how it works. An offering is a sellable package with one outcome and one next step, which a campaign can ask a buyer to accept.

### How do I test what my knowledge base will say?

Run `firstsales kb query` with a fixed set of about twenty questions that cover positioning, specifics, proof and things the product does not do. Save the answers and grade each as supported, unsupported or wrong.

### What should never go into a knowledge base?

Secrets, customer lists, unreleased roadmap, draft pricing and anything you would not want quoted in an email to a stranger. If a document is marked internal, leave it out.

### Do I need to write the JSON bodies myself?

Yes, for mutating commands, through `--data` or `--data-file`. Take the field names from the public OpenAPI contract at `developer.firstsales.io`, or from `firstsales commands --json`, rather than guessing them.

### What does `--dry-run` do?

It prints the method, URL, redacted headers and body without sending the request. It also works without a key, so you can inspect a command safely before you run it for real.

### Why use an idempotency key on creates?

It makes a retry safe. If a network error hides the response and you run the command again, the same key tells the API it is the same request, so you do not end up with two knowledge bases.

Do not use one with `api-keys create`.

### How many offerings should I create?

Only as many as you would sell in a first conversation. Two to four is common.

Each should have one outcome and one next step.

### Can I add testimonials without a campaign?

The documented commands tie testimonials to a campaign with `--campaign`. Create or pick the campaign first, then add the proof to it.

### Is it safe to let Claude write testimonials?

No. A testimonial is a record of what a person said and agreed to share.

Claude can format approved text, and it cannot supply permission or invent a quote.

### How often should I update the knowledge base?

Review it monthly, and also whenever pricing, features or positioning change. Give every claim a review date so staleness shows up on its own.

### What happens if two sources disagree?

Retrieval can return either one. Fix the disagreement at the source, remove the stale document, and re-run your test set to confirm the answers settle.

### Should I upload my whole website?

Upload the pages that state facts you stand behind: product, pricing, limits and proof. Skip blog posts that describe old versions and anything you would not want quoted back.

### Can I delete a knowledge base and restore it?

Deletion needs `--confirm` and cannot be undone through the CLI. Keep your source files in git, so you can load them into a new knowledge base if you need to.

### How does this relate to compliance?

The knowledge base lowers the chance of false claims, but your emails still need to follow rules such as the FTC's CAN-SPAM requirements, which apply to business-to-business email as well. See [the 2026 legality guide](/blog/is-cold-email-legal-2026) for the practical checklist.

### Do I still need human review if the knowledge base is good?

Yes. Run the readiness check, send a test email to yourself and keep a person on the approval path.

Retrieval reduces errors and does not remove the need for review.

### What is a claims register?

It is a file that lists each claim your emails may make, with its source, owner, review date and whether it is allowed in cold email. It turns the knowledge base from a pile of documents into a controlled set of statements.

### Where do I start if I have nothing written down?

Write the limits file first. List what the product does not do, then write the three claims you are most confident about, with sources.

Load those, test them and grow from there.

## Conclusion

The takeaway is plain. Product knowledge belongs in one governed place, and the cheapest way to keep an agent honest is to control what it is allowed to know.

Here is the short version of the workflow:

- Treat the knowledge base as a claims register, not a library.
- Keep sources, claims and test answers in git.
- Preview every write with `--dry-run`, and use idempotency keys on creates.
- Test with twenty questions, including the ones about what you do not do.
- Create offerings with one clear ask each.
- Add only permissioned testimonials.
- Review monthly, and retire claims on purpose.
- Keep a person on the send path, with readiness check and test email first.

If you want to run this workflow in a real workspace, install the CLI with `npm i -g @firstsales.io/cli`, start with `firstsales whoami`, and read the state before you change anything. Next, set up the campaign side with [building a cold email campaign from Claude Code](/blog/claude-code-cold-email-campaign).

Never paste an API key into a prompt or a post, and remember that delete commands cannot be undone.