Jonatan Matajonmatum.com
conceptsnotesexperimentsessays
© 2026 Jonatan Mata. All rights reserved.v2.1.1
Experiments

Serverless Second Brain

Production-ready serverless backend for a personal knowledge graph — DynamoDB, Lambda, Bedrock, MCP, Step Functions. The implementation of the architecture described in the 'From Prototype to Production' essay.

evergreen#serverless#aws#knowledge-graph#second-brain#terraform#bedrock#dynamodb#mcp#agentcore#lambda#architecture#production

What it is

The production implementation of the serverless second brain described in the essay of the same name. While the essay defines the architecture — memory, compute, and interface layers with "two doors" for humans and agents — this repository is the code that brings it to life.

Available as source code.

Architecture

The system separates three layers with clear responsibilities:

Loading diagram...
  • Memory: DynamoDB single-table design with GSIs for bidirectional queries + S3 for long-form content
  • Compute: 5 specialized Lambda functions (capture, search, graph, connect, flag) orchestrated by Step Functions
  • Interface: two doors — API Gateway REST for the human SPA, AgentCore Gateway for MCP agents

Bedrock provides classification (Claude) and embeddings (Titan 1,024 dimensions).

Progress

The project follows four phases defined in the essay. All four phases are complete and deployed to dev:

PhaseComponentsStatus
1 — CaptureTerraform foundation, DynamoDB, S3, Capture Lambda, API Gateway, Step Functions, data migration✅ Complete
2 — ReadSearch Lambda (hybrid keyword + semantic), Graph Lambda, CloudFront + S3 frontend✅ Complete
3 — AgentAgentCore MCP Gateway with 6 tools, Connect Lambda, Flag Lambda, write safety✅ Complete
4 — SurfacingSurfacing Lambda with 5 analyzers, EventBridge daily digest, SNS email✅ Complete
Cross-cuttingBenchmarks, domain-agnostic config, observability🔲 Pending

What works today

Human door (API Gateway REST):

  • POST /capture — ingests text, classifies with Bedrock Claude, generates embeddings with Titan, persists to DynamoDB + S3 via Step Functions
  • GET /search?q= — hybrid keyword + semantic search with cosine similarity over 1,024-dimension embeddings
  • GET /graph — full knowledge graph (nodes + bidirectional edges)
  • GET /nodes/{id} — single node with edges and related nodes
  • GET /health — health check

Agent door (AgentCore MCP Gateway):

  • read_node — reads a node by slug with metadata, edges, and related nodes
  • list_nodes — lists nodes with filters by type, status, and tags
  • search — hybrid keyword + semantic search
  • add_node — creates a seed node with automatic Bedrock classification
  • connect_nodes — creates bidirectional edges with audit trail
  • flag_stale — flags a node for human review without modifying it

Surfacing (daily digest):

  • 5 analyzers: stale seeds, orphan nodes, missing connections, promotion candidates, content gaps
  • EventBridge daily cron at 8 AM UTC → Surfacing Lambda → SNS email
  • Configurable thresholds via environment variables (STALE_DAYS, MIN_EDGES, SIMILARITY_THRESHOLD)
  • Verified in dev: 17 stale seeds, 1 orphan, 40 content gaps in ~2.5s for 170 nodes

Infrastructure:

  • CloudFront + S3 for static frontend hosting
  • Full migration of ~160 nodes from jonmatum.com MDX to DynamoDB + S3
  • Embedding backfill for all existing nodes
  • CI/CD with GitHub Actions OIDC (no static credentials)
  • Smoke test script with 12 endpoint verifications
  • GitHub Actions OIDC role in bootstrap Terraform

