Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/gitlock_mcp/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
25 changes: 25 additions & 0 deletions apps/gitlock_mcp/lib/gitlock_mcp.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule GitlockMCP do
@moduledoc """
Gitlock MCP Server — codebase intelligence for AI coding agents.

Exposes behavioral code analysis (hotspots, coupling, ownership, risk)
as MCP tools that AI coding agents like Claude Code and Cursor can use
to write safer code.

## How it works

1. Agent connects via stdio
2. First tool call triggers repo indexing (parses git log, runs analysis)
3. Results cached in memory — subsequent queries are instant
4. Agent gets risk context before modifying files

## Tools

- `gitlock_assess_file` — Risk assessment for a specific file
- `gitlock_hotspots` — Find riskiest files in a directory
- `gitlock_file_ownership` — Who owns this file? Knowledge silo risk?
- `gitlock_find_coupling` — What files change together with this one?
- `gitlock_review_pr` — Analyze a set of changed files together
- `gitlock_repo_summary` — Overview of codebase health
"""
end
24 changes: 24 additions & 0 deletions apps/gitlock_mcp/lib/gitlock_mcp/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule GitlockMCP.Application do
@moduledoc false
use Application
require Logger

@default_port 4100

@impl true
def start(_type, _args) do
port = Application.get_env(:gitlock_mcp, :port, @default_port)

children = [
GitlockMCP.Cache,
Hermes.Server.Registry,
{GitlockMCP.Server, transport: :streamable_http},
{Bandit, plug: GitlockMCP.Router, port: port}
]

Logger.info("Gitlock MCP server starting on http://localhost:#{port}/mcp")

opts = [strategy: :one_for_one, name: GitlockMCP.Supervisor]
Supervisor.start_link(children, opts)
end
end
Loading
Loading