Skip to main content

Claude Code runner and orchestrator — thin job lifecycle, repo management, and OTEL pipeline

Project description

Agenticore

Claude Code runner and orchestrator. Manages job lifecycle, repo cloning/caching, profile-based execution, auto-PR creation, and OTEL observability pipeline.

Agenticore Architecture

License: MIT Tests Docker Python 3.12+

How It Works

Request (MCP or REST)
  │
  ├─ Router selects profile
  ├─ Clone/fetch repo (flock-protected cache)
  ├─ Spawn: claude --worktree -p "task" (with profile flags + OTEL env)
  ├─ Collect telemetry → OTEL Collector → Langfuse + PostgreSQL
  ├─ Ship Claude session transcript → Langfuse (via SDK)
  ├─ Auto-PR on success (when profile enables it)
  └─ Job result → Redis (or file fallback)
  1. Takes a task via MCP tool or REST API
  2. Clones the repo into a cached directory (flock-serialized, reuses on subsequent runs)
  3. Runs Claude Code as a subprocess with profile-derived CLI flags and OTEL environment
  4. Streams telemetry through Claude's native OTEL support to a collector (exported to Langfuse and/or PostgreSQL)
  5. Ships transcripts from the Claude session to Langfuse as spans for full visibility
  6. Creates a PR automatically if the profile has auto_pr: true and the job succeeds

Quick Start

Local (no Docker)

pip install -e .

# Start server with SSE transport (HTTP server on :8200)
AGENTICORE_TRANSPORT=sse agenticore serve

# Or stdio transport (for use as an MCP server in Claude Code)
python -m agenticore

Docker Compose (local development)

The compose stack spins up agenticore alongside local Redis, PostgreSQL, and an OTEL Collector so you can test the full pipeline without any external infrastructure.

cp .env.example .env
# Edit .env — at minimum set GITHUB_TOKEN if you want auto-PR

docker compose up --build -d

This starts:

Service Purpose Port
agenticore The runner server 8200
redis Job store 6379
postgres OTEL telemetry sink 5432
otel-collector Receives OTEL from Claude, exports to Langfuse + Postgres 4317 (gRPC), 4318 (HTTP)

All services are wired together automatically — agenticore points at redis://redis:6379/0 and the OTEL collector at http://otel-collector:4317.

Production Deployment

In production you run only the agenticore container. Redis, PostgreSQL, and the OTEL Collector are external managed services (e.g., AWS ElastiCache, RDS, a hosted OTEL backend).

docker build -t agenticore .

docker run -d \
  -p 8200:8200 \
  -e AGENTICORE_TRANSPORT=sse \
  -e AGENTICORE_HOST=0.0.0.0 \
  -e AGENTICORE_PORT=8200 \
  -e REDIS_URL=redis://your-redis-host:6379/0 \
  -e AGENTICORE_OTEL_ENABLED=true \
  -e OTEL_EXPORTER_OTLP_ENDPOINT=https://your-otel-collector:4317 \
  -e OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
  -e POSTGRES_URL=postgresql://user:pass@your-postgres:5432/agenticore \
  -e GITHUB_TOKEN=ghp_... \
  agenticore

The key difference from local dev:

Concern Local (docker-compose) Production
Redis Local container (redis:7-alpine) External managed service
PostgreSQL Local container (postgres:16-alpine) External managed service
OTEL Collector Local container (otel-collector-contrib) External hosted collector
Agenticore Built from source Same image, external config
Config Hardcoded service names Env vars pointing to real endpoints

If Redis is unavailable, agenticore falls back to file-based job storage at ~/.agenticore/jobs/. This means you can run without Redis entirely for simple setups.

Configuration

All configuration is loaded from ~/.agenticore/config.yml with environment variable overrides. Env vars always take priority.

Environment Variables

Server

Variable Default Description
AGENTICORE_TRANSPORT stdio sse for HTTP server, stdio for MCP pipe
AGENTICORE_HOST 127.0.0.1 Bind address (0.0.0.0 in Docker)
AGENTICORE_PORT 8200 Server port
AGENTICORE_API_KEYS (empty) Comma-separated API keys for auth (optional)

Redis

Variable Default Description
REDIS_URL (empty) Redis connection URL. Empty = file fallback
REDIS_KEY_PREFIX agenticore Key namespace prefix (keys: {prefix}:job:{id})

Claude Code

