Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.3ngram.ai/llms.txt

Use this file to discover all available pages before exploring further.

3ngram works as an MCP server for Claude Managed Agents with zero configuration changes on the 3ngram side. Your agents get structured memory types, semantic search, due-date tracking, and proactive follow-through that Anthropic’s built-in Memory Stores don’t offer.

What are Managed Agents?

Claude Managed Agents is a hosted agent runtime from Anthropic. You define an agent config (model, system prompt, tools), then start sessions where Anthropic runs the agent loop and provisions a sandboxed container for tool execution. Agents connect to external services like 3ngram via MCP servers.

Prerequisites

  • A 3ngram account with at least one memory saved
  • An Anthropic API key with Managed Agents beta access
  • The Anthropic SDK installed (npm install @anthropic-ai/sdk or pip install anthropic)

Step 1: Complete the 3ngram OAuth flow

Before registering credentials with Anthropic, you need OAuth tokens from 3ngram. The easiest way is through any MCP client that supports OAuth:
  1. Connect to https://mcp.3ngram.ai/mcp from Claude Desktop, Claude Code, or Cursor (see Connecting Clients)
  2. Complete the OAuth authorization in your browser
  3. Note your access_token, refresh_token, and client_id from the OAuth response
If you already use 3ngram with Claude Code or Claude Desktop, you already have valid OAuth tokens. Check your client’s MCP configuration for the stored credentials.

Step 2: Create a vault and store credentials

Vaults hold MCP credentials that Anthropic auto-refreshes on your behalf. Create one and register your 3ngram OAuth tokens:
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

// Create a vault (one per workspace, reusable across agents)
const vault = await client.beta.vaults.create({
  metadata: { description: "3ngram memory credentials" },
});

// Register the 3ngram OAuth credential
await client.beta.vaults.credentials.create(vault.id, {
  display_name: "3ngram Memory",
  auth: {
    type: "mcp_oauth",
    mcp_server_url: "https://mcp.3ngram.ai/mcp",
    access_token: "<your-access-token>",
    expires_at: "2026-05-01T00:00:00Z",
    refresh: {
      refresh_token: "<your-refresh-token>",
      client_id: "<your-client-id>",
      token_endpoint: "https://mcp.3ngram.ai/mcp/oauth/token",
      token_endpoint_auth: { type: "none" },
    },
  },
});

console.log(`Vault ID: ${vault.id}`); // Save this for session creation
Anthropic matches credentials to MCP servers by URL and auto-refreshes tokens before they expire. You never need to manually rotate tokens.

Step 3: Create an agent with 3ngram

Agents are persistent, versioned configs. Create one once, then reuse it across sessions:
const agent = await client.beta.agents.create({
  name: "Knowledge Worker",
  model: "claude-sonnet-4-6",
  system: `You are a knowledge worker with persistent memory via 3ngram.

At the start of every session:
1. Use the briefing prompt to load open commitments, blockers, and recent decisions
2. Review what's overdue or stale

During work:
- Use remember() to persist decisions, context, and learnings
- Use search() to find relevant history across memories and indexed content
- Use propose_action() before taking irreversible actions

At the end of every session:
- Use the debrief prompt to extract and persist what was accomplished
- Use resolve() to mark completed commitments`,
  mcp_servers: [
    {
      type: "url",
      name: "3ngram",
      url: "https://mcp.3ngram.ai/mcp",
    },
  ],
  tools: [
    { type: "agent_toolset_20260401", default_config: { enabled: true } },
    {
      type: "mcp_toolset",
      mcp_server_name: "3ngram",
      default_config: {
        permission_policy: { type: "always_ask" },
      },
      configs: [
        { name: "search", permission_policy: { type: "always_allow" } },
        { name: "get_prompt", permission_policy: { type: "always_allow" } },
        { name: "get_schedule_history", permission_policy: { type: "always_allow" } },
        { name: "get_trigger_history", permission_policy: { type: "always_allow" } },
        { name: "export_doc", permission_policy: { type: "always_allow" } },
        { name: "remember", permission_policy: { type: "always_allow" } },
        { name: "set_preference", permission_policy: { type: "always_allow" } },
        { name: "configure_scope", permission_policy: { type: "always_allow" } },
        { name: "propose_action", permission_policy: { type: "always_allow" } },
      ],
    },
  ],
});

console.log(`Agent ID: ${agent.id}`); // Save this — reuse across sessions
Don’t create a new agent every run. Store the agent ID and reuse it. To change behavior, update the existing agent with client.beta.agents.update(agentId, { ... }) — each update creates a new version.

Step 4: Start a session

Each session is one run of your agent. Reference the agent, environment, and vault:
const environment = await client.beta.environments.create({
  name: "3ngram-env",
  config: {
    type: "cloud",
    networking: { type: "unrestricted" },
  },
});

const session = await client.beta.sessions.create({
  agent: agent.id,
  environment_id: environment.id,
  vault_ids: [vault.id],
});

// Stream-first: open stream before sending the kickoff message
const stream = await client.beta.sessions.stream(session.id);

await client.beta.sessions.events.send(session.id, {
  events: [
    {
      type: "user.message",
      content: [
        { type: "text", text: "Run my briefing, then help me plan today's work." },
      ],
    },
  ],
});

for await (const event of stream) {
  if (event.type === "agent.message") {
    for (const block of event.content) {
      if (block.type === "text") process.stdout.write(block.text);
    }
  }
  if (event.type === "session.status_terminated") break;
  if (event.type === "session.status_idle" && event.stop_reason?.type !== "requires_action") break;
}

