Customizing your DKG agent

Each DKG node includes a collocated neuro-symbolic AI agent that combines neural model capabilities (e.g., LLMs) with symbolic reasoning over RDF-based graph data. This enables DKG nodes to not only publish and query semantic knowledge but also perform knowledge graph reasoning, summarization, and data transformation tasks directly on locally or remotely stored knowledge.

The DKG Agent is built around a modular plugin system centered on the Model Context Protocol (MCP). Plugins define how the agent interacts with external tools, APIs, and reasoning systems. A generic DKG Node ships with a base set of plugins for common operations- such as knowledge publishing, retrieval, and validation - while developers can extend functionality by creating custom plugins.

Build your first plugin for the DKG Agent

The rest of this page will focus on how you can build custom plugins for your DKG agent. For example, you might build a Scientific Research plugin to ingest papers and publish structured knowledge on the DKG, helping your agent drive research. Or a Social Media plugin to extract relevant posts, build a knowledge pool on the DKG, and run sentiment analysis.

Option 1: Create a custom plugin inside the DKG monorepo

This is the easiest path if you’re already working inside the DKG monorepo.

🔨 Steps

  1. Use turbo to generate a plugin scaffold (from the project root folder)

    turbo gen plugin

This will create all the files for your plugin in a new folder.

  1. Name your plugin

We suggest you start your name with plugin- (example: plugin-pdf-parser), but it is not a hard requirement.

It will be created under packages/plugin-<your-name>

  1. Edit the plugin source

Open the plugin source packages/plugin-<your-name>/src/index.ts

Your plugin comes pre-scaffolded with examples that show how to expose a tool both as an MCP tool and as a REST API route (more details on this in the Exposing tools in your plugin section below). Your index.ts file should look something like this:

Within the defineDkgPlugin module, on line 6 we expose the plugin code via an MCP tool through mcp.registerTool() and on line 50 the plugin exposes a classic HTTP API, in this case a GET route, via api.get()

We recommend writing your custom plugin logic in your custom functions, like yourCustomFunction above, then use it within the mcp.registerTool() and api.get() code block.

  1. (Optional) Add dependencies

    npm install --save <package-name>

    Run this inside your plugin-<your-name> directory.

  2. (optional) Add additional source files if needed (e.g., utils.ts)

    • Place them in the src/ directory.

    • Import them into your index.ts.

  3. Once your are done, make sure to build your plugin by running

    npm run build

    or:

    turbo build
  4. Install your plugin in the DKG Node Agent

    cd apps/agent
    npm install --save @dkg/plugin-<your-name>

    This package name is auto-generated (check packages/plugin-<your-name>/package.json).

  5. Make sure to import your plugin and register it through createPluginServer Open apps/agent/src/server/index.ts and add:

    import myCustomPlugin from "@dkg/plugin-<your-name>";
    
    const app = createPluginServer({
      // ... other config (name, context, dkg client, etc.)
      plugins: [
        defaultPlugin,
        oauthPlugin,
        dkgEssentialsPlugin,
        examplePlugin.withNamespace("protected", {
          middlewares: [authorized(["scope123"])],
        }),
        
        // Add your own plugin here
        myCustomPlugin,
      ],
    });
  6. Run your DKG Node Agent

    Start the agent from the project root folder and run npm run dev . Test that your plugin is registered and working

To learn how DKG plugins work internally, see the How do DKG plugins work? section below.

Option 2: Create a standalone DKG plugin (npm package)

If you want to create your plugin outside of the monorepo and manage it as your separate package, you can! Follow the steps below

🔨 Steps

  1. Create a new Node.js project

    npm init

    (or use an existing project)

  2. Add "@dkg/plugins" package as a dependency

    npm install --save @dkg/plugins
  3. Define your plugin

    import { defineDkgPlugin } from "@dkg/plugins";
    
    const myCustomPlugin = defineDkgPlugin((ctx, mcp, api) => {
      // Example MCP tool
      // mcp.registerTool("my-mcp-tool", ... );
    
      // Example API route
      // api.get("/my-get-route", (req, res) => ... );
    });
    
    export default myCustomPlugin;
  4. (Optional) Add configuration support You can export your plugin as a function that accepts options:

    const configurablePlugin = (options: {...}) =>
      defineDkgPlugin((ctx, mcp, api) => { ... });
  5. (Optional) Publish to npm

    • Run npm publish to share with the DKG builder community.

How do DKG plugins work?

DKG plugins are functions applied in the order you register them. While you can define inline functions, using defineDkgPlugin is recommended for:

  • Type-safety

  • Extension methods

defineDkgPlugin arguments

When you define a plugin, the DKG Node automatically injects three objects:

  1. ctx (Context)

    • ctx.logger → Logger instance for logging messages

    • ctx.dkg → DKG Client instance for interacting with the DKG network

  2. mcp (MCP Server)

    • An instance of the MCP Server from @modelcontextprotocol/sdk

    • Use it to register MCP tools and resources

  3. api (API Server)

    • Express server instance from the express npm package

    • Use it to expose REST API routes from your plugin

All registered routes and MCP tools become part of the DKG Node API server.

Exposing tools in your plugin

Exposing as MCP Tools

MCP tools are automatically available to the DKG Agent (or any MCP client connected to your Node).

Example of how to expose tools (auto-scaffolded by turbo gen plugin):

mcp.registerTool(
  "add",
  {
    title: "Tool name",
    description: "Tool description",
    inputSchema: { /* expected input variables and format */ },
  },
  // YOUR TOOL CODE HERE
);

Including source Knowledge Assets in your MCP tool responses

Exposing as REST API routes

Expose routes through the API server for more “traditional” API calls.

Example of how to expose tools through API routes (auto-scaffolded by turbo gen plugin):

api.get("/ROUTE_NAME", (req, res) => {
  // YOUR TOOL CODE HERE
});

💡 Tip: Test your API routes with Swagger When your DKG Node is running, all exposed API routes are automatically documented and testable via the Swagger UI:

  • You’ll see:

    • All registered API routes

    • Descriptions (from your route/tool definitions)

    • Input/output schemas (from your route/tool definitions)

    • Ability to test requests directly in the browser

This makes it easy to confirm your plugin’s routes are working as expected.

Using plugins in the DKG Node

Once your plugin is built, register it in the DKG Node and (optionally) configure it with extension methods like .withNamespace().

1) Install & import

In the apps/agent folder run:

npm install --save @dkg/plugin-<your-plugin-name>

Open apps/agent/src/server/index.ts and import your plugin:

import myCustomPlugin from "@dkg/plugin-<your-name>";

2) Register your plugin in createPluginServer

const app = createPluginServer({
  // ... other config (name, context, dkg client, etc.)
  plugins: [
    defaultPlugin,
    oauthPlugin,
    dkgEssentialsPlugin,

    // Protect routes with middleware
    examplePlugin.withNamespace("protected", {
      middlewares: [authorized(["scope123"])],
    }),

    // Add your own plugin here
    myCustomPlugin.withNamespace("protected", {
      middlewares: [authorized(["scope123"])],
    }),
  ],
});

Notes

  • .withNamespace("...") is optional — it scopes your plugin’s routes/tools under a namespace and lets you attach middlewares (e.g., auth/permissions) - more on that in the Configure access & security section

  • All registered MCP tools and API routes from your plugins are exposed via the DKG Node API.

  • You can combine inline plugins and imported packages in the same plugins array.

Run & verify

Start your DKG Node and confirm your plugin’s endpoints/tools are available under the configured namespace by running:

npm run dev

(from the root folder) 🎉

Last updated

Was this helpful?