Quickstart

Connect Marrow Core to your application or agent. Learn how to ingest your first source document, query task-specific context with inspectable source lineage, and verify how connected tools receive up-to-date details.

Before you start

  1. Create a Marrow account with email, Google, or Apple, then open Console.
  2. Create an API key named Quickstart. HTTP, TypeScript, Python, and CLI need ingest, query, and query.answer. Server-managed MCP and MCP over stdio need query, query.answer, memory.read, and memory.write.
  3. Copy the key once and store it in your shell, process manager, or secret store. Never put it in source code, browser code, command arguments, MCP configuration, screenshots, logs, or chat.
  4. For HTTP, TypeScript, Python, or CLI, create the example file below. Hosted MCP and MCP over stdio add the same two facts as messages.
printf '%s\n' \
  '# Launch update' \
  'Project updates should begin with the decision and use short bullets.' \
  'The open launch risk is onboarding copy approval.' \
  > marrow-quickstart.md

Every route uses the same example and question:

How should the launch update be structured, and what risk is still open?

The current Answer mode reports supported output with disposition: partial; it does not claim that it proved a complete answer.

The public clients used below are @marrowid/cli@1.0.11, @marrowid/sdk@1.0.11, and marrowid==1.0.11. Python imports the client with from marrow import Marrow.

Choose a route

HTTP

Create a key with ingest, query, and query.answer, then set these server-side environment variables:

export MARROW_API_BASE_URL="https://api.marrow.id"
export MARROW_API_KEY="<copy-once key>"

Submit the file and keep the returned job.id:

CONTENT_BASE64="$(base64 < marrow-quickstart.md | tr -d '\n')"

curl -sS -X POST "$MARROW_API_BASE_URL/v1/ingest/file" \
  -H "Authorization: Bearer $MARROW_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"marrow-quickstart.md\",\"contentType\":\"text/markdown\",\"contentBase64\":\"$CONTENT_BASE64\",\"dryRun\":false,\"datedAt\":\"2026-07-22\",\"idempotencyKey\":\"quickstart-http-20260722\"}"

Poll until the job reaches succeeded, failed, or quarantined:

export MARROW_JOB_ID="<job.id>"
curl -sS "$MARROW_API_BASE_URL/v1/ingest/jobs/$MARROW_JOB_ID" \
  -H "Authorization: Bearer $MARROW_API_KEY"

After the job succeeds, ask the question:

curl -sS -X POST "$MARROW_API_BASE_URL/v1/query" \
  -H "Authorization: Bearer $MARROW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"idempotencyKey":"quickstart-http-query-20260722","mode":"answer","preset":"accuracy","query":"How should the launch update be structured, and what risk is still open?"}'

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: marrow-quickstart.md, including the update format and the open launch risk.

Troubleshooting

  • Keep polling while the job is queued or running.
  • Reuse the same idempotency key only when retrying the same file bytes.
  • A 401 or 403 response usually means the key is missing, revoked, or lacks the required scope.

TypeScript

Create a key with ingest, query, and query.answer, set MARROW_API_KEY, and install the SDK in a trusted Node.js application:

npm install @marrowid/sdk@1.0.11
import { readFile } from "node:fs/promises";
import { Marrow } from "@marrowid/sdk";

const marrow = new Marrow({
  apiKey: process.env.MARROW_API_KEY!,
  baseURL: "https://api.marrow.id",
});

const queued = await marrow.ingest.file({
  filename: "marrow-quickstart.md",
  contentType: "text/markdown",
  content: await readFile("marrow-quickstart.md"),
  dryRun: false,
  datedAt: "2026-07-22",
  idempotencyKey: "quickstart-typescript-20260722",
});

if (queued.schemaVersion !== "marrow-ingest-job-v1") {
  throw new Error("Expected a queued ingest job.");
}

const job = await marrow.ingest.jobs.wait(queued.job.id);
if (job.job.status !== "succeeded") {
  throw new Error(`Ingest ended with ${job.job.status}`);
}

const result = await marrow.query(
  "How should the launch update be structured, and what risk is still open?",
  {
    mode: "answer",
    preset: "accuracy",
    idempotencyKey: "quickstart-typescript-query-20260722",
  },
);

console.log(result.answer?.text);

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: marrow-quickstart.md, including the update format and the open launch risk.

Troubleshooting

  • Run this code on the server, not in a browser bundle.
  • Wait for succeeded before querying.
  • If TypeScript rejects a field, confirm that @marrowid/sdk@1.0.11 is installed.

Python

Create a key with ingest, query, and query.answer, set MARROW_API_KEY, and install the Python client:

python -m pip install marrowid==1.0.11
import os
from marrow import Marrow

client = Marrow(
    api_key=os.environ["MARROW_API_KEY"],
    host="https://api.marrow.id",
)

