mfish-nocode: a low-code platform with per-tenant AI assistants
摸鱼低代码平台,是一款致力于让开发像摸鱼一样轻松的低代码/无代码平台。首创微服务单体服务一体化架构。基于SpringBoot4、Spring Ai、Vue3等最新前后端技术栈。已用于多个成熟项目,学习和实战两不误。我们希望打破技术门槛,让程序员和非程序员都能快速构建业务系统,提升效率,释放创造力。
At a glance
- What is it?
- mfish-nocode is an Apache 2.0 licensed low-code and no-code business platform built on Spring Boot 4, Spring Cloud Alibaba and Vue 3, with self-service APIs and dashboards, annotation-driven permissions, per-tenant model configuration and seven domain AI assistants behind a natural language router. The judgement is that the platform is unusually complete for a Chinese open source project of its kind, and that the AI layer is the part with a real design decision in it, namely how a ChatModel is cached so that tenant count does not drive memory use.
- Who is it for?
- mfish-nocode fits a Chinese enterprise team that wants an internal system, an ERP or a dashboard assembled from configuration rather than from code, and that wants the AI feature to be tenant aware rather than a single shared assistant.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A business platform whose name jokes about its own promise
mfish-nocode is a low-code and no-code platform for building business systems, and its Chinese name is a joke that translates loosely as a low-code platform for slacking off at work. The readme leans into the humour, describing the platform as an efficiency shortcut for programmers who want a break, a tool for newcomers to put a site together, and a way for a manager to sketch a prototype.
Underneath the joke the ambition is conventional and large. The stated goal is to break down the technical barrier so that both programmers and non-programmers can build business systems quickly, and the repository description says the platform has already been used in several mature projects, with learning and practice combined.
What it actually is, technically, is a Spring Boot 4 and Spring Cloud Alibaba backend with a Vue 3 and Ant Design frontend, and the platform runs in two modes at once, a low-code mode where you generate business code and a no-code mode where you configure APIs and dashboards without writing anything. The same repository hosts the front end, the back end and the database scripts, with the front end living in a separate repository that is mirrored across several forges.
The project is Apache 2.0 licensed, the default branch is main, the documentation site is mfish.com.cn, and the last push to the repository was on 2026-10-20.
One codebase that deploys as a monolith or as microservices
The architectural claim at the centre of the project is that the microservice and the monolith are the same code.
The readme describes a single instance microservice integration architecture, which supports both a monolithic service and a microservice deployment mode, with one codebase solving both architectures. The backend is Spring Boot 4 with Spring Cloud Alibaba, and the front end is Vue 3 with Ant Design.
The registry and configuration centre are Nacos, and the readme makes the important qualifier explicit: they are not needed when the platform runs as a monolith. That is the point of the design. A team that starts with one service and a single database can later split the same code into services without rewriting it, and the pieces that force a distributed deployment, the registry and the configuration server, are simply switched off.
The rest of the platform follows from that. OAuth2 is the unified authentication layer, with three login methods listed, account and password, SMS code and WeChat QR code. Tenants can be switched at runtime, and each tenant manages its own people, organisations and roles, which is the usual multi-tenant arrangement with the tenant as the isolation boundary rather than the schema.
There is also a monitoring module, a task scheduling module, a workflow module with a form designer, and a storage module, so the platform is a system rather than a framework.
Self-service APIs that generate their own SQL
The low-code and no-code sides of the platform are two different workflows over the same data.
The no-code side is the more interesting technically. The readme states that the platform supports configuring query APIs visually, with the backend automatically generating and executing the SQL. So the user is not writing a query endpoint by hand, they are describing it, and the service compiles the description into SQL at runtime.
The low-code side is the code generator, which produces backend and front end code for the entities and pages you describe, so the output is a codebase you own and can edit afterwards, rather than configuration trapped inside a platform.
The module list in the readme shows how much is in the box. Under low-code there is self-service dashboards, self-service APIs, data sources and code generation. Under system management there is menu, organisation, role, account, dictionary, category, log, file, online users, application and database management. Under tenant management there is tenant configuration and the tenant's own organisation, roles and people. There is approval management with a list of requests, my applications and process management, a task scheduling module with task and log views, a system monitoring centre, and a set of usage examples that cover upload and download, import and export, multi-level directories, master and detail tables, and data permissions.
There is also a cockpit with a workbench, which is the landing area a user actually sees.
Permissions live in annotations, not in the business code
Two design decisions in the platform deserve separating out, because both are about keeping generated code clean.
The first is access control. The readme describes enterprise grade permission control that is fully decoupled from the business code and driven by annotations. The point is that when a page or an API is generated, the generated code does not contain permission logic, and the permission rules are applied separately. For a low-code platform this is the difference between a generated codebase you can still refactor and one where every generated file carries a copy of the same authorisation scaffolding.
The second is data permission, which is handled the same way, by annotation, and is one of the usage examples in the sample module list alongside the master and detail tables. Data permission is the harder of the two, because it means the same query returns different rows for different users, and doing that from a single annotation rather than from a per-screen filter is what lets a platform offer row level rules without asking the user to wire them into every generated query.
The combination with the tenant model is what gives the platform its shape. A tenant owns people, organisations and roles, and those in turn feed the permission system, so a query in a multi-tenant installation is filtered by tenant, by the user's place in the organisation and by the data permission rules, and none of that has to be written by hand.
Seven domain assistants sit behind a natural language router
The AI layer is built on Spring AI 2.0 and it has three parts: a router, a model layer and a set of domain assistants.
The router is the GatewayAssistant, which makes the routing decision with the language model itself. The user asks a question in natural language, the model works out the intent, and the request is routed to the matching domain assistant, with no manual selection of an entry point. That is a nicer idea than a menu of seven chat windows, and it is also the part that depends most on prompt quality.
The domain assistants are listed in a table in the readme, and the routing paths are visible. There is a general assistant at /ai/agent/chat for platform questions and general chat, an authentication centre assistant at /ai/oauth2/assist covering menus, organisations, roles, accounts and tenants, a system centre assistant at /ai/sys/assist covering dictionaries, category directories, logs, code generation, the database and data sources, a low-code centre assistant at /ai/nocode/assist for dashboards, APIs, component management and formula information, a scheduling centre assistant at /ai/scheduler/assist for timed task scheduling, execution logs and callback status, a storage centre assistant at /ai/storage/assist for file storage information, file management and resource retrieval, and a workflow assistant at /ai/workflow/assist for process deployment, process instances, task approval and to-do tasks.
Seven assistants, each with a bounded job, is a sensible decomposition. The alternative, one assistant with a very large prompt and a very large tool list, tends to answer the wrong question confidently.
The model layer is per tenant, and the ChatModel cache is keyed by configuration
The multi-tenant model management is the part of the AI design with a real engineering decision in it.
Model configuration is isolated per tenant, so different tenants can use different providers, and the readme names OpenAI, Ollama, a Chinese provider and a router service as examples. The important detail is how the model object is cached. The ChatModel is shared and cached by a signature of its configuration, and the readme states that it does not grow with the number of tenants.
That single line is the whole trick. A naive implementation keeps one ChatModel per tenant, which means a platform with two hundred tenants holds two hundred clients, two hundred connection pools and two hundred sets of credentials in memory, and the memory grows with the customer count rather than with the number of distinct configurations. Keying the cache on the configuration signature means two tenants with identical settings share one client, and a new tenant with a different provider adds one entry.
The other part of the model layer is the compatibility surface. The platform exposes an OpenAI compatible /v1/chat/completions proxy, with streaming and non-streaming handled automatically, which means anything that speaks the OpenAI protocol, including your own tools, can talk to the tenant-aware gateway without knowing that the gateway exists.
The assistant routes from the previous section sit on top of that, so the request path is: a question arrives, the gateway model routes it, the domain assistant calls the tenant's model, and the answer comes back.
A Maven multi-module project with one container image to build
The repository is a Maven multi-module project, and the module names describe the platform.
There is mf-start, which holds the boot module and is the image the compose file builds, then mf-api, mf-business, mf-common, mf-gateway, mf-monitor, mf-oauth, mf-scheduler, mf-storage, mf-test and mf-wechat, with a db directory for the database scripts and a pom.xml at the root. The gateway module is the microservice entry point, the oauth module is the authentication service, and the monitor and scheduler modules cover the operational surface.
The compose file shows how the platform is run in the simplest shape, a single service built from the boot module:
services:
mfish-nocode-service:
build: mf-start/mf-start-boot
container_name: mfish-nocode-service
restart: always
environment:
- TZ=Asia/Shanghai
ports:
- 11116:8888
volumes:
- /home/srv/docker_volumes/mfish-nocode-service/logs:/app/logs
- /home/srv/docker_volumes/mfish-nocode-service/code:/app/code
- /home/srv/docker_volumes/mfish-nocode-service/storage:/app/storageThree directories are mounted, and they are worth reading as a design. The logs directory is obvious. The code directory is the interesting one, because it is where the generated code and the generated artefacts live, mounted so that they survive a container rebuild. The storage directory holds uploaded files. There is a second compose file, docker-compose-cloud.yml, for the distributed arrangement.
The container runs in the Asia/Shanghai time zone, and the service is published on port 11116 in front of the port 8888 the application listens on, which matches the online preview address given in the readme at app.mfish.com.cn on port 11119.
Editorial conclusion
mfish-nocode fits a Chinese enterprise team that wants an internal system, an ERP or a dashboard assembled from configuration rather than from code, and that wants the AI feature to be tenant aware rather than a single shared assistant. It is the wrong choice if you need a small, sharp tool, because the platform ships a whole system management console, tenant management, scheduling, workflow design and monitoring before it gets to your feature, and it is the wrong choice if your organisation cannot operate a Spring Cloud deployment with Nacos, even though the monolith mode removes the registry requirement. Before you deploy, read the version numbers carefully, because the badge in the readme says 2.4.1 while the newest release tag listed is V2.3.1, check that the Spring Boot 4 and Spring AI 2.0 stack matches your Java runtime, and plan for the fact that the documentation and the tutorial videos are in Chinese.
Frequently asked questions
What is mfish-nocode?
It is an Apache 2.0 licensed low-code and no-code platform for building business systems, with a Spring Boot 4 and Spring Cloud Alibaba backend, a Vue 3 and Ant Design front end, self-service dashboards and APIs, code generation, multi-tenant OAuth2 and seven domain AI assistants.
Can the same code run as a monolith and as microservices?
Yes. The backend is built for both, and the registry and configuration centre are Nacos, which the readme says are not needed when the platform runs as a single monolith, so the distributed parts can simply be switched off.
How does the AI layer handle multiple tenants?
Model configuration is isolated per tenant, so different tenants can use different providers, and the ChatModel is cached by a configuration signature so that the cache does not grow with the number of tenants. The platform also exposes an OpenAI compatible /v1/chat/completions proxy with automatic streaming and non-streaming handling.
How are permissions applied in mfish-nocode?
Through annotations, with the access control fully decoupled from the business code, and data permissions handled the same way, so generated code does not carry a copy of the authorisation logic.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mfish-qf-mfish-nocode)Was this useful?