intpot 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- intpot-0.1.0/.github/workflows/ci.yml +38 -0
- intpot-0.1.0/.github/workflows/release.yml +30 -0
- intpot-0.1.0/.gitignore +31 -0
- intpot-0.1.0/.pre-commit-config.yaml +15 -0
- intpot-0.1.0/CHANGELOG.md +31 -0
- intpot-0.1.0/CONTRIBUTING.md +88 -0
- intpot-0.1.0/LICENSE +21 -0
- intpot-0.1.0/Makefile +27 -0
- intpot-0.1.0/PKG-INFO +355 -0
- intpot-0.1.0/README.md +312 -0
- intpot-0.1.0/examples/README.md +37 -0
- intpot-0.1.0/examples/api_app.py +17 -0
- intpot-0.1.0/examples/cli_app.py +23 -0
- intpot-0.1.0/examples/conversions/api_to_cli.py +31 -0
- intpot-0.1.0/examples/conversions/api_to_mcp.py +31 -0
- intpot-0.1.0/examples/conversions/cli_to_api.py +34 -0
- intpot-0.1.0/examples/conversions/cli_to_mcp.py +31 -0
- intpot-0.1.0/examples/conversions/mcp_to_api.py +34 -0
- intpot-0.1.0/examples/conversions/mcp_to_cli.py +31 -0
- intpot-0.1.0/examples/mcp_server.py +17 -0
- intpot-0.1.0/pyproject.toml +87 -0
- intpot-0.1.0/src/intpot/__init__.py +7 -0
- intpot-0.1.0/src/intpot/cli.py +26 -0
- intpot-0.1.0/src/intpot/commands/__init__.py +0 -0
- intpot-0.1.0/src/intpot/commands/init.py +40 -0
- intpot-0.1.0/src/intpot/commands/to_api.py +77 -0
- intpot-0.1.0/src/intpot/commands/to_cli.py +77 -0
- intpot-0.1.0/src/intpot/commands/to_mcp.py +77 -0
- intpot-0.1.0/src/intpot/converter.py +80 -0
- intpot-0.1.0/src/intpot/core/__init__.py +0 -0
- intpot-0.1.0/src/intpot/core/detector.py +84 -0
- intpot-0.1.0/src/intpot/core/discovery.py +50 -0
- intpot-0.1.0/src/intpot/core/generators/__init__.py +0 -0
- intpot-0.1.0/src/intpot/core/generators/_render.py +19 -0
- intpot-0.1.0/src/intpot/core/generators/api.py +12 -0
- intpot-0.1.0/src/intpot/core/generators/base.py +14 -0
- intpot-0.1.0/src/intpot/core/generators/cli.py +12 -0
- intpot-0.1.0/src/intpot/core/generators/mcp.py +12 -0
- intpot-0.1.0/src/intpot/core/inspectors/__init__.py +0 -0
- intpot-0.1.0/src/intpot/core/inspectors/api.py +95 -0
- intpot-0.1.0/src/intpot/core/inspectors/base.py +15 -0
- intpot-0.1.0/src/intpot/core/inspectors/cli.py +93 -0
- intpot-0.1.0/src/intpot/core/inspectors/mcp.py +86 -0
- intpot-0.1.0/src/intpot/core/models.py +36 -0
- intpot-0.1.0/src/intpot/py.typed +0 -0
- intpot-0.1.0/src/intpot/templates/api_app.py.j2 +34 -0
- intpot-0.1.0/src/intpot/templates/cli_app.py.j2 +25 -0
- intpot-0.1.0/src/intpot/templates/mcp_server.py.j2 +24 -0
- intpot-0.1.0/src/intpot/templates/scaffold/api/main.py +11 -0
- intpot-0.1.0/src/intpot/templates/scaffold/cli/main.py +15 -0
- intpot-0.1.0/src/intpot/templates/scaffold/mcp/server.py +15 -0
- intpot-0.1.0/tests/__init__.py +0 -0
- intpot-0.1.0/tests/conftest.py +20 -0
- intpot-0.1.0/tests/test_commands/__init__.py +0 -0
- intpot-0.1.0/tests/test_commands/test_init.py +46 -0
- intpot-0.1.0/tests/test_commands/test_to_api.py +52 -0
- intpot-0.1.0/tests/test_commands/test_to_cli.py +53 -0
- intpot-0.1.0/tests/test_commands/test_to_mcp.py +52 -0
- intpot-0.1.0/tests/test_converter.py +129 -0
- intpot-0.1.0/tests/test_detector.py +60 -0
- intpot-0.1.0/tests/test_discovery.py +91 -0
- intpot-0.1.0/tests/test_generators/__init__.py +0 -0
- intpot-0.1.0/tests/test_generators/test_api_generator.py +38 -0
- intpot-0.1.0/tests/test_generators/test_cli_generator.py +44 -0
- intpot-0.1.0/tests/test_generators/test_mcp_generator.py +27 -0
- intpot-0.1.0/tests/test_inspectors/__init__.py +0 -0
- intpot-0.1.0/tests/test_inspectors/test_api_inspector.py +54 -0
- intpot-0.1.0/tests/test_inspectors/test_cli_inspector.py +52 -0
- intpot-0.1.0/tests/test_inspectors/test_mcp_inspector.py +46 -0
- intpot-0.1.0/uv.lock +1840 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
- run: uv sync --all-extras
|
|
16
|
+
- run: uv run ruff check src/ tests/
|
|
17
|
+
- run: uv run ruff format --check src/ tests/
|
|
18
|
+
|
|
19
|
+
typecheck:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
- run: uv sync --all-extras
|
|
25
|
+
- run: uv run pyright src/ tests/
|
|
26
|
+
|
|
27
|
+
test:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
strategy:
|
|
30
|
+
matrix:
|
|
31
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: astral-sh/setup-uv@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python-version }}
|
|
37
|
+
- run: uv sync --all-extras
|
|
38
|
+
- run: uv run pytest tests/ -v --cov=src/intpot --cov-report=term-missing
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: astral-sh/setup-uv@v5
|
|
13
|
+
- run: uv build
|
|
14
|
+
- uses: actions/upload-artifact@v4
|
|
15
|
+
with:
|
|
16
|
+
name: dist
|
|
17
|
+
path: dist/
|
|
18
|
+
|
|
19
|
+
publish:
|
|
20
|
+
needs: build
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
environment: pypi
|
|
23
|
+
permissions:
|
|
24
|
+
id-token: write
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/download-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
intpot-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# Testing
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.coverage
|
|
17
|
+
htmlcov/
|
|
18
|
+
|
|
19
|
+
# Type checking / linting
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
|
|
26
|
+
# IDE
|
|
27
|
+
.vscode/
|
|
28
|
+
.idea/
|
|
29
|
+
*.swp
|
|
30
|
+
*.swo
|
|
31
|
+
*~
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
|
|
10
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
+
rev: v0.9.0
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff
|
|
14
|
+
args: [--fix]
|
|
15
|
+
- id: ruff-format
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Python API** — `intpot.load()` accepts file paths or live app instances (FastMCP, Typer, FastAPI) and returns an `IntpotApp` with `.to_cli()`, `.to_mcp()`, `.to_api()` methods
|
|
13
|
+
- **Directory auto-discovery** — `intpot to cli ./myproject/` scans a directory for convertible apps
|
|
14
|
+
- `detect_instance()` function for detecting live Python objects (not just files)
|
|
15
|
+
- `discover_sources()` function for recursive directory scanning
|
|
16
|
+
- `IntpotApp` wrapper class for programmatic conversions
|
|
17
|
+
- New tests for Python API and discovery (13 new tests, 42 total)
|
|
18
|
+
|
|
19
|
+
## [0.1.0] - 2026-03-02
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Core inspection engine for CLI (Typer), MCP (FastMCP), and API (FastAPI) apps
|
|
24
|
+
- Code generation for all 6 conversion directions (CLI↔MCP↔API)
|
|
25
|
+
- `intpot to cli` command — convert MCP/API source to a Typer CLI
|
|
26
|
+
- `intpot to mcp` command — convert CLI/API source to a FastMCP server
|
|
27
|
+
- `intpot to api` command — convert CLI/MCP source to a FastAPI app
|
|
28
|
+
- `intpot init` command — scaffold new CLI, MCP, or API projects
|
|
29
|
+
- Jinja2-based template rendering for generated code
|
|
30
|
+
- Auto-detection of source framework type
|
|
31
|
+
- Full test suite (29 tests)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Contributing to intpot
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
1. Fork and clone the repository:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/YOUR_USERNAME/intpot.git
|
|
11
|
+
cd intpot
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. Install dependencies (requires [uv](https://docs.astral.sh/uv/)):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
uv sync --all-extras
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. Install pre-commit hooks:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv run pre-commit install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Code Style
|
|
27
|
+
|
|
28
|
+
- We use [Ruff](https://docs.astral.sh/ruff/) for linting and formatting.
|
|
29
|
+
- Run `make format` to auto-format your code.
|
|
30
|
+
- Run `make lint` to check for issues.
|
|
31
|
+
- Pre-commit hooks will run automatically on each commit.
|
|
32
|
+
|
|
33
|
+
## Type Checking
|
|
34
|
+
|
|
35
|
+
We use [Pyright](https://github.com/microsoft/pyright) for static type analysis.
|
|
36
|
+
|
|
37
|
+
- Run `make typecheck` to check types.
|
|
38
|
+
- Add type annotations to all new functions and methods.
|
|
39
|
+
- Use `from __future__ import annotations` for forward references.
|
|
40
|
+
- Pyright is configured in `pyproject.toml` under `[tool.pyright]`.
|
|
41
|
+
|
|
42
|
+
## Running Tests
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
make test
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or run the full check suite (lint + typecheck + test):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
make check
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Project Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
src/intpot/
|
|
58
|
+
├── __init__.py # Package exports (load, IntpotApp)
|
|
59
|
+
├── cli.py # Main CLI entry point
|
|
60
|
+
├── converter.py # Python API (IntpotApp, load())
|
|
61
|
+
├── commands/ # CLI command handlers (to_cli, to_mcp, to_api, init)
|
|
62
|
+
├── core/
|
|
63
|
+
│ ├── models.py # Shared data models (ToolInfo, ParameterInfo, SourceType)
|
|
64
|
+
│ ├── detector.py # Auto-detect source type from files or live instances
|
|
65
|
+
│ ├── discovery.py # Directory scanning for convertible apps
|
|
66
|
+
│ ├── inspectors/ # Framework-specific inspectors (extract tools)
|
|
67
|
+
│ └── generators/ # Framework-specific generators (render code)
|
|
68
|
+
└── templates/ # Jinja2 templates for code generation
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Key concepts:
|
|
72
|
+
- **Detection** — identify framework type from a file path or live object
|
|
73
|
+
- **Inspection** — extract normalized `ToolInfo` from framework-specific apps
|
|
74
|
+
- **Generation** — render `ToolInfo` into target framework code via Jinja2 templates
|
|
75
|
+
- **Python API** — `intpot.load(source)` returns an `IntpotApp` for programmatic use
|
|
76
|
+
|
|
77
|
+
## Pull Request Process
|
|
78
|
+
|
|
79
|
+
1. Create a feature branch from `main`.
|
|
80
|
+
2. Make your changes and add tests if applicable.
|
|
81
|
+
3. Ensure `make check` passes (lint, typecheck, and tests).
|
|
82
|
+
4. Open a pull request with a clear description of your changes.
|
|
83
|
+
|
|
84
|
+
## Reporting Issues
|
|
85
|
+
|
|
86
|
+
- Use GitHub Issues to report bugs or request features.
|
|
87
|
+
- Include steps to reproduce for bug reports.
|
|
88
|
+
- Check existing issues before opening a new one.
|
intpot-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 intpot contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
intpot-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.PHONY: install test lint format typecheck check build clean
|
|
2
|
+
|
|
3
|
+
install:
|
|
4
|
+
uv sync --all-extras
|
|
5
|
+
|
|
6
|
+
test:
|
|
7
|
+
uv run pytest tests/ -v
|
|
8
|
+
|
|
9
|
+
lint:
|
|
10
|
+
uv run ruff check src/ tests/
|
|
11
|
+
uv run ruff format --check src/ tests/
|
|
12
|
+
|
|
13
|
+
format:
|
|
14
|
+
uv run ruff check --fix src/ tests/
|
|
15
|
+
uv run ruff format src/ tests/
|
|
16
|
+
|
|
17
|
+
typecheck:
|
|
18
|
+
uv run pyright src/ tests/
|
|
19
|
+
|
|
20
|
+
check: lint typecheck test
|
|
21
|
+
|
|
22
|
+
build:
|
|
23
|
+
uv build
|
|
24
|
+
|
|
25
|
+
clean:
|
|
26
|
+
rm -rf dist/ build/ *.egg-info .pytest_cache .ruff_cache .mypy_cache
|
|
27
|
+
find . -type d -name __pycache__ -exec rm -rf {} +
|
intpot-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: intpot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal converter between CLI (Typer), MCP (FastMCP), and API (FastAPI) interfaces
|
|
5
|
+
Project-URL: Homepage, https://github.com/tugrulguner/intpot
|
|
6
|
+
Project-URL: Repository, https://github.com/tugrulguner/intpot
|
|
7
|
+
Project-URL: Issues, https://github.com/tugrulguner/intpot/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/tugrulguner/intpot/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Tugrul Guner
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,code-generation,converter,fastapi,mcp,typer
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: jinja2>=3.1.0
|
|
22
|
+
Requires-Dist: rich>=13.0.0
|
|
23
|
+
Requires-Dist: typer>=0.9.0
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'all'
|
|
26
|
+
Requires-Dist: fastmcp>=2.0.0; extra == 'all'
|
|
27
|
+
Requires-Dist: uvicorn>=0.20.0; extra == 'all'
|
|
28
|
+
Provides-Extra: api
|
|
29
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'api'
|
|
30
|
+
Requires-Dist: uvicorn>=0.20.0; extra == 'api'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: fastmcp>=2.0.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pyright>=1.1.390; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: uvicorn>=0.20.0; extra == 'dev'
|
|
40
|
+
Provides-Extra: mcp
|
|
41
|
+
Requires-Dist: fastmcp>=2.0.0; extra == 'mcp'
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
# intpot
|
|
45
|
+
|
|
46
|
+
[](https://github.com/tugrulguner/intpot/actions/workflows/ci.yml)
|
|
47
|
+
[](https://pypi.org/project/intpot/)
|
|
48
|
+
[](https://pypi.org/project/intpot/)
|
|
49
|
+
[](https://opensource.org/licenses/MIT)
|
|
50
|
+
|
|
51
|
+
**Universal converter between CLI (Typer), MCP (FastMCP), and API (FastAPI) interfaces.**
|
|
52
|
+
|
|
53
|
+
intpot bridges three popular Python frameworks:
|
|
54
|
+
|
|
55
|
+
- **[Typer](https://typer.tiangolo.com/)** — CLI applications
|
|
56
|
+
- **[FastMCP](https://github.com/jlowin/fastmcp)** — Model Context Protocol servers
|
|
57
|
+
- **[FastAPI](https://fastapi.tiangolo.com/)** — REST API applications
|
|
58
|
+
|
|
59
|
+
Given a source file written in any of these frameworks, intpot detects the framework, inspects its functions/tools/endpoints, and generates equivalent code in the target framework.
|
|
60
|
+
|
|
61
|
+
## Features
|
|
62
|
+
|
|
63
|
+
- **6 conversion directions** — CLI to MCP, CLI to API, MCP to CLI, MCP to API, API to CLI, API to MCP
|
|
64
|
+
- **Auto-detection** — automatically identifies the source framework by analyzing imports and patterns
|
|
65
|
+
- **Project scaffolding** — `intpot init` creates new CLI, MCP, or API projects from templates
|
|
66
|
+
- **Jinja2 templates** — clean, readable generated code with proper type hints
|
|
67
|
+
- **Fully typed** — PEP 561 compatible with `py.typed` marker
|
|
68
|
+
- **Zero config** — just point at a Python file and specify the target
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install intpot # core (CLI conversions only)
|
|
74
|
+
pip install intpot[mcp] # + FastMCP support
|
|
75
|
+
pip install intpot[api] # + FastAPI support
|
|
76
|
+
pip install intpot[all] # everything
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
### Scaffold a new project
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
intpot init my-server --type mcp
|
|
85
|
+
intpot init my-app --type cli
|
|
86
|
+
intpot init my-api --type api
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Convert between frameworks
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# MCP server -> Typer CLI
|
|
93
|
+
intpot to cli server.py
|
|
94
|
+
|
|
95
|
+
# CLI app -> FastMCP server
|
|
96
|
+
intpot to mcp app.py
|
|
97
|
+
|
|
98
|
+
# CLI app -> FastAPI app
|
|
99
|
+
intpot to api app.py
|
|
100
|
+
|
|
101
|
+
# Write output to a file
|
|
102
|
+
intpot to cli server.py --output cli_app.py
|
|
103
|
+
|
|
104
|
+
# Convert all apps in a directory
|
|
105
|
+
intpot to cli ./myproject/
|
|
106
|
+
intpot to mcp ./myproject/ --output ./converted/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Python API
|
|
110
|
+
|
|
111
|
+
Use intpot programmatically from Python:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import intpot
|
|
115
|
+
|
|
116
|
+
# From a file
|
|
117
|
+
app = intpot.load("mcp_server.py")
|
|
118
|
+
cli_code = app.to_cli()
|
|
119
|
+
api_code = app.to_api()
|
|
120
|
+
|
|
121
|
+
# From a live instance
|
|
122
|
+
from fastmcp import FastMCP
|
|
123
|
+
|
|
124
|
+
mcp = FastMCP("my-server")
|
|
125
|
+
|
|
126
|
+
@mcp.tool()
|
|
127
|
+
def greet(name: str) -> str:
|
|
128
|
+
return f"Hello, {name}!"
|
|
129
|
+
|
|
130
|
+
app = intpot.load(mcp)
|
|
131
|
+
print(app.to_cli())
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `load()` function accepts file paths (str or Path) and live app instances (FastMCP, Typer, FastAPI). The returned `IntpotApp` object provides `.to_cli()`, `.to_mcp()`, and `.to_api()` methods that return generated code as strings.
|
|
135
|
+
|
|
136
|
+
## Architecture
|
|
137
|
+
|
|
138
|
+
intpot uses a four-stage pipeline:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
+-----------+
|
|
142
|
+
| SOURCE |
|
|
143
|
+
| (.py file)|
|
|
144
|
+
+-----+-----+
|
|
145
|
+
|
|
|
146
|
+
1. DETECT
|
|
147
|
+
(identify framework)
|
|
148
|
+
|
|
|
149
|
+
+-----v-----+
|
|
150
|
+
| SourceType|
|
|
151
|
+
| cli/mcp/api|
|
|
152
|
+
+-----+-----+
|
|
153
|
+
|
|
|
154
|
+
2. INSPECT
|
|
155
|
+
(extract functions)
|
|
156
|
+
|
|
|
157
|
+
+-----v-----+
|
|
158
|
+
| ToolDef[] |
|
|
159
|
+
| (normalized|
|
|
160
|
+
| schema) |
|
|
161
|
+
+-----+-----+
|
|
162
|
+
|
|
|
163
|
+
3. GENERATE
|
|
164
|
+
(render template)
|
|
165
|
+
|
|
|
166
|
+
+-----v-----+
|
|
167
|
+
| OUTPUT |
|
|
168
|
+
| (.py code)|
|
|
169
|
+
+-----------+
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
1. **DETECT** — `core/detector.py` imports the source file and identifies whether it's a Typer app, FastMCP server, or FastAPI app
|
|
173
|
+
2. **INSPECT** — Framework-specific inspectors (`core/inspectors/`) extract function signatures, parameters, types, defaults, and docstrings into a normalized `ToolDef` schema
|
|
174
|
+
3. **GENERATE** — Framework-specific generators (`core/generators/`) render the normalized schema into target code using Jinja2 templates
|
|
175
|
+
|
|
176
|
+
## Examples
|
|
177
|
+
|
|
178
|
+
### MCP server to CLI app
|
|
179
|
+
|
|
180
|
+
**Input** (`mcp_server.py`):
|
|
181
|
+
```python
|
|
182
|
+
from fastmcp import FastMCP
|
|
183
|
+
|
|
184
|
+
mcp = FastMCP("example-server")
|
|
185
|
+
|
|
186
|
+
@mcp.tool()
|
|
187
|
+
def greet(name: str, greeting: str = "Hello") -> str:
|
|
188
|
+
"""Greet someone by name."""
|
|
189
|
+
return f"{greeting}, {name}!"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Command**: `intpot to cli mcp_server.py`
|
|
193
|
+
|
|
194
|
+
**Output**:
|
|
195
|
+
```python
|
|
196
|
+
import typer
|
|
197
|
+
|
|
198
|
+
app = typer.Typer()
|
|
199
|
+
|
|
200
|
+
@app.command()
|
|
201
|
+
def greet(
|
|
202
|
+
name: str = typer.Argument(..., help=""),
|
|
203
|
+
greeting: str = typer.Option('Hello', help=""),
|
|
204
|
+
) -> None:
|
|
205
|
+
"""Greet someone by name."""
|
|
206
|
+
# TODO: implement
|
|
207
|
+
typer.echo("greet called")
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### CLI app to FastAPI
|
|
211
|
+
|
|
212
|
+
**Input** (`cli_app.py`):
|
|
213
|
+
```python
|
|
214
|
+
import typer
|
|
215
|
+
|
|
216
|
+
app = typer.Typer()
|
|
217
|
+
|
|
218
|
+
@app.command()
|
|
219
|
+
def add(
|
|
220
|
+
a: int = typer.Argument(..., help="First number"),
|
|
221
|
+
b: int = typer.Argument(..., help="Second number"),
|
|
222
|
+
) -> None:
|
|
223
|
+
"""Add two numbers together."""
|
|
224
|
+
typer.echo(a + b)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Command**: `intpot to api cli_app.py`
|
|
228
|
+
|
|
229
|
+
**Output**:
|
|
230
|
+
```python
|
|
231
|
+
from fastapi import FastAPI
|
|
232
|
+
from pydantic import BaseModel, Field
|
|
233
|
+
|
|
234
|
+
app = FastAPI()
|
|
235
|
+
|
|
236
|
+
class AddRequest(BaseModel):
|
|
237
|
+
a: int = Field(..., description="First number")
|
|
238
|
+
b: int = Field(..., description="Second number")
|
|
239
|
+
|
|
240
|
+
@app.post("/add")
|
|
241
|
+
def add(request: AddRequest) -> dict:
|
|
242
|
+
"""Add two numbers together."""
|
|
243
|
+
# TODO: implement
|
|
244
|
+
return {"result": "add called"}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### API app to MCP server
|
|
248
|
+
|
|
249
|
+
**Input** (`api_app.py`):
|
|
250
|
+
```python
|
|
251
|
+
from fastapi import FastAPI
|
|
252
|
+
|
|
253
|
+
app = FastAPI()
|
|
254
|
+
|
|
255
|
+
@app.post("/greet")
|
|
256
|
+
def greet(name: str, greeting: str = "Hello") -> dict:
|
|
257
|
+
"""Greet someone by name."""
|
|
258
|
+
return {"message": f"{greeting}, {name}!"}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Command**: `intpot to mcp api_app.py`
|
|
262
|
+
|
|
263
|
+
**Output**:
|
|
264
|
+
```python
|
|
265
|
+
from fastmcp import FastMCP
|
|
266
|
+
|
|
267
|
+
mcp = FastMCP("generated-server")
|
|
268
|
+
|
|
269
|
+
@mcp.tool()
|
|
270
|
+
def greet(
|
|
271
|
+
name: str,
|
|
272
|
+
greeting: str = 'Hello',
|
|
273
|
+
) -> dict:
|
|
274
|
+
"""Greet someone by name."""
|
|
275
|
+
# TODO: implement
|
|
276
|
+
return "greet called"
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
See the [`examples/`](examples/) directory for all 6 conversion outputs.
|
|
280
|
+
|
|
281
|
+
## CLI Reference
|
|
282
|
+
|
|
283
|
+
### `intpot init`
|
|
284
|
+
|
|
285
|
+
Scaffold a new project from a template.
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
intpot init <name> --type <mcp|cli|api>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
| Argument/Option | Description |
|
|
292
|
+
|----------------|-------------|
|
|
293
|
+
| `name` | Project name (creates a directory) |
|
|
294
|
+
| `--type`, `-t` | Project type: `mcp`, `cli`, or `api` (required) |
|
|
295
|
+
|
|
296
|
+
### `intpot to cli`
|
|
297
|
+
|
|
298
|
+
Convert an MCP or API source file to a Typer CLI app.
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
intpot to cli <source> [--output <path>]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### `intpot to mcp`
|
|
305
|
+
|
|
306
|
+
Convert a CLI or API source file to a FastMCP server.
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
intpot to mcp <source> [--output <path>]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### `intpot to api`
|
|
313
|
+
|
|
314
|
+
Convert a CLI or MCP source file to a FastAPI app.
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
intpot to api <source> [--output <path>]
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
| Argument/Option | Description |
|
|
321
|
+
|----------------|-------------|
|
|
322
|
+
| `source` | Path to a source Python file or directory |
|
|
323
|
+
| `--output`, `-o` | Output file path (prints to stdout if omitted) |
|
|
324
|
+
|
|
325
|
+
## Development
|
|
326
|
+
|
|
327
|
+
Requires [uv](https://docs.astral.sh/uv/).
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
git clone https://github.com/tugrulguner/intpot.git
|
|
331
|
+
cd intpot
|
|
332
|
+
uv sync --all-extras
|
|
333
|
+
uv run pre-commit install
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Run the full check suite:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
make check # lint + typecheck + test
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Individual targets:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
make lint # ruff check + format check
|
|
346
|
+
make typecheck # pyright
|
|
347
|
+
make test # pytest
|
|
348
|
+
make format # auto-format code
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
|
|
352
|
+
|
|
353
|
+
## License
|
|
354
|
+
|
|
355
|
+
MIT
|