Variable Default Description
AGENTICORE_CLAUDE_BINARY claude Path to Claude Code binary
AGENTICORE_CLAUDE_TIMEOUT 3600 Max job runtime in seconds
AGENTICORE_DEFAULT_PROFILE code Profile used when none specified
AGENTICORE_CLAUDE_CONFIG_DIR (empty) Custom Claude config directory

Repos

Variable Default Description
AGENTICORE_REPOS_ROOT ~/agenticore-repos Clone cache directory
AGENTICORE_MAX_PARALLEL_JOBS 3 Max concurrent jobs
AGENTICORE_JOB_TTL 86400 Job expiry in seconds

OTEL

Variable Default Description
AGENTICORE_OTEL_ENABLED true Enable/disable telemetry
OTEL_EXPORTER_OTLP_ENDPOINT http://otel-collector:4317 Collector endpoint
OTEL_EXPORTER_OTLP_PROTOCOL grpc OTLP protocol (grpc or http)
AGENTICORE_OTEL_LOG_PROMPTS false Log user prompts to telemetry
AGENTICORE_OTEL_LOG_TOOL_DETAILS true Log tool execution to telemetry

GitHub

Variable Default Description
GITHUB_TOKEN (empty) GitHub token for auto-PR (uses gh CLI)

Langfuse

Variable Default Description
LANGFUSE_HOST https://cloud.langfuse.com Langfuse API host
LANGFUSE_PUBLIC_KEY (empty) Langfuse public key (enables SDK tracing)
LANGFUSE_SECRET_KEY (empty) Langfuse secret key
LANGFUSE_BASIC_AUTH (empty) Base64(public_key:secret_key) for OTEL collector

Agentihooks

Variable Default Description
AGENTICORE_AGENTIHOOKS_PATH (empty) Path to cloned agentihooks repo (e.g. /app)

PostgreSQL

Variable Default Description
POSTGRES_URL (empty) PostgreSQL connection URL (OTEL sink)

MCP Tools

Connect agenticore as an MCP server in Claude Code or any MCP client. All task submissions are async (fire and forget) by default — pass wait=true to block until completion.

Tool Description
run_task Submit a task (async by default, wait=true to block)
get_job Get job status, output, artifacts, and PR URL
list_jobs List recent jobs with status
cancel_job Cancel a running job
list_profiles List available execution profiles

REST API

When running with AGENTICORE_TRANSPORT=sse, the same operations are available over HTTP. Same semantics: async by default, "wait": true to block.

# Submit a job (async — returns job ID immediately)
curl -X POST http://localhost:8200/jobs \
  -H "Content-Type: application/json" \
  -d '{"task": "fix the auth bug", "repo_url": "https://github.com/org/repo"}'

# Submit and wait for completion
curl -X POST http://localhost:8200/jobs \
  -H "Content-Type: application/json" \
  -d '{"task": "fix the auth bug", "repo_url": "https://github.com/org/repo", "wait": true}'

# Check status
curl http://localhost:8200/jobs/{job_id}

# List jobs
curl http://localhost:8200/jobs

# Cancel
curl -X DELETE http://localhost:8200/jobs/{job_id}

# List profiles
curl http://localhost:8200/profiles

# Health check
curl http://localhost:8200/health

If AGENTICORE_API_KEYS is set, include X-API-Key: <key> header or ?api_key=<key> query param.

Profiles

Profiles are directory-based packages that define how Claude Code runs. Each profile is a directory containing a profile.yml for agenticore-specific metadata, plus native Claude Code config files (.claude/ directory and .mcp.json).

Default profiles are bundled in defaults/profiles/. External profiles can be loaded from an agentihooks repo via AGENTICORE_AGENTIHOOKS_PATH. Custom profiles go in ~/.agenticore/profiles/ and override everything with the same name.

Profile priority (highest wins): user (~/.agenticore/profiles/) > agentihooks > defaults.

Directory Structure

profiles/
  code/
    profile.yml              # Agenticore metadata
    .claude/
      CLAUDE.md              # Profile-specific instructions
      settings.json          # Tool permissions
    .mcp.json                # MCP server config (optional)
  review/
    profile.yml
    .claude/
      CLAUDE.md
      settings.json
    .mcp.json

code (default)

Autonomous coding worker. Writes code, commits, and triggers auto-PR.

name: code
description: "Autonomous coding worker"
claude:
  model: sonnet
  max_turns: 80
  permission_mode: bypassPermissions
  no_session_persistence: true
  output_format: json
  worktree: true
  effort: high
  timeout: 3600
auto_pr: true

review

Read-only code reviewer. Analyzes code without modifying files.

