Thank you for your interest in contributing. This document covers everything you need to get from zero to a merged pull request.
This project follows the Contributor Covenant v2.1. Please read it before participating.
- Bug reports — open an issue with steps to reproduce, expected behavior, and actual behavior.
- Feature proposals — open an issue first and describe the use case before writing code. The project has a specific scope (protocol-agnostic registry with multi-transport and ephemeral-agent support) and not every feature belongs here.
- Pull requests — bug fixes, tests, and documentation improvements are always welcome. For larger changes, discuss in an issue first.
- .NET 10 SDK
- PostgreSQL 14+ (local instance, Docker, or a remote dev cluster)
- Redis 7+ (local instance or Docker)
dotnet-efglobal tool:dotnet tool install --global dotnet-ef
git clone <repo-url>
cd AgentRegistry
dotnet restoreUse .NET user secrets — never commit connection strings or tokens:
dotnet user-secrets set "ConnectionStrings:Postgres" \
"Host=localhost;Port=5432;Database=agentregistry;Username=agentregistry;Password=<password>" \
--project src/AgentRegistry.Api
dotnet user-secrets set "ConnectionStrings:Redis" \
"localhost:6379" \
--project src/AgentRegistry.Apipsql -U postgres -c "CREATE DATABASE agentregistry;"
psql -U postgres -d agentregistry -c "CREATE USER agentregistry WITH PASSWORD '<password>';"
psql -U postgres -d agentregistry -c "GRANT ALL ON SCHEMA public TO agentregistry;"The AGENTREGISTRY_DB environment variable is used by the EF Core design-time factory so dotnet ef commands connect to a real database:
export AGENTREGISTRY_DB="Host=localhost;Database=agentregistry;Username=agentregistry;Password=<password>"
dotnet ef database update -p src/AgentRegistry.Infrastructure -s src/AgentRegistry.Apiappsettings.Development.json has Database:AutoMigrate: true, so running the API locally will also apply pending migrations automatically.
dotnet run --project src/AgentRegistry.Api- API:
http://localhost:5000 - Scalar explorer:
http://localhost:5000/scalar/v1 - Liveness:
http://localhost:5000/healthz - Readiness:
http://localhost:5000/readyz
# Set a bootstrap token in user secrets
dotnet user-secrets set "Bootstrap:Token" "dev-bootstrap-token" --project src/AgentRegistry.Api
# Bootstrap an Admin key
curl -X POST http://localhost:5000/api-keys/bootstrap \
-H "X-Bootstrap-Token: dev-bootstrap-token" \
-H "Content-Type: application/json" \
-d '{"ownerId": "local-dev", "description": "local admin"}'# All tests
dotnet test
# A single project
dotnet test tests/AgentRegistry.Api.Tests
# With detailed output
dotnet test --logger "console;verbosity=normal"Tests are split into three projects:
| Project | Contents |
|---|---|
AgentRegistry.Domain.Tests |
Domain logic unit tests — pure, no infrastructure |
AgentRegistry.Application.Tests |
Service tests using Rocks source-gen mocks |
AgentRegistry.Api.Tests |
HTTP integration tests via WebApplicationFactory with in-memory fakes |
Integration tests use in-memory repositories and a fake API key service — no real database or Redis is needed to run them.
src/
AgentRegistry.Domain/ Pure domain types — zero external dependencies
Agents/ Agent, Endpoint, Capability, enums
ApiKeys/ ApiKey, ApiKeyScope
AgentRegistry.Application/ Interfaces and use-case services
Agents/ AgentService, IAgentRepository, ILivenessStore
Auth/ IApiKeyService
AgentRegistry.Infrastructure/ Concrete implementations
Auth/ SqlApiKeyService, NotImplementedApiKeyService
Liveness/ RedisLivenessStore, health checks
Persistence/ AgentRegistryDbContext, SqlAgentRepository
AgentRegistry.Api/ ASP.NET Core 10 host
Agents/ Registration and discovery endpoints
ApiKeys/ Key management and bootstrap endpoints
Auth/ ApiKeyAuthenticationHandler, policies, claims
tests/
AgentRegistry.Domain.Tests/
AgentRegistry.Application.Tests/
AgentRegistry.Api.Tests/
Infrastructure/ WebApplicationFactory, in-memory fakes
k8s/
redis.yaml Redis deployment for the cluster
agentregistry/ Service deployment manifests
The domain has no external dependencies. Application interfaces (IAgentRepository, ILivenessStore, IApiKeyService) are defined in the Application project and implemented in Infrastructure. Keep the dependency direction pointing inward — Domain ← Application ← Infrastructure ← Api.
- Add a value to
TransportTypeinAgentRegistry.Domain/Agents/TransportType.cs. - Update
AgentRegistryDbContextif any index or constraint references transport. - Add a migration.
- Update the
AgentSearchFilterandInMemoryAgentRepositoryif the new transport needs special filtering.
- Add a value to
ProtocolTypeinAgentRegistry.Domain/Agents/ProtocolType.cs. - Protocol-specific metadata (tool manifests, agent cards, etc.) is stored as JSON in
Endpoint.ProtocolMetadata— no schema change needed for the metadata itself.
export AGENTREGISTRY_DB="Host=localhost;Database=agentregistry;..."
dotnet ef migrations add <DescriptiveName> \
-p src/AgentRegistry.Infrastructure \
-s src/AgentRegistry.ApiMigrations live in src/AgentRegistry.Infrastructure/Migrations/. Always review the generated migration before committing — check that Up and Down are correct, that indexes are named following the existing ix_<table>_<columns> convention, and that any new columns have appropriate defaults.
Domain tests — plain xUnit, no mocks needed.
Application service tests — use Rocks for mocking interfaces. Add [assembly: Rock(typeof(IYourInterface), BuildType.Create)] at the top of the test file and use new IYourInterfaceCreateExpectations() in tests.
Integration tests — extend or add to the AgentRegistryFactory-based tests in AgentRegistry.Api.Tests. The factory replaces all infrastructure with in-memory fakes. Use CreateAdminClient() for operations requiring Admin scope and CreateAgentClient() for Agent scope.
- Fork the repository and create a branch from
main. - Write or update tests covering your change. PRs that reduce test coverage will not be merged.
- Ensure
dotnet testpasses cleanly. - Ensure
dotnet buildproduces no warnings (warnings are not treated as errors in CI yet, but they will be). - Describe what your PR changes and why in the PR description. Reference any related issues.
- A maintainer will review within a reasonable time. Be prepared for feedback and iteration.
Use short, imperative present-tense commit messages:
Add queue-backed liveness TTL renewal
Fix discovery filter when agent has no endpoints
Update EF Core mapping for new transport types
One logical change per commit. Squash fixup commits before marking a PR ready for review.
By submitting a pull request you agree that your contribution will be licensed under the MIT License that covers this project.