Skip to main content

intpot

intpot: Python tools served as CLI, API, or MCP

Part of ModePot.   Project website   Created by Tugrul Guner

One typed definition. Three interfaces.

Define typed tools once for CLI, HTTP, or MCP. Convert apps between Typer, FastAPI, and FastMCP.

PyPI version Python versions CI Join the ModePot Discord GitHub stars MIT License

Quick start · Playground · Deep docs · README quick start · Convert an app · Conversion scope · Architecture · Community · Contributing

Intpot uses the same normalized ToolInfo schema in two workflows: registered Python tools can be served or ejected as CLI, API, or MCP interfaces, while existing Typer, FastAPI, or FastMCP apps can be inspected and converted into standalone code

Why intpot?

A useful Python function often needs three interfaces: a command for people, an HTTP endpoint for applications, and an MCP tool for AI agents. Maintaining three copies means three signatures, three sets of descriptions, and three places for behavior to drift.

intpot gives you two ways out:

Starting point What intpot does
Plain Python functions Register them once with @app.tool(), then serve or eject CLI, API, and MCP interfaces
An existing Typer, FastAPI, or FastMCP app Inspect it, normalize its tools, and generate either of the other two frameworks

The output is ordinary Python. Ejected and converted apps do not depend on intpot.

Quick start

Install every runtime for the complete experience:

pip install "intpot[all]"

Write once, serve everywhere

Save this as app.py:

from intpot import App

app = App("my-app")

