[Feature Request] Expose Session Metadata via Environment Variables and API

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Jan 9, 2026 · closed May 5, 2026

Problem Description

Claude Code currently lacks programmatic access to session metadata (session ID and user-defined session names). This creates a significant integration barrier for external tooling, particularly multi-agent orchestration systems, git worktree automation, and cross-tool session tracking.

Current Limitations

  1. No Environment Variables: Claude Code does not expose CLAUDE_SESSION_ID or CLAUDE_SESSION_NAME to hook scripts or subprocesses
  2. Internal-Only Storage: Session names set via /rename are stored internally and not accessible externally
  3. Limited Session Discovery: The only ways to identify the current session are:
  • Parsing the status line JSON input (session_id field)
  • Extracting UUID from transcript file path (~/.claude/projects/.../UUID.jsonl)
  1. No CLI Query: No command like claude --current-session to retrieve session info programmatically

Real-World Impact

This limitation prevents:

  • Multi-agent orchestration: External systems cannot correlate Claude Code sessions with their own session tracking
  • Git worktree integration: Cannot automatically map session → branch → worktree without manual intervention
  • Status line customization: Cannot display meaningful session names in custom status line implementations
  • Post-mortem analysis: Difficult to trace session activity across multiple tools (Claude Code + Cursor + Windsurf)
  • Hook automation: Git hooks cannot make session-aware decisions

---

Use Cases

1. Multi-Agent Orchestration

Scenario: A framework (multi-agent-os) delegates tasks to sub-agents running in isolated Claude Code sessions.

Current Problem: Parent orchestrator cannot determine which session a sub-agent is using without complex file path parsing.

With Session API: Environment variable CLAUDE_SESSION_ID allows instant correlation.

2. Git Worktree Automation

Scenario: Session-based isolation using git worktrees (1 session = 1 branch = 1 worktree).

Current Problem: Hook scripts must parse transcript paths to determine session UUID, which is fragile.

With Session API: CLAUDE_SESSION_ID directly maps to worktree directory name.

3. Status Line Enhancement

Scenario: Custom status line showing meaningful session context (e.g., "Session: feature/login-refactor").

Current Problem: /rename names are internal-only; status line can only show UUID.

With Session API: CLAUDE_SESSION_NAME provides user-friendly display.

4. Cross-Tool Session Tracking

Scenario: Developer switches between Claude Code, Cursor, and Windsurf for the same task.

Current Problem: No unified session identifier across tools.

With Session API: External system uses CLAUDE_SESSION_ID to maintain consistent session records.

5. Audit & Debugging

Scenario: Post-mortem analysis of which sessions created which commits.

Current Problem: Must reverse-engineer session IDs from transcript file paths.

With Session API: Git commit metadata includes CLAUDE_SESSION_ID via hook injection.

---

Proposed Solution

Primary: Environment Variables

Expose the following environment variables to all subprocesses (hooks, scripts, CLI commands):

# UUID of the current session
CLAUDE_SESSION_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"

# User-defined name from /rename (empty if not renamed)
CLAUDE_SESSION_NAME="feature/user-authentication"

# Timestamp when session started (ISO 8601)
CLAUDE_SESSION_STARTED="2026-01-09T10:30:00-03:00"

Benefits:

  • Zero friction for hook scripts
  • Standard POSIX convention
  • Backward compatible (empty if not set)
  • Works across all shells (bash, zsh, fish)

Secondary: CLI Query Command

Provide a command to retrieve session metadata as JSON:

$ claude --current-session
{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "session_name": "feature/user-authentication",
  "started_at": "2026-01-09T10:30:00-03:00",
  "project_path": "/Users/dev/Projects/MyApp",
  "transcript_path": "~/.claude/projects/MyApp/a1b2c3d4-e5f6-7890-abcd-ef1234567890.jsonl"
}

Tertiary: Enhanced Session Start Hook

Improve the existing session start hook to include metadata:

{
  "event": "session-start",
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "session_name": "",
  "project_path": "/Users/dev/Projects/MyApp",
  "timestamp": "2026-01-09T10:30:00-03:00"
}

---

Alternatives Considered

We evaluated 7 synchronization scenarios using a multi-agent analysis framework:

| Scenario | Description | Score | Status |
|----------|-------------|-------|--------|
| Scenario 3 | Environment Variable Injection (this request) | 8.3-8.6/10 | Ideal (requires vendor) |
| Scenario 5 | Git Branch-Based Identity (workaround) | 8.1-9.0/10 | Current workaround |
| Scenario 2 | MAOS Primary Extension | 6.6-7.8/10 | Complex |
| Scenario 7 | Phased Approach | 6.5-6.95/10 | Deferred |
| Scenario 1 | Session Bridge Registry | 4.8-6.6/10 | High maintenance |
| Scenario 4 | Transcript Parsing | 5.2-5.8/10 | Fragile |
| Scenario 6 | Hybrid Hierarchical | 5.2-5.9/10 | Over-engineered |

Unanimous Recommendation: All 6 independent agents identified Environment Variables as the ideal long-term solution.

Current Workaround: We use Git Branch-Based Identity where branch name = session identifier (e.g., b7d2-feature-name). This works but requires discipline and doesn't expose /rename names.

---

Implementation Notes

Backward Compatibility

  • All new environment variables default to empty strings if not set
  • Existing hook scripts continue to work unchanged
  • CLI command returns error if called outside a session

Security Considerations

  • Session IDs are UUIDs (already safe to expose)
  • Session names are user-defined (no sensitive data)
  • Environment variables only visible to child processes

