document/content/docs/introduction/guide/plugins/dev_system_tool.en.mdx
Starting from version 4.10.0, the FastGPT system plugin project moved to the standalone fastgpt-plugin repository, using a pure code approach for tool development.
After the plugin marketplace update in version 4.14.0, the system tool development process changed — please follow the latest documentation when contributing code.
You can develop and debug plugins independently in the fastgpt-plugin project, then submit a PR directly to FastGPT without needing to run the main FastGPT service.
Currently, system plugins only support the "Tool" type.
In fastgpt-plugin, you can create one tool or toolset at a time. Each submission accepts only one tool/toolset. To develop multiple, create separate PRs.
Fork the repository at https://github.com/labring/fastgpt-plugin
<Tabs items={['One-Click Setup via Bunx','Manual Setup']}> <Tab value="One-Click Setup via Bunx"> Note: Due to Bun-specific APIs, you must use bunx for installation. Using npx or pnpm will cause errors.
Create a new directory and run:
bunx @fastgpt-sdk/plugin-cli
This creates a fastgpt-plugin directory and adds two remotes:
Uses sparse-checkout by default to avoid pulling all official plugin code.
</Tab> <Tab value="Manual Setup"> - Initialize a `git` repository in a new local directory:git init
If you have a Git SSH key configured:
git remote add origin [email protected]:[your-name]/fastgpt-plugin.git
git remote add upstream [email protected]:labring/fastgpt-plugin.git
Otherwise use HTTPS:
git remote add origin https://github.com/[your-name]/fastgpt-plugin.git
git remote add upstream https://github.com/labring/fastgpt-plugin.git
git sparse-checkout init --no-cone
git sparse-checkout add "/*" "!/modules/tool/packages/*"
git pull
Create a new tool:
bun i
bun run new:tool
Follow the prompts to choose between creating a tool or toolset, and enter a directory name (use camelCase).
System tool file structure:
src // Source code and processing logic
└── index.ts
test // Test cases
└── index.test.ts
config.ts // Configuration: tool name, description, type, icon, etc.
index.ts // Entry point — do not modify this file
logo.svg // Logo — replace with your tool's logo
README.md // (Optional) README with usage instructions and examples
assets/ // (Optional) Resource files such as images, audio, etc.
package.json // npm package
Toolset file structure:
children
└── tool // Same structure as a tool above, but without README and assets
config.ts
index.ts
logo.svg
README.md
assets/
package.json
activation information, typically including keys, Endpoint, Port, etc. (see secretInputList format below)For tools within a Toolset, type, courseUrl, and author are inherited from the Toolset configuration and don't need to be specified.
General format:
{
key: 'key', // Unique key
label: 'Frontend display label',
description: 'Frontend display description', // Optional
inputType: 'input' | 'secret' | 'switch' | 'select' | 'numberInput', // Frontend input type
// secret: Encrypted input — the value is symmetrically encrypted when saved
// switch: Toggle switch
// select: Dropdown select
// numberInput: Number input
// input: Plain text input
}
Here's an example from the dalle3 configuration. See dalle3's config.ts for the full file.
{
// Other configuration
secretInputConfig: [
{
key: 'url',
label: 'Dalle3 API Base URL',
description: 'e.g., https://api.openai.com',
inputType: 'input',
required: true
},
{
key: 'authorization',
label: 'API Credential (without Bearer prefix)',
description: 'sk-xxxx',
required: true,
inputType: 'secret'
}
]
}
General format:
{
key: 'Unique key within this tool, matching the InputType definition in src/index.ts',
label: 'Frontend display label',
renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference], // Frontend input type
valueType: WorkflowIOValueTypeEnum.string, // Data type
toolDescription: 'Description used during tool invocation' // Required if this is a tool call parameter
}
dalle3 inputs example:
{
//...
versionList: [
{
// Other configuration
inputs: [
{
key: 'prompt',
label: 'Drawing Prompt',
valueType: WorkflowIOValueTypeEnum.string,
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.input],
toolDescription: 'Drawing prompt'
}
],
}
// ...
]
}
{
key: 'link', // Unique key
valueType: WorkflowIOValueTypeEnum.string, // See the Enum type definition for options
label: 'Image Access Link', // Display name
description: 'Image access link' // Description (optional)
}
dalle3 outputs example:
{
// ...
versionList: [
{
// ...
outputs: [
{
valueType: WorkflowIOValueTypeEnum.string,
key: 'link',
label: 'Image Access Link',
description: 'Image access link'
},
{
type: FlowNodeOutputTypeEnum.error,
valueType: WorkflowIOValueTypeEnum.string,
key: 'system_error',
label: 'Error Message'
}
]
}
],
}
Write your processing logic in [your-tool-name]/src/index.ts as the entry point. Key requirements:
InputType and OutputType schemas.tool. You can define additional helper functions.import { format } from 'date-fns';
import { z } from 'zod';
export const InputType = z.object({
formatStr: z.string().optional()
});
export const OutputType = z.object({
time: z.string()
});
export async function tool(props: z.infer<typeof InputType>): Promise<z.infer<typeof OutputType>> {
const formatStr = props.formatStr || 'yyyy-MM-dd HH:mm:ss';
return {
time: format(new Date(), formatStr)
};
}
The example above takes a formatStr (format string) and returns the current time. To install packages, run bun install PACKAGE from the /modules/tools/packages/[your-tool-name] directory.
Starting from FastGPT v4.14.0, system plugins are packaged as .pkg files. Run:
bun run build:pkg
This builds and packages all local plugins as .pkg files in the dist/pkgs directory.
FastGPT-plugin uses Vitest as its testing framework.
Write test cases in test/index.test.ts. Run them with bun run test index.test.ts <full-path>.
Note: Never include secret keys in test cases.
When using AI agent tools to write test cases, the agent may modify your processing logic or even the testing framework itself.
Open coverage/index.html in a browser to view coverage for each plugin module.
To submit plugins to the official repository, you must write unit tests that achieve:
Simple tools may not need E2E testing. For complex tools, the review team may require it.
cd runtime && cp .env.template .env.local to copy the environment variable template, then connect to the Minio, Mongo, and Redis instances from step 1bun run dev to start the development environment, then update FastGPT's environment variables to connect to your fastgpt-plugin instanceStart the fastgpt-plugin development environment.
Open http://localhost:PORT/openapi in a browser to access the fastgpt-plugin OpenAPI page for API debugging. Replace PORT with your fastgpt-plugin port number.
First, use the /tool/list endpoint to get the tool list and find the toolId of the tool you want to debug. Then use /tool/runStream to run the tool and get results.
By default, fastgpt-plugin automatically loads all tools under modules/tool/packages/ and watches for file changes with hot reload. You can use these tools directly in FastGPT.
Set the FastGPT-plugin environment variable DISABLE_DEV_TOOLS=true to disable automatic loading of development tools, allowing you to test tool uploads instead.
After completing all the steps above, submit a PR to the official repository at https://github.com/labring/fastgpt-plugin. Once reviewed and approved, your tool will be included as an official FastGPT plugin.
If you don't need official inclusion, refer to Upload System Tool to use it in your own FastGPT deployment.