Emulating the Claude Code Backend for LLM's hosted on Databricks & Azure Anthropic (with MCP, Git tools, and prompt caching)

7 min read Original article ↗

Claude Code has a really nice workflow: repo-aware chat, Git helpers, tests, web tools, and now MCP servers – all from a single CLI.

But there’s a catch: the Claude Code CLI expects to talk to Anthropic’s hosted backend. If you want it to talk to other backends (Databricks, Azure Anthropic, your own MCP tools, etc.), you’re on your own.

I wanted to keep the Claude Code UX while:

routing traffic to Databricks-hosted Claude models

optionally using Azure’s Anthropic /anthropic/v1/messages endpoint

composing local tools + MCP servers

adding prompt caching and some repo intelligence

keeping everything self-hosted and hackable

So I built Lynkr – a small Node.js HTTP proxy that pretends to be the Claude Code backend and sits between the Claude Code CLI (or any compatible client) and your actual model providers.

Repo is here if you want to look at the code or try it:

https://github.com/vishalveerareddy123/Lynkr

What Lynkr actually does

At a high level:

Lynkr is a CLI-invoked HTTP proxy that implements a Claude-flavored /v1/messages API, forwards requests to Databricks or Azure Anthropic, and wires in workspace tools, Git helpers, prompt caching, and MCP servers.

So instead of:

Claude Code CLI → Anthropic cloud

you get:

Claude Code CLI → Lynkr proxy → Databricks / Azure Anthropic / tools / MCP

The idea is not to clone Anthropic’s backend feature-for-feature, but to keep the ergonomics and make the backend behavior fully visible and configurable.

Some of the main pieces:

Claude provider adapters

MODEL_PROVIDER=databricks (default)

MODEL_PROVIDER=azure-anthropic Requests are normalized to each provider, but responses look like Claude.

Workspace awareness

Local repo indexing into SQLite

Auto-generated CLAUDE.md with language mix, frameworks, configs, etc.

Symbol/reference search (TS/JS/Python via Tree-sitter, heuristics for others)

Model Context Protocol (MCP)

Manifest discovery from ~/.claude/mcp or custom dirs

Launches JSON-RPC 2.0 servers and re-exposes their tools through the proxy

Optional Docker sandbox for isolation

Prompt cache

Local LRU+TTL cache keyed by prompt signature

Reuses responses for identical turns to save latency/tokens

Policy engine

Env flags like POLICY_GIT_ALLOW_PUSH, POLICY_GIT_REQUIRE_TESTS, etc.

Lets you gate git pushes, require tests before commit, control web fetch, etc.

Architecture (short version)

Internally, Lynkr is just an Express service with a few core subsystems:

Express API gateway (/v1/messages) – speaks a Claude-like API to clients.

Orchestrator – runs the agent loop: model calls, tool invocation, prompt cache, policies.

Prompt cache – LRU store with TTL, SHA-256 keyed on request signature.

Session store (SQLite) – keeps conversational transcripts and task state.

Repo indexer – crawls WORKSPACE_ROOT, updates a SQLite catalog, and regenerates CLAUDE.md.

Tool registry & policy engine – built-in tools for workspace, Git, diff, tests, tasks, MCP bridging. – all guarded by a centralized policy layer.

MCP registry + sandbox – scans manifests, spins up MCP servers, connects via JSON-RPC client. – optionally runs them in a container with restricted mounts.

Provider adapters – Databricks serving endpoints – Azure Anthropic /anthropic/v1/messages – room for more backends later.

The whole thing is meant to be understandable without wading through a giant framework: most entrypoints live under src/api, src/orchestrator, src/tools, src/indexer, and src/mcp.

Core capabilities in practice

  1. Repo intelligence & navigation

Lynkr keeps a lightweight SQLite catalog of your repo:

language and framework mix

symbol definitions + references (where possible)

file metadata and framework hints

From that, it generates a CLAUDE.md summary so the model always has context on:

what languages you’re using

which frameworks / build systems appear

how tests and linting seem to work

The index is invalidated and rebuilt via a tool (workspace_index_rebuild), and removed files disappear from results after a rebuild.

  1. Git workflow hooks

Git operations are implemented as tools in src/tools/git.js:

status, diff, stage, commit, push, pull

diff review endpoints that summarize changes and risk areas

release note generation from Git history

Policies let you lock this down:

POLICY_GIT_ALLOW_PUSH=false → push is blocked

POLICY_GIT_REQUIRE_TESTS=true → commits require a test run

POLICY_GIT_TEST_COMMAND → which test command to run

