Wednesday, September 09, 2026

Building a Snowflake Cortex DBA Alert Analyst Agent

This document outlines the creation of an AI-assisted Database Operations Alert Analyst Agent designed to reduce operational "alert noise". It utilizes a standardized schema across on-premise Oracle and AWS RDS databases, with data synchronized into Snowflake in near real-time via Fivetran replication. A dedicated semantic view maps the rigid database schema into natural language synonyms, allowing users to interact with the data without writing manual SQL. Built natively within Snowflake using standard compute resources, the agent is configured with a specific persona to identify recurring patterns, prioritize critical severities, and explain database error codes. Ultimately, this MVP deployment establishes a foundational architecture for real-time operational awareness and future automated workflows.


Saturday, August 08, 2026

Prompt-Based AI Agents: Designing Systems Where Plain Text Is the Architecture

Prompt-Based AI Agents: Designing Systems Where Plain Text Is the Architecture

Prompt-Based AI Agents: Designing Systems Where Plain Text Is the Architecture

Software architecture usually treats code as the source of truth and natural language as documentation. Prompt-based AI agents flip this model entirely: the workflow, domain rules, and decision-making logic live in plain English Markdown files, while code acts solely as an execution engine.

By paring an agent down to its essentials, you can build a flexible system around two core primitives: * The Playbook (The Instructions): A natural language document defining goals, step-by-step reasoning, constraints, and output formats. * The Runtime (The Engine): A lightweight script that feeds the playbook to a Large Language Model (LLM) and executes any actions the model requests.


Architectural Breakdown: Separating Logic from Code

In traditional software, adding a feature requires writing explicit if/else logic, custom functions, and output parsers. In a prompt-based architecture, control flow is emergent—the LLM decides the steps dynamically based on the playbook.

  • Code as a Dumb Pipe: The underlying code knows nothing about business domains, databases, or specific APIs. It simply passes user input and playbook instructions to the model, executes generic requests (like making an HTTP call), and returns raw responses back to the model.
  • The Autonomous ReAct Loop: The agent operates on a continuous Reason -> Act -> Observe cycle. The model evaluates user intent against the playbook, decides whether to trigger an action, observes the result, and repeats until it can construct a final answer.
  • Instant Domain Swapping: Because domain knowledge is completely decoupled from the codebase, changing the agent's entire function requires only pointing the runtime at a different Markdown file. The code stays identical whether the agent is querying a database, auditing system health, or managing internal tickets.

Conceptual Parallels: Playbooks vs. Claude Code Skills

This design pattern closely mirrors how Claude Code Skills operate. Both treat structured natural language as executable code:

Concept Prompt-Based Agent Claude Code Skills
Logic Layer Playbook (.md file) Custom Skill (SKILL.md)
Action Layer Generic HTTP Tool OS Primitives (Bash, Read, Write)
Runtime Custom LLM Script Claude Code CLI Engine
  • Declarative Capabilities: Instead of writing Python or TypeScript modules to expand what the agent can do, you write clear instructions describing how to perform a task.
  • General-Purpose Primitives: Both systems avoid bespoke, single-use tools. Instead, they give the LLM broad execution primitives (like raw API requests or shell commands) and rely on the instruction file to guide how those tools are used safely and effectively.
  • Adaptive Control Flow: If an action fails—such as an API returning an error—the LLM uses the playbook's guidance to interpret the failure and dynamically adjust its strategy without crashing the application.

High-Level Trade-offs

Pros

  • Zero-Code Expansion: Adding new capability requires writing Markdown, not code.
  • Human-Readable Logic: Non-engineers can review and audit agent behavior easily.
  • Minimal Maintenance: Very small codebase footprint with minimal wrapper boilerplate.

Cons

  • Non-Deterministic Output: Models may occasionally deviate from instructional paths.
  • Prompt Brittleness: Unclear prompt wording can trigger unexpected tool calls or formats.
  • Higher Cost & Latency: Multi-step tool loops send prompts back and forth across every iteration.

When to Use This Pattern

  • Ideal Use Cases: Internal automation tools, rapid prototyping, and flexible domains where requirements change rapidly and non-engineers need to tune behavior without redeploying code.
  • Poor Use Cases: Safety-critical or financial operations requiring strict determinism, or high-throughput microservices where LLM round-trip latency is unacceptable.

Explore the Codebase

To see how a minimal runtime script and Markdown playbooks work together in practice, check out the repository on GitHub:

Wednesday, July 01, 2026

Using Oracle SQLcl MCP with Claude Code CLI tool

While SQL Developer for VS Code provides a built-in "one-click" MCP for Copilot, Claude Code requires you to explicitly add the database MCP server (like SQLcl for Oracle or generic SQL servers) using its CLI.

Here are the steps I used to configure it with CC: 

 (1) Download SQLcl 

You may download the latest Oracle SQLcl tool which supports MCP at https://www.oracle.com/database/sqldeveloper/technologies/sqlcl/download/ , current version 26.1.
 
