MCP and Skills in AI Agents: Integrating External Knowledge Bases (continued)
published: ⏰ 8The previous article included an example of connecting a skill to work with an external knowledge base. But that’s not all you can do with MCPs and agents. There’s a more convenient way to manage behavior by defining your agents.
Introduction
While previously it was necessary to explicitly specify which skill to apply or rely on the LLM to determine it based on the task context, this time a special agent will be used. This agent will have predefined behavior, tasks, and actions it should perform. The main advantage of using an agent with predefined behavior is the ability to work within the specified rules unconditionally; that is, these are priority rules that will be applied to each request.
As an example, I’ll use OpenCode, which supports custom agents (https://opencode.ai/docs/agents). It has several built-in agents that can be selected directly in the console (plan, build), and several hidden ones. You can also create your own custom agents, which will be needed later.
Using an agent is again about integrating with an external knowledge base via an MCP server. In this case, as in the previous example, tekBlueprint.kbase will be used.
General scheme of interaction
This is somewhat similar to the previous scheme, but now the agent itself can contain or load the necessary skills.
AGENT.md is a description of the agent itself, the creation and description of which will be given below.
The data flow is again similar to the previous example, but with slight differences:
- At startup, the agent and its behavior (AGENT.md) + skills (SKILLS.md) are loaded.
- The user asks a question in chat with the agent (AI Agent).
- The agent analyzes the request, activates the skill (SKILLS.md), if any, and understands that it needs to access the knowledge base.
- Through the client (MCP Client), the agent sends a request to the server (MCP Server) (for example, tools/call for searching or resources/read for reading).
- The server (MCP Server) receives the request, authenticates it, and converts it into a request understandable by the internal API (Internal API).
- The Internal API processes the request or requests data from the database (Databases) via REST, gRPC, or a direct SQL/vector query.
- The knowledge base server (Databases) finds relevant documents/facts and returns them back along the Internal API → MCP Server chain.
- The server (MCP Server) packages the result in MCP format and passes it back to the agent (AI Agent).
- The agent (AI Agent) enriches its context with the received data and generates the final response to the user.
Working with an Agent Using MCP
As a demonstration example, I’ll use the task of creating the ubiquitous ToDo manager in React with a PrimeReact UI. But before that, a few preparatory steps will be required:
- Create an agent in OpenCode with instructions for working with MCP.
- Create a
PrimeReact Frontend Developeragent in the knowledge base, on whose behalf we’ll generate the application.
Creating a new agent
AGENT.md is a simple text file with frontmatter, a brief description of the agent, and some parameters. If you’re using OpenCode, creating it is quite simple: just run the command and answer the questions.
opencode agent createIt’s best to formulate the agent description in sufficient detail. Based on this, OpenCode will use LLM to generate a full agent description, which will be used later.
Here’s a short description example to help you understand what this looks like when using an external MCP.
---
description: >-
Use this agent when a user requests an action or task and specifies a
particular role (e.g., "Can you help me with coding as the code reviewer?",
"Execute this as the project planner", "Handle this like a devops engineer
would"). The agent must fetch role-specific instructions from the external
knowledge base using the tB.kbase skill, then follow those retrieved
to complete the requested action. This is appropriate when the
user's request implicitly requires fetching how that role operates, what their
responsibilities are, or what specific steps they would take.
**Carefully read your instructions.**
mode: all
---
You are a role-based instruction follower agent. Your core function is to fetch role-specific instructions
from an external knowledge base and apply them to complete user requests.
## Your Workflow
1. **Identify the Role**: When a user requests an action and specifies a role (explicitly or implicitly),
extract the role from their request. Examples of role references to include: "role: [role]", "as a [role]",
"like a [role]", "[role]-style", or simply mentioning a role title.
2. **Fetch Instructions**: Always use the `tB.kbase` skill to retrieve the agent/role description from the
external knowledge base by using `search-agents` and `get-agent-by-uri`. The knowledge base contains
detailed instructions, responsibilities, and methodologies for each role.
3. **Follow Retrieved Instructions**: Apply the fetched instructions to complete the user's requested action.
This may involve:
- Following specific decision-making frameworks outlined in the role description
- Applying the role's code standards and patterns
- Executing methodologies as prescribed by that role
- Making judgments consistent with the role's established practices
4. **Execute the Task**: Complete the user's request using the approach and standards defined in the retrieved
role instructions.
## Important Guidelines
- Always **fetch the role instructions** first before responding or taking action
- Do not assume how a role operates - retrieve their explicit instructions from the knowledge base
- If the user request is ambiguous about which role, ask for clarification
- If the knowledge base does not contain instructions for the specified role, inform the user and ask for
an alternative role or confirmation to proceed with general best practices
- Maintain fidelity to the fetched role instructions - do not deviate from their prescribed methodologies
unless the user explicitly requests otherwise
## Output Format
When you complete the task, provide your response in the format appropriate to the role whose instructions you
followed, as specified in the retrieved description.Most of the description will be generated, if something in the description is incorrect, you can correct it manually.
Knowledge Base
In the example above, this is a general-purpose agent that will load instructions from the knowledge base for the requested role. This isn’t ideal, and a proper approach would involve loading instructions directly into the agent, meaning instead of loading a Markdown file from the file system, the description should be retrieved directly from an external service. But I think this will suffice for demonstrating the work and approach.
For this example, I created a simple agent in the knowledge base for developing web applications using PrimeReact, which contains:
- Work instructions.
- Skills and experience.
- Checklists.
- Example artifacts.
- Activation rules.

This agent will be loaded at the start of a task if the user requests to act in any role while completing the task.
Application Generation
Below is the generation process itself. It shows that the required instructions were followed and, as a result, a project was generated with the required structure and using PrimeReact components.
Execution log
⚙ kbase_get-spec-by-uri [arg0=kb://ai-agent/staff-it:webdev-primereact:1.0]
Thinking: Now I have the PrimeReact developer instructions. Let me also get the related library specs for reference and then implement the app. Let me check what libraries/skills are referenced to understand the full tooling:
- React 19
- PrimeReact 10
- PrimeFlex 3
- PrimeIcons 7
- TypeScript
- Vite
- Vite
- Biome (linting)
The instructions say:
- Use functional components with TypeScript
- Keep components under 300 lines
- Use TypeScript interfaces
- Prefer PrimeReact controls over creating new ones
- Organize by domain
- Extract reusable logic into hooks
- Use hooks for state management
- Import PrimeReact styles properly
- Biome (linting)
The instructions say:
- Use functional components with TypeScript
- Keep components under 300 lines
- Use TypeScript interfaces
- Prefer PrimeReact controls over creating new ones
- Organize by domain
- Extract reusable logic into hooks
- Use hooks for state management
- Import PrimeReact styles properly
...
Project Structure
todo/
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
└── src/
├── main.tsx # Entry point — imports PrimeReact themes & styles
├── App.tsx # Root layout: Panel, ProgressBar, Toast wiring
├── features/
│ └── todo/
│ ├── useTodos.ts # Custom hook with localStorage persistence & filter logic
│ └── TodoList.tsx # Filtered list with filter tabs, stats, empty state
└── shared/
└── ui/
├── TodoInput.tsx # Add-todo form using InputText + Button
└── TodoItem.tsx # Individual item: Checkbox, text, Delete button
PrimeReact Components Used
Panel — main card with toggle functionality
Button — add button, filter tabs, delete & clear-completed (with severity)
InputText — todo input field
Checkbox — per-item completion toggle
Message — empty-state messaging
ProgressBar — completion progress bar
Toast — notification popupsThe result is this mess, and it even works without errors.


Potential Issues
As I mentioned above, the knowledge base isn’t used optimally here, since the agent is loaded from within the agent (a dream within a dream). Ideally, it’s better to write a specialized agent that would immediately receive instructions from the knowledge base and know how to apply them optimally, loading additional information as needed. This means that instead of OpenCode, a tekblueprint.agent is launched, which is work with tekBlueprint.kbase.
Here, too, it may be necessary to save token generation: you can use TOONS in some places, and use Markdown instead of JSON. There’s also a small hack using specific response generation rules for LLM, which, according to some estimates, can reduce the number of tokens by 46%. One example is caveman skills.
LLM doesn’t always follow instructions, especially at low quanta. If explicitly stated, it reverts to normal generation.
Conclusion
If you use agents like Claude Code, OpenCode, or Qwen Code, you can create specialized agents that rely on updated information from a shared knowledge base. This significantly simplifies maintaining a development or analytics environment. Plus, this approach fits well with agent orchestration solutions like Agent Swarm.