Performance Impact

  • Negligible: Environment variables set once at session start
  • CLI command reads from in-memory session state

---

Expected Impact

  1. Enable Multi-Agent Ecosystems: External orchestrators (multi-agent-os, CrewAI, AutoGen) can integrate seamlessly
  2. Improve Git Workflows: Automated worktree management tied to session lifecycle
  3. Enhance Observability: Better session tracking for debugging and auditing
  4. Reduce Integration Friction: No more fragile file path parsing

---

Prior Art

  • VS Code: Exposes VSCODE_PID and workspace metadata via environment variables
  • Cursor: Provides session context through internal APIs
  • GitHub Copilot: Exposes session metadata for telemetry and debugging

---

Contact

Author: Emilson de Queiroz Moraes
Email: emilson.moraes@gmail.com
Role: DevOps Engineer & AI Evangelist @ Vek
Location: Florianópolis, SC, Brazil

We are willing to beta test this feature and provide feedback.

---

Document prepared using multi-agent analysis framework (6 agents, 100% consensus)

View original on GitHub ↗

6 Comments

extemporalgenome · 7 months ago

I would also benefit from this, for the purpose of writing slash commands that facilitate session recovery following an OS crash, and marking sessions as done (so that they're not candidates for recovery). Without CLAUDE_SESSION_ID, this is a lot more awkward to achieve (e.g. by needing to have the model output unique sentinel values and then read through ~/.claude/history.jsonl to identify its own session). To be sure, in the meantime I _will_ do that either way, but it means the model is spending more work for less value gained compared to being able to query this easily, e.g. via a builtin tool.

NicolasPetermann134 · 6 months ago

1+

Wirasm · 6 months ago

+1 — building an agent orchestration tool that manages parallel Claude Code sessions in isolated git worktrees. Need to capture the session ID after launch for stop/resume flows. Currently working around it with --session-id to control the UUID upfront, but reading Claude's native session ID via env var would be cleaner.

techjoec · 6 months ago

Workaround: Get your session ID via a SessionStart hook

Claude Code hooks receive session_id in their stdin JSON — you just need to feed it back. This gives you $CLAUDE_CODE_SESSION_ID in both the conversation context and the shell environment.

---

Setup (2 files)

Step 1 — Create the hook script

Save this as ~/.local/bin/claude-session-id-hook (or anywhere on your PATH):

#!/usr/bin/env bash
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')

# Inject into conversation context so the model can see it
jq -n --arg ctx "CLAUDE_CODE_SESSION_ID=$SESSION_ID" \
    '{ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: $ctx } }'

# Inject into shell environment so Bash tool calls can use it
# Guard: each session gets its own env file — skip if already written (resume/continue)
if [ -n "$CLAUDE_ENV_FILE" ] && ! grep -q "CLAUDE_CODE_SESSION_ID" "$CLAUDE_ENV_FILE" 2>/dev/null; then
    echo "export CLAUDE_CODE_SESSION_ID=\"$SESSION_ID\"" > "$CLAUDE_ENV_FILE"
fi

Then: chmod +x ~/.local/bin/claude-session-id-hook

Step 2 — Register the hook

Add to your ~/.claude/settings.json (merge into existing hooks if you have them):

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "claude-session-id-hook",
            "timeout": 5000
          }
        ]
      }
    ]
  }
}

---

Verify it works

Start a new Claude Code session, then run:

!echo $CLAUDE_CODE_SESSION_ID

You should get a UUID like a4b692e2-9095-43e4-849d-385e9e454782.

You can also ask Claude: "What is your CLAUDE_CODE_SESSION_ID from your system reminder?" — it will be able to read it directly from its context.

---

How it works

| Channel | Mechanism | Available to |
|---|---|---|
| Conversation context | hookSpecificOutput.additionalContext | The model (system reminder) |
| Shell environment | $CLAUDE_ENV_FILE | Bash tool calls (echo $CLAUDE_CODE_SESSION_ID) |

Edge cases handled

| Scenario | Behavior |
|---|---|
| Resumed/continued session | Same env file path — grep guard skips the write |
| Forked session | New session ID, new env file — writes fresh |
| Parallel sessions | Each session invokes its own hook with its own stdin JSON |
| Subagents | Get the session ID via their parent's context (add a SubagentStart hook entry with the same script if you want it explicitly) |

Requirements
  • jq installed
  • Claude Code with hooks support
melawad · 6 months ago

Use case: Custom skills that know the session name before the user does

I run a monorepo with 4 products, each with its own phase roadmap (e.g., FI.1.25, IP.4, PI.2.5). I have custom slash commands (/fi-next, /ip-next, /pi-next) that read the roadmap, identify the next phase, and present it for confirmation.

The skill already knows the phase number — it's right there in the confirmation message. But to name the session, I have to manually paste /rename IP.4 after confirming. As a workaround, I've updated my skills to output a ready-to-paste /rename command:

Ready to start IP.4 — Multi-Patent & Estoppel?

📌 Rename this session: /rename IP.4

This works but is an unnecessary manual step. What I'd want is a write path in addition to the read path proposed here — something like:

# From a hook or skill context:
export CLAUDE_SESSION_NAME="IP.4"   # or a dedicated API

This would let skills/hooks that determine session purpose (phase tracking, PR review, feature work) automatically label the session at the moment the context is established, rather than requiring the user to do it after the fact.

The read side (env vars for external tooling) and the write side (programmatic rename from hooks/skills) are complementary — both are needed for session identity to be truly useful in automated workflows.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.