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
9 changes: 8 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,12 @@ repos:
rev: v0.12.4
hooks:
- id: ruff-format
- id: ruff
- id: ruff-check
args: [--fix]
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.45.0
hooks:
- id: markdownlint
args:
- "--config=.markdownlint.yaml"
- "docs/docs/**/*.mdx"
146 changes: 146 additions & 0 deletions CAPABILITIES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
## Infrahub MCP Server 0.1.0
| 🟢 Tools (10) | 🟢 Prompts | 🟢 Resources | <span style="opacity:0.6">🔴 Logging</span> | 🟢 Experimental |
| --- | --- | --- | --- | --- |
## 🛠️ Tools (10)

<table style="text-align: left;">
<thead>
<tr>
<th style="width: auto;"></th>
<th style="width: auto;">Tool Name</th>
<th style="width: auto;">Description</th>
<th style="width: auto;">Inputs</th>
</tr>
</thead>
<tbody style="vertical-align: top;">
<tr>
<td>1.</td>
<td>
<code><b>branch_create</b></code>
</td>
<td>Create a new branch in infrahub.<br/><br/>Parameters:<br/> name: Name of the branch to create.<br/> sync_with_git: Whether to sync the branch with git. Defaults to False.<br/><br/>Returns:<br/> Dictionary with success status and branch details.</td>
<td>
<ul>
<li> <code>name</code> : string<br /></li>
<li> <code>sync_with_git</code> : boolean<br /></li>
</ul>
</td>
</tr>
<tr>
<td>2.</td>
<td>
<code><b>get_branches</b></code>
</td>
<td>Retrieve all branches from infrahub.</td>
<td>
<ul>
</ul>
</td>
</tr>
<tr>
<td>3.</td>
<td>
<code><b>get_graphql_schema</b></code>
</td>
<td>Retrieve the GraphQL schema from Infrahub<br/><br/>Parameters:<br/> None<br/><br/>Returns:<br/> MCPResponse with the GraphQL schema as a string.</td>
<td>
<ul>
</ul>
</td>
</tr>
<tr>
<td>4.</td>
<td>
<code><b>get_node_filters</b></code>
</td>
<td>Retrieve all the available filters for a specific schema node kind.<br/><br/>There's multiple types of filters<br/>attribute filters are in the form attribute__value<br/><br/>relationship filters are in the form relationship__attribute__value<br/>you can find more information on the peer node of the relationship using the <code>get_schema</code> tool<br/><br/>Filters that start with parent refer to a related generic schema node.<br/>You can find the type of that related node by inspected the output of the <code>get_schema</code> tool.<br/><br/>Parameters:<br/> kind: Kind of the objects to retrieve.<br/> branch: Branch to retrieve the objects from. Defaults to None (uses default branch).<br/><br/>Returns:<br/> MCPResponse with success status and filters.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
<li> <code>kind</code> : string<br /></li>
</ul>
</td>
</tr>
<tr>
<td>5.</td>
<td>
<code><b>get_nodes</b></code>
</td>
<td>Get all objects of a specific kind from Infrahub.<br/><br/>To retrieve the list of available kinds, use the <code>get_schema_mapping</code> tool.<br/>To retrieve the list of available filters for a specific kind, use the <code>get_node_filters</code> tool.<br/><br/>Parameters:<br/> kind: Kind of the objects to retrieve.<br/> branch: Branch to retrieve the objects from. Defaults to None (uses default branch).<br/> filters: Dictionary of filters to apply.<br/> partial_match: Whether to use partial matching for filters.<br/><br/>Returns:<br/> MCPResponse with success status and objects.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
<li> <code>filters</code> : unknown<br /></li>
<li> <code>kind</code> : string<br /></li>
<li> <code>partial_match</code> : boolean<br /></li>
</ul>
</td>
</tr>
<tr>
<td>6.</td>
<td>
<code><b>get_related_nodes</b></code>
</td>
<td>Retrieve related nodes by relation name and a kind.<br/><br/>Args:<br/> kind: Kind of the node to fetch.<br/> filters: Filters to apply on the node to fetch.<br/> relation: Name of the relation to fetch.<br/> branch: Branch to fetch the node from. Defaults to None (uses default branch).<br/><br/>Returns:<br/> MCPResponse with success status and objects.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
<li> <code>filters</code> : unknown<br /></li>
<li> <code>kind</code> : string<br /></li>
<li> <code>relation</code> : string<br /></li>
</ul>
</td>
</tr>
<tr>
<td>7.</td>
<td>
<code><b>get_schema</b></code>
</td>
<td>Retrieve the full schema for a specific kind.<br/>This includes attributes, relationships, and their types.<br/><br/>Parameters:<br/> kind: Schema Kind to retrieve.<br/> branch: Branch to retrieve the schema from. Defaults to None (uses default branch).<br/><br/>Returns:<br/> Dictionary with success status and schema.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
<li> <code>kind</code> : string<br /></li>
</ul>
</td>
</tr>
<tr>
<td>8.</td>
<td>
<code><b>get_schema_mapping</b></code>
</td>
<td>List all schema nodes and generics available in Infrahub<br/><br/>Parameters:<br/> branch: Branch to retrieve the mapping from. Defaults to None (uses default branch).<br/><br/>Returns:<br/> Dictionary with success status and schema mapping.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
</ul>
</td>
</tr>
<tr>
<td>9.</td>
<td>
<code><b>get_schemas</b></code>
</td>
<td>Retrieve all schemas from Infrahub, optionally excluding Profiles and Templates.<br/><br/>Parameters:<br/> infrahub_client: Infrahub client to use<br/> branch: Branch to retrieve schemas from<br/> exclude_profiles: Whether to exclude Profile schemas. Defaults to True.<br/> exclude_templates: Whether to exclude Template schemas. Defaults to True.<br/><br/>Returns:<br/> Dictionary with success status and schemas.</td>
<td>
<ul>
<li> <code>branch</code> : string | null<br /></li>
<li> <code>exclude_profiles</code> : boolean<br /></li>
<li> <code>exclude_templates</code> : boolean<br /></li>
</ul>
</td>
</tr>
<tr>
<td>10.</td>
<td>
<code><b>query_graphql</b></code>
</td>
<td>Execute a GraphQL query against Infrahub.<br/><br/>Parameters:<br/> query: GraphQL query to execute.<br/><br/>Returns:<br/> MCPResponse with the result of the query.</td>
<td>
<ul>
<li> <code>query</code> : string<br /></li>
</ul>
</td>
</tr>
</tbody>
</table>
200 changes: 178 additions & 22 deletions LLMS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,199 @@

