{"id":50164077,"url":"https://github.com/jonmatum/serverless-second-brain","last_synced_at":"2026-05-24T19:08:48.052Z","repository":{"id":345842274,"uuid":"1187605698","full_name":"jonmatum/serverless-second-brain","owner":"jonmatum","description":"Serverless backend for a personal knowledge graph on AWS — DynamoDB, Lambda, Bedrock, API Gateway, CloudFront. Phases 1-2 deployed, 3-4 in progress.","archived":false,"fork":false,"pushed_at":"2026-04-24T04:02:13.000Z","size":718,"stargazers_count":0,"open_issues_count":22,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T06:07:59.321Z","etag":null,"topics":["ai-agents","api-gateway","aws","bedrock","dynamodb","eventbridge","infrastructure-as-code","knowledge-graph","lambda","mcp","pkm","second-brain","serverless","step-functions","terraform"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonmatum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-20T23:25:13.000Z","updated_at":"2026-04-24T04:00:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jonmatum/serverless-second-brain","commit_stats":null,"previous_names":["jonmatum/serverless-second-brain"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jonmatum/serverless-second-brain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonmatum%2Fserverless-second-brain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonmatum%2Fserverless-second-brain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonmatum%2Fserverless-second-brain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonmatum%2Fserverless-second-brain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonmatum","download_url":"https://codeload.github.com/jonmatum/serverless-second-brain/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonmatum%2Fserverless-second-brain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33446824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-24T18:26:54.182Z","status":"ssl_error","status_checked_at":"2026-05-24T18:26:53.408Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","api-gateway","aws","bedrock","dynamodb","eventbridge","infrastructure-as-code","knowledge-graph","lambda","mcp","pkm","second-brain","serverless","step-functions","terraform"],"created_at":"2026-05-24T19:08:42.786Z","updated_at":"2026-05-24T19:08:48.043Z","avatar_url":"https://github.com/jonmatum.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless Second Brain\n\n\u003e ⚠️ **Work in progress** — Phases 1–2 deployed and functional, Phases 3–4 not yet started.\n\nServerless backend for a personal knowledge graph on AWS. DynamoDB, Lambda, Bedrock, API Gateway, CloudFront, and Cognito.\n\nFrom the essay: [From Prototype to Production: A Serverless Second Brain on AWS](https://jonmatum.com/essays/from-prototype-to-production-serverless-second-brain)\n\n## Architecture\n\n```mermaid\nflowchart TB\n  accTitle: Serverless second brain architecture\n  accDescr: Three layers — Interface, Compute, Memory — with AWS services per block and two access doors for humans and AI agents\n\n  User((User))\n  Agent((AI Agent))\n\n  subgraph Interface\n    CF[CloudFront + S3]\n    APIGW[API Gateway REST]\n    GW[AgentCore Gateway]\n  end\n\n  subgraph Compute\n    LCapture[Lambda Capture]\n    LSearch[Lambda Search]\n    LGraph[Lambda Graph]\n    ACR[AgentCore Runtime]\n    EB[EventBridge Scheduler]\n    LSurface[Lambda Surfacing]\n  end\n\n  subgraph Memory\n    DDB[(DynamoDB)]\n    S3C[S3 Content]\n  end\n\n  subgraph AI\n    BR[Bedrock Claude]\n    BRE[Bedrock Embeddings]\n  end\n\n  User -- \"browser\" --\u003e CF\n  User -- \"REST API\" --\u003e APIGW\n  Agent -- \"MCP\" --\u003e GW\n\n  APIGW -- \"/capture\" --\u003e LCapture\n  APIGW -- \"/search\" --\u003e LSearch\n  APIGW -- \"/graph\" --\u003e LGraph\n\n  LCapture -- \"async\" --\u003e LEnrich[Lambda Enrich]\n\n  GW -- \"MCP tools\" --\u003e LCapture\n  GW -- \"MCP tools\" --\u003e LSearch\n  GW -- \"MCP tools\" --\u003e LGraph\n\n  ACR -- \"reasons\" --\u003e BR\n  EB -- \"daily cron\" --\u003e LSurface\n\n  LCapture -- \"writes\" --\u003e DDB\n  LCapture -- \"stores MDX\" --\u003e S3C\n  LCapture -- \"classifies\" --\u003e BR\n  LCapture -- \"embeddings\" --\u003e BRE\n\n  LSearch -- \"queries\" --\u003e DDB\n  LSearch -- \"query embedding\" --\u003e BRE\n  LGraph -- \"reads edges\" --\u003e DDB\n  LSurface -- \"reads\" --\u003e DDB\n  LSurface -- \"notifies\" --\u003e SNS[SNS]\n```\n\n## Two doors, same brain\n\n| Door | Protocol | Auth | Use case |\n|---|---|---|---|\n| Human | REST API (API Gateway) | Cognito JWT for writes, open reads | SPA, curl, integrations |\n| Agent | MCP (AgentCore Gateway) | OAuth + semantic discovery | AI agents, Copilot, Claude |\n\nBoth doors call the same Lambda functions — the difference is protocol and auth.\n\n## Cost\n\nScales to zero. No minimum costs beyond S3 storage.\n\n| Load | Monthly cost |\n|---|---|\n| Idle (0 req/day) | ~$0.51 |\n| Moderate (100 req/day) | ~$2.44 |\n| High (1,000 req/day) | ~$11.21 |\n\nReal cost data: [`docs/benchmarks/results.md`](docs/benchmarks/results.md)\n\n## API\n\n| Method | Endpoint | Description | Auth |\n|---|---|---|---|\n| `POST` | `/capture` | Ingest text → Bedrock classifies → DynamoDB | Cognito JWT |\n| `GET` | `/search?q=` | Hybrid keyword + semantic search | None |\n| `GET` | `/graph` | Full knowledge graph (nodes + edges) | None |\n| `GET` | `/nodes/{id}` | Single node with edges and related nodes | None |\n| `GET` | `/health` | Service health check | None |\n\nFull API spec: [`.kiro/steering/api-spec.md`](.kiro/steering/api-spec.md)\n\n## MCP tools (agent door)\n\n| Tool | Lambda | Description |\n|---|---|---|\n| `read_node` | Graph | Read a single node by slug |\n| `list_nodes` | Graph | List nodes with filters |\n| `search` | Search | Semantic + keyword search |\n| `add_node` | Capture | Create a new knowledge node |\n| `connect_nodes` | Capture | Create an edge between nodes |\n| `flag_stale` | Surfacing | Mark a node for review |\n\nFull MCP spec: [`.kiro/steering/mcp-tools.md`](.kiro/steering/mcp-tools.md)\n\n## Phased delivery\n\nEach phase is independently deployable.\n\n| Phase | Components | Status |\n|---|---|---|\n| 1 — Capture | Terraform foundation, DynamoDB, S3, Capture Lambda, API Gateway, Cognito auth | ✅ Deployed |\n| 2 — Read | Search Lambda, Graph Lambda, CloudFront + S3 frontend | ✅ Deployed |\n| 3 — Agent | AgentCore Gateway + Runtime, MCP tools, reasoning agent | 🔲 Not started |\n| 4 — Proactive | EventBridge scheduler, Surfacing Lambda, SNS notifications | 🔲 Not started |\n\n## Architecture Decision Records\n\nEvery significant technical decision is documented in [`docs/decisions/`](docs/decisions/):\n\n| ADR | Decision | Status |\n|---|---|---|\n| [001](docs/decisions/001-lambda-packaging-and-framework.md) | Lambda packaging (zip) with no web framework | Accepted |\n| [002](docs/decisions/002-mcp-write-safety.md) | Write safety — 6 controls for MCP agent mutations | Accepted |\n| [003](docs/decisions/003-authentication-and-visibility.md) | Cognito authentication and visibility model | Accepted |\n| [004](docs/decisions/004-dynamodb-single-table-design.md) | DynamoDB single-table design with 2 GSIs | Accepted |\n| [005](docs/decisions/005-hybrid-search-strategy.md) | Hybrid keyword + semantic search | Accepted |\n| [006](docs/decisions/006-step-functions-express-capture-pipeline.md) | Step Functions Express for capture pipeline | Superseded |\n| [007](docs/decisions/007-agentcore-gateway-over-self-hosted-mcp.md) | AgentCore Gateway over self-hosted MCP server | Accepted |\n| [008](docs/decisions/008-in-memory-embedding-scan.md) | In-memory embedding scan (temporary) | Accepted |\n| [009](docs/decisions/009-spec-driven-development.md) | Spec-Driven Development approach | Accepted |\n| [010](docs/decisions/010-bedrock-token-optimization.md) | Bedrock token optimization — recent slugs | Accepted |\n| [011](docs/decisions/011-cloudfront-s3-static-hosting.md) | CloudFront + S3 over Vercel/Amplify | Accepted |\n| [012](docs/decisions/012-github-actions-oidc.md) | GitHub Actions OIDC over static credentials | Accepted |\n| [013](docs/decisions/013-vite-spa-over-nextjs.md) | Vite SPA over Next.js | Accepted |\n| [014](docs/decisions/014-async-enrichment-pipeline.md) | Async enrichment — split capture into sync + async | Accepted |\n\n\u003e ADR-006 superseded: capture now uses a monolithic Lambda handler via API Gateway Lambda proxy integration. Step Functions infrastructure and step handlers have been fully removed.\n\n## Prerequisites\n\n- AWS account with Bedrock model access enabled:\n  - `us.anthropic.claude-sonnet-4-20250514-v1:0`\n  - `amazon.titan-embed-text-v2:0`\n- Terraform \u003e= 1.5\n- Node.js 22.x\n- GitHub repo with OIDC configured for AWS\n\n## Project structure\n\n```\ninfra/\n  bootstrap/              → One-time Terraform state backend\n  modules/                → Reusable Terraform modules\n  environments/{dev,prod} → Environment roots\n\nsrc/\n  functions/{capture,enrich,search,graph,connect,flag,surfacing}/\n  shared/                 → Types, clients, HTTP helpers, math, key prefixes\n\nfrontend/                 → React SPA (Vite + TailwindCSS)\n\nscripts/                  → Migration, benchmarks, utilities\ndocs/decisions/           → ADRs\ndocs/benchmarks/          → Performance and cost data\n.kiro/steering/           → SDD specifications\n.github/workflows/        → CI/CD (GitHub Actions OIDC)\n```\n\n## Specifications\n\nAll contracts defined before code — [Spec-Driven Development](https://jonmatum.com/concepts/spec-driven-development):\n\n- [`architecture.md`](.kiro/steering/architecture.md) — layers, services, cost constraints, phases\n- [`dynamodb-schema.md`](.kiro/steering/dynamodb-schema.md) — single-table design, item types, GSIs\n- [`api-spec.md`](.kiro/steering/api-spec.md) — REST endpoints, schemas, error codes\n- [`mcp-tools.md`](.kiro/steering/mcp-tools.md) — MCP tool definitions, write safety rules\n- [`event-schemas.md`](.kiro/steering/event-schemas.md) — EventBridge, SNS contracts\n- [`terraform-conventions.md`](.kiro/steering/terraform-conventions.md) — naming, modules, state, security\n- [`code-conventions.md`](.kiro/steering/code-conventions.md) — TypeScript, Lambda patterns, commits\n\n## Development\n\n```sh\n# Bootstrap (one-time)\ncd infra/bootstrap \u0026\u0026 terraform init \u0026\u0026 terraform apply\n\n# Deploy\ncd infra/environments/dev \u0026\u0026 terraform init \u0026\u0026 terraform apply\n\n# Lambda development\ncd src/functions/capture \u0026\u0026 npm install \u0026\u0026 npm run build\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonmatum%2Fserverless-second-brain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonmatum%2Fserverless-second-brain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonmatum%2Fserverless-second-brain/lists"}