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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 4.0.1

- Made the published PyPI package and official MCP Registry the primary local
installation path in the README and deployment guides.
- Added `uvx` and pinned-release examples for stdio and loopback HTTP use.
- Clarified that source checkout setup is for contributors and unreleased
changes, while preserving the operator-owned credential model.

## 4.0.0

- Added the local-first MCP launcher, Docker/Compose self-hosting path, and
Expand Down
2 changes: 1 addition & 1 deletion MCP_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Expected result:
```json
{
"status": "ok",
"version": "4.0.0",
"version": "4.0.1",
"mcp": {
"enabled": true,
"url": "https://YOUR-SERVICE.onrender.com/mcp",
Expand Down
66 changes: 53 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,53 @@ endpoints remain available for backward compatibility, including

## Start here

### Run the local MCP server
### Use the published package (recommended)

The default path is local MCP over stdio. Provider credentials remain in your
environment and the process does not open a public network port.
Partuno is published on [PyPI](https://pypi.org/project/partuno/) and listed in
the [official MCP Registry](https://registry.modelcontextprotocol.io/). The
recommended local MCP launcher is:

```bash
uvx --from partuno partuno-mcp
```

This downloads the current published release and runs the default local stdio
transport. To pin the current release exactly, use:

```bash
uvx --from 'partuno==4.0.1' partuno-mcp
```

MCP clients that accept a local command can use `uvx` with these arguments:

```json
{
"command": "uvx",
"args": ["--from", "partuno", "partuno-mcp"]
}
```

Keep your operator-owned DigiKey and Mouser credentials in the MCP client's
environment. See the [local deployment guide](docs/deployment/local.md) for
the supported variables and the [native MCP setup guide](MCP_SETUP.md) for
operator-owned remote deployments. For a hosted directory listing, see
[Partuno on Glama](https://glama.ai/mcp/servers/JPMarhefka/partuno).

### Install with pip

If `uvx` is not available, install the published package into an existing
Python environment:

```bash
python3 -m pip install partuno
partuno-mcp
```

<details>
<summary><strong>Develop from source</strong></summary>

Use a checkout only when contributing, running unreleased changes, or needing
the repository's `.env.example` and test suite:

```bash
git clone https://github.com/JPMarhefka/partuno.git
Expand All @@ -43,19 +86,16 @@ python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
set -a
source .env
set +a
python -m partuno
```

Then configure your MCP client to launch `python -m partuno` from the checkout.
See [MCP setup](MCP_SETUP.md) and the [local deployment guide](docs/deployment/local.md).
For a hosted directory listing, see [Partuno on Glama](https://glama.ai/mcp/servers/JPMarhefka/partuno).

After the `partuno` PyPI package is published, the equivalent package-based
launcher is:
See the [local deployment guide](docs/deployment/local.md) for loopback HTTP
and source-checkout details.

```bash
uvx --from partuno partuno-mcp
```
</details>

### Self-host a remote MCP server

Expand Down Expand Up @@ -217,7 +257,7 @@ default and does not require Partuno OAuth.

## Project status

Partuno 4.0.0 is an active open-source release. The test suite covers offline
Partuno 4.0.1 is an active open-source release. The test suite covers offline
provider contracts, MCP tool behavior, REST compatibility, credential safety,
normalization, and the multi-distributor workflows. Live provider calls are
opt-in because they require operator credentials and are subject to provider
Expand Down
2 changes: 1 addition & 1 deletion VALIDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contracts, cross-distributor normalization, and Cart confirmation safety.

```json
{
"version": "4.0.0",
"version": "4.0.1",
"full_paths": 45,
"full_operations": 52,
"compact_paths": 34,
Expand Down
2 changes: 1 addition & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def mcp_health() -> dict[str, Any]:
)
return {
"status": "ok" if mcp_active else "disabled",
"version": "4.0.0",
"version": "4.0.1",
"mcp": {
"enabled": mcp_active,
"url": mcp_url,
Expand Down
50 changes: 30 additions & 20 deletions docs/deployment/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,28 @@ Partuno's default distribution path is a local MCP process. It does not need
Render, Azure, a database, Redis, or a Partuno account. Provider credentials
stay in the operator's environment.

## Quick start
## Quick start with the published package

From a checkout of the repository:
For normal use, launch the published PyPI package with `uvx`:

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
set -a
source .env
set +a
python -m partuno
uvx --from partuno partuno-mcp
```

The default transport is MCP stdio, which is the safest path for desktop MCP
clients. Configure the client to launch `python -m partuno` from this
directory. The process does not open a listening network socket.
clients. Configure the client to launch `uvx` with `--from partuno partuno-mcp`.
The process does not open a listening network socket.

For an exact reproducible release, pin the package version:

```bash
uvx --from 'partuno==4.0.1' partuno-mcp
```

For clients that require HTTP, use the loopback-only transport:

```bash
python -m partuno --transport streamable-http --host 127.0.0.1 --port 8000
uvx --from partuno partuno-mcp --transport streamable-http --host 127.0.0.1 --port 8000
```

The MCP endpoint is `http://127.0.0.1:8000/mcp`. The default bind host must
Expand All @@ -38,19 +37,30 @@ an authenticated and encrypted reverse proxy.
Set only credentials obtained by the operator from the relevant provider. A
local DigiKey MCP process accepts an optional `DIGIKEY_ACCESS_TOKEN` for
catalog and account calls; it is never returned by a tool or written to logs.
Mouser search and account capabilities use their corresponding API-key
variables in `.env.example`.
Mouser search and account capabilities use `MOUSER_SEARCH_API_KEY` and
`MOUSER_ACCOUNT_API_KEY`. The complete variable reference is in the
[`.env.example`](../../.env.example) file.

Do not put credentials in MCP tool arguments, source control, screenshots, or
client configuration files that are shared with other people.

## Installed command
## Develop from source

After installing the project with `python -m pip install -e .`, the equivalent
command is:
Use a repository checkout when contributing, testing unreleased changes, or
needing the example environment file:

```bash
partuno-mcp
git clone https://github.com/JPMarhefka/partuno.git
cd partuno
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
set -a
source .env
set +a
python -m partuno
```

Run `partuno-mcp --help` to see the transport options.
The published package exposes the same `partuno-mcp` command. Run
`partuno-mcp --help` to see the transport options.
12 changes: 10 additions & 2 deletions docs/guides/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ These are practical entry points for people looking for a DigiKey MCP server,
Mouser MCP server, electronics BOM MCP server, or AI component-sourcing tool.
Each guide includes setup, a public demo, supported workflows, and limitations.

When Partuno's website is published, use these guides as the source content for
the following descriptive routes:
Partuno is published on [PyPI](https://pypi.org/project/partuno/) and listed in
the [official MCP Registry](https://registry.modelcontextprotocol.io/). For
normal local use, launch it with:

```bash
uvx --from partuno partuno-mcp
```

When Partuno's website is published, these guides can also be adapted into the
following descriptive routes:

- [`/digikey-mcp-server/`](digikey-mcp-server.md)
- [`/mouser-mcp-server/`](mouser-mcp-server.md)
Expand Down
20 changes: 8 additions & 12 deletions docs/guides/digikey-mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,18 @@ Use Partuno to:

## Setup

The default deployment is local MCP over stdio. Credentials remain in the
operator's environment and no public network port is required:
The default deployment is local MCP over stdio. Partuno is published on PyPI,
so the shortest setup is:

```bash
git clone https://github.com/JPMarhefka/partuno.git
cd partuno
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
python -m partuno
uvx --from partuno partuno-mcp
```

Then configure the MCP client to launch `python -m partuno` from the checkout.
See the [native MCP setup guide](../../MCP_SETUP.md) for local and
operator-owned remote deployments.
Credentials remain in the operator's environment and no public network port is
required. See the [local deployment guide](../deployment/local.md) for the
supported credential variables and the [native MCP setup guide](../../MCP_SETUP.md)
for operator-owned remote deployments. Use the source-checkout path only when
contributing or testing unreleased changes.

## Supported MCP workflows

Expand Down
17 changes: 6 additions & 11 deletions docs/guides/electronics-bom-mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,16 @@ previews.

## Setup

The default path is local MCP over stdio:
The default path is local MCP over stdio. Partuno is published on PyPI:

```bash
git clone https://github.com/JPMarhefka/partuno.git
cd partuno
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
python -m partuno
uvx --from partuno partuno-mcp
```

Configure the MCP client to launch `python -m partuno` from the checkout. The
[native MCP setup guide](../../MCP_SETUP.md) also covers loopback HTTP and an
operator-owned remote deployment.
Configure the MCP client to launch `uvx` with `--from partuno partuno-mcp`.
The [local deployment guide](../deployment/local.md) covers credential
variables and loopback HTTP, while the [native MCP setup guide](../../MCP_SETUP.md)
covers an operator-owned remote deployment.

## Supported MCP workflows

Expand Down
16 changes: 6 additions & 10 deletions docs/guides/mouser-mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,18 @@ Use Partuno to:

## Setup

Start with the [native MCP setup guide](../../MCP_SETUP.md). For a local
deployment, install Partuno and configure the operator-owned Mouser keys in the
environment alongside the DigiKey settings:
For a local deployment, launch the published package and configure the
operator-owned Mouser keys in the environment alongside the DigiKey settings:

```bash
git clone https://github.com/JPMarhefka/partuno.git
cd partuno
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
python -m partuno
uvx --from partuno partuno-mcp
```

Mouser Search and Account API keys remain separate. They are read from the
deployment configuration and are never supplied as MCP tool parameters.
See the [local deployment guide](../deployment/local.md) for the supported
variables and the [native MCP setup guide](../../MCP_SETUP.md) for
operator-owned remote deployments.

## Supported MCP workflows

Expand Down
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@

app = FastAPI(
title="Partuno",
version="4.0.0",
version="4.0.1",
description=(
"Open-source MCP server for DigiKey and Mouser electronic component research, "
"BOM analysis, sourcing comparison, and safe distributor workflows. "
Expand Down
2 changes: 1 addition & 1 deletion mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ def build_mcp_server(*, local: bool = False) -> FastMCP | None:

mcp = FastMCP(
name="Partuno",
version="4.0.0",
version="4.0.1",
website_url=None if local else settings.mcp_base_url,
auth=auth_provider,
instructions=(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "partuno"
version = "4.0.0"
version = "4.0.1"
description = "Provider-neutral DigiKey and Mouser MCP server for electronic component research, BOM analysis, and sourcing comparison"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
"sizes": ["any"]
}
],
"version": "4.0.0",
"version": "4.0.1",
"packages": [
{
"registryType": "pypi",
"registryBaseUrl": "https://pypi.org",
"identifier": "partuno",
"version": "4.0.0",
"version": "4.0.1",
"runtimeHint": "uvx",
"packageArguments": [
{
Expand Down
4 changes: 2 additions & 2 deletions tests/test_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ def test_public_metadata_uses_partuno_brand_and_version() -> None:
schema = app.openapi()

assert app.title == "Partuno"
assert app.version == "4.0.0"
assert app.version == "4.0.1"
assert schema["info"]["title"] == "Partuno"
assert "Open-source MCP server" in schema["info"]["description"]
assert mcp_health()["version"] == "4.0.0"
assert mcp_health()["version"] == "4.0.1"


def test_openapi_operation_ids_are_unique_and_expose_no_ordering_api() -> None:
Expand Down