Infrahub MCP Server connects your AI assistants to Infrahub using the open MCP standard—so agents can read and (optionally) change your infra state through a consistent, audited, human-approved interface.

## Key Directories
## Agent Operating Principles

1. **Plan → Ask → Act → Verify → Record**
Plan briefly, ask for missing context, act via the narrowest tool, verify the result, and leave a succinct record (commit/PR/comment).

2. **Default to read-only.**
Switch to write/apply only with explicit instruction **and** human approval.

3. **Be specific and reversible.**
Prefer minimal, scoped changes that are easy to roll back. Avoid broad or implicit mutations.

4. **Match existing patterns.**
New code and behavior should look like it’s always been here.

5. **Idempotency & safety.**
Favor idempotent operations; use dry-runs where available; never print or guess secrets.

## Required Development Workflow

**CRITICAL**: Always run these commands in sequence before committing:

```bash
uv sync # Install dependencies
uv run pre-commit run # Ruff + Mypy
uv run pytest # Run full test suite
```

**All three must pass** — enforced by CI. Alternatives (granular tasks):

```bash
uv run invoke lint # Run all linters (yaml, ruff, pylint, mypy)
uv run invoke lint-ruff # Run ruff linter only
uv run invoke lint-pylint # Run pylint only
uv run invoke lint-mypy # Run mypy type checking only
uv run invoke lint-yaml # Run yamllint only
uv run invoke format # Auto-format code with ruff
```

**Policy:** Tests must pass and lint/typing must be clean before committing.

## Repository Structure

```bash
infrahub-mcp/
├── docs/ # Documentation (UPDATE FOR CHANGES)
├── src/ # Python Code
│   └── infrahub_mcp/
│ ├── __init__.py
| ├── branch.py
| ├── constants.py
| ├── gql.py
| ├── nodes.py
| ├── prompts/
| │   └── main.md
| ├── schema.py
| ├── server.py
| └── utils.py
├── src/infrahub_mcp # Library source code (Python ≥ 3.13)
| ├── prompts/ # Prompt templates
| ├── resources/ # Resources, templates
| └── tools/ # Tool implementations
└── tests/ # Python/integration tests
```

## Code Standards
## Core MCP Objects

When modifying MCP functionality, changes typically need to be applied across all object types:

- **Tools** (`src/infrahub_mcp/tools/`)
- **Resources** (`src/infrahub_mcp/resources/`)
- **Prompts** (`src/infrahub_mcp/prompts/`)

## Code Standards (single source of truth)

### Python

- **Python ≥ 3.13** with **full type annotations** for all new/changed code.
- **MyPy clean** — `uv run pre-commit run mypy`
- **Ruff clean** — `uv run pre-commit run ruff`
- Prefer clear, maintainable code over cleverness.
- Public functions/classes **must** have docstrings (consistent style).
- Raise **specific exceptions**; avoid bare `except:`.
- For MCP result objects in tests, use `# type: ignore[attr-defined]` instead of brittle type assertions.

### Python Backend
### Testing

