The `get_terminal_logs` MCP tool has problems that make it hard to tail logs:
## Current Issues
**File**: `/rails/app/controllers/api/v1/mcp_controller.rb` - `handle_get_terminal_logs`
### 1. Logs Are Chunked, Not Line-by-Line
- Logs are stored in chunks (each chunk = multiple terminal lines)
- Each chunk is max ~500 lines
- `limit=1` returns 1 chunk which may contain 20+ lines
- This is by design, but makes "get last 50 lines" difficult
### 2. No Way to Get "Latest" Logs
- No offset/pagination support
- Can't tail logs (get last N chunks)
- Always returns from beginning of session/chunks
- No `order=desc` to get most recent chunks first
### 3. No Individual Timestamps
- Logs only have session-level timestamps
- Each chunk doesn't have its own timestamp
- Can't tell when each line/chunk was captured
### 4. Requires Extra API Call to Get Latest Session
- When filtering by `agent_id`, returns logs from ALL sessions
- Must call `list_agent_sessions` first to get latest `session_id`
- Extra round trip just to get current logs
## Requirements
### Cap `limit` Parameter at Maximum 5
- **Maximum `limit` is 5 chunks** (~2500 lines max)
- If `limit > 5` is requested, either:
- Reject with error, OR
- Silently cap at 5
- Chunks are max 500 lines each, so 5 chunks = ~2500 lines (safe)
### Default to Latest Session When No session_id Provided
- When `session_id` is not provided, automatically use the most recent session
- Avoids needing a separate `list_agent_sessions` call first
- If agent has no sessions, return empty result
### Add "Tail" Behavior (Most Recent First)
- Add `order: 'desc'` parameter (default: 'asc')
- When `order=desc`, return most recent chunks first
- This enables tailing: `?limit=5&order=desc` gets last 5 chunks
### Add Pagination/Offset
- Add `offset` parameter to skip N chunks
- Enable pagination: `?limit=10&offset=20`
### Add Timestamps to Each Log Chunk
- Add `created_at` or `timestamp` field to each chunk
- Store when each chunk was captured
- Return in ISO 8601 format
### Optional: Add `all_sessions` Flag
- Add `all_sessions: true` to get logs from all sessions instead of just latest
- Default: `false` (latest session only)
## Proposed API
```
GET /api/v1/terminal_logs?
agent_id=4&
limit=1&
offset=0&
order=desc&
session_id=null&
all_sessions=false
```
**`limit` constraints:**
- Minimum: 1
- Maximum: 5 (enforced)
- Default: **1** (enough for agents to check status)
When `session_id` is null and `all_sessions=false`:
→ Automatically use the most recent session for this agent
**Response:**
```json
{
"total_chunks": 1234,
"returned_chunks": 1,
"session_id": 24,
"logs": [
{
"id": 123456,
"line": "chunk of terminal output...",
"timestamp": "2025-12-28T05:15:23.456Z",
"session_id": 24,
"agent_identifier": "worker_2"
}
]
}
```
## Acceptance Criteria
- [ ] `limit` parameter capped at maximum 5 (reject or silently cap)
- [ ] `limit` defaults to 1
- [ ] When `session_id` not provided, defaults to most recent session automatically
- [ ] `order=desc` returns most recent chunks first (essential for tailing)
- [ ] `offset` parameter works for chunk pagination
- [ ] Each log chunk has `timestamp` field
- [ ] Can still filter by specific `session_id` when needed
- [ ] `all_sessions=true` returns from all sessions
- [ ] Tests verify limit cap, default session, order, and offset behavior
The `get_terminal_logs` MCP tool has problems that make it hard to tail logs:
## Current Issues
**File**: `/rails/app/controllers/api/v1/mcp_controller.rb` - `handle_get_terminal_logs`
### 1. Logs Are Chunked, Not Line-by-Line
- Logs are stored in chunks (each chunk = multiple terminal lines)
- Each chunk is max ~500 lines
- `limit=1` returns 1 chunk which may contain 20+ lines
- This is by design, but makes "get last 50 lines" difficult
### 2. No Way to Get "Latest" Logs
- No offset/pagination support
- Can't tail logs (get last N chunks)
- Always returns from beginning of session/chunks
- No `order=desc` to get most recent chunks first
### 3. No Individual Timestamps
- Logs only have session-level timestamps
- Each chunk doesn't have its own timestamp
- Can't tell when each line/chunk was captured
### 4. Requires Extra API Call to Get Latest Session
- When filtering by `agent_id`, returns logs from ALL sessions
- Must call `list_agent_sessions` first to get latest `session_id`
- Extra round trip just to get current logs
## Requirements
### Cap `limit` Parameter at Maximum 5
- **Maximum `limit` is 5 chunks** (~2500 lines max)
- If `limit > 5` is requested, either:
- Reject with error, OR
- Silently cap at 5
- Chunks are max 500 lines each, so 5 chunks = ~2500 lines (safe)
### Default to Latest Session When No session_id Provided
- When `session_id` is not provided, automatically use the most recent session
- Avoids needing a separate `list_agent_sessions` call first
- If agent has no sessions, return empty result
### Add "Tail" Behavior (Most Recent First)
- Add `order: 'desc'` parameter (default: 'asc')
- When `order=desc`, return most recent chunks first
- This enables tailing: `?limit=5&order=desc` gets last 5 chunks
### Add Pagination/Offset
- Add `offset` parameter to skip N chunks
- Enable pagination: `?limit=10&offset=20`
### Add Timestamps to Each Log Chunk
- Add `created_at` or `timestamp` field to each chunk
- Store when each chunk was captured
- Return in ISO 8601 format
### Optional: Add `all_sessions` Flag
- Add `all_sessions: true` to get logs from all sessions instead of just latest
- Default: `false` (latest session only)
## Proposed API
```
GET /api/v1/terminal_logs?
agent_id=4&
limit=1&
offset=0&
order=desc&
session_id=null&
all_sessions=false
```
**`limit` constraints:**
- Minimum: 1
- Maximum: 5 (enforced)
- Default: **1** (enough for agents to check status)
When `session_id` is null and `all_sessions=false`:
→ Automatically use the most recent session for this agent
**Response:**
```json
{
"total_chunks": 1234,
"returned_chunks": 1,
"session_id": 24,
"logs": [
{
"id": 123456,
"line": "chunk of terminal output...",
"timestamp": "2025-12-28T05:15:23.456Z",
"session_id": 24,
"agent_identifier": "worker_2"
}
]
}
```
## Acceptance Criteria
- [ ] `limit` parameter capped at maximum 5 (reject or silently cap)
- [ ] `limit` defaults to 1
- [ ] When `session_id` not provided, defaults to most recent session automatically
- [ ] `order=desc` returns most recent chunks first (essential for tailing)
- [ ] `offset` parameter works for chunk pagination
- [ ] Each log chunk has `timestamp` field
- [ ] Can still filter by specific `session_id` when needed
- [ ] `all_sessions=true` returns from all sessions
- [ ] Tests verify limit cap, default session, order, and offset behavior