Resilience (deep review #3):

  • invokeWithRetry() with exponential backoff for Bedrock throttling (1s, 2s, 4s)
  • Capture pipeline creates bidirectional edges (consistency with connect_nodes)
  • batchGetNodes() eliminates N+1 queries in Graph Lambda
  • CORS on all error paths, Content-Type on all responses
  • Prod deployment in CI/CD gated on environment approval

Agent door: MCP Gateway

The "agent door" exposes Lambda functions as MCP tools via Bedrock AgentCore. Any MCP-compatible agent can discover and use the tools semantically:

MCP ToolLambdaOperationWrite
read_nodeGraphRead node + edges + relatedNo
list_nodesGraphList/filter nodesNo
searchSearchHybrid keyword + semantic searchNo
add_nodeCaptureCreate seed node with AI classificationYes
connect_nodesConnectCreate bidirectional edgeYes
flag_staleFlagFlag node for reviewYes

Write safety

Write operations follow strict controls:

  • Audit trail: every mutation creates an AUDIT# item in DynamoDB with actor, action, changes, and 90-day TTL
  • Seed-only: nodes created by agents start as seed — human review required for promotion
  • No deletes: agents cannot delete nodes, only flag them for review with flag_stale
  • Actor tracking: every operation records the actor (agent:{session_id} or api)
  • Existence validation: connect_nodes verifies both nodes exist before creating edges
// Audit trail on every write operation
const audit: AuditItem = {
  PK: `AUDIT#${now}`,
  SK: `NODE#${slug}`,
  action: "connect",
  actor,
  changes: { source, target, edge_type, weight },
  ttl: Math.floor(Date.now() / 1000) + 90 * 86400,
};
await putAudit(audit);

DynamoDB design

Single-table design with four item types:

PKSKData
NODE#serverlessMETAType, status, titles, summaries, tags, timestamps
NODE#serverlessEDGE#aws-lambdaRelationship type, weight, direction
NODE#serverlessEMBED1,024-dimension vector (Titan V2)
AUDIT#2026-03-19T10:30:00ZNODE#serverlessAction, author, diff

Two GSIs enable inverse queries and status filters:

  • GSI1: SK (hash) + PK (range) — "what nodes point to serverless?"
  • GSI2: GSI2PK (status) — "all seeds not updated in 7 days"

Capture pipeline

Step Functions orchestrates the full pipeline with automatic retry on Bedrock throttling:

Loading diagram...

Each step is a separate Lambda invocation. Express Workflow (synchronous) keeps the response within API Gateway timeout.

Hybrid search

The Search Lambda combines keyword matching and semantic similarity:

// Hybrid search: keyword + semantic
const keywordResults = await queryByKeywords(query, table);
const queryEmbedding = await generateEmbedding(query);
const allEmbeddings = await scanEmbeddings(table);
 
const semanticResults = allEmbeddings
  .map(item => ({
    slug: item.PK.replace("NODE#", ""),
    score: cosineSimilarity(queryEmbedding, item.embedding),
  }))
  .sort((a, b) => b.score - a.score);
 
// Combine scores with configurable weights
const combined = mergeResults(keywordResults, semanticResults, {
  keywordWeight: 0.3,
  semanticWeight: 0.7,
});

At current scale (~160 nodes, ~700KB of vectors) the in-memory scan is sufficient. The scalability benchmark (issue #12) will evaluate alternatives for 10K+ nodes.

Infrastructure as code

All infrastructure is defined with Terraform using reusable modules:

infra/
  bootstrap/              → State backend (S3 + DynamoDB lock)
  modules/
    dynamodb/             → Single-table design + GSIs
    lambda/               → Compute functions
    api-gateway/          → Human door (REST)
    step-functions/       → Pipeline orchestration
    s3/                   → Content and frontend
    cloudfront/           → CDN + security headers
    iam/                  → Roles and policies
    agentcore-gateway/    → Agent door (MCP)
    sns/                  → Notifications
  environments/
    dev/                  → Dev config (deployed)
    prod/                 → Prod config

CI/CD uses GitHub Actions with OIDC — no static AWS credentials:

  • terraform-plan.yml — plan on PRs
  • terraform-apply.yml — apply on merge to main
  • lambda-deploy.yml — function packaging and deployment

Cost

Scales to zero. No minimum costs beyond S3 storage:

LoadMonthly cost
Idle (0 req/day)~$0.51
Moderate (100 req/day)~$2.44
High (1,000 req/day)~$11.21

Architecture decision records

The repository includes 12 ADRs (Architecture Decision Records) in docs/decisions/ documenting every technical decision with context, alternatives evaluated, benchmark data, and revisit criteria:

ADRDecision
001Lambda packaging (zip) with no web framework
002Write safety — 6 controls for MCP agent mutations
003Cognito authentication and visibility model (proposed)
004DynamoDB single-table design with 2 GSIs
005Hybrid keyword + semantic search with configurable weights
006Step Functions Express for capture pipeline
007AgentCore Gateway over self-hosted MCP server
008In-memory embedding scan (temporary, until ~5K nodes)
009Spec-Driven Development — 7 steering files before code
010Bedrock token optimization — 20 recent slugs vs all
011CloudFront + S3 over Vercel/Amplify
012GitHub Actions OIDC over static credentials

Next steps

  • AgentCore Runtime (issue #8) — hosting the reasoning agent in serverless microVMs with access to all Gateway tools
  • Observability (issue #14) — CloudWatch dashboards, alarms, X-Ray tracing
  • Domain-agnostic config (issue #13) — make the system deployable for any domain with terraform apply
  • Authentication (issue #17) — implement ADR-003: Cognito + public/private visibility model

Why it matters

This project translates a reference architecture into deployable code. The goal is for any builder to take the repository, configure their domain (legal, research, education) in terraform.tfvars, and deploy a complete second brain with terraform apply. The essay explains the "why" behind each decision; the code implements the "how."

All four phases already demonstrate the architecture works: capture with automatic classification, hybrid semantic search, a bidirectional knowledge graph, an MCP door for AI agents with write safety controls, and a proactive daily digest that identifies forgotten seeds and missing connections — all serverless, all in Terraform, scaling to zero at ~$0.51/month idle cost.

References

  • From Prototype to Production: A Serverless Second Brain — Essay defining the complete architecture.
  • GitHub Repository — Project source code.
  • AWS Serverless Lens — AWS, 2024. Framework for serverless applications.
  • DynamoDB Developer Guide — AWS, 2024. Single-table design guide.
  • Bedrock AgentCore — AWS, 2025. MCP Gateway and Runtime for agents.
  • AgentCore Gateway Developer Guide — AWS, 2025. MCP gateway documentation for Lambda tools.
  • MCP Specification — Anthropic, 2025. Interoperability protocol for agents.
  • Step Functions Developer Guide — AWS, 2024. Serverless workflow orchestration.

Related content

  • Serverless

    Cloud computing model where the provider manages infrastructure automatically, allowing code execution without provisioning or managing servers, paying only for actual usage.

  • AWS Lambda

    AWS serverless compute service that runs code in response to events without provisioning or managing servers, automatically scaling from zero to thousands of concurrent executions.

  • AWS DynamoDB

    AWS serverless NoSQL database with single-digit millisecond latency at any scale, ideal for applications requiring high performance and automatic scalability.

  • AWS Bedrock

    AWS serverless service providing access to foundation models from multiple providers (Anthropic, Meta, Mistral, Amazon) via unified API, without managing ML infrastructure.

  • AWS API Gateway

    AWS managed service for creating, publishing, and managing REST, HTTP, and WebSocket APIs that act as entry points to Lambda functions and other backend services.

  • AWS Step Functions

    AWS serverless orchestration service that coordinates multiple services into visual workflows using Amazon States Language (ASL), with built-in error handling, retries, and parallel execution.

  • AWS EventBridge

    AWS serverless event bus connecting applications using events, enabling decoupled event-driven architectures with rule-based routing.

  • AWS SNS

    AWS pub/sub messaging service that distributes messages to multiple subscribers simultaneously, enabling fan-out patterns and notifications at scale.

  • AWS S3

    AWS object storage service with 99.999999999% durability, unlimited scalability, and multiple storage classes for cost optimization.

  • AWS IAM

    AWS identity and access management service controlling who can do what in your account, with granular policies based on the principle of least privilege.

  • Knowledge Graphs

    Data structures representing knowledge as networks of entities and relationships, enabling reasoning, connection discovery, and semantic queries over complex domains.

  • Model Context Protocol (MCP)

    Open protocol created by Anthropic that standardizes how AI applications connect with external tools, data, and services through a universal interface.

  • Infrastructure as Code

    Practice of defining and managing infrastructure through versioned configuration files instead of manual processes. Foundation of modern operations automation.

  • Cost Optimization

    Practices and strategies to minimize cloud spending without sacrificing performance, including right-sizing, reservations, spot instances, and eliminating idle resources.

  • AWS Well-Architected Framework

    AWS framework with six pillars of best practices for designing and operating reliable, secure, efficient, and cost-effective cloud systems.

Experiments