- **Type hints required** for all new code
- **MyPy compliant** - run `pre-commit run mypy`
- **Ruf compliant**- run `pre-commit run ruff`
- **pytest** for testing
- Every test is atomic, self-contained, and targets **one** behavior.
- Use **parametrization** for variants; avoid loops in tests.
- Imports at file top; no dynamic imports inside tests.
- **ALWAYS** run `uv run pytest` after significant changes.
- Each feature requires corresponding tests (happy path + key edge cases).

## Documentation Requirements
## Documentation

- **docs/**: Update for any user-facing changes
- **Docstrings**: Required for new functions/classes

## Test Utilities
### Documentation Guidelines

- All documentation files are in `docs/docs/` and use `.mdx` format
- **ALWAYS run markdownlint before committing documentation changes**: `markdownlint docs/docs/**/*.mdx`
- Use `markdownlint --fix docs/docs/**/*.mdx` to automatically fix formatting issues
- Follow the project's `.markdownlint.yaml` configuration
- Test documentation builds with `cd docs && npm run build` before submitting
- Documentation follows the Diataxis framework (Getting Started, Features, Guides, Reference)

### Documentation Build

```bash
uv run invoke docs # Build documentation website (requires npm)
```

## Development Rules

### Git & CI

- Pre-commit hooks are required (run automatically on commits).
- Don’t amend commits to fix pre-commit failures; make a follow-up commit.
- Apply PR labels: **bugs / breaking / enhancements / features**.
- Improvements = **enhancements** unless explicitly a **feature**.
- **NEVER** force-push on collaborative repos.
- **ALWAYS** run pre-commit before PRs.

### Commit Messages & Agent Attribution

- **Agents MUST identify themselves** (e.g., `🤖 Generated with Claude Code`) in commits/PRs.
- Keep messages brief — headline of **what** changed. (How/why goes in the PR body.)
- Always read issue comments for context; maintainers are authoritative.

### PR Messages — Required Structure

- 1–2 concise paragraphs: **problem/tension** + **solution** (PRs are documentation).
- A focused **code example** showing the key capability.
- **Avoid:** bullet dumps, exhaustive change lists, verbose closes/fixes, marketing language.
- **Do:** explain why the change matters; show before/after when helpful.
- Minor fixes: keep the body extremely short.
- No separate “test plan” sections or testing summaries.

## Review Process (for humans and agents)

- **Read the full context** (related files, tests, docs).
- **Check against established patterns**; keep consistency.
- **Verify functionality claims** by tracing the code and, if possible, running a focused check.
- **Consider edge cases** (timeouts, empty inputs, network/permission errors).

### Avoid in Reviews

- Generic feedback without specifics
- Unlikely hypotheticals
- Bikeshedding style when functionality is correct
- Requests without suggested solutions
- Summarizing what’s already in the PR

### Tone

- Acknowledge good decisions (“This API design is clean”).
- Be direct and respectful.
- Explain impact (“This will confuse users because …”).
- Remember: someone else maintains this code forever.

### Decision Framework (before approve)

1. Does this PR achieve its stated purpose?
2. Is that purpose aligned with where the codebase should go?
3. Would I be comfortable maintaining this code?
4. Do I actually understand what it does (not just claims)?
5. Does this change introduce technical debt?

If something needs work, help it get there with **specific, actionable** feedback. If it solves the wrong problem, say so clearly.

### Review Comment Examples

- ❌ “Add more tests”
✅ “The `handle_timeout` method needs tests for the edge case where `timeout=0`.”
- ❌ “This API is confusing”
✅ “The parameter name `data` is ambiguous—consider `message_content` to match the MCP specification.”
- ❌ “This could be better”
✅ “Works, but creates a circular dependency. Consider moving the validation to `utils/validators.py`.”

### Review Checklist

Before approving, verify:

- [ ] All required workflow steps completed (uv sync, pre-commit, pytest)
- [ ] Changes align with repository patterns and conventions
- [ ] API changes are documented and backwards-compatible where possible
- [ ] Error handling follows project patterns (specific exception types)
- [ ] Tests cover new functionality and edge cases

## Operational & Safety Guidelines for Agents

- **Human approval required** before any write/apply operation. Present a clear plan and a diff.
- Prefer **dry runs** and attach their output to the PR where available.
- **Least privilege**: call the most specific tool with the smallest scope.
- **Idempotency & retries**: safe to re-run; add backoff on transient failures.
- **Observability**: include request IDs and context in logs; never log secrets.
- **Concurrency**: avoid stepping on active branches/migrations; coordinate via PRs.

> If unsure, **stop and ask** with a concrete question.

## Security & Secrets

### Running Tests
- Configure credentials via **environment variables**; never hardcode.
- Never print tokens, keys, or sensitive paths in logs, exceptions, or PRs.
- Redact sensitive values in examples and tests.

## Platform-Specific Instructions

Expand Down
Loading