Metadata-Version: 2.4
Name: mcpmini
Version: 0.0.2
Summary: A small readable MCP library for serving Python functions as tools and calling MCP servers
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
License: Apache-2.0
Project-URL: Repository, https://github.com/AnswerDotAI/mcpmini
Project-URL: Documentation, https://AnswerDotAI.github.io/mcpmini/
Keywords: nbdev
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastcore>=2.1.18
Requires-Dist: httpx>=0.28.1
Requires-Dist: starlette>=1.3.1
Requires-Dist: uvicorn>=0.52.0
Dynamic: license-file

# mcpmini


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Usage

### Installation

``` sh
pip install mcpmini
```

## How to use

An MCP tool is a docmented Python function — the docments become the tool’s schema, with no registration ceremony. Serve some functions over stdio or HTTP:

``` python
from mcpmini.core import MCPServer, MCPClient, serve_stdio, serve_mcp
import asyncio, socket
```

``` python
def fahrenheit(
    celsius:float, # Temperature to convert
)->float:
    "Convert Celsius to Fahrenheit"
    return celsius*9/5+32

srv = MCPServer('demo', [fahrenheit])
```

`asyncio.run(serve_stdio(srv))` serves it as a host-launched stdio server; `asyncio.run(serve_mcp(srv, port=8000, token='S'))` serves it over streamable HTTP behind a bearer token (non-loopback binds refuse to start tokenless unless you pass `no_token=True`). A file of docmented functions serves straight from the command line — `mcpmini tools.py`, or `mcpmini tools.py --transport http --port 8000` — which is the shape MCP host configs launch. Then any MCP client can connect — for example Claude Code:

``` sh
claude mcp add --transport http demo http://127.0.0.1:8000/mcp -H "Authorization: Bearer S"
```

And mcpmini is a client too: server tools come back as bound Python functions, with their signatures, docs, and defaults rebuilt from the wire schema.

``` python
def free_port():
    with socket.socket() as s:
        s.bind(('127.0.0.1', 0))
        return s.getsockname()[1]
port = free_port()
task = asyncio.create_task(serve_mcp(srv, port=port, token='S'))
await asyncio.sleep(0.2)
async with MCPClient.http(f'http://127.0.0.1:{port}/mcp', token='S') as c: res = await c.tools.fahrenheit(celsius=100)
task.cancel()
res
```

    '212.0'
