Content
# mcp-canadabuys
[](https://pypi.org/project/mcp-canadabuys/)
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
[](LICENSE)
An [MCP](https://modelcontextprotocol.io/) server that gives AI agents structured
access to Canadian federal procurement data from
[CanadaBuys](https://canadabuys.canada.ca/).
## What it does
`mcp-canadabuys` wraps CanadaBuys open data — live tenders and historical contract
awards — and exposes it to AI agents as a small set of well-described MCP tools.
It normalizes the messy bilingual CSV feeds into clean schemas, scores expiring
contracts for Buy Canadian rebid potential, and lets an agent research departments
and incumbent vendors. All defense-related procurement is permanently excluded at
the data layer.
## Quick start — Claude Code
```bash
claude mcp add mcp-canadabuys -- uvx mcp-canadabuys
```
## Quick start — Claude Desktop
Add this to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"canadabuys": {
"command": "uvx",
"args": ["mcp-canadabuys"]
}
}
}
```
## Quick start — from source
```bash
git clone https://github.com/alaylik-png/mcp-canadabuys.git
cd mcp-canadabuys
uv sync --extra dev
uv run mcp-canadabuys
```
## Tools
| Tool | Description | Key parameters |
|---|---|---|
| `search_open_tenders` | Search currently open federal tenders, sorted by closing date (most urgent first). | `keywords`, `category`, `department`, `region`, `closing_within_days` |
| `get_tender` | Retrieve full details for a tender by its CanadaBuys reference number. | `source_ref` |
| `search_awards` | Search historical federal contract awards to find incumbents and competitive history. | `vendor_name`, `department`, `category`, `gsin_prefix`, `year` |
| `get_award` | Retrieve full details for an award notice by reference number. | `source_ref` |
| `get_expiring_contracts` | Find contracts expiring within a window — rebid opportunities — with a Buy Canadian score. | `days_ahead`, `category`, `department`, `foreign_incumbent_only` |
| `get_department_profile` | Procurement intelligence profile for a department: spend, top categories, repeat vendors, expiries. | `department_name` |
| `get_vendor_history` | Complete government contracting history for a vendor, by fiscal year and department. | `vendor_name`, `include_expiring` |
Every tool result is wrapped in a `_meta` envelope carrying Open Government Licence
attribution and cache/freshness metadata.
## Resources and prompts
**Resources**
| URI | Contents |
|---|---|
| `data://canadabuys/categories` | The four procurement category codes (CNST, GD, SRV, SRVTGD) with labels and examples. |
| `data://canadabuys/departments` | Canonical federal department names with known variants and acronyms. |
| `data://canadabuys/data-dictionary` | Key field definitions parsed from the official CanadaBuys data dictionary. |
**Prompts**
| Prompt | What it does |
|---|---|
| `find_opportunities` | Guided workflow: ranks open tenders and expiring contracts for what a vendor sells, with barrier-to-entry and next actions. |
| `research_incumbent` | Builds a plain-language intelligence brief on an incumbent vendor: footprint, vulnerable contracts, Buy Canadian exposure. |
## Data sources and freshness
All data is published by the Government of Canada under the Open Government
Licence – Canada via [CanadaBuys open data](https://canadabuys.canada.ca/en/open-data).
| Dataset | Refresh cadence |
|---|---|
| New tenders | Every 2 hours |
| Open tenders | Daily |
| Award notices | Monthly (transferred from the ABE system) |
Award data is not exhaustive — not every contract has a published award notice.
Estimated expiry dates are derived from award dates and stated contract durations
and are approximate.
## Defense exclusion policy
Defense-related procurement **never** appears in any result. This is a permanent
product decision, applied at the data layer before any tool returns data — the
model never sees an excluded record. A record is excluded when any of the
following holds:
- The buyer/department matches National Defence, Defence nationale, DND, MND,
Communications Security Establishment (CSE), Defence Research (DRDC), or
Defence Construction (case- and accent-insensitive).
- The GSIN code falls in military Federal Supply Classification groups 10–14.
- The CanadaBuys reference number begins with `W` (the PWGSC W-file prefix
reserved for DND).
- The tender title contains a military keyword (e.g. ammunition, munition,
ordnance, armoured, warship, submarine, missile, torpedo, radar system).
Exclusion rules are config-driven and can be extended, never removed.
## Data licence
> Contains information licensed under the Open Government Licence – Canada.
> <https://open.canada.ca/en/open-government-licence-canada>
## Contributing
Contributions are welcome. To add a new data module:
1. Fork the repository.
2. Create `src/mcp_canadabuys/modules/<name>/` following the mandatory 7-file
pattern (`__init__.py`, `constants.py`, `schemas.py`, `client.py`, `tools.py`,
`prompts.py`, `resources.py`). Modules are auto-discovered.
3. Apply the defense exclusion in `client.py` before returning data, and wrap
every tool result in the `_meta` envelope.
4. Add unit tests under `tests/` (mock HTTP, no live calls) and keep coverage
above 80%. Run `uv run pytest`.
5. Open a pull request.
See [CLAUDE.md](CLAUDE.md) for the full conventions.
## License
[MIT](LICENSE)