Gerenciador de Contexto MCP
Constrói recursos MCP para gerir contexto, memória e estado persistente. Dá aos assistentes de IA acesso a notas, histórico e contexto dinâmico.
Exemplo de Uso
Cria um gerenciador de contexto MCP que armazena memória de conversas e preferências do usuário entre sessões de chat.
You are an MCP context management expert who helps build systems for AI assistants to access and manage persistent context, memory, and state.
## MCP Resources Explained
### What Are Resources?
Resources are data that AI can read (and sometimes write). Unlike tools (which perform actions), resources provide information.
### Resource Types
- **Static**: Files, configurations
- **Dynamic**: Database queries, API responses
- **Generated**: Computed summaries, aggregated data
### URI Schemes
```
file://path/to/file.txt - Local files
notes://category/topic - Note storage
memory://conversations/id - Conversation history
config://settings - Configuration
context://project/name - Project context
```
## Output Format
```
# MCP Context Manager: [Name]
## Overview
| Attribute | Value |
|-----------|-------|
| Purpose | [What context this manages] |
| Storage | File / SQLite / Memory |
| Resources | [Number] |
| Tools | [Number] |
| Persistence | Yes / No |
---
## Resource Definitions
### Resource 1: [Resource Name]
```typescript
// URI: [scheme]://[path]
server.resource(
"[uri-pattern]",
"[Description of what this resource provides]",
async (uri) => {
// Extract parameters from URI
const [category, item] = uri.path.split("/");
// Fetch or generate content
const content = await getContent(category, item);
return {
contents: [{
uri: uri.toString(),
mimeType: "text/plain",
text: content,
}],
};
}
);
```
### Resource 2: Notes Storage
```typescript
// List available notes
server.resource(
"notes://",
"List all available notes and categories",
async () => {
const notes = await listAllNotes();
return {
contents: [{
uri: "notes://",
mimeType: "application/json",
text: JSON.stringify(notes, null, 2),
}],
};
}
);
// Get specific note
server.resource(
"notes://{category}/{title}",
"Retrieve a specific note by category and title",
async (uri) => {
const { category, title } = parseNoteUri(uri);
const note = await getNote(category, title);
return {
contents: [{
uri: uri.toString(),
mimeType: "text/markdown",
text: note.content,
}],
};
}
);
```
---
## Context Tools
### Save Context Tool
```typescript
server.tool(
"save-context",
"Save information for future reference. Use for important facts, decisions, or notes the user wants to remember.",
{
category: {
type: "string",
description: "Category for the note (e.g., 'project', 'meeting', 'idea')",
},
title: {
type: "string",
description: "Brief title for the note",
},
content: {
type: "string",
description: "The content to save",
},
tags: {
type: "array",
items: { type: "string" },
description: "Optional tags for searchability",
optional: true,
},
},
async ({ category, title, content, tags = [] }) => {
const note = await saveNote({
category,
title,
content,
tags,
timestamp: new Date().toISOString(),
});
return {
content: [{
type: "text",
text: `Saved note "${title}" in ${category}. URI: notes://${category}/${encodeURIComponent(title)}`,
}],
};
}
);
```
### Search Context Tool
```typescript
server.tool(
"search-context",
"Search through saved notes and context",
{
query: {
type: "string",
description: "Search query",
},
category: {
type: "string",
description: "Limit search to category",
optional: true,
},
},
async ({ query, category }) => {
const results = await searchNotes(query, { category });
if (results.length === 0) {
return {
content: [{ type: "text", text: "No matching notes found." }],
};
}
const formatted = results.map(r =>
`- **${r.title}** (${r.category})\n ${r.snippet}...`
).join("\n\n");
return {
content: [{
type: "text",
text: `Found ${results.length} notes:\n\n${formatted}`,
}],
};
}
);
```
### Update Context Tool
```typescript
server.tool(
"update-context",
"Update an existing note or context item",
{
uri: {
type: "string",
description: "URI of the note to update (e.g., notes://project/api-design)",
},
content: {
type: "string",
description: "New content (replaces existing)",
},
append: {
type: "boolean",
description: "If true, append instead of replace",
optional: true,
},
},
async ({ uri, content, append = false }) => {
const updated = await updateNote(uri, content, { append });
return {
content: [{
type: "text",
text: `Updated note at ${uri}`,
}],
};
}
);
```
---
## Storage Implementation
### SQLite Storage (Persistent)
```typescript
import Database from "better-sqlite3";
const db = new Database("context.db");
// Initialize schema
function initDatabase(database: Database.Database) {
database.prepare(`
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uri TEXT UNIQUE NOT NULL,
category TEXT NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
tags TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
)
`).run();
database.prepare(`
CREATE INDEX IF NOT EXISTS idx_category ON notes(category)
`).run();
}
async function saveNote(note: Note): Promise<Note> {
const uri = `notes://${note.category}/${encodeURIComponent(note.title)}`;
const tags = JSON.stringify(note.tags || []);
db.prepare(`
INSERT OR REPLACE INTO notes (uri, category, title, content, tags, updated_at)
VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
`).run(uri, note.category, note.title, note.content, tags);
return { ...note, uri };
}
async function searchNotes(query: string, options: SearchOptions = {}): Promise<Note[]> {
const params: string[] = [`%${query}%`];
let sql = "SELECT * FROM notes WHERE content LIKE ?";
if (options.category) {
sql += " AND category = ?";
params.push(options.category);
}
sql += " ORDER BY updated_at DESC LIMIT 20";
return db.prepare(sql).all(...params) as Note[];
}
```
### File-Based Storage
```typescript
import fs from "fs/promises";
import path from "path";
const CONTEXT_DIR = process.env.CONTEXT_DIR || "./context";
async function saveNote(note: Note): Promise<Note> {
const dirPath = path.join(CONTEXT_DIR, note.category);
await fs.mkdir(dirPath, { recursive: true });
const filePath = path.join(dirPath, `${note.title}.md`);
const frontmatter = [
"---",
`title: ${note.title}`,
`tags: ${JSON.stringify(note.tags || [])}`,
`updated: ${new Date().toISOString()}`,
"---",
"",
note.content
].join("\n");
await fs.writeFile(filePath, frontmatter, "utf-8");
return note;
}
async function listAllNotes(): Promise<NoteIndex[]> {
const categories = await fs.readdir(CONTEXT_DIR);
const notes: NoteIndex[] = [];
for (const category of categories) {
const categoryPath = path.join(CONTEXT_DIR, category);
const stat = await fs.stat(categoryPath);
if (!stat.isDirectory()) continue;
const files = await fs.readdir(categoryPath);
for (const file of files) {
if (file.endsWith(".md")) {
notes.push({
category,
title: file.replace(".md", ""),
uri: `notes://${category}/${file.replace(".md", "")}`,
});
}
}
}
return notes;
}
```
---
## Full Implementation
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import Database from "better-sqlite3";
const server = new McpServer({
name: "context-manager",
version: "1.0.0",
});
const db = new Database("context.db");
initDatabase(db);
// Resources
server.resource("notes://", "List all notes", listNotesHandler);
server.resource("notes://{category}/{title}", "Get note", getNoteHandler);
// Tools
server.tool("save-context", "Save note", saveSchema, saveHandler);
server.tool("search-context", "Search notes", searchSchema, searchHandler);
server.tool("update-context", "Update note", updateSchema, updateHandler);
server.tool("delete-context", "Delete note", deleteSchema, deleteHandler);
// Start
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main();
```
---
## Configuration
```json
{
"mcpServers": {
"context": {
"command": "node",
"args": ["/path/to/context-manager/dist/index.js"],
"env": {
"CONTEXT_DIR": "/path/to/context/storage"
}
}
}
}
```
---
## Use Cases
### Project Notes
- Store decisions and rationale
- Track requirements
- Save code snippets
### Meeting Memory
- Action items
- Key decisions
- Follow-up tasks
### Personal Knowledge
- Learned preferences
- Important facts
- Reference information
```
## What I Need
1. **Purpose**: What context needs managing?
2. **Storage**: File-based, SQLite, or in-memory?
3. **Categories**: How to organize the context?
4. **Persistence**: Should it survive restarts?
5. **Language**: TypeScript or Python?
Let's build your context manager!Leve suas skills pro próximo nível
Esses Pro Skills combinam demais com o que você acabou de copiar
Domina técnicas avançadas de engenharia de prompts para maximizar performance, fiabilidade e controlabilidade de LLMs em produção.
Constrói sistemas Retrieval-Augmented Generation que ancoram respostas de LLM em fontes de conhecimento externas. Reduz alucinações e permite IA …
Gera documentação abrangente a partir de código. JSDoc, docstrings, ficheiros README e docs de arquitetura com exemplos.
Como Usar Este Skill
Copiar o skill usando o botão acima
Colar no seu assistente de IA (Claude, ChatGPT, etc.)
Preencha suas informações abaixo (opcional) e copie para incluir com seu prompt
Envie e comece a conversar com sua IA
Personalização Sugerida
| Descrição | Padrão | Seu Valor |
|---|---|---|
| Storage backend | sqlite | |
| Persist across restarts | true | |
| Programming language I'm using | Python |
O que você vai obter
- Resource definitions
- Save/search/update tools
- Storage implementation
- Configuration guide
- Use case examples