Metadata-Version: 2.5
Name: flotilla-mcp
Version: 0.1.1
Summary: A self-developing fleet of MCP servers, with guardrails.
Project-URL: Homepage, https://github.com/OmPrakashSingh1704/flotilla-mcp
Project-URL: Source, https://github.com/OmPrakashSingh1704/flotilla-mcp
Project-URL: Issues, https://github.com/OmPrakashSingh1704/flotilla-mcp/issues
Project-URL: Changelog, https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CHANGELOG.md
Project-URL: Security, https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md
Author: OmPrakashSingh1704
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: agents,deployment,mcp,model-context-protocol,self-development
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Software Distribution
Requires-Python: >=3.11
Requires-Dist: anyio<5,>=4.7
Requires-Dist: mcp<1.3,>=1.2
Requires-Dist: pygithub<3,>=2.4
Requires-Dist: pyyaml<7,>=6.0
Requires-Dist: requests<3,>=2.31
Requires-Dist: starlette>=0.40
Requires-Dist: uvicorn>=0.30
Provides-Extra: watcher
Requires-Dist: docker<8,>=7.1; extra == 'watcher'
Description-Content-Type: text/markdown

<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/OmPrakashSingh1704/flotilla-mcp/main/assets/logo-dark.svg">
    <img src="https://raw.githubusercontent.com/OmPrakashSingh1704/flotilla-mcp/main/assets/logo.svg" alt="Flotilla MCP" width="425">
  </picture>
</p>

<p align="center">
  A self-developing fleet of MCP servers, with guardrails.
</p>

<p align="center">
  <a href="https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/LICENSE"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
  <a href="https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CONTRIBUTING.md"><img alt="Contributions welcome" src="https://img.shields.io/badge/contributions-welcome-teal.svg"></a>
</p>