@app.tool()
def add(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b

@app.tool()
def greet(name: str, greeting: str = "Hello") -> str:
    """Greet someone by name."""
    return f"{greeting}, {name}!"

Then serve in any mode:

intpot serve app.py --cli          # Run as Typer CLI
intpot serve app.py --api          # Run as FastAPI on port 8000
intpot serve app.py --mcp          # Run as MCP server for AI agents

In CLI mode, everything after the flags belongs to your app:

$ intpot serve app.py --cli add 2 3
5
$ intpot serve app.py --cli greet World --greeting Hi
Hi, World!

With API mode running, call the same names as POST routes with JSON request bodies:

$ curl -s -X POST http://127.0.0.1:8000/add \
    -H "Content-Type: application/json" \
    -d '{"a": 2, "b": 3}'
5

MCP mode exposes add and greet as FastMCP tools with schemas derived from their type annotations and defaults.

Or eject to standalone framework code:

intpot eject app.py --to api       # Export as standalone FastAPI app
intpot eject app.py --to cli       # Export as standalone Typer CLI
intpot eject app.py --to mcp       # Export as standalone FastMCP server

Scaffold a new project

intpot init my-server --type mcp
intpot init my-app --type cli
intpot init my-api --type api

Install only the frameworks you need if you do not want the full extra:

pip install intpot          # Core commands and Typer output
pip install "intpot[mcp]"   # Add FastMCP support
pip install "intpot[api]"   # Add FastAPI support

Convert an existing app

intpot detects Typer, FastAPI, and FastMCP apps from a Python file and supports every conversion between them:

# MCP server -> Typer CLI
intpot to cli server.py

# CLI app -> FastMCP server
intpot to mcp app.py

# CLI app -> FastAPI app
intpot to api app.py

# Write output to a file
intpot to cli server.py --output cli_app.py

# Convert all apps in a directory
intpot to cli ./myproject/
intpot to mcp ./myproject/ --output ./converted/

Directory output mirrors the source tree, so myproject/alpha/tools.py becomes converted/alpha/tools_mcp.py. Sources sharing a filename in different packages stay separate files.

Use intpot inspect app.py first when you want to see the normalized tool definitions before generating code. Converted output is readable Python that you can review, test, and change.

Give your coding agent intpot context

Install project-local instructions for Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, or OpenAI Codex:

# Auto-detect agents in your project
intpot add skills

# Target a specific agent
intpot add skills --agent claude
intpot add skills --agent cursor
intpot add skills --agent windsurf
intpot add skills --agent copilot
intpot add skills --agent cline
intpot add skills --agent codex

# Specify a project directory
intpot add skills --path ./myproject/

What intpot handles

  • One definition, three live interfaces: serve an intpot.App through Typer, FastAPI, or FastMCP.
  • Six conversion directions: move existing apps between all three frameworks.
  • Standalone output: eject or convert to normal framework code with no intpot runtime dependency.
  • Behavior-aware transforms: preserve recoverable function bodies and the direct imports they use, and translate framework conventions such as typer.echo() into return values.
  • Interface fidelity: carry types, defaults, and async functions through supported conversions, and apply FastAPI parameter sources when generating an API.
  • Inspectable semantic core: use intpot.load().schema for an immutable ApplicationSchema, inspect target projections before generation, or use detached ToolInfo compatibility objects through .tools.
  • Project tooling: scan directories, scaffold projects, and install agent guidance for six coding agents.

Python API

Universal App (write once, serve everywhere)

from intpot import App

app = App("my-app")

@app.tool()
def greet(name: str, greeting: str = "Hello") -> str:
    """Greet someone."""
    return f"{greeting}, {name}!"

# Serve as any framework
app.serve(mode="cli")                         # Run as Typer CLI
app.serve(mode="api", port=8000)              # Run as FastAPI on 127.0.0.1
app.serve(mode="mcp")                         # Run as MCP server

# Eject to standalone code
cli_code = app.eject("cli")                   # Returns Typer code string
api_code = app.eject("api")                   # Returns FastAPI code string

# Inspect the canonical application schema
print(app.schema.to_dict())
for tool in app.schema.tools:
    print(tool.name, tool.parameters)

Conversion API (convert existing framework code)

import intpot

# From a file
app = intpot.load("mcp_server.py")
api_schema = app.project("api")               # Immutable target semantics
cli_code = app.to_cli()
api_code = app.to_api()

# From a live instance
from fastmcp import FastMCP

mcp = FastMCP("my-server")

@mcp.tool()
def greet(name: str) -> str:
    return f"Hello, {name}!"

app = intpot.load(mcp)
print(app.to_cli())

# Write directly to a file
app.write("output/cli_app.py", "cli")
app.write("output/api_app.py", "api")

App (universal runtime):

  • .tool(name=None, description=None) — decorator to register functions as tools; both arguments override the defaults taken from the function name and docstring. Functions with *args or **kwargs are rejected because those parameters have no consistent CLI, HTTP API, and MCP representation.
  • .serve(mode, host, port) — serve as CLI, API, or MCP
  • .eject(target) — generate standalone framework code
  • .schema — immutable ApplicationSchema snapshot shared with conversion
  • .tools — detached ToolInfo compatibility objects

IntpotApp (conversion wrapper, returned by intpot.load()):

  • .to_cli(), .to_mcp(), .to_api() — return generated code as strings
  • .schema — immutable source ApplicationSchema, compiled once
  • .project(target) — immutable target projection used by generation
  • .write(path, target) — generate and write to a file in one step
  • .tools — detached ToolInfo compatibility objects; mutating them does not alter the schema
  • .source_type — detected framework type

What conversion preserves

intpot is designed to produce code you can own, rather than hide conversion behind a runtime adapter. ApplicationSchema is the application-level semantic boundary; immutable ToolSchema and ParameterSchema records carry the parts that the three frameworks share:

  • tool names, descriptions, types, defaults, and async behavior;
  • recoverable function bodies and the direct imports they reference;
  • framework metadata that has a target equivalent, including supported Query, Header, Path, and Body parameter sources when generating FastAPI;
  • scalar returns translated into a shape the target framework can serve correctly.

Frameworks do not have one-to-one equivalents for every feature. FastAPI dependencies (Depends, Security, nested dependencies, and route/router/app-level dependencies) are preserved by inspection, but API-to-CLI/MCP conversion refuses them with UnsupportedFastAPIDependencyError rather than emitting code with missing values. Full dependency injection mapping remains tracked in #20. Review generated code when a source uses nested Typer command groups, repeatable CLI options, Annotated[..., Body(...)], Pydantic model parameters, routes with multiple HTTP methods, streaming, background tasks, or framework-specific error handling.

Typer/Click parameter callbacks remain inspectable as unsupported_callback=True on parameter metadata (to_dict() includes the marker only when true). CLI-to-API/MCP projection and generation raise intpot.UnsupportedCLIParameterCallbackError, naming all affected tools/parameters and the target, rather than dropping callback validation or transformation. Assignment-style and Annotated declarations are detected. The CLI reports refusal on stderr with exit status 1 before writing output; --dry-run also refuses. This is a focused known-loss guard, not a general conversion assessment or callback transpiler. Source CLI behavior is unchanged.

intpot carries direct import statements referenced by a tool body. It does not yet copy same-module helpers, constants, classes, models, or closure values that the body references, and it does not follow dependencies across imported modules. Factory-created apps are not detected by the current AST pre-check. Loading a source file directly also does not add its directory to sys.path, so a sibling import such as from helpers import normalize may require installing the package or setting PYTHONPATH. External services and configuration are not provisioned for you. If intpot cannot recover a body, public conversion raises intpot.MissingFunctionBodyError before writing output. app.assess() returns JSON-compatible body-recovery diagnostics (body_recovery_complete, missing_function_body, and per-tool diagnostics); this is not a general fidelity guarantee. intpot inspect --json includes an assessment when bodies are missing. Schema inspection and the original source remain usable.

Explicit allow_scaffold=True on .project(), .to_cli(), .to_api(), .to_mcp(), or .write() (CLI: --allow-scaffold) emits labeled NotImplementedError implementations, not successful dummy results. Mixed directory conversions refuse before any output is written. This permission does not bypass callback or dependency refusals. Recovered pass, ellipsis, and docstring-only no-ops are not missing bodies. Low-level generators remain scaffold-capable for compatibility; they do not perform converter assessment, and live App serving/ejection is unchanged. See missing_body.py for an executable example.

Architecture

Both halves of intpot meet at one canonical ApplicationSchema. It owns immutable ToolSchema and ParameterSchema records. Existing ToolInfo and ParameterInfo objects remain detached compatibility views at the edges.

   @app.tool()                        source .py file
   (intpot.App)                    (Typer / FastMCP / FastAPI)
        |                                    |
        |                              1. DETECT
        |                              2. INSPECT
        |                                    |
        +-----------> ApplicationSchema <----+
                           ToolSchema[]
                              |
              +---------------+---------------+
              |                               |
        build a live                    3. GENERATE
      framework instance            (render a template)
              |                               |
       serve --cli/--api/--mcp        .py output on disk
                                    (to cli/mcp/api, eject)

Conversion follows four stages: detect the framework, inspect its tools, compile one immutable ApplicationSchema, then project target-specific semantics before rendering. The runtime side compiles @app.tool() registrations into the same schema. serve keeps the registered callables for live execution; eject renders detached views of the stable schema. Access .schema.to_dict() when a human, build tool, or agent needs to inspect exactly what Intpot compiled.

to_dict() is directly JSON-serializable. Every non-JSON-native default uses an unambiguous {"$intpot": {"type": ...}} envelope, preserving distinctions such as list versus tuple and bytes versus an ordinary dictionary. Enum and opaque defaults, as well as timezone-aware/folded temporal values, are rejected with TypeError because standalone generated code cannot preserve their semantics reliably.

Conversion examples

The repository includes checked-in source and generated output for every direction:

Source Typer target FastAPI target FastMCP target
Typer — cli_to_api.py cli_to_mcp.py
FastAPI api_to_cli.py — api_to_mcp.py
FastMCP mcp_to_cli.py mcp_to_api.py —

examples/ also contains advanced inputs with direct imports, async tools, request bodies, Depends(), and path parameters. The FastAPI dependency example remains inspectable, but API-to-CLI/MCP conversion intentionally refuses it until issue #20 is implemented. The FastAPI input also includes routes with multiple HTTP methods. See semantic_schema.py for a runnable canonical-schema inspection example. See callback_cli.py for executable source validation, callback inspection, and intentional conversion refusal.

CLI Reference

intpot --version (or -V) prints the installed version; intpot <command> --help works for any command below.

intpot serve

Serve an intpot App as CLI, API, or MCP server.

intpot serve <source> --cli|--api|--mcp [--host <host>] [--port <port>] [--] [args...]
Argument/Option Description
source Path to a Python file containing an intpot.App
--cli Serve as a Typer CLI
--api Serve as a FastAPI app
--mcp Serve as a FastMCP server
--host API server host (default: 127.0.0.1 — pass 0.0.0.0 to expose it on the network)
--port API server port (default: 8000)
args... Passed straight to your app in --cli mode: intpot serve app.py --cli add 2 3

Anything intpot doesn't recognise is forwarded, so your own options work as-is. Use -- when your app defines a flag intpot also defines:

intpot serve app.py --cli -- greet World --port 5

intpot inspect

Show the tools intpot extracts from a source, without generating anything. Useful for checking what a conversion will see before you run it.

intpot inspect <source> [--json] [--verbose]
Argument/Option Description
source Path to a source Python file or directory
--json Emit the canonical tool schema as JSON instead of a table
--verbose, -v Print detection details to stderr
$ intpot inspect mcp_server.py

Source: mcp_server.py (mcp)
┏━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━┓
┃ Name  ┃ Description            ┃ Parameters            ┃ Return Type ┃ Async ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━┩
│ greet │ Greet someone by name. │ name: str, greeting:  │ str         │ No    │
│       │                        │ str='Hello'           │             │       │
└───────┴────────────────────────┴───────────────────────┴─────────────┴───────┘

intpot eject

Export an intpot App as standalone framework code.

intpot eject <source> --to <cli|mcp|api> [--output <path>]
Argument/Option Description
source Path to a Python file containing an intpot.App
--to, -t Target framework: cli, mcp, api (required)
--output, -o Output file path (prints to stdout if omitted). Missing parent directories are created

intpot init

Scaffold a new project from a template.

intpot init <name> --type <mcp|cli|api>
Argument/Option Description
name Project name (creates a directory)
--type, -t Project type: mcp, cli, or api (required)

intpot to cli / to mcp / to api

Convert a source file — or every app in a directory — to the target framework. For a directory, the output mirrors the source tree: each generated file keeps its source's position, with only the filename changing.

intpot to cli <source> [--output <path>] [--dry-run] [--allow-scaffold] [--verbose]
intpot to mcp <source> [--output <path>] [--dry-run] [--allow-scaffold] [--verbose]
intpot to api <source> [--output <path>] [--dry-run] [--allow-scaffold] [--verbose]

All three take the same arguments:

Argument/Option Description
source Path to a source Python file or directory
--output, -o Output file/directory path (prints to stdout if omitted). Missing directories are created
--dry-run Print what would be generated, without writing any files
--allow-scaffold Explicitly emit failing scaffolds for unrecovered function bodies
--verbose, -v Print detection details to stderr

to cli accepts MCP or API sources, to mcp accepts CLI or API, to api accepts CLI or MCP. A source that already matches the target is skipped.

--dry-run shows generated output without writing generated files, but it is not a sandbox: detection still imports the source and executes arbitrary module-level code. Only point intpot at source you trust:

$ intpot to cli mcp_server.py --dry-run
# --- Would generate: mcp_server_cli.py ---
"""CLI app generated by intpot."""
...

intpot add skills

Install intpot skills/rules for AI coding agents. Auto-detects which agents are configured in the project, or specify one explicitly.

intpot add skills [--agent <name>] [--path <dir>]
Option Description
--agent, -a Target agent: claude, cursor, windsurf, copilot, cline, codex
--path, -p Project root directory (defaults to current directory)

Supported agents and output locations:

Agent Detected by Files created
Claude Code .claude/ .claude/skills/intpot-cli/SKILL.md, .claude/skills/intpot-python/SKILL.md
Cursor .cursor/ .cursor/rules/intpot-cli.mdc, .cursor/rules/intpot-python.mdc
Windsurf .windsurf/ .windsurf/rules/intpot-cli.md, .windsurf/rules/intpot-python.md
GitHub Copilot .github/copilot-instructions.md .github/copilot-instructions.md (managed block)
Cline .clinerules/ .clinerules/intpot-cli.md, .clinerules/intpot-python.md
OpenAI Codex never auto-detected AGENTS.md (managed block)

Codex has to be asked for by name — intpot add skills --agent codex. It reads AGENTS.md, but so does nearly every other tool now, so the presence of that file says nothing about whether you use Codex. Since installing appends to it, guessing wrong would edit your own documentation. The same reasoning is why Copilot keys off .github/copilot-instructions.md rather than .github/, which only means the project is on GitHub.

Running with no --agent and no detected marker exits without writing anything. Copilot and Codex installations use bounded intpot-managed blocks, so rerunning the command updates or repairs intpot guidance while preserving surrounding project content. For Codex, intpot warns when the resulting AGENTS.md exceeds Codex's default 32 KiB instruction limit.

Community

The ModePot Discord is the shared community for intpot, summonpot, dexpot, and the rest of the project family. Join to discuss use cases, ask implementation questions, and help shape declaration-first Python frameworks.

Use GitHub issues for reproducible bugs and scoped feature proposals. Use Discord for open-ended design discussion, early ideas, and help applying the frameworks to real projects.

Contributing

intpot has a small core with clear extension points: inspectors turn frameworks into ToolInfo, generators turn ToolInfo into source, and runtime builders expose live interfaces. Contributions can improve conversion fidelity, add real-world examples, strengthen generated-code tests, or make the developer experience clearer.

Open an issue before substantial public-contract work; focused fixes, tests, documentation, and maintenance may be direct pull requests. User-facing work uses an issue-backed or Towncrier-generated orphan changelog fragment—never a pull-request-number fragment.

Development setup

Requires uv.

git clone https://github.com/tugrulguner/intpot.git
cd intpot
uv sync --all-extras
uv run pre-commit install

Run the full check suite:

make check   # lint + typecheck + test

Individual targets:

make lint              # ruff check + format check
make typecheck         # pyright
make test              # pytest
make format            # auto-format code
make changelog-draft   # preview the next release section
make changelog         # assemble changelog.d/ into CHANGELOG.md (release only)

Changelog entries are written as one fragment file per PR in changelog.d/ rather than by editing CHANGELOG.md, and CI asks every PR for one. See changelog.d/README.md — it's short.

Roadmap

See ROADMAP.md for the current polish backlog and the planned full AST transform pipeline.

Support intpot

If intpot removes a duplicate interface from your project, consider starring the repository. Stars help other Python developers find the project, while issues and pull requests make it better.

Missing body bindings (v0.11)

Public conversion now raises intpot.MissingBindingError before output writes when a retained implementation refers to globals absent from the generated target module. app.assess() and conditional intpot inspect --json assessment include per-target missing_binding diagnostics with tool, target, and sorted names. Existing body_recovery_complete and missing_function_body fields retain their meaning: recovering a body does not mean its dependencies are available.

Analysis reuses Python scope-aware binding analysis against statically rendered target implementations, accounting for locals, nested scopes, comprehensions, retained imports, builtins and generated self-recursion bindings. It renders but does not execute generated code. Binding availability assumes a normally file-loaded Python module, including loader-provided __file__, __cached__, and other standard module globals. Their values belong to the generated file; this does not preserve the original path, resources, or package environment. Custom exec namespaces must provide their own module globals. Targets blocked by existing rendering guards report reference_analysis_unavailable in assessment instead of implying a successful binding check. Inspection still imports trusted source code and is not a sandbox.

This first slice checks retained body bindings, not complete annotations/defaults, import availability, conditional binding initialization, runtime state, validation parity, or arbitrary Python equivalence. Recovery of the bounded subset is described below. Callback and FastAPI dependency refusal remain authoritative; allow_scaffold=True / --allow-scaffold does not bypass missing-binding refusal. Live App serving/ejection and direct low-level generator compatibility are unchanged. See examples/missing_binding.py for an original helper-based implementation with a dynamically initialized dependency that returns 21 and is explicitly refused.

Bounded helper recovery (v0.11)

Converters recover required undecorated functions and immutable literal constants from an inspected callable's owning module, including transitive helpers, ordinary imports, and recursive helper calls. Ordered support_definitions is separate from source_imports, immutable in ToolSchema, and detached in ToolInfo compatibility views. Generated output remains ordinary framework Python with no intpot runtime bridge.

Recovery reads the actual callable's globals and source file, verifies helper code and literal defaults against the live function, and rejects ambiguous or rebound bindings. It does not copy unrelated startup statements or app registration. Mutable globals, closures, decorated helpers, classes, dynamic defaults/global lookup, and helpers that write global/nonlocal state remain outside the supported subset. Unsupported dependencies still diagnose/refuse before writes; explicit scaffold permission does not bypass them. Conflicting support bindings and collisions with generated public names are refused. This is bounded source recovery, not purity analysis or arbitrary Python equivalence. Live App serving/ejection is unchanged; recovery currently applies to existing framework applications inspected by the CLI, API, and MCP inspectors.

Run uv run python examples/helper_recovery.py to exercise the helper chain returning 21 through generated CLI, HTTP API, and MCP consumers. examples/missing_binding.py retains a refusal control using a dynamically initialized module value rather than a recoverable literal. These capabilities are included in v0.11.0; the documented unsupported cases remain explicit.

License

MIT

Metadata

Release files for intpot 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for intpot 0.11.0
File Size Uploaded Provenance Actions
intpot-0.11.0.tar.gz 1.5 MB With provenance Details for intpot-0.11.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for intpot 0.11.0
File Interpreter ABI Platform Actions
intpot-0.11.0-py3-none-any.whl Python 3 none any Details for intpot-0.11.0-py3-none-any.whl

Total release size: 1.6 MB

Release files / intpot-0.11.0.tar.gz

Download URL intpot-0.11.0.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
0b750669bad6982b68ce78cefa5eac43f6a6506f798ababf30cc8fa2e3fbc374
BLAKE2b-256 checksum
How to use checksums
c79197cc9408885231c3080fc9431b5f9cc45fd1a8a7da8baa2e4b1d6b291e46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / intpot-0.11.0-py3-none-any.whl

Download URL intpot-0.11.0-py3-none-any.whl
Size 102.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17be503d9722013dd353f2e77ed1965e13c2d6bb2a485749aa65bd064b5cfc37
BLAKE2b-256 checksum
How to use checksums
dfeb0e13fa1900c5e5f3ed0a19dee2a68ed98a0a8b900f19fea82f4062f3f0f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Security for intpot 0.11.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for intpot-0.11.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page