nexusx
nexusx turns a SQLModel database into two things: a GraphQL query interface that's friendlier than writing SQL, and business logic that ships as REST, GraphQL, MCP, and CLI from a single signature.
flowchart LR
subgraph Logic["Business logic — one signature, many transports"]
s["UseCaseService<br/>methods"]
s --> rest["REST / OpenAPI"]
s --> gql2["GraphQL"]
s --> mcp2["MCP (AI agents)"]
s --> cli["CLI"]
end
subgraph Query["Query surface — friendlier than SQL"]
e["SQLModel entities<br/>+ relationships"]
e --> gql1["GraphQL"]
e --> mcp1["MCP"]
e --> er["ER diagrams (Voyager)"]
end
What it does for you
1. A query interface over your database — not another query writer.
GraphQLHandler reflects your entities and relationships into a read surface
where you declare the shape you want — users { posts { comments } } — and
nexusx compiles it to optimal SQL: one batched round-trip per level, columns
pruned to what you selected, per-parent pagination. N+1 and over-fetching
aren't pitfalls to avoid; they're structurally impossible. Turn on
auto_query_config for by_id and equality by_filter; richer predicates
(range, like, ordering) are one @query method that rejoins the same surface.
Voyager renders the schema as an interactive ER
diagram, so the query interface is self-documenting.
2. Business logic, on every transport.
A UseCaseService method is plain async Python. One signature becomes a
FastAPI route (with OpenAPI), an MCP tool for AI agents, a CLI command — and a
GraphQL field. Note this GraphQL is different from the one above: it projects
business operations, not your raw data graph, and it's built AI-first
(compact describe_* discovery, no 50K-token introspection dump). The same
codebase serves a web frontend, power integrations, and an AI agent without
rewriting the logic three times.
Both pillars speak "GraphQL," but they are different surfaces:
SQLModel GraphQL (GraphQLHandler) |
UseCaseService GraphQL (compose_query) |
|
|---|---|---|
| What it is | A query interface over your DB | A projection of business methods |
| Source | Auto-reflected from entities + relations | Hand-written @query / @mutation |
| Built for | Browsing / slicing your data graph | Invoking operations (app + AI) |
| Introspection | Full (GraphiQL-friendly) | Rejected (AI-first, compact describe_*) |
In 30 seconds
The query surface — entities become a GraphQL and MCP query interface:
from sqlmodel import SQLModel, Field, Relationship, select
from nexusx import query, GraphQLHandler
from nexusx.mcp import create_simple_mcp_server
class User(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str
posts: list["Post"] = Relationship(back_populates="author") # ← the entire resolver
@query
async def users(cls, limit: int = 10) -> list["User"]:
async with session() as s:
return (await s.exec(select(cls).limit(limit))).all()
class Post(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
title: str
author_id: int = Field(foreign_key="user.id")
author: User | None = Relationship(back_populates="posts")
# GraphQL — { users { posts { title } } } is 2 SQL round-trips, not 1+N
GraphQLHandler(base=SQLModel, session_factory=session)
# MCP — Claude / Cursor call get_schema + graphql_query, fetching SDL on demand
create_simple_mcp_server(base=SQLModel, name="Blog", session_factory=session)
The business-logic surface — one service class becomes REST + MCP:
from nexusx import (
query, UseCaseService, UseCaseAppConfig,
create_use_case_router, create_use_case_graphql_mcp_server,
)
class SprintService(UseCaseService):
@query
async def list_sprints(cls) -> list[SprintSummary]:
"""Get all sprints with task counts."""
...
cfg = UseCaseAppConfig(name="project", services=[SprintService])
app.include_router(create_use_case_router(cfg)) # REST + OpenAPI
create_use_case_graphql_mcp_server(apps=[cfg]).run() # MCP for AI agents
When to reach for it
- You want a friendlier query interface over a SQLModel database than writing SQL — graph-shaped reads, N+1-proof, selection-driven.
- You need more than one transport from one codebase — REST + GraphQL, or app + AI agent.
- You have non-ORM relations (Redis, search, external APIs) that should flow through the same loader / DTO / diagram plumbing as native ones.
When not to
- You only ever need one REST handler per endpoint and are happy writing them by hand — plain FastAPI is simpler.
- You want fine-grained resolver control over a large GraphQL schema — Strawberry gives you more knobs.
Install
pip install nexusx
pip install nexusx[fastmcp] # MCP support
Requires Python ≥ 3.10.
Learn more
- Quick Start — entities, DTOs, the UseCase layer
- Feature highlights — the design decisions, in depth
- Voyager visualization — interactive ER + service diagrams
- Federation — compose multiple nexusx services into one graph (same-architecture; no gateway)
- Auto query —
by_id/by_filterwithout writing@query - Clean Architecture comparison
- Changelog
- Demos:
bash start_all.sh· 4-phase AI skill
Status
Stable — follows semantic versioning. Bug reports and PRs welcome. MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nexusx-5.3.0.tar.gz.
File metadata
- Download URL: nexusx-5.3.0.tar.gz
- Upload date:
- Size: 1.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fdc4f2f0dc91bd80b20452c11cd92cdf2056f04f031f4aac7c3f6861beaf6c4
|
|
| MD5 |
f1263f4bab97fa116288636f31eff822
|
|
| BLAKE2b-256 |
8ff8f57a28a91236c2833a2929d0ca8a86ee7fea51f11de980ef9d295423ff19
|
File details
Details for the file nexusx-5.3.0-py3-none-any.whl.
File metadata
- Download URL: nexusx-5.3.0-py3-none-any.whl
- Upload date:
- Size: 828.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d58adef200b1eaad404690cf5f3acd680beddad0a12c240fde821673e073ca53
|
|
| MD5 |
9944cba663a911de03a370ac176023b2
|
|
| BLAKE2b-256 |
e7585f05a394ac94d5c3019abe05432bf3dc176c753f31e9f51c5d6372acf186
|