This lets you keep Claude-style “make these changes and push” flows, but under your own rules.

  1. Diff & change management

There’s a unified diff tool surface, with:

repo-wide diff summaries (workspace_diff_review)

release note synthesis

integration with the test harness so you can gate risky changes

The roadmap includes more fine-grained per-file threaded reviews and risk scoring.

  1. Execution, tests, and tools

The execution pipeline:

decides whether to run tools directly in the workspace or through a sandbox

exposes helpers like workspace_test_run, workspace_test_history, and workspace_test_summary

wires in MCP servers as additional tools

Prompt caching happens at this layer too: tool-invoking requests are not cached (to avoid re-running side-effecting tools), but plain chat turns are.

  1. Workflow & collaboration

There’s a simple task tracker on top of SQLite:

workspace_task_create / workspace_task_update

set status, list tasks, delete tasks

Session transcripts (user, assistant, tool turns) are saved for auditing and reproducibility.

Running it locally

Prereqs:

Node.js 18+ (for global fetch)

npm

A Databricks workspace or Azure Anthropic endpoint

(Optional) Docker if you want MCP sandboxing

(Optional) Claude Code CLI

Install:

recommended: global npm install

npm install -g lynkr lynkr start

Or from source:

git clone https://github.com/vishalveerareddy123/Lynkr.git cd Lynkr npm install npm start

Then configure the environment:

MODEL_PROVIDER=databricks DATABRICKS_API_BASE=https://.cloud.databricks.com DATABRICKS_API_KEY= WORKSPACE_ROOT=/path/to/your/repo PORT=8080 PROMPT_CACHE_ENABLED=true

For Azure Anthropic instead:

MODEL_PROVIDER=azure-anthropic AZURE_ANTHROPIC_ENDPOINT=https://.services.ai.azure.com/anthropic/v1/messages AZURE_ANTHROPIC_API_KEY= AZURE_ANTHROPIC_VERSION=2023-06-01 WORKSPACE_ROOT=/path/to/your/repo PORT=8080

You can also run it via Docker / docker-compose if you prefer containers; the repo includes both.

Hooking up Claude Code CLI

Once the proxy is running:

export ANTHROPIC_BASE_URL=http://localhost:8080 export ANTHROPIC_API_KEY=dummy # CLI insists on this, but Lynkr ignores it

Then run the Claude Code CLI inside your repo (WORKSPACE_ROOT), and it will talk to Lynkr instead of api.anthropic.com. From there, you can use the usual commands; they’re just being handled by your own backend.

Prompt caching behavior

Lynkr’s cache is intentionally simple:

controlled by PROMPT_CACHE_ENABLED, PROMPT_CACHE_TTL_MS, PROMPT_CACHE_MAX_ENTRIES

caches only non-tool /v1/messages calls

on a cache hit, no Databricks/Azure request is made; the response is served from the LRU store and annotated with cache metadata

This makes iterative “explain this again, tweak the same prompt” workflows a lot cheaper and faster, without trying to fully replicate Anthropic’s internal caching semantics.

MCP orchestration

Lynkr discovers Manifest files from ~/.claude/mcp (or directories in MCP_MANIFEST_DIRS):

On startup, it scans for MCP manifests.

For each manifest, it launches the defined MCP server.

Tools are re-exposed into the proxy namespace.

You can call them directly, or let the assistant call them when needed.

If MCP_SANDBOX_ENABLED=true and MCP_SANDBOX_IMAGE is set, servers run inside a container with controlled mounts and env. If you turn sandboxing off, MCP tools run with full access to the host, which can be useful for local hacking but obviously less safe.

What’s missing / future work

Some gaps and roadmap items:

Per-file diff comment threads and richer review UX

Automated risk scoring attached to diffs (e.g., tests touched, coverage deltas)

Deeper language-server integration or LSP bridging instead of pure Tree-sitter

A safe, declarative “skills” layer similar in spirit to Claude Skills

Coverage dashboards and longer-term trend tracking

The goal is to keep the codebase small enough that it’s inspectable and fork-able, while still being a viable backend for day-to-day Claude Code work.

Why share this?

I wanted a Claude Code–style workflow that I could:

point at Databricks or Azure Anthropic,

extend with my own tools and MCP servers,

and understand end-to-end without a black-box backend.

If you’re experimenting with Claude, Databricks, or MCP – or if you want more control over your editor/CLI agent backend – you might find Lynkr useful or at least interesting to poke at.

Repo (with full README, config matrix, Docker setup, and test matrix):

https://github.com/vishalveerareddy123/Lynkr

Feedback, issues, and PRs are very welcome.