Tool permission policies

MCP tools default to always_ask, which pauses the agent for human approval on every tool call. For autonomous operation, configure always_allow on safe tools. The table below shows recommended policies based on each tool’s behavior: These tools are safe for autonomous use. Read-only tools have no side effects; remember is scoped to memory persistence.
ToolRead-onlyWhy allow
searchYesCanonical search across memories + content, no side effects
get_promptYesReads prompt template
get_schedule_historyYesReads schedule history
get_trigger_historyYesReads trigger history
export_docYesExports Google Doc as text
rememberNoCore memory persistence
set_preferenceNoStores user/project settings
configure_scopeNoMaps project to scope
propose_actionNoExternalizes decisions for approval
These tools create, update, or delete resources. Require human approval to prevent unintended changes.
ToolDestructiveWhy ask
update_memoriesYesBulk-changes memory type/status, including archiving
set_memory_sharingYesCan revoke previously granted memory access
delete_promptYesRemoves prompt template
delete_scheduleYesRemoves scheduled run
delete_triggerYesRemoves trigger
create_scheduleNoCreates recurring agent runs
create_triggerNoCreates event listeners
create_promptNoCreates prompt template
update_promptNoModifies existing prompt
update_scheduleNoModifies schedule config
update_triggerNoModifies trigger config
create_docNoCreates Google Doc (external)
resolveYesMarks commitments complete and can trigger sync side effects
unresolveNoReopens resolved items
reindexYesFull reindex prunes orphan content_chunks for files no longer present
sync_sourceNoTriggers source re-sync
reapply_scope_mappingsNoBulk scope updates
To set per-tool policies, keep the mcp_toolset default at always_ask and explicitly allow only the safe autonomous tools. This fail-closed default ensures unlisted or newly-added tools still require human approval:
{
  "type": "mcp_toolset",
  "mcp_server_name": "3ngram",
  "default_config": {
    "permission_policy": { "type": "always_ask" }
  },
  "configs": [
    { "name": "search", "permission_policy": { "type": "always_allow" } },
    { "name": "get_prompt", "permission_policy": { "type": "always_allow" } },
    { "name": "get_schedule_history", "permission_policy": { "type": "always_allow" } },
    { "name": "get_trigger_history", "permission_policy": { "type": "always_allow" } },
    { "name": "export_doc", "permission_policy": { "type": "always_allow" } },
    { "name": "remember", "permission_policy": { "type": "always_allow" } },
    { "name": "set_preference", "permission_policy": { "type": "always_allow" } },
    { "name": "configure_scope", "permission_policy": { "type": "always_allow" } },
    { "name": "propose_action", "permission_policy": { "type": "always_allow" } }
  ]
}

Multi-agent pattern

Managed Agents support multi-agent sessions where a coordinator delegates to specialists. All agents in a session authenticate as the same user (via the shared vault), so they share the same 3ngram memory namespace. Pattern: The coordinator reads commitments for overall status and delegates tasks. Specialists use remember to persist findings and search to access shared context. All agents see the same memory pool. Use project tags and scopes for finer isolation between agents or workstreams within the shared namespace. See multi-agent-coordinator.json for a complete example config.

System prompt examples

Session startup

At the start of this session, use the 3ngram briefing prompt to load your
current context. Review open commitments, blockers, and overdue items before
beginning any work.

During work

When you learn something worth remembering, use remember() with an appropriate
memory type (decision, context, commitment, blocker, or learning).

Before making irreversible changes, use propose_action() to get user approval.

Use search() to check if relevant context exists before starting
new research.

Session end

Before ending this session, use the 3ngram debrief prompt to extract and
persist decisions, commitments, and learnings from this conversation.
Mark completed work with resolve().

Troubleshooting

Token refresh fails

Anthropic auto-refreshes tokens using the refresh.token_endpoint stored in your vault credential. If refresh fails:
  • Verify token_endpoint is https://mcp.3ngram.ai/mcp/oauth/token
  • Ensure the original refresh token hasn’t expired (30-day TTL — the access token has a 1-hour TTL and is rotated automatically)
  • Re-authorize via any MCP client and update the vault credential

Tools not discovered

  • Confirm the MCP server URL is exactly https://mcp.3ngram.ai/mcp
  • Check that mcp_toolset in tools references the correct mcp_server_name
  • Verify the vault credential’s mcp_server_url matches the agent’s mcp_servers[].url

MCP resources not accessible

Managed Agents cannot read MCP resources (like engram://commitments) directly. Use the briefing tool to fan all four accountability views into one call, or fall back to scoped search(source_type="memory", memory_type=...) calls:
  • briefing(project=...) returns commitments, blockers, overdue, and stale in one structured payload
  • search(source_type="memory", memory_type="commitment", status="open") for open commitments only
  • search(source_type="memory", memory_type="blocker", status="open") for active blockers
  • search(source_type="memory", memory_type="commitment", status="open", due_before=<today>) for past-due items

Rate limits

3ngram’s rate limiter is tuned for interactive use. Long-running agent sessions with many tool calls may hit per-tool cooldowns. If you see rate limit errors, space out tool calls or contact support for higher limits.

Budget limits

3ngram tracks LLM-cost spend per user via user_budgets (default budget is provisioned on activation). Any tool call that invokes an LLM internally draws from this budget — including embedding-backed tools like remember and search, and scheduled agent runs that issue model calls. Active subscriptions also gate access to MCP tools via require_subscription. If you see “LLM budget exceeded” errors during managed-agent runs, check usage and current plan on the dashboard.

What’s next