queued = client.ingest.file(
    "marrow-quickstart.md",
    content_type="text/markdown",
    dry_run=False,
    dated_at="2026-07-22",
    idempotency_key="quickstart-python-20260722",
)
job = client.ingest.jobs.wait(queued["job"]["id"])
if job["job"]["status"] != "succeeded":
    raise RuntimeError(f"Ingest ended with {job['job']['status']}")

result = client.query(
    "How should the launch update be structured, and what risk is still open?",
    mode="answer",
    preset="accuracy",
    idempotency_key="quickstart-python-query-20260722",
)
print(result["answer"]["text"] if result["answer"] else result["execution"])

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: marrow-quickstart.md, including the update format and the open launch risk.

Troubleshooting

  • Confirm the installed version with python -c "from marrow import __version__; print(__version__)".
  • Wait for succeeded before querying.
  • A missing MARROW_API_KEY raises an authentication error before a useful result can be returned.

CLI

Install the CLI, create a key with ingest, query, and query.answer, and set MARROW_API_KEY in the terminal session:

npm install -g @marrowid/cli@1.0.11
marrow --version
marrow init
marrow doctor

Add the file, inspect the job, and ask the question:

marrow ingest file ./marrow-quickstart.md \
  --dated-at 2026-07-22 \
  --idempotency-key quickstart-cli-20260722

marrow ingest jobs show <job-id>

marrow query \
  "How should the launch update be structured, and what risk is still open?" \
  --mode answer \
  --preset accuracy \
  --idempotency-key quickstart-cli-query-20260722

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: marrow-quickstart.md, including the update format and the open launch risk.

Troubleshooting

  • Run marrow doctor to check local configuration and key presence.
  • Keep polling until the ingest job succeeds.
  • Add --json only when automation needs the structured response.

Hosted MCP

Connect a remote-capable MCP client to:

https://mcp.marrow.id

A person connecting their own client can use interactive authorization. A server-managed client can use a dedicated key with query, query.answer, memory.read, and memory.write in the client’s protected authorization setting.

Confirm that the client lists the 14 Marrow tools in the MCP tool table. For this example, use a group peer named quickstart-launch-team and a session named quickstart-launch-update, then make these calls:

create_peer
{"peer":"quickstart-launch-team"}

create_session
{"session":"quickstart-launch-update"}

add_messages_to_session
{"peer":"quickstart-launch-team","session":"quickstart-launch-update","messages":[{"role":"user","content":"Project updates should begin with the decision and use short bullets."},{"role":"user","content":"The open launch risk is onboarding copy approval."}]}

get_event_status
{"event":"<event_id returned by add_messages_to_session>"}

query_context
{"mode":"answer","peer_ids":["quickstart-launch-team"],"session_ids":["quickstart-launch-update"],"query":"How should the launch update be structured, and what risk is still open?"}

Poll get_event_status until the write succeeds before calling query_context.

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: the two messages added to the quickstart-launch-update session for group peer quickstart-launch-team.

Troubleshooting

  • If the client lists a different tool count, reconnect it and check the Marrow endpoint.
  • A wrong-scope error means the connected application or key lacks a required query, Answer, or memory permission.
  • Disconnect the application in Console if the client should no longer have access.

MCP over stdio

Install the CLI and create a dedicated key with query, query.answer, memory.read, and memory.write. The MCP host process must inherit MARROW_API_KEY; do not put the key in client JSON.

npm install -g @marrowid/cli@1.0.11
marrow mcp --help

Configure the client to launch Marrow locally:

{
  "mcpServers": {
    "marrow": {
      "command": "marrow",
      "args": ["mcp"],
      "env": {
        "MARROW_WORKSPACE": "default"
      }
    }
  }
}

For this example, use a group peer named quickstart-launch-team and a session named quickstart-launch-update. Restart the client, confirm that it lists the 14 tools in the MCP tool table, then call create_peer, create_session, add_messages_to_session, get_event_status, and query_context with the same arguments shown in the Hosted MCP route.

Expected result

The launch update should begin with the decision and use short bullets. The open risk is onboarding copy approval.

Supporting source: the two messages added to the quickstart-launch-update session for group peer quickstart-launch-team.

Troubleshooting

  • Start the MCP client from the process that has MARROW_API_KEY.
  • If marrow mcp is not found, check the global npm binary directory or use an absolute command path in the client configuration.
  • Poll the returned event until it succeeds before reading memory.

Remove the Quickstart data

For HTTP, TypeScript, Python, or CLI, delete the example source with its job.sourceId, then poll the returned deletion job until it succeeds:

curl -sS -X DELETE "$MARROW_API_BASE_URL/v1/sources/<job.sourceId>" \
  -H "Authorization: Bearer $MARROW_API_KEY"

For Hosted MCP or MCP over stdio, call delete_session for quickstart-launch-update and delete_peer for quickstart-launch-team, then poll each returned event id with get_event_status. These deletions remove only the named example resources.

Next steps