In my case, it was downloaded last year with version 25.2 it is at my local path: C:\users\dsun\sqlcl-latest\sqlcl\bin 

(2) Add the SQL MCP Server In my project directory C:\Users\dsun\ClaudeCode_DBA_Assistant:
PS C:\Users\dsun\ClaudeCode_DBA_Assistant> claude mcp add --transport stdio sqlcl -- C:\users\dsun\sqlcl-latest\sqlcl\bin\sql -mcp
Added stdio MCP server sqlcl with command: C:\users\dsun\sqlcl-latest\sqlcl\bin\sql -mcp to local config
File modified: C:\Users\dsun\.claude.json [project: C:\Users\dsun\ClaudeCode_DBA_Assistant]
(3) Verify the Connection
 
PS C:\Users\dsun\ClaudeCode_DBA_Assistant> claude mcp list
sqlcl: C:\users\dsun\sqlcl-latest\sqlcl\bin\sql -mcp - v Connected
PS C:\Users\dsun\ClaudeCode_DBA_Assistant>

(4) Create a saved connection Note: using -thin is necessary in my environment to avoid error from " thick client "
PS C:\users\dsun\sqlcl-latest\sqlcl\bin> .\sql -thin 'test/"xxzzzzzz"@dbhost1.mycompany.com:1521/testdb'


SQLcl: Release 25.2 Production on Wed Jul 01 07:07:37 2026

Copyright (c) 1982, 2026, Oracle.  All rights reserved.

Last Successful login time: Wed Jul 01 2026 07:07:42 -04:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.28.0.0.0

SQL> conn -save testdb_cc -savepwd
Name: testdb_cc
Connect String: dbhost1.mycompany.com:1521/testdb
User: test
Password: ******
 
(5) Interact with database in CC CLI Using natural language e.g. sqlcl show 10 largest tables in testdb_cc
PS C:\Users\dsun\ClaudeCode_DBA_Assistant> claude
 ¦?¦¦¦?¦   Claude Code v2.1.181
??¦¦¦¦¦??  Haiku 4.5 · API Usage Billing
  ?? ??    ~\ClaudeCode_DBA_Assistant


> sqlcl show 10 largest tables in testdb_cc

  Thought for 3s, called MCP (ctrl+o to expand)

? I'll connect to testdb_cc and query the 10 largest tables using sqlcl.

  Called sqlcl 2 times (ctrl+o to expand)

? Now I'll query the 10 largest tables by size.

  Called sqlcl (ctrl+o to expand)

? Let me check the available columns in DBA_TABLES and use the correct approach.

  Called sqlcl 2 times (ctrl+o to expand)

? Let me use DBA_SEGMENTS instead, which contains the actual allocated space:

  Called sqlcl (ctrl+o to expand)

? Here are the 10 largest tables in testdb_cc:

  +-------------------------------------------------------------------+
  ¦ Owner ¦    Table Name     ¦ Size (GB) ¦ Segment Type ¦ Tablespace ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ TEST  ¦ LOGFILE_SYNC_TEST ¦ 57.30     ¦ TABLE        ¦ USERS      ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER1 ¦ CF1               ¦ 2.06      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER3 ¦ CF1               ¦ 2.01      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER5 ¦ CF1               ¦ 2.00      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER4 ¦ CF1               ¦ 2.00      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER7 ¦ CF1               ¦ 2.00      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER6 ¦ CF1               ¦ 2.00      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER2 ¦ CF1               ¦ 1.99      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ USER8 ¦ CF1               ¦ 1.98      ¦ TABLE        ¦ IOPS       ¦
  +-------+-------------------+-----------+--------------+------------¦
  ¦ TPCC  ¦ STOCK             ¦ 0.18      ¦ TABLE        ¦ TPCC_DATA  ¦
  +-------------------------------------------------------------------+

  Key observations:
  - The TEST.LOGFILE_SYNC_TEST table dominates storage at 57.3 GB (likely a test/load table)
  - Multiple user schemas (USER1-USER8) have similarly-sized CF1 tables (~2 GB each) in the IOPS tablespace
  - The TPCC.STOCK table is relatively small at 0.18 GB in the TPCC_DATA tablespace

  Would you like to analyze space usage patterns, identify candidates for cleanup, or investigate the purposes of these large tables?

? Worked for 25s

? recap: Identified 10 largest tables in testdb_cc: TEST.LOGFILE_SYNC_TEST dominates at 57.3GB, followed by USER schemas' CF1 tables at ~2GB each. Awaiting next diagnostic step. (disable recaps in /config)


In summary, this post demonstrates how to connect Oracle SQLcl to the Claude Code CLI tool using the Model Context Protocol (MCP). By registering SQLcl as an MCP server and saving database credentials locally, users can query Oracle databases using natural language commands directly within the Claude Code interface. In the provided walkthrough, Claude successfully identifies the 10 largest tables in an Oracle 19c database by dynamically inspecting data dictionary views like DBA_SEGMENTS.