Flotilla MCP is a fleet of [Model Context Protocol](https://modelcontextprotocol.io)
servers that can read GitHub issues, edit its own source, open pull requests,
and — once a human merges the change — redeploy itself, without ever being
able to take the fleet down or disarm its own safety controls. The parts of
the system that could do real damage (the deploy pipeline, the permission
layer, the rule that defines what's off-limits) are structurally walled off
from the part that writes code, and enforced at more than one independent
layer.

This repository is the foundation of that system: the protected-core
enforcement engine, the Self-Dev MCP server, and the Deploy Watcher's
blue/green deploy and rollback machinery. It is real, tested code, not a
prototype — see [Status](#status--roadmap) below for exactly what's built and
what isn't yet.

## Install

Self-Dev MCP only:

```bash
pip install flotilla-mcp
```

Self-Dev MCP plus the Deploy Watcher (needs the Docker SDK):

```bash
pip install "flotilla-mcp[watcher]"
```

Or run it without installing anything, via [uvx](https://docs.astral.sh/uv/guides/tools/):

```bash
uvx flotilla-mcp
```

This installs three console scripts:

- `flotilla-mcp` and `flotilla-self-dev` (identical — two names for the same
  entry point) — the Self-Dev MCP server: `flotilla-self-dev --transport
  stdio|http` (default `stdio`; `--transport http` serves `/health` on port
  8080 for container health checks); `--version` prints the installed
  version.
- `flotilla-watcher` — the Deploy Watcher. Needs
  `pip install "flotilla-mcp[watcher]"`; without the `docker` package installed,
  it prints `flotilla-watcher needs the Docker SDK. Install it with: pip
  install "flotilla-mcp[watcher]"` and exits rather than crashing with an import
  traceback.

Self-Dev MCP reads its configuration from environment variables (see
[.env.example](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/.env.example) and
[flotilla_mcp/self_dev_mcp/config.py](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/flotilla_mcp/self_dev_mcp/config.py)).
**`SELF_DEV_GITHUB_TOKEN` is the only variable you have to set** — run it from
inside a git checkout with a GitHub `origin` remote and everything else is
detected:

| Variable | Required | Meaning |
|---|---|---|
| `SELF_DEV_GITHUB_TOKEN` | yes | fine-grained token (or bot token): contents, pull requests, and issues read/write on the target repo |
| `SELF_DEV_REPO_REMOTE` | no (auto-detected) | git remote URL used for the clone/branch/commit/push workflow. When unset, detected by running `git remote get-url origin` in the server's working directory. |
| `GITHUB_REPO_FULL_NAME` | no (auto-detected) | `owner/repo`. When unset, parsed from `SELF_DEV_REPO_REMOTE` (explicit or detected). A non-GitHub remote (or a local path) parses to nothing — the editing tools (`start_issue`, `read_file`, `write_file`, `run_tests`) still work; the GitHub-backed tools (`list_assigned_issues`, `check_pr_status`, `submit_pr`) return an `ERROR: no GitHub repository configured` string instead of failing to start. |
| `FLEET_MANIFEST_PATH` | no | path to the fleet manifest. When unset, resolved in order: `fleet_manifest.yaml` in the current directory, then `fleet_manifest.yaml` at the git repo root. If none of those exist either, the server starts with an empty manifest (no services declared) and logs one warning — only the built-in always-protected paths apply until a manifest exists. An *explicit* `FLEET_MANIFEST_PATH` that doesn't exist is still a hard error. |
| `SELF_DEV_MAX_ATTEMPTS` | no (default `5`) | per-issue write attempt cap |
| `SELF_DEV_TEST_TIMEOUT_SECONDS` | no (default `600`) | `run_tests` timeout, in seconds |

An explicitly set environment variable always wins over auto-detection. If
`SELF_DEV_REPO_REMOTE` is unset and no `origin` remote can be detected, the
server exits with a one-line error naming both fixes: run it inside a git
repository with an `origin` remote, or set `SELF_DEV_REPO_REMOTE`.

Read
[SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo)
before pointing this at a repository you care about.

## Use with an MCP client

Both snippets below point `uvx` at the `flotilla-mcp` PyPI package and pass
configuration through environment variables — see
[SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo)
first.

### Claude Desktop

Add to your Claude Desktop config (`claude_desktop_config.json`). The token
is the only variable that's required — as long as the server's working
directory is inside a git checkout with a GitHub `origin` remote, the repo
remote and `owner/repo` are auto-detected (see [Install](#install) above):

```json
{
  "mcpServers": {
    "flotilla-mcp": {
      "command": "uvx",
      "args": ["flotilla-mcp"],
      "env": {
        "SELF_DEV_GITHUB_TOKEN": "<fine-grained token>"
      }
    }
  }
}
```

If your client doesn't run the server with a working directory inside the
target repo (or you want to be explicit), set `SELF_DEV_REPO_REMOTE` (and
optionally `GITHUB_REPO_FULL_NAME`, `FLEET_MANIFEST_PATH`) in `env` the same
way as before -- an explicit value always overrides auto-detection.

### Claude Code

The `claude` CLI wasn't available in the environment this doc was written
in, so its exact `claude mcp add ... -e KEY=VALUE` flag syntax couldn't be
verified against a real `claude mcp add --help`; run that yourself before
scripting the command form. The JSON form above is not client-specific —
paste the same `mcpServers` block into whatever configuration surface your
`claude` CLI version reads for MCP servers.

## Why Flotilla MCP

Most "self-modifying agent" demos either can't touch production or can touch
too much of it. Flotilla MCP is built around one design principle: **the agent
reasons, MCP servers provide capabilities, and guardrails sit in between,
independent of the agent's own judgment.**

- The agent (any LLM-backed orchestrator, via the MCP gateway) decides *what*
  to build or fix.
- MCP servers like Self-Dev MCP expose narrow, auditable primitives — read a
  file, write a file, run tests, open a PR — not blanket shell access.
- Guardrails (the fleet manifest, workspace containment, the attempt cap,
  GitHub branch protection, credential scoping) sit *between* the agent's
  intent and anything irreversible. They work in two layers:
  - the **tool-level checks** stop a *cooperative* agent, one that only
    edits through `write_file`, from touching protected paths or `.git/`;
  - **GitHub branch protection plus a separate bot identity** is the real
    backstop against a *hostile* (e.g. prompt-injected) agent. `run_tests`
    executes code the agent wrote, with the self-dev token, so that code
    can write protected files into its PR branch or call the GitHub API
    directly. What stops it from reaching `main` is a required CI check and
    a required human (code-owner) review that the bot identity can't give
    itself. In either case Self-Dev MCP never holds a Docker socket.

The result is an agent that can fix its own bugs and extend its own fleet,
while every change that could take the system down or weaken its own
oversight has to pass a human review on GitHub, **provided** the
[preconditions](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo)
are in place.

## Key features

**Implemented today:**

- **Protected-core enforcement** (`flotilla_mcp/common/manifest.py`): a fleet
  manifest defines which services and paths are off-limits. A hardcoded
  core is protected no matter what the manifest says: the manifest, its
  loader, `flotilla_mcp/__init__.py`, `requirements.txt`,
  `requirements-dev.txt`, `docker-compose.yml`, `pyproject.toml`,
  `.gitattributes`, `.gitignore`, and the whole `flotilla_mcp/common/` and
  `.github/` trees. Path checks canonicalize
  separators, `..` segments, NTFS aliases and case, and are applied to the
  symlink-resolved target too.
- **Self-Dev MCP server**: a [FastMCP](https://github.com/modelcontextprotocol/python-sdk)
  server exposing `start_issue`, `read_file`, `write_file`, `run_tests`,
  `submit_pr`, `list_assigned_issues`, and `check_pr_status`. Every write is
  checked against the fleet manifest *and* confined to an ephemeral,
  per-issue workspace before it touches disk. Absolute paths, drive letters,
  UNC paths, `..` escapes and any `.git` path are refused, and each refusal
  is audit-logged. Every git call runs with hooks and fsmonitor disabled
  and pushes with an explicit, non-forcing refspec. A per-issue attempt cap
  (default 5) stops runaway writes; a refused write never consumes an
  attempt. These checks bind a cooperative agent; see
  [the safety model](#the-protected-core-and-the-safety-model) for what
  backs them up.
- **Limited blast radius**: the Self-Dev MCP has no Docker socket access,
  no deploy credentials, and no merge code path. It can open and update
  PRs. Making them live takes a human review enforced by GitHub branch
  protection, which is a
  [precondition](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo),
  not something this code can enforce.
- **Deploy Watcher** — polls `main` for new commits, builds each
  non-protected service that has a `container` entry in the manifest from a
  fresh checkout of that commit, and performs a
  blue/green deploy: the new container must pass 3 consecutive health checks
  before it's promoted, and then survives a 30-minute probation window
  during which a single failed check triggers an automatic rollback to the
  last *proven* image. An image is only recorded as known-good after it
  clears probation, so a rollback can never target a build that hasn't
  actually been proven to work.
- **Resumable, non-destructive self-dev cycles** — re-invoking `start_issue`
  for an issue that already has an open PR resumes the same
  `selfdev/issue-N` branch instead of branching again, so follow-up commits
  land on the same PR. There is no force-push anywhere in the pipeline.
- **Docker Compose + per-service Dockerfiles** — `docker-compose.yml` brings
  up the fixture service, Self-Dev MCP, and the Deploy Watcher on a
  dedicated `mcp-fleet` network, each with its own non-root Dockerfile and
  only the credentials/mounts it actually needs (see
  [Quickstart](#quickstart)).
- **Self-Dev MCP HTTP transport**: `--transport http` serves Self-Dev MCP
  over SSE (`/sse`, `/messages/`) plus `GET /health` on port 8080, which
  the compose healthcheck probes. Tools run in worker threads, so a long
  `run_tests` never blocks `/health`. `--transport stdio` (the default) is
  unchanged for local/CLI use. For this release self-dev-mcp is
  compose-managed (`docker compose up --build`), not redeployed by the
  Deploy Watcher.

**Roadmap (not built yet — see [Status](#status--roadmap)):**

- MCP gateway and permission manager (the layer that sits between an
  orchestrating agent and every capability server, including Self-Dev MCP)
- `model-adapters-mcp` and `credentials-manager`, and the chat-side "Model
  Manager" flow for adding support for a new LLM backend on request

## How it fits together

```mermaid
flowchart TD
    subgraph gh["GitHub (system of record)"]
        issue["Issue labeled self-dev"]
        pr["Pull Request"]
        ci["CI status checks"]
        branchprot["Branch protection + CODEOWNERS"]
        main["main branch"]
    end

    subgraph host["Fleet host"]
        selfdev["Self-Dev MCP<br/>(git/PR ops only —<br/>no Docker, no deploy creds)"]
        watcher["Deploy Watcher<br/>(PROTECTED — Docker socket,<br/>blue/green, rollback)"]
        gateway["MCP Gateway +<br/>Permission Manager<br/>(PROTECTED — planned)"]
        registry["Service registry +<br/>known-good store"]
    end

    subgraph fleet["Watcher-deployed containers"]
        svc1["fixture-hello-mcp"]
        svcN["... other unprotected services<br/>with a container entry"]
    end

    issue -->|start_issue| selfdev
    selfdev -->|read_file / write_file<br/>manifest-checked| selfdev
    selfdev -->|run_tests, informational| selfdev
    selfdev -->|submit_pr| pr
    pr --> ci
    ci --> branchprot
    branchprot -->|human merge only| main
    main -->|poll| watcher
    watcher -->|build + health-check +<br/>blue/green swap| fleet
    watcher --> registry
    gateway -.orchestrates calls to.-> selfdev
    gateway -.orchestrates calls to.-> svcN
```

See [ARCHITECTURE.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/ARCHITECTURE.md) for the full component breakdown,
trust boundaries, and the rollback state machine.

## The protected core and the safety model

A small set of things can never be edited by the Self-Dev MCP, no matter
what an agent's reasoning concludes it should do:

- The **fleet manifest** (`fleet_manifest.yaml`), the **manifest loader**
  (`flotilla_mcp/common/manifest.py`) and everything else in `flotilla_mcp/common/`,
  plus the build/dependency files (`flotilla_mcp/__init__.py`,
  `requirements.txt`, `requirements-dev.txt`, `docker-compose.yml`,
  `pyproject.toml`, `.gitattributes`, `.gitignore`) and CI/CODEOWNERS
  (`.github/`). These are
  hardcoded-protected, so `write_file` refuses them even if the manifest
  were rewritten to claim they're safe.
- **Git metadata** (`.git/`): no tool can read or write it, and every git
  call runs with hooks and fsmonitor disabled and an explicit push refspec.
- The **Deploy Watcher**, **permission manager** (planned), and **MCP
  gateway** (planned) services — marked `protected: true` in the manifest.
  These hold real authority (Docker socket access, routing, auth), so they
  are off-limits at the tool layer *and* would additionally require
  CODEOWNERS sign-off at the GitHub layer — the workflow and CODEOWNERS file
  exist; enforcement requires branch protection, which the repo admin
  enables — see
  [CONTRIBUTING.md#enabling-branch-protection](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CONTRIBUTING.md#enabling-branch-protection).

On top of that:

- **Workspace containment**: every `read_file`/`write_file`/`run_tests`
  call is resolved against the current issue's ephemeral workspace.
  Absolute paths, drive letters, UNC paths, `..` segments, and symlinks or
  junctions that lead to a protected or outside path are refused before
  anything touches disk.
- **No merge code path**: Self-Dev MCP can open and update a pull request,
  and nothing in this codebase calls a merge API. The self-dev token *could*
  merge through the API, though, so merge-by-a-human-only is enforced by
  GitHub branch protection and CODEOWNERS. The workflow and CODEOWNERS file
  exist; the repo admin enables branch protection (see
  [CONTRIBUTING.md#enabling-branch-protection](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CONTRIBUTING.md#enabling-branch-protection)).
- **No deploy authority in Self-Dev MCP** — it holds no Docker socket, no
  deploy credentials, and never imports `docker`. Only the Deploy Watcher —
  a separate, protected service — can build an image or swap a container.
- **Known-good floor** — the Deploy Watcher only records an image as
  known-good after it survives a full probation window with zero failed
  checks. Rollback always targets that proven image, never a build that
  merely passed its first three health checks.

This is defense in depth, not a single check: even a bug in the manifest
parser doesn't expose the manifest file or the parser itself, because those
paths are hardcoded rather than manifest-driven.

**What the tool checks do *not* stop.** They bind a *cooperative* agent.
`run_tests` executes code the agent wrote, with the self-dev token. That
code can write any file (protected ones included), which `submit_pr`'s
`git add -A` then commits to the PR branch, and it can call the GitHub API
directly. The backstop is GitHub branch protection (required `test` check,
required review, code-owner review, `enforce_admins`) plus a **separate
bot identity** for self-dev. With the owner's own PAT, self-dev PRs are
authored by the owner, and a sole owner can't approve their own PR under
`enforce_admins`. See [SECURITY.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#known-limitations).

## Quickstart

### Run the test suite (works today)

```bash
git clone https://github.com/OmPrakashSingh1704/flotilla-mcp.git
cd flotilla-mcp
python -m venv .venv && source .venv/bin/activate   # or .venv\Scripts\activate on Windows
pip install -r requirements-dev.txt
python -m pytest tests -m "not docker" -v -W error::DeprecationWarning -W error::pytest.PytestUnhandledCoroutineWarning
```

`requirements-dev.txt` pulls in `requirements.txt` plus the packaging tools
(`build`, `twine`, `hatchling`, `hatch-fancy-pypi-readme`) that
`tests/test_packaging.py` needs to build a wheel as part of the suite.

(`-m docker` runs the Docker integration test separately; it needs a
reachable Docker daemon.)

This runs the full suite for the protection engine, the Self-Dev MCP tools,
and the Deploy Watcher — including the adversarial tests that assert a
protected-path write is refused and a probation failure triggers rollback.

### Run the fleet locally

> **Precondition before pointing a live agent at a repo:** enable branch
> protection on `main` (required `test` check, required review, code-owner
> review, `enforce_admins`) **and** give self-dev its own bot identity (a
> machine user or GitHub App), not your own PAT. On a private repo, branch
> protection needs GitHub Pro, Team or Enterprise. See
> [SECURITY.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#preconditions-before-pointing-a-live-agent-at-a-repo).
> Running the stack with placeholder values to look around is fine.

```bash
cp .env.example .env
# edit .env: set SELF_DEV_GITHUB_TOKEN, WATCHER_GITHUB_TOKEN,
# GITHUB_REPO_FULL_NAME, REPO_REMOTE, SELF_DEV_REPO_REMOTE
docker compose up --build
```

`SELF_DEV_GITHUB_TOKEN` (fine-grained: contents, pull requests and issues
read/write on this repo) and `WATCHER_GITHUB_TOKEN` (contents read-only) are
separate tokens. The old shared `GITHUB_TOKEN` variable is no longer read.
Git authenticates with them through a credential helper, so never put a
token in a remote URL.

This brings up three containers on the `mcp-fleet` network:

- **fixture-hello-mcp** — `http://localhost:8081/health` — a minimal Flask
  service used as the Deploy Watcher's local smoke-test target.
- **self-dev-mcp** — `http://127.0.0.1:8082/health` (bound to loopback only,
  not published to other hosts — see
  [SECURITY.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md#known-limitations)) — the Self-Dev MCP server
  over `--transport http`. Compose-managed: after merging a change to it,
  update it with `docker compose up --build self-dev-mcp`. The Deploy
  Watcher does not redeploy it.
- **deploy-watcher** — no published port; it only talks outbound to GitHub
  and to the Docker daemon via the mounted `docker.sock`.

With placeholder `.env` values (or real ones that just don't resolve),
`fixture-hello-mcp` and `self-dev-mcp` still start and their `/health`
checks still pass — GitHub credentials are only resolved lazily, on the
first tool call that actually needs them. Any Self-Dev MCP tool that talks
to GitHub (`list_assigned_issues`, `submit_pr`, `check_pr_status`, ...) will
return an `"ERROR: ..."` string until `SELF_DEV_GITHUB_TOKEN` and
`GITHUB_REPO_FULL_NAME` are set to real values.

## Repo layout

```
flotilla_mcp/
  common/manifest.py        fleet manifest loader + protected-path engine
  self_dev_mcp/              Self-Dev MCP: git ops, workspace, tools, server,
                                Dockerfile
  deploy_watcher/             Deploy Watcher: checkout, build, health, blue/green,
                                rollback, service registry, known-good store,
                                Dockerfile, entrypoint.sh
  fixture_hello_mcp/          fixture Flask service + Dockerfile, used as the
                                Deploy Watcher's local smoke-test target
tests/                      unit tests, mirroring the flotilla_mcp/ layout
docs/design/                design documents (historical / planned; code and
                              ARCHITECTURE.md are authoritative)
fleet_manifest.yaml         the fleet manifest (protected)
docker-compose.yml          local fleet: mcp-fleet network + all three services (protected)
.env.example                template for the .env docker-compose reads secrets from
```

## Status / Roadmap

| Component | Status |
|---|---|
| Fleet manifest + protected-path engine | Built |
| Self-Dev MCP (7 tools, workspace containment, attempt cap) | Built |
| Deploy Watcher (blue/green, probation, rollback, known-good floor) | Built |
| Docker Compose + per-service Dockerfiles | Built |
| Self-Dev MCP HTTP transport (`--transport http`) | Built |
| CI workflow + CODEOWNERS | Built (CODEOWNERS names a real owner, `@OmPrakashSingh1704`; branch protection must still be enabled by the repo admin for that review to be enforced, rather than advisory; see [CONTRIBUTING.md#enabling-branch-protection](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CONTRIBUTING.md#enabling-branch-protection)) |
| MCP gateway | Planned |
| Permission manager | Planned |
| `model-adapters-mcp` | Planned |
| `credentials-manager` | Planned |
| Model Manager chat flow | Planned |

Nothing in this table is aspirational marketing — if it says "Built," it has
passing tests in this repository today. If it says "Planned" or "In
progress," there is no working code for it yet.

The one thing "Built" doesn't cover automatically: a real run against your
own GitHub repo (a live PR, CI, and merge). See
[docs/acceptance-checklist.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/docs/acceptance-checklist.md) for that manual
verification pass.

## Documentation

- [ARCHITECTURE.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/ARCHITECTURE.md) — components, trust boundaries, the
  self-dev cycle, and the rollback state machine
- [SECURITY.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SECURITY.md) — threat model, how to report a vulnerability,
  and known limitations
- [CONTRIBUTING.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CONTRIBUTING.md) — dev setup, PR flow, and how to add a
  new fleet service
- [CODE_OF_CONDUCT.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CODE_OF_CONDUCT.md)
- [GOVERNANCE.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/GOVERNANCE.md) — maintainers and decision-making
- [SUPPORT.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/SUPPORT.md) — where to ask for help
- [CHANGELOG.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/CHANGELOG.md)
- [RELEASING.md](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/RELEASING.md) — how a `flotilla-mcp` release is cut and
  published to PyPI

## License

Apache License 2.0 — see [LICENSE](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/LICENSE) and [NOTICE](https://github.com/OmPrakashSingh1704/flotilla-mcp/blob/main/NOTICE).
