Marona SDK
Official developer SDK for building Marona-compatible apps, MCP servers, tool servers, skills, and workflows.
Use marona-sdk when you are building an app that exposes tools to Marona Hub.
Use marona when you are building an application or interface that calls a
Marona-compatible runtime.
The SDK helps your app expose the Marona standard automatically:
GET /healthGET /manifestGET /hub-registrationPOST /mcp/using the official MCP Python SDKFastMCP- tool outputs with
status,success,message,content,content_type,presentation_hint, andcontext
Install
Python:
pip install marona-sdk
In requirements.txt:
marona-sdk
Import it as:
from marona_sdk import AgentApp, HostingConfig, success
Dart:
dart pub add marona_sdk
dart pub global activate marona_sdk
TypeScript:
npm install marona-sdk
1. Create An App
Every app needs a unique app ID, also called a slug. Examples:
weather-mcpknowledge-mcpcompany-crm-mcp
from marona_sdk import AgentApp, success
agent_app = AgentApp(
name="Weather Tools",
slug="weather-mcp",
description="Weather lookup tools for agents and AI interfaces.",
category="Weather",
visibility="public",
)
Use visibility="public" when the app should be discoverable in Hub.
Use visibility="private" when the app is only for the owner's workspace.
Apps also declare where they can run:
agent_app = AgentApp(
name="Knowledge Tools",
slug="knowledge-mcp",
description="Search company knowledge.",
category="Knowledge",
execution_modes=["online", "offline", "hybrid"],
execution_targets=[
{
"mode": "offline",
"type": "python_package",
"package_url": "https://packages.example.com/knowledge-mcp-1.0.0.zip",
"sha256": "<64-character-sha256>",
"entrypoint": "marona_offline:call_tool",
"runtime_contract": "marona:tool-component@1",
"transport": "streamable_http",
"endpoint": "/mcp",
"port": 62750,
"assets": ["knowledge-index", "document-cache"],
}
],
)
execution_modes can be online, offline, or hybrid. execution_targets
must use remote_mcp or marona_hosted for online execution and signed
python_package, wasm, static_cache, or builtin targets for offline
execution. Do not submit device-local runtime fields; Marona clients resolve
those after an app is installed on a device or private network.
2. Add A Tool
@agent_app.tool(
title="Get forecast",
description="Return the weather forecast for a city.",
input_schema={
"type": "object",
"properties": {
"city": {"type": "string"},
},
"required": ["city"],
"additionalProperties": False,
},
)
def get_forecast(city: str) -> dict:
return success(
f"The forecast for {city} is sunny.",
content=f"The forecast for {city} is sunny.",
content_type="text",
presentation_hint="display_as_provided",
context="Display the forecast directly unless the user asks for another format.",
data={"city": city, "condition": "sunny"},
)
3. Run The Server
app = agent_app.create_fastapi_app()
Run locally:
uvicorn examples.hello_server:app --host 127.0.0.1 --port 62900
Inspect:
http://127.0.0.1:62900/health
http://127.0.0.1:62900/manifest
http://127.0.0.1:62900/hub-registration
http://127.0.0.1:62900/mcp/
4. Choose Hosting
Marona supports two hosting models.
Option A: self-hosted
You run the server yourself and register its public MCP URL in Marona Hub.
agent_app = AgentApp(
name="Weather Tools",
slug="weather-mcp",
description="Weather lookup tools.",
category="Weather",
hosting=HostingConfig(mode="self_hosted"),
)
Your deployment is responsible for uptime, logs, scaling, secrets, storage, domains, and monitoring. Marona Hub can still list and review the app, and runtime users can discover it after approval.
Option B: Marona-hosted
For Marona-hosted apps, provide source from a repository or source archive. Marona builds and deploys it internally, then manages health, logs, metrics, secrets, regions, scaling, storage, and public URLs.
agent_app = AgentApp(
name="Weather Tools",
slug="weather-mcp",
description="Weather lookup tools.",
category="Weather",
hosting=HostingConfig(
mode="marona_hosted",
source_type="repository",
source_url="https://github.com/example/weather-mcp",
version="1.0.0",
runtime="python",
region="africa-south-1",
resource_class="shared-small",
replicas=1,
storage_gb=1,
secrets={"OPENAI_API_KEY": "set-in-portal"},
environment={"LOG_LEVEL": "info"},
runtime_config={"port": 8000, "endpoint": "/mcp"},
),
)
Secret values are not exposed in /hub-registration; only configured secret
names are shown. Developers do not need to manage hosting infrastructure. Use
runtime config for MCP runtime settings such as port and endpoint.
5. Publish To Marona Hub
DeveloperHubClient is for developer workflow commands such as create, sync,
submit, and hosted deployment setup.
from marona_sdk import DeveloperHubClient
client = DeveloperHubClient(
hub_url="https://hub.marona.ai",
token="DEVELOPER_PORTAL_TOKEN",
)
Apps, devices, bots, and user interfaces should use the separate marona
runtime client package.
Create, sync, submit, then publish and deploy:
detail = await client.create_agent_app(agent_app.hub_registration(
server_url="https://weather.example.com/mcp/",
health_check_url="https://weather.example.com/health",
))
await client.sync_agent_app(detail["id"])
await client.submit_agent_app(detail["id"])
deployment = await client.create_hosted_deployment(
detail["id"],
source_type="repository",
source_url="https://github.com/example/weather-mcp",
runtime="python",
region="africa-south-1",
runtime_config={"port": 8000, "endpoint": "/mcp"},
secrets={"OPENAI_API_KEY": "set-in-portal"},
)
Or use the CLI. This is a Marona Hub core deliverable for developers who want to build, publish, and deploy MCP apps without managing Hub API calls manually.
marona publish --registration app-registration.json --submit
marona deploy \
--app-id app_123 \
--source-url https://github.com/example/weather-mcp \
--source-type repository \
--version 1.0.0 \
--region africa-south-1 \
--runtime-config '{"port":8000,"endpoint":"/mcp"}'
Marona returns a deployment record with status, region, workload id, public URL, MCP URL, health URL, logs URL, and metrics URL. Admin activation provisions the workload and points the app’s live MCP endpoint at the hosted URL after health checks pass.
Standard Tool Results
All Marona-compatible tools should return the SDK result shape:
status: machine-readable result statussuccess: boolean result success flagmessage: short user-facing status linecontent: primary user-facing text or contentcontent_type: provider-neutral content type, such astext,document,message,list,media, orsearch_resultspresentation_hint: provider-neutral usage hint, such asdisplay_as_providedcontext: short guidance for interpreting the result
Provider-specific data should live under generic fields:
data: one structured objectitems: a list of structured objectscount: item count whenitemsis usedartifacts: generic artifact descriptorsjob: generic async job metadata
If a tool declares its own output_schema, the SDK merges these standard fields
into that schema before exposing /manifest and /hub-registration.
Standard Tool Inputs For User Files
Tools that consume uploaded files should declare the SDK-standard
attachments input property. The runtime injects the current conversation
files into that array automatically.
from marona_sdk import standard_attachments_property
input_schema = {
"type": "object",
"properties": {
"question": {"type": "string"},
"attachments": standard_attachments_property(),
},
"required": [],
"additionalProperties": False,
}
Each attachment can include artifact_id, filename, mime_type, kind,
url, file_url, content_base64, content, and metadata.
Package Names
- Python developer SDK:
marona-sdk, importmarona_sdk - Dart developer SDK:
marona_sdk, importpackage:marona_sdk/marona_sdk.dart - TypeScript developer SDK:
marona-sdk, import from"marona-sdk" - Runtime client SDKs:
marona
Metadata
Release files for marona-sdk 0.1.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| marona_sdk-0.1.14.tar.gz | 26.5 kB | Without provenance | Details for marona_sdk-0.1.14.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| marona_sdk-0.1.14-py3-none-any.whl | Python 3 | none | any | Details for marona_sdk-0.1.14-py3-none-any.whl |
Total release size: 48.3 kB
Release files / marona_sdk-0.1.14.tar.gz
| Download URL | marona_sdk-0.1.14.tar.gz |
|---|---|
| Size | 26.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b712b73b71b7df3687b1c8e2613b9e96cd5f050f0ffcf623eab7d3bee055883
|
|
BLAKE2b-256 checksum How to use checksums |
aa922dc85572e246f419a9f7ada011633ec03b9666cf6a62cbd18bff109a3059
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / marona_sdk-0.1.14-py3-none-any.whl
| Download URL | marona_sdk-0.1.14-py3-none-any.whl |
|---|---|
| Size | 21.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
068989d836592cb969972ee7188e822587d1b1d218fd50f65bc3a366ba2f5e27
|
|
BLAKE2b-256 checksum How to use checksums |
e711d134e24b5c1aee6001656816ab0bbf7a8347b02fa2f66d0413fa935da121
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for marona-sdk 0.1.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.