name: review
description: "Code review analyst"
claude:
  model: haiku
  max_turns: 20
  permission_mode: bypassPermissions
  no_session_persistence: true
  output_format: json
  worktree: true
  timeout: 1800
auto_pr: false

Profile Fields

Field Description
claude.model Claude model to use (sonnet, haiku, opus)
claude.max_turns Maximum agentic turns
claude.output_format Output format (json, text, stream-json)
claude.permission_mode Permission mode for tool use
claude.no_session_persistence Disable session persistence (default: true)
claude.effort Effort level (e.g. high)
claude.timeout Job timeout in seconds
claude.worktree Use git worktree (isolates from main branch)
claude.max_budget_usd Optional max budget in USD
claude.fallback_model Optional fallback model
auto_pr Create PR on successful completion
extends Inherit from another profile

Architecture

Modules

Module Purpose
server.py FastMCP server (5 tools) + REST routes + SSE
config.py YAML config loader with env var overrides
profiles.py Load profile packages into CLI flags
repos.py Git clone/fetch with flock serialization
jobs.py Job store — Redis hash or JSON file fallback
runner.py Spawn Claude subprocess with OTEL env vars
telemetry.py Langfuse trace lifecycle + transcript shipping
router.py Profile selection (explicit or default)
pr.py Auto-PR via git push + gh pr create
cli.py CLI client (agenticore run, agenticore serve, etc.)

Container

The Dockerfile builds a Python 3.12 image with:

  • git and curl for repo operations
  • gh CLI for auto-PR creation
  • Claude Code must be available at the path specified by AGENTICORE_CLAUDE_BINARY

The container exposes port 8200 and runs in SSE transport mode by default.

OTEL Pipeline

Claude Code (subprocess)
  │ OTLP gRPC/HTTP
  ▼
OTEL Collector
  │ batch processor
  ├──► Langfuse (otlphttp/langfuse)
  └──► PostgreSQL / debug

Claude Code has native OTEL support. Agenticore sets the OTEL env vars on the subprocess so telemetry flows to the OTEL Collector, which exports to both Langfuse (via OTLP HTTP) and PostgreSQL/debug. Additionally, the runner ships Claude session transcripts directly to Langfuse via the SDK as spans on the job trace.

Set LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY to enable SDK-level tracing. Set LANGFUSE_BASIC_AUTH for the OTEL collector export path.

CLI

agenticore run "fix the bug" \  # Submit task (async, returns job ID)
  --repo https://github.com/org/repo \
  --profile code
agenticore run "add tests" --wait  # Submit and wait for completion
agenticore jobs                 # List recent jobs
agenticore job <id>             # Get job details
agenticore cancel <id>          # Cancel a running job
agenticore profiles             # List available profiles
agenticore serve                # Start the server (SSE mode)
agenticore status               # Server health check
agenticore version              # Print version

Development

pip install -e ".[dev]"

# Tests
pytest tests/unit -v -m unit --cov=agenticore

# Lint
ruff check agenticore/ tests/
ruff format --check agenticore/ tests/

Code Quality

This project is continuously analyzed by SonarQube for code quality, security vulnerabilities, and test coverage.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agenticore-0.1.2.tar.gz (32.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agenticore-0.1.2-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

Details for the file agenticore-0.1.2.tar.gz.

File metadata

  • Download URL: agenticore-0.1.2.tar.gz
  • Upload date:
  • Size: 32.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agenticore-0.1.2.tar.gz
Algorithm Hash digest
SHA256 eca2953303d0ed639634c83b8c0fc049d73373efa2e367356121cd941321c879
MD5 afd103c9de5c89bee82fc89f733b6808
BLAKE2b-256 b20b5de348efa987c88b9989f31cab2603e1176d1482ef35960cc5279048a621

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenticore-0.1.2.tar.gz:

Publisher: publish-pypi.yml on The-Cloud-Clock-Work/agenticore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agenticore-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: agenticore-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 32.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agenticore-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b757ecea21fd6ba4ea812f4f7338a95f3c3f195bac5bb0250aaebb83221cac09
MD5 1a956c38ca033b7d62c337f8e8428506
BLAKE2b-256 5dd0b35ff9033a079fa548eebe767c791e95da9f37062710393b636927b45147

See more details on using hashes here.

Provenance

The following attestation bundles were made for agenticore-0.1.2-py3-none-any.whl:

Publisher: publish-pypi.yml on The-Cloud-Clock-Work/agenticore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page