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
49 changes: 49 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Agent Guidelines for LangChain MCP

## Build/Lint/Test Commands

**Primary Commands:**

- `mix test` - Run all tests
- `mix test --exclude live_call` - Run only unit tests
- `mix test test/specific_test.exs` - Run single test file
- `mix format --check-formatted` - Check code formatting
- `mix test --cover --exclude live_call` - check code coverage
- `mix quality_check` - Run all quality checks (format, credo, dialyzer, tests)
- `mix credo --strict` - Run linting checks
- `mix dialyzer` - Run type checking
- `mix compile --warnings-as-errors` - Compile with strict warnings

**Integration Tests:**

```bash
# Terminal 1: Start test server
mix test_server

# Terminal 2: Run integration tests
mix test --include live_call
```

## Code Style Guidelines

**Formatting:**

- Line length: 100 characters (`.formatter.exs`)
- Use `mix format` for consistent formatting

**Testing:**

- Unit tests use `Mimic` for mocking, tagged `:live_call` for integration tests
- Tests in `test/` directory follow ExUnit patterns
- Integration tests require running test server (`mix test_server`)

**Architecture:**

- Core modules: `LangChain.MCP.*` (Adapter, Config, SchemaConverter, ContentMapper)
- Use proper error handling with `{:ok, _}` / `{:error, _}` tuples
- Follow Elixir naming conventions: snake_case functions, PascalCase modules

**Dependencies:**

- Uses `:langchain`, `:anubis_mcp`, `:credo`, `:dialyxir`
- Dev/test deps include mocking (`:mimic`) and docs (`:ex_doc`)
27 changes: 22 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Initial release
- **Status Monitor**: Lightweight solution for monitoring MCP clients in real-time with uptime percentage tracking
- **Langchain.MCP.Client wrapper**: Decouples Anubis from application, removing dependency requirement
- **Automated release process**: CI workflow automation for streamlined publishing

### Changed

- **Default test server port**: Changed from 4000 to 5000 to avoid conflicts with Phoenix applications
- **Folder structure reorganization**: Flattened paths (`lib/langchain/mcp` → `langchain_mcp`, `test/langchain/mcp` → `test/langchain_mcp`)
- **Markdown formatting**: Auto-formatted documentation files using CommonMark standards

### Fixed

- ToolExecutor issues resolved
- Test flakiness problems fixed with centralized client management (`async: false` and proper cleanup)
- Registry test bleed eliminated through centralized deregistration
- Dialyzer type checking issues resolved
- Credo linting readability/refactoring opportunities addressed

## [0.1.0] - Initial release

### Added

- `LangChain.MCP.Adapter` for converting MCP tools to LangChain functions
- `LangChain.MCP.SchemaConverter` for JSON Schema to FunctionParam conversion
- `LangChain.MCP.ToolExecutor` for executing MCP tools
Expand All @@ -19,7 +40,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Configurable tool caching
- Test infrastructure with mcp/time Docker server
- Comprehensive documentation and examples

## [0.1.0] - TBD

- Initial release
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,37 @@ Many MCP servers are available via Docker Hub:

See [Docker Hub MCP Catalog](https://hub.docker.com/mcp) for more.

## Contributing

### Quality Checks
Before pushing, ensure code meets quality standards:

```bash
# Run all checks (same as CI)
mix quality_check

# Or run individually:
mix format --check-formatted # Code formatting
mix credo --strict # L linting
mix dialyzer # Type checking
mix test --exclude live_call # Unit tests only
```

The automated release workflow requires these checks to pass. Use `mix quality_check` locally before committing.

### Testing

- **Unit tests**: Standard ExUnit with mocking via `:mimic`
- **Integration tests**: Tagged `:live_call`, require running test server

```bash
# Start test server (Terminal 1)
mix test_server

# Run integration tests (Terminal 2)
mix test --include live_call
```

## Architecture

```
Expand Down
78 changes: 78 additions & 0 deletions lib/mix/tasks/quality_check.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
defmodule Mix.Tasks.QualityCheck do
@moduledoc """
Runs all quality checks: format, linting, type checking, and tests.

## Usage

mix quality_check

This runs the same checks as CI:
- Code formatting validation
- Credo linting (strict mode)
- Dialyzer type checking
- Unit tests (excludes live_call integration tests)

Use before committing to ensure code meets quality standards.
"""

@shortdoc "Run all quality checks"

use Mix.Task

@impl Mix.Task
def run(_args) do
IO.puts("🔍 Running quality checks...\n")

check_formatting()
check_linting()
check_types()
run_tests()

IO.puts("\n🎉 All quality checks passed!")
end

defp check_formatting do
IO.puts("📋 Checking formatting...")

if Mix.shell().cmd("mix format --check-formatted") != 0 do
IO.puts("�️ Formatting issues found - run 'mix format' to fix")
System.halt(1)
else
IO.puts("✅ Formatting OK")
end
end

defp check_linting do
IO.puts("\n🔋 Running Credo linting...")

if Mix.shell().cmd("mix credo --strict") != 0 do
IO.puts("�️ Linting issues found - run 'mix credo' to see details")
System.halt(1)
else
IO.puts("✅ Code quality OK")
end
end

defp check_types do
IO.puts("\n🔋 Running Dialyzer type checking...")

if Mix.shell().cmd("mix dialyzer") != 0 do
IO.puts("�️ Type issues found - run 'mix dialyzer' to see details")
System.halt(1)
else
IO.puts("✅ Type checking OK")
end
end

defp run_tests do
IO.puts("\n🧪 Running unit tests...")
{_, exit_code} = System.cmd("mix", ["test", "--exclude", "live_call"])

if exit_code != 0 do
IO.puts("�️ Test failures - check output above")
System.halt(1)
else
IO.puts("✅ All tests pass")
end
end
end