knowledge-os-mcp-server 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- knowledge_os_mcp_server-0.3.1/LICENSE +21 -0
- knowledge_os_mcp_server-0.3.1/PKG-INFO +292 -0
- knowledge_os_mcp_server-0.3.1/README.md +260 -0
- knowledge_os_mcp_server-0.3.1/pyproject.toml +87 -0
- knowledge_os_mcp_server-0.3.1/setup.cfg +4 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/__init__.py +3 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/__init__.py +0 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/deps.py +13 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/main.py +112 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/__init__.py +0 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/_common.py +41 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/connection.py +115 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/item.py +236 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/project.py +128 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/relation.py +24 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/tag.py +35 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/routes/workspace.py +118 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/schemas/__init__.py +0 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/schemas/requests.py +42 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/schemas/responses.py +128 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/css/app.css +532 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/css/tokens.css +134 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/index.html +1357 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/api.js +66 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/main.js +47 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/markdown.js +70 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/router.js +68 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/shortcuts.js +60 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/store.js +417 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/theme.js +9 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/util.js +181 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/connections.js +210 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/editor.js +223 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/graph.js +406 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/item.js +270 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/listing.js +233 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/palette.js +167 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/project.js +34 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/sidebar.js +13 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/subject.js +36 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/tags.js +93 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/js/views/workspace.js +29 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/alpine.esm.js +11 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/d3-drag.esm.js +7 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/d3-force.esm.js +7 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/d3-selection.esm.js +7 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/d3-zoom.esm.js +7 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/highlight.esm.js +1242 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/marked.esm.js +2188 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/api/static/vendor/purify.esm.js +1345 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/cli.py +543 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/config.py +224 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/exceptions.py +25 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/main.py +230 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/mcp/INSTRUCTIONS.md +68 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/mcp/__init__.py +1 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/mcp/instructions.py +80 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/mcp/tools.py +756 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/model.py +345 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/__init__.py +6 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/item_schemas.py +134 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/project_schemas.py +50 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/relation_schemas.py +27 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/tag_schemas.py +22 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/schemas/workspace_schemas.py +26 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/__init__.py +1 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/_common.py +18 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/brain.py +869 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/connection_service.py +316 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/context_service.py +272 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/gh_cli.py +135 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/git_repo_service.py +482 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/graph.py +200 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/item_file.py +414 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/item_service.py +763 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/migrate.py +167 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/project_service.py +198 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/relation_service.py +183 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/repo_service.py +233 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/secret_guard.py +56 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/secret_run.py +185 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/secret_service.py +149 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/subject_service.py +183 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/tag_service.py +180 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/vault.py +125 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/services/workspace_service.py +209 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/storage/__init__.py +1 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/storage/access.py +179 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/storage/files.py +302 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/storage/local_state.py +275 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os/storage/search.py +486 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/PKG-INFO +292 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/SOURCES.txt +144 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/dependency_links.txt +1 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/entry_points.txt +2 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/requires.txt +20 -0
- knowledge_os_mcp_server-0.3.1/src/knowledge_os_mcp_server.egg-info/top_level.txt +1 -0
- knowledge_os_mcp_server-0.3.1/tests/test_brain_context.py +55 -0
- knowledge_os_mcp_server-0.3.1/tests/test_brain_search.py +96 -0
- knowledge_os_mcp_server-0.3.1/tests/test_brain_snapshot.py +70 -0
- knowledge_os_mcp_server-0.3.1/tests/test_brain_write.py +158 -0
- knowledge_os_mcp_server-0.3.1/tests/test_caminhos_seguros.py +213 -0
- knowledge_os_mcp_server-0.3.1/tests/test_cli_brain.py +362 -0
- knowledge_os_mcp_server-0.3.1/tests/test_cli_sync_connection.py +88 -0
- knowledge_os_mcp_server-0.3.1/tests/test_cli_ui.py +197 -0
- knowledge_os_mcp_server-0.3.1/tests/test_concorrencia.py +133 -0
- knowledge_os_mcp_server-0.3.1/tests/test_config.py +189 -0
- knowledge_os_mcp_server-0.3.1/tests/test_connections.py +267 -0
- knowledge_os_mcp_server-0.3.1/tests/test_contrato.py +139 -0
- knowledge_os_mcp_server-0.3.1/tests/test_default_inacessivel.py +78 -0
- knowledge_os_mcp_server-0.3.1/tests/test_delete_feedback.py +101 -0
- knowledge_os_mcp_server-0.3.1/tests/test_gh_cli.py +98 -0
- knowledge_os_mcp_server-0.3.1/tests/test_git_repo_service.py +391 -0
- knowledge_os_mcp_server-0.3.1/tests/test_graph.py +150 -0
- knowledge_os_mcp_server-0.3.1/tests/test_home.py +96 -0
- knowledge_os_mcp_server-0.3.1/tests/test_item_file.py +223 -0
- knowledge_os_mcp_server-0.3.1/tests/test_item_search.py +149 -0
- knowledge_os_mcp_server-0.3.1/tests/test_item_service_git_publish.py +332 -0
- knowledge_os_mcp_server-0.3.1/tests/test_item_tools.py +45 -0
- knowledge_os_mcp_server-0.3.1/tests/test_items.py +25 -0
- knowledge_os_mcp_server-0.3.1/tests/test_items_v2.py +206 -0
- knowledge_os_mcp_server-0.3.1/tests/test_main.py +43 -0
- knowledge_os_mcp_server-0.3.1/tests/test_migrate.py +100 -0
- knowledge_os_mcp_server-0.3.1/tests/test_model.py +138 -0
- knowledge_os_mcp_server-0.3.1/tests/test_modo_pr.py +137 -0
- knowledge_os_mcp_server-0.3.1/tests/test_organization.py +133 -0
- knowledge_os_mcp_server-0.3.1/tests/test_pack.py +154 -0
- knowledge_os_mcp_server-0.3.1/tests/test_relations.py +44 -0
- knowledge_os_mcp_server-0.3.1/tests/test_relations_v2.py +179 -0
- knowledge_os_mcp_server-0.3.1/tests/test_report.py +79 -0
- knowledge_os_mcp_server-0.3.1/tests/test_revisao_seguranca.py +327 -0
- knowledge_os_mcp_server-0.3.1/tests/test_schemas_tools.py +18 -0
- knowledge_os_mcp_server-0.3.1/tests/test_scope.py +67 -0
- knowledge_os_mcp_server-0.3.1/tests/test_search_service.py +184 -0
- knowledge_os_mcp_server-0.3.1/tests/test_search_v2.py +255 -0
- knowledge_os_mcp_server-0.3.1/tests/test_segredos.py +511 -0
- knowledge_os_mcp_server-0.3.1/tests/test_services.py +270 -0
- knowledge_os_mcp_server-0.3.1/tests/test_signals.py +80 -0
- knowledge_os_mcp_server-0.3.1/tests/test_static_v2.py +323 -0
- knowledge_os_mcp_server-0.3.1/tests/test_stdio.py +164 -0
- knowledge_os_mcp_server-0.3.1/tests/test_sync_trava.py +50 -0
- knowledge_os_mcp_server-0.3.1/tests/test_tags.py +42 -0
- knowledge_os_mcp_server-0.3.1/tests/test_tags_v2.py +140 -0
- knowledge_os_mcp_server-0.3.1/tests/test_tools_mcp.py +310 -0
- knowledge_os_mcp_server-0.3.1/tests/test_ui_resource.py +37 -0
- knowledge_os_mcp_server-0.3.1/tests/test_workspace_level.py +33 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kauã Leal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: knowledge-os-mcp-server
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: MCP server: local knowledge base for Claude agents
|
|
5
|
+
Author-email: Kauã Leal <kaualealdev@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/KauaLealz/knowledge-os-mcp-server
|
|
8
|
+
Project-URL: Issues, https://github.com/KauaLealz/knowledge-os-mcp-server/issues
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: mcp<3,>=2
|
|
13
|
+
Requires-Dist: fastmcp<5,>=4
|
|
14
|
+
Requires-Dist: pydantic<3,>=2.0
|
|
15
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
16
|
+
Requires-Dist: fastapi>=0.110.0
|
|
17
|
+
Requires-Dist: uvicorn>=0.27.0
|
|
18
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
19
|
+
Requires-Dist: cryptography>=42
|
|
20
|
+
Requires-Dist: keyring>=24
|
|
21
|
+
Requires-Dist: pyyaml<7,>=6.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
26
|
+
Requires-Dist: httpx>=0.27.0; extra == "dev"
|
|
27
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
28
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
29
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
30
|
+
Requires-Dist: types-PyYAML>=6.0; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# Knowledge OS — segundo cérebro para agentes
|
|
34
|
+
|
|
35
|
+
Servidor MCP local que guarda o conhecimento durável do seu trabalho — regras, decisões e o
|
|
36
|
+
porquê, como fazer, contexto e specs — e o devolve aos agentes com pouco custo de contexto. É a
|
|
37
|
+
memória obrigatória do [Plumb](https://github.com/KauaLealz/plumb-harness): o hook de início de
|
|
38
|
+
sessão injeta o pacote do projeto e o fechamento de cada mudança grava o que valeu, numa chamada.
|
|
39
|
+
|
|
40
|
+
- **Só arquivos, num repositório git seu:** cada conexão é uma pasta (repositório git) que você
|
|
41
|
+
escolhe; cada item é um arquivo Markdown com frontmatter YAML, e cada escrita é um commit. O
|
|
42
|
+
que está na pasta é a verdade; não há banco nem índice para reconstruir.
|
|
43
|
+
- **Alcance pela hierarquia:** o item vale onde mora — workspace, project ou subject — e abaixo;
|
|
44
|
+
a busca, o pacote e o grafo respeitam isso, sem campo de scope.
|
|
45
|
+
- **Busca explicada, sem embeddings, que acerta em PT-BR:** em memória, sem acento, por radical e
|
|
46
|
+
prefixo, entende identificadores (`ItemService.saveBatch` acha "service" e "batch") e diz por
|
|
47
|
+
que cada resultado veio (`matched_in`, `snippet`, `where`).
|
|
48
|
+
- **Escrita em lote e idempotente:** `item_save` grava até 20 itens numa publicação; a `key`
|
|
49
|
+
estável regrava sem duplicar.
|
|
50
|
+
- **Corrige-se com o uso:** item errado ou velho, o agente ajusta ou remove (é git, dá para
|
|
51
|
+
voltar) — sem um sistema de feedback à parte.
|
|
52
|
+
- **Segredos sem passar pelo modelo:** o agente cria o segredo vazio, você preenche na UI local e
|
|
53
|
+
ele é usado por `knowledge-mcp run`, que entrega o valor só ao processo filho.
|
|
54
|
+
- **Seguro:** recusa segredos em itens comuns; operações destrutivas pedem confirmação e mostram
|
|
55
|
+
uma prévia antes.
|
|
56
|
+
|
|
57
|
+
## Como começar
|
|
58
|
+
|
|
59
|
+
1. **Instalar**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv tool install "git+https://github.com/KauaLealz/knowledge-os-mcp-server" # comando `knowledge-mcp`
|
|
63
|
+
knowledge-mcp --version
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Para desenvolver, clone e instale editável: `uv tool install --editable <pasta-do-clone>`.
|
|
67
|
+
|
|
68
|
+
2. **Registrar no cliente MCP.** O instalador do Plumb (`npx plumb-harness install`) registra o
|
|
69
|
+
servidor no Claude Code e no Cursor, com o hook de início de sessão. À mão:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
claude mcp add --scope user knowledge-os -e LOG_LEVEL=WARNING -- knowledge-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
// ~/.cursor/mcp.json
|
|
77
|
+
{ "mcpServers": { "knowledge-os": { "command": "knowledge-mcp",
|
|
78
|
+
"env": { "LOG_LEVEL": "WARNING" } } } }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
3. **Criar a primeira conexão, pelo MCP.** Nada é criado sozinho: até existir uma conexão, toda
|
|
82
|
+
operação responde "Nenhuma conexão configurada. Crie uma com connection_create(name, path[,
|
|
83
|
+
remote_url])." Peça ao agente (ou chame a ferramenta):
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
connection_create(name="pessoal", path="C:\\caminho\\da\\pasta")
|
|
87
|
+
connection_create(name="empresa", path="/home/eu/empresa-knowledge", remote_url="git@github.com:org/knowledge.git")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`path` é uma pasta absoluta: se já for um repositório git, é usada como está; senão vira um
|
|
91
|
+
(`git init`, preservando o que já tiver dentro). Com `remote_url`, a pasta é o destino do
|
|
92
|
+
clone e cada escrita é empurrada para lá. A primeira conexão vira a padrão. A UI
|
|
93
|
+
(`knowledge-mcp ui`) lista, edita, testa, define a padrão e apaga conexões, mas não cria.
|
|
94
|
+
|
|
95
|
+
4. **Ligar o repositório do projeto.** Dentro do repositório em que você trabalha, rode
|
|
96
|
+
`/plumb-setup` (no Plumb) ou `knowledge-mcp link --repo .` — ou peça ao agente
|
|
97
|
+
`repo(action="link", repo=".")`. O project é o repositório; o workspace, o do dono do remote.
|
|
98
|
+
|
|
99
|
+
Se a pasta já tem arquivos de uma versão anterior do Knowledge OS, nada precisa ser migrado: a
|
|
100
|
+
leitura traduz o formato antigo e a próxima gravação de cada item já sai no formato atual.
|
|
101
|
+
|
|
102
|
+
## Onde ficam os dados
|
|
103
|
+
|
|
104
|
+
- **Na pasta de cada conexão** (o repositório git que você escolheu): todos os itens, como
|
|
105
|
+
`<workspace>/<project>/<key>.md`, os `.knowledge.yaml` (descrição de workspaces, projects e
|
|
106
|
+
subjects, e o vocabulário de tags) e os valores de segredos cifrados em `.secrets/`
|
|
107
|
+
(fora do git: nunca entram nele).
|
|
108
|
+
- **No home** (`KNOWLEDGE_OS_HOME`, padrão `~/.knowledge-os`), só estado desta máquina:
|
|
109
|
+
`connections.json` (as conexões e a padrão), `repos.json` (repositório local → conexão,
|
|
110
|
+
workspace e project), `usage/<conexão>.json` (contadores de uso por item),
|
|
111
|
+
`searches/<conexão>.jsonl` (buscas que voltaram vazias), `locks/` (travas de escrita entre
|
|
112
|
+
processos) e a fila offline `pending.jsonl`. Nenhum item fica aí.
|
|
113
|
+
|
|
114
|
+
Fazer backup ou levar para outra máquina é o mesmo que com qualquer repositório git: commit,
|
|
115
|
+
push, clone.
|
|
116
|
+
|
|
117
|
+
## Modelo
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Workspace = contexto de trabalho ex.: Polara (empresa), Pessoal
|
|
121
|
+
└── Project = um repositório ex.: app, synapse
|
|
122
|
+
└── Subject (opcional) conceito dentro do project, ex.: pagamentos
|
|
123
|
+
└── Item: type · key · title · summary · content · tags · links
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
O item **mora** num nível da hierarquia (workspace, project ou subject) e **vale onde mora e
|
|
127
|
+
abaixo** — não há campo de scope. Cinco tipos; a nuance e o ciclo vão em **tags** (a taxonomia
|
|
128
|
+
abaixo é a mesma que o servidor envia ao agente nas instruções):
|
|
129
|
+
|
|
130
|
+
| Tipo | Guarda |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `rule` | o que deve ser seguido + o porquê (convenção, decisão, regra de negócio) |
|
|
133
|
+
| `howto` | passos repetíveis ou diagnóstico (sintoma/causa/solução) |
|
|
134
|
+
| `context` | pano de fundo: produto, mapa, stack, glossário, ambiente |
|
|
135
|
+
| `work` | o trabalho: plano/spec + decisões (o porquê durável); ciclo por tag |
|
|
136
|
+
| `secret` | referência a um segredo (sem o valor) |
|
|
137
|
+
|
|
138
|
+
| Campo | Valores |
|
|
139
|
+
|---|---|
|
|
140
|
+
| tags de ciclo | `draft`, `active`, `done`, `archived` |
|
|
141
|
+
| tags de nuance (base, extensível) | `decision`, `troubleshoot`, `security`, `pattern`, `map`, `glossary`, `product`, `environment`, `business`, `process` |
|
|
142
|
+
| link item→item (`rel`) | `depends_on`, `relates_to` |
|
|
143
|
+
|
|
144
|
+
Key: `<tipo>/<nome>` (nome em minúsculas com `-`); fora do padrão grava com aviso, e a key de um item existente nunca muda.
|
|
145
|
+
|
|
146
|
+
Alcance: o item vale onde mora na hierarquia (workspace → project → subject) e abaixo. Não há `scope`, `status`, `subtype`, `origin` nem expiração — a nuance e o ciclo vão em `tags`.
|
|
147
|
+
|
|
148
|
+
`links` (unificado): `{item, rel}` liga a outro item; `{url[, title]}` a uma URL; `{path}` a um arquivo/glob do repositório.
|
|
149
|
+
|
|
150
|
+
### Alcance pela hierarquia
|
|
151
|
+
|
|
152
|
+
Um item no nível do **workspace** vale em todos os projects dele; no **project**, só nele; no
|
|
153
|
+
**subject**, só nele. Na busca, quanto mais perto do project do repositório, maior o peso; o que
|
|
154
|
+
está fora do alcance é invisível. `item_get(ids=[...])` e `item_search(everywhere=True)` leem a
|
|
155
|
+
conexão inteira. Um segredo vale pelo mesmo alcance: para usá-lo fora do seu project, guarde-o no
|
|
156
|
+
nível do workspace.
|
|
157
|
+
|
|
158
|
+
### Ciclo de vida
|
|
159
|
+
|
|
160
|
+
Sem aprovação: o que o agente grava já vale. Para corrigir, regrave pela mesma `key`; para
|
|
161
|
+
aposentar, a tag `archived`. Itens com a tag `archived` saem da busca e do contexto. O servidor
|
|
162
|
+
nunca apaga sozinho: `item_delete` sem chaves lista candidatos (arquivados ou nunca abertos há
|
|
163
|
+
muito tempo) e só remove com `confirm=True`.
|
|
164
|
+
|
|
165
|
+
## Ferramentas (31)
|
|
166
|
+
|
|
167
|
+
| Ferramenta | Faz |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `connection_create` · `connection_list` · `connection_delete` | cria (a única forma de criar), lista ou tira do cadastro uma conexão — apagar não mexe na pasta |
|
|
170
|
+
| `workspace_list` · `workspace_create` · `workspace_update` · `workspace_merge` · `workspace_delete` | organização dos workspaces; `create`/`update` aceitam `description` |
|
|
171
|
+
| `project_list` · `project_create` · `project_update` · `project_merge` · `project_delete` | o mesmo, por workspace (a lista traz os subjects) |
|
|
172
|
+
| `subject_list` · `subject_create` · `subject_update` · `subject_merge` · `subject_delete` | o mesmo, por project |
|
|
173
|
+
| `repo` | `action="link"`, `"list"`, `"unlink"` ou `"sync"`: liga o repositório a um workspace/project, ou puxa o que mudou no remote |
|
|
174
|
+
| `item_search` | busca explicada pela hierarquia, até 5 consultas por chamada, com `paths`, `types` e `tags` |
|
|
175
|
+
| `item_get` | itens completos por keys ou ids, vários de uma vez |
|
|
176
|
+
| `item_save` | cria, atualiza, regrava por `key`, move; até 20 itens, atômico |
|
|
177
|
+
| `item_delete` | candidatos à limpeza, prévia e remoção com `confirm=True` |
|
|
178
|
+
| `item_graph` | vizinhança por links item↔item, até 3 saltos |
|
|
179
|
+
| `relation_create` · `relation_delete` | links `depends_on`/`relates_to` em lote entre itens |
|
|
180
|
+
| `tag_list` · `tag_create` · `tag_update` · `tag_delete` | tags gerenciadas: contagem, renomear/mesclar, prévia ao apagar |
|
|
181
|
+
| `health_check` | versão, conexões, arquivos que não leram e `gh` autenticado |
|
|
182
|
+
|
|
183
|
+
Todas aceitam `connection_id` opcional, menos `connection_*` e `health_check`. Guia por tarefa,
|
|
184
|
+
com exemplos: [docs/MCP_USAGE.md](docs/MCP_USAGE.md).
|
|
185
|
+
|
|
186
|
+
## Conexões: cada uma é um repositório git
|
|
187
|
+
|
|
188
|
+
Cada item não secreto vira um arquivo Markdown com frontmatter YAML na pasta da conexão. A
|
|
189
|
+
leitura é direta dos arquivos (com um cache em memória por arquivo, invalidado por data e
|
|
190
|
+
tamanho), então editar, apagar ou puxar arquivos por fora também vale. Um arquivo que não lê não
|
|
191
|
+
derruba nada: aparece em `parse_errors` do `health_check`.
|
|
192
|
+
|
|
193
|
+
`review_mode`, por conexão:
|
|
194
|
+
|
|
195
|
+
- `direct` (padrão): as escritas comitam direto na branch principal (com push, se houver
|
|
196
|
+
`remote_url`).
|
|
197
|
+
- `pr`: a mesma gravação vai para uma branch nova e abre um Pull Request (ou uma Issue, se o
|
|
198
|
+
token não tiver permissão de push); a resposta traz `pending_review`/`pr_url` (ou
|
|
199
|
+
`issue_opened`/`issue_url`) em vez do resultado de sempre — a mudança aparece depois que o PR
|
|
200
|
+
for mergeado e alguém rodar `repo(action="sync")`.
|
|
201
|
+
|
|
202
|
+
## CLI
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
knowledge-mcp # servidor MCP (stdio)
|
|
206
|
+
knowledge-mcp context --repo . --paths src/payments/Charge.java --budget 1500
|
|
207
|
+
knowledge-mcp context --hook claude|cursor # hook de início de sessão (lê o JSON no stdin)
|
|
208
|
+
knowledge-mcp link --repo . # project = repo; workspace = o do dono
|
|
209
|
+
knowledge-mcp recent --since 2026-10-01 --json # o que mudou (usado pela daily)
|
|
210
|
+
knowledge-mcp report --json # o que revisar no cérebro (usado pelo dream)
|
|
211
|
+
knowledge-mcp pending --repo . # grava a fila offline (~/.knowledge-os/pending.jsonl)
|
|
212
|
+
knowledge-mcp ui [--port 8765] # UI web local (127.0.0.1; já sobe com o MCP)
|
|
213
|
+
knowledge-mcp run --env NPM_TOKEN=secret/npm-token -- npm publish # segredo só no filho
|
|
214
|
+
knowledge-mcp --version
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Os subcomandos do cérebro não carregam o servidor MCP: o hook responde em ~1 s.
|
|
218
|
+
|
|
219
|
+
**Pacote de contexto** (`context`): pelo mesmo alcance da busca, nesta ordem — Em foco (o que
|
|
220
|
+
casa `--paths`/`--query`, com o começo do `content`), Segurança (tag `security`), Regras,
|
|
221
|
+
Contexto, Como fazer (só títulos), Trabalho ativo (`work`), Segredos (estado e como usar) e
|
|
222
|
+
Regras por arquivo (as com um link `{path}` que casa). Item de fora do project do repositório
|
|
223
|
+
leva de onde vem (`[<workspace>]`). Respeita o orçamento em tokens e lista o que ficou de fora.
|
|
224
|
+
Sem conexão, devolve o exemplo de `connection_create`; o hook nunca derruba a sessão.
|
|
225
|
+
|
|
226
|
+
**Relatório** (`report --json`): `never_opened_60d`, `archived` (candidatos a remover),
|
|
227
|
+
`empty_searches` (as buscas que voltaram vazias, com contagem) e `tags_unused`, cada lista com
|
|
228
|
+
`key`, `where` e o motivo.
|
|
229
|
+
|
|
230
|
+
## UI
|
|
231
|
+
|
|
232
|
+
`knowledge-mcp ui` (ou o servidor MCP, que já a sobe) abre uma UI local em
|
|
233
|
+
`http://127.0.0.1:8765`. Mostra os itens com tipo e tags, `links` e as ligações do item em grafo;
|
|
234
|
+
as tags com contagem; a organização em workspaces, projects e subjects; e as conexões, com o
|
|
235
|
+
caminho da pasta.
|
|
236
|
+
É também onde você preenche o valor de um segredo. Só escuta em `127.0.0.1`.
|
|
237
|
+
|
|
238
|
+
## Segredos
|
|
239
|
+
|
|
240
|
+
Token, senha ou chave de API viram um item `secret` (key `secret/<nome>`), no mesmo esquema do
|
|
241
|
+
resto: no project do repositório, ou num nível mais alto da hierarquia para compartilhar. O fluxo:
|
|
242
|
+
|
|
243
|
+
1. O agente grava o item **sem valor** (`item_save` recusa qualquer campo de valor) e a resposta
|
|
244
|
+
traz `fill_url`, o link da UI local direto no item.
|
|
245
|
+
2. Você abre o link e cola o valor num campo de senha. Ele é cifrado (Fernet) e guardado à parte,
|
|
246
|
+
em `<pasta-da-conexão>/.secrets/<item_id>.enc` (fora do git); nenhuma ferramenta, rota,
|
|
247
|
+
busca ou contexto o devolve — só `has_value`. Na UI dá para substituir ou apagar; não existe
|
|
248
|
+
"revelar".
|
|
249
|
+
3. O agente usa: `knowledge-mcp run --env VAR=secret/<nome> [--stdin secret/<nome>] -- <comando>`.
|
|
250
|
+
O valor vai só para o ambiente (ou stdin) do filho, que roda sem shell e sem a chave mestra;
|
|
251
|
+
a saída volta com o valor e as codificações comuns (base64, URL) trocados por `***`. A key é
|
|
252
|
+
procurada pelo mesmo alcance da busca. A redação cobre o valor exato, base64 (inclusive
|
|
253
|
+
dentro de `Basic user:token`), URL, JSON escapado, as codepages do Windows e UTF-16, e cada
|
|
254
|
+
linha de um valor de várias linhas.
|
|
255
|
+
|
|
256
|
+
A chave mestra é aleatória e fica no keyring do sistema (no Windows, o Gerenciador de
|
|
257
|
+
Credenciais). `KNOWLEDGE_OS_VAULT_KEY` existe só para CI e máquinas sem keyring — nunca a
|
|
258
|
+
ponha na config do MCP (`.mcp.json`) nem no ambiente do agente: quem a lê, com a pasta
|
|
259
|
+
`.secrets/`, abre todos os valores. Os arquivos `.enc` guardam só texto cifrado, cada valor
|
|
260
|
+
amarrado ao seu item. Se a chave some depois de criada, o servidor dá erro em vez de gerar outra
|
|
261
|
+
por cima.
|
|
262
|
+
|
|
263
|
+
No Windows, o `run` acha o comando só pelo PATH (nunca pela pasta do projeto, onde um `gh.cmd`
|
|
264
|
+
plantado receberia o token). Comandos `.cmd`/`.bat` (npm, az...) rodam pelo `cmd.exe`: o `run`
|
|
265
|
+
recusa argumentos com `" % & | < > ^ !` nesses casos. Valores com menos de 4 caracteres são
|
|
266
|
+
recusados (não daria para escondê-los na saída).
|
|
267
|
+
|
|
268
|
+
**Modelo de ameaça.** Protege o valor do contexto do modelo, do histórico das conversas, dos
|
|
269
|
+
itens e do repositório git. **Não** protege contra: um agente ou comando feito para vazar (quem
|
|
270
|
+
roda `knowledge-mcp run` pode escrever um filho que imprime o valor transformado de um jeito que
|
|
271
|
+
a redação não reconhece); malware rodando com o seu usuário (lê o keyring e chama a UI local); o
|
|
272
|
+
próprio comando gravar o valor em log ou arquivo. Segredo nunca expira sozinho.
|
|
273
|
+
|
|
274
|
+
Conteúdo com cara de segredo (chaves de nuvem, tokens, chaves privadas, `password=...`,
|
|
275
|
+
URLs com senha) em itens comuns é recusado sem eco do valor (a mensagem ensina o fluxo de
|
|
276
|
+
segredos acima).
|
|
277
|
+
|
|
278
|
+
## Desenvolvimento
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
uv pip install -e ".[dev]"
|
|
282
|
+
pytest -q # inclusive ponta a ponta via stdio
|
|
283
|
+
ruff check src tests
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Arquitetura: [docs/ARQUITETURA.md](docs/ARQUITETURA.md). O contrato da v2 está em
|
|
287
|
+
[docs/V2_MVP.md](docs/V2_MVP.md). Mudanças são conduzidas pelo Plumb (o plano de cada mudança
|
|
288
|
+
fica guardado no próprio cérebro).
|
|
289
|
+
|
|
290
|
+
## Licença
|
|
291
|
+
|
|
292
|
+
MIT
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Knowledge OS — segundo cérebro para agentes
|
|
2
|
+
|
|
3
|
+
Servidor MCP local que guarda o conhecimento durável do seu trabalho — regras, decisões e o
|
|
4
|
+
porquê, como fazer, contexto e specs — e o devolve aos agentes com pouco custo de contexto. É a
|
|
5
|
+
memória obrigatória do [Plumb](https://github.com/KauaLealz/plumb-harness): o hook de início de
|
|
6
|
+
sessão injeta o pacote do projeto e o fechamento de cada mudança grava o que valeu, numa chamada.
|
|
7
|
+
|
|
8
|
+
- **Só arquivos, num repositório git seu:** cada conexão é uma pasta (repositório git) que você
|
|
9
|
+
escolhe; cada item é um arquivo Markdown com frontmatter YAML, e cada escrita é um commit. O
|
|
10
|
+
que está na pasta é a verdade; não há banco nem índice para reconstruir.
|
|
11
|
+
- **Alcance pela hierarquia:** o item vale onde mora — workspace, project ou subject — e abaixo;
|
|
12
|
+
a busca, o pacote e o grafo respeitam isso, sem campo de scope.
|
|
13
|
+
- **Busca explicada, sem embeddings, que acerta em PT-BR:** em memória, sem acento, por radical e
|
|
14
|
+
prefixo, entende identificadores (`ItemService.saveBatch` acha "service" e "batch") e diz por
|
|
15
|
+
que cada resultado veio (`matched_in`, `snippet`, `where`).
|
|
16
|
+
- **Escrita em lote e idempotente:** `item_save` grava até 20 itens numa publicação; a `key`
|
|
17
|
+
estável regrava sem duplicar.
|
|
18
|
+
- **Corrige-se com o uso:** item errado ou velho, o agente ajusta ou remove (é git, dá para
|
|
19
|
+
voltar) — sem um sistema de feedback à parte.
|
|
20
|
+
- **Segredos sem passar pelo modelo:** o agente cria o segredo vazio, você preenche na UI local e
|
|
21
|
+
ele é usado por `knowledge-mcp run`, que entrega o valor só ao processo filho.
|
|
22
|
+
- **Seguro:** recusa segredos em itens comuns; operações destrutivas pedem confirmação e mostram
|
|
23
|
+
uma prévia antes.
|
|
24
|
+
|
|
25
|
+
## Como começar
|
|
26
|
+
|
|
27
|
+
1. **Instalar**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv tool install "git+https://github.com/KauaLealz/knowledge-os-mcp-server" # comando `knowledge-mcp`
|
|
31
|
+
knowledge-mcp --version
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Para desenvolver, clone e instale editável: `uv tool install --editable <pasta-do-clone>`.
|
|
35
|
+
|
|
36
|
+
2. **Registrar no cliente MCP.** O instalador do Plumb (`npx plumb-harness install`) registra o
|
|
37
|
+
servidor no Claude Code e no Cursor, com o hook de início de sessão. À mão:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
claude mcp add --scope user knowledge-os -e LOG_LEVEL=WARNING -- knowledge-mcp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
// ~/.cursor/mcp.json
|
|
45
|
+
{ "mcpServers": { "knowledge-os": { "command": "knowledge-mcp",
|
|
46
|
+
"env": { "LOG_LEVEL": "WARNING" } } } }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. **Criar a primeira conexão, pelo MCP.** Nada é criado sozinho: até existir uma conexão, toda
|
|
50
|
+
operação responde "Nenhuma conexão configurada. Crie uma com connection_create(name, path[,
|
|
51
|
+
remote_url])." Peça ao agente (ou chame a ferramenta):
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
connection_create(name="pessoal", path="C:\\caminho\\da\\pasta")
|
|
55
|
+
connection_create(name="empresa", path="/home/eu/empresa-knowledge", remote_url="git@github.com:org/knowledge.git")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`path` é uma pasta absoluta: se já for um repositório git, é usada como está; senão vira um
|
|
59
|
+
(`git init`, preservando o que já tiver dentro). Com `remote_url`, a pasta é o destino do
|
|
60
|
+
clone e cada escrita é empurrada para lá. A primeira conexão vira a padrão. A UI
|
|
61
|
+
(`knowledge-mcp ui`) lista, edita, testa, define a padrão e apaga conexões, mas não cria.
|
|
62
|
+
|
|
63
|
+
4. **Ligar o repositório do projeto.** Dentro do repositório em que você trabalha, rode
|
|
64
|
+
`/plumb-setup` (no Plumb) ou `knowledge-mcp link --repo .` — ou peça ao agente
|
|
65
|
+
`repo(action="link", repo=".")`. O project é o repositório; o workspace, o do dono do remote.
|
|
66
|
+
|
|
67
|
+
Se a pasta já tem arquivos de uma versão anterior do Knowledge OS, nada precisa ser migrado: a
|
|
68
|
+
leitura traduz o formato antigo e a próxima gravação de cada item já sai no formato atual.
|
|
69
|
+
|
|
70
|
+
## Onde ficam os dados
|
|
71
|
+
|
|
72
|
+
- **Na pasta de cada conexão** (o repositório git que você escolheu): todos os itens, como
|
|
73
|
+
`<workspace>/<project>/<key>.md`, os `.knowledge.yaml` (descrição de workspaces, projects e
|
|
74
|
+
subjects, e o vocabulário de tags) e os valores de segredos cifrados em `.secrets/`
|
|
75
|
+
(fora do git: nunca entram nele).
|
|
76
|
+
- **No home** (`KNOWLEDGE_OS_HOME`, padrão `~/.knowledge-os`), só estado desta máquina:
|
|
77
|
+
`connections.json` (as conexões e a padrão), `repos.json` (repositório local → conexão,
|
|
78
|
+
workspace e project), `usage/<conexão>.json` (contadores de uso por item),
|
|
79
|
+
`searches/<conexão>.jsonl` (buscas que voltaram vazias), `locks/` (travas de escrita entre
|
|
80
|
+
processos) e a fila offline `pending.jsonl`. Nenhum item fica aí.
|
|
81
|
+
|
|
82
|
+
Fazer backup ou levar para outra máquina é o mesmo que com qualquer repositório git: commit,
|
|
83
|
+
push, clone.
|
|
84
|
+
|
|
85
|
+
## Modelo
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Workspace = contexto de trabalho ex.: Polara (empresa), Pessoal
|
|
89
|
+
└── Project = um repositório ex.: app, synapse
|
|
90
|
+
└── Subject (opcional) conceito dentro do project, ex.: pagamentos
|
|
91
|
+
└── Item: type · key · title · summary · content · tags · links
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
O item **mora** num nível da hierarquia (workspace, project ou subject) e **vale onde mora e
|
|
95
|
+
abaixo** — não há campo de scope. Cinco tipos; a nuance e o ciclo vão em **tags** (a taxonomia
|
|
96
|
+
abaixo é a mesma que o servidor envia ao agente nas instruções):
|
|
97
|
+
|
|
98
|
+
| Tipo | Guarda |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `rule` | o que deve ser seguido + o porquê (convenção, decisão, regra de negócio) |
|
|
101
|
+
| `howto` | passos repetíveis ou diagnóstico (sintoma/causa/solução) |
|
|
102
|
+
| `context` | pano de fundo: produto, mapa, stack, glossário, ambiente |
|
|
103
|
+
| `work` | o trabalho: plano/spec + decisões (o porquê durável); ciclo por tag |
|
|
104
|
+
| `secret` | referência a um segredo (sem o valor) |
|
|
105
|
+
|
|
106
|
+
| Campo | Valores |
|
|
107
|
+
|---|---|
|
|
108
|
+
| tags de ciclo | `draft`, `active`, `done`, `archived` |
|
|
109
|
+
| tags de nuance (base, extensível) | `decision`, `troubleshoot`, `security`, `pattern`, `map`, `glossary`, `product`, `environment`, `business`, `process` |
|
|
110
|
+
| link item→item (`rel`) | `depends_on`, `relates_to` |
|
|
111
|
+
|
|
112
|
+
Key: `<tipo>/<nome>` (nome em minúsculas com `-`); fora do padrão grava com aviso, e a key de um item existente nunca muda.
|
|
113
|
+
|
|
114
|
+
Alcance: o item vale onde mora na hierarquia (workspace → project → subject) e abaixo. Não há `scope`, `status`, `subtype`, `origin` nem expiração — a nuance e o ciclo vão em `tags`.
|
|
115
|
+
|
|
116
|
+
`links` (unificado): `{item, rel}` liga a outro item; `{url[, title]}` a uma URL; `{path}` a um arquivo/glob do repositório.
|
|
117
|
+
|
|
118
|
+
### Alcance pela hierarquia
|
|
119
|
+
|
|
120
|
+
Um item no nível do **workspace** vale em todos os projects dele; no **project**, só nele; no
|
|
121
|
+
**subject**, só nele. Na busca, quanto mais perto do project do repositório, maior o peso; o que
|
|
122
|
+
está fora do alcance é invisível. `item_get(ids=[...])` e `item_search(everywhere=True)` leem a
|
|
123
|
+
conexão inteira. Um segredo vale pelo mesmo alcance: para usá-lo fora do seu project, guarde-o no
|
|
124
|
+
nível do workspace.
|
|
125
|
+
|
|
126
|
+
### Ciclo de vida
|
|
127
|
+
|
|
128
|
+
Sem aprovação: o que o agente grava já vale. Para corrigir, regrave pela mesma `key`; para
|
|
129
|
+
aposentar, a tag `archived`. Itens com a tag `archived` saem da busca e do contexto. O servidor
|
|
130
|
+
nunca apaga sozinho: `item_delete` sem chaves lista candidatos (arquivados ou nunca abertos há
|
|
131
|
+
muito tempo) e só remove com `confirm=True`.
|
|
132
|
+
|
|
133
|
+
## Ferramentas (31)
|
|
134
|
+
|
|
135
|
+
| Ferramenta | Faz |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `connection_create` · `connection_list` · `connection_delete` | cria (a única forma de criar), lista ou tira do cadastro uma conexão — apagar não mexe na pasta |
|
|
138
|
+
| `workspace_list` · `workspace_create` · `workspace_update` · `workspace_merge` · `workspace_delete` | organização dos workspaces; `create`/`update` aceitam `description` |
|
|
139
|
+
| `project_list` · `project_create` · `project_update` · `project_merge` · `project_delete` | o mesmo, por workspace (a lista traz os subjects) |
|
|
140
|
+
| `subject_list` · `subject_create` · `subject_update` · `subject_merge` · `subject_delete` | o mesmo, por project |
|
|
141
|
+
| `repo` | `action="link"`, `"list"`, `"unlink"` ou `"sync"`: liga o repositório a um workspace/project, ou puxa o que mudou no remote |
|
|
142
|
+
| `item_search` | busca explicada pela hierarquia, até 5 consultas por chamada, com `paths`, `types` e `tags` |
|
|
143
|
+
| `item_get` | itens completos por keys ou ids, vários de uma vez |
|
|
144
|
+
| `item_save` | cria, atualiza, regrava por `key`, move; até 20 itens, atômico |
|
|
145
|
+
| `item_delete` | candidatos à limpeza, prévia e remoção com `confirm=True` |
|
|
146
|
+
| `item_graph` | vizinhança por links item↔item, até 3 saltos |
|
|
147
|
+
| `relation_create` · `relation_delete` | links `depends_on`/`relates_to` em lote entre itens |
|
|
148
|
+
| `tag_list` · `tag_create` · `tag_update` · `tag_delete` | tags gerenciadas: contagem, renomear/mesclar, prévia ao apagar |
|
|
149
|
+
| `health_check` | versão, conexões, arquivos que não leram e `gh` autenticado |
|
|
150
|
+
|
|
151
|
+
Todas aceitam `connection_id` opcional, menos `connection_*` e `health_check`. Guia por tarefa,
|
|
152
|
+
com exemplos: [docs/MCP_USAGE.md](docs/MCP_USAGE.md).
|
|
153
|
+
|
|
154
|
+
## Conexões: cada uma é um repositório git
|
|
155
|
+
|
|
156
|
+
Cada item não secreto vira um arquivo Markdown com frontmatter YAML na pasta da conexão. A
|
|
157
|
+
leitura é direta dos arquivos (com um cache em memória por arquivo, invalidado por data e
|
|
158
|
+
tamanho), então editar, apagar ou puxar arquivos por fora também vale. Um arquivo que não lê não
|
|
159
|
+
derruba nada: aparece em `parse_errors` do `health_check`.
|
|
160
|
+
|
|
161
|
+
`review_mode`, por conexão:
|
|
162
|
+
|
|
163
|
+
- `direct` (padrão): as escritas comitam direto na branch principal (com push, se houver
|
|
164
|
+
`remote_url`).
|
|
165
|
+
- `pr`: a mesma gravação vai para uma branch nova e abre um Pull Request (ou uma Issue, se o
|
|
166
|
+
token não tiver permissão de push); a resposta traz `pending_review`/`pr_url` (ou
|
|
167
|
+
`issue_opened`/`issue_url`) em vez do resultado de sempre — a mudança aparece depois que o PR
|
|
168
|
+
for mergeado e alguém rodar `repo(action="sync")`.
|
|
169
|
+
|
|
170
|
+
## CLI
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
knowledge-mcp # servidor MCP (stdio)
|
|
174
|
+
knowledge-mcp context --repo . --paths src/payments/Charge.java --budget 1500
|
|
175
|
+
knowledge-mcp context --hook claude|cursor # hook de início de sessão (lê o JSON no stdin)
|
|
176
|
+
knowledge-mcp link --repo . # project = repo; workspace = o do dono
|
|
177
|
+
knowledge-mcp recent --since 2026-10-01 --json # o que mudou (usado pela daily)
|
|
178
|
+
knowledge-mcp report --json # o que revisar no cérebro (usado pelo dream)
|
|
179
|
+
knowledge-mcp pending --repo . # grava a fila offline (~/.knowledge-os/pending.jsonl)
|
|
180
|
+
knowledge-mcp ui [--port 8765] # UI web local (127.0.0.1; já sobe com o MCP)
|
|
181
|
+
knowledge-mcp run --env NPM_TOKEN=secret/npm-token -- npm publish # segredo só no filho
|
|
182
|
+
knowledge-mcp --version
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Os subcomandos do cérebro não carregam o servidor MCP: o hook responde em ~1 s.
|
|
186
|
+
|
|
187
|
+
**Pacote de contexto** (`context`): pelo mesmo alcance da busca, nesta ordem — Em foco (o que
|
|
188
|
+
casa `--paths`/`--query`, com o começo do `content`), Segurança (tag `security`), Regras,
|
|
189
|
+
Contexto, Como fazer (só títulos), Trabalho ativo (`work`), Segredos (estado e como usar) e
|
|
190
|
+
Regras por arquivo (as com um link `{path}` que casa). Item de fora do project do repositório
|
|
191
|
+
leva de onde vem (`[<workspace>]`). Respeita o orçamento em tokens e lista o que ficou de fora.
|
|
192
|
+
Sem conexão, devolve o exemplo de `connection_create`; o hook nunca derruba a sessão.
|
|
193
|
+
|
|
194
|
+
**Relatório** (`report --json`): `never_opened_60d`, `archived` (candidatos a remover),
|
|
195
|
+
`empty_searches` (as buscas que voltaram vazias, com contagem) e `tags_unused`, cada lista com
|
|
196
|
+
`key`, `where` e o motivo.
|
|
197
|
+
|
|
198
|
+
## UI
|
|
199
|
+
|
|
200
|
+
`knowledge-mcp ui` (ou o servidor MCP, que já a sobe) abre uma UI local em
|
|
201
|
+
`http://127.0.0.1:8765`. Mostra os itens com tipo e tags, `links` e as ligações do item em grafo;
|
|
202
|
+
as tags com contagem; a organização em workspaces, projects e subjects; e as conexões, com o
|
|
203
|
+
caminho da pasta.
|
|
204
|
+
É também onde você preenche o valor de um segredo. Só escuta em `127.0.0.1`.
|
|
205
|
+
|
|
206
|
+
## Segredos
|
|
207
|
+
|
|
208
|
+
Token, senha ou chave de API viram um item `secret` (key `secret/<nome>`), no mesmo esquema do
|
|
209
|
+
resto: no project do repositório, ou num nível mais alto da hierarquia para compartilhar. O fluxo:
|
|
210
|
+
|
|
211
|
+
1. O agente grava o item **sem valor** (`item_save` recusa qualquer campo de valor) e a resposta
|
|
212
|
+
traz `fill_url`, o link da UI local direto no item.
|
|
213
|
+
2. Você abre o link e cola o valor num campo de senha. Ele é cifrado (Fernet) e guardado à parte,
|
|
214
|
+
em `<pasta-da-conexão>/.secrets/<item_id>.enc` (fora do git); nenhuma ferramenta, rota,
|
|
215
|
+
busca ou contexto o devolve — só `has_value`. Na UI dá para substituir ou apagar; não existe
|
|
216
|
+
"revelar".
|
|
217
|
+
3. O agente usa: `knowledge-mcp run --env VAR=secret/<nome> [--stdin secret/<nome>] -- <comando>`.
|
|
218
|
+
O valor vai só para o ambiente (ou stdin) do filho, que roda sem shell e sem a chave mestra;
|
|
219
|
+
a saída volta com o valor e as codificações comuns (base64, URL) trocados por `***`. A key é
|
|
220
|
+
procurada pelo mesmo alcance da busca. A redação cobre o valor exato, base64 (inclusive
|
|
221
|
+
dentro de `Basic user:token`), URL, JSON escapado, as codepages do Windows e UTF-16, e cada
|
|
222
|
+
linha de um valor de várias linhas.
|
|
223
|
+
|
|
224
|
+
A chave mestra é aleatória e fica no keyring do sistema (no Windows, o Gerenciador de
|
|
225
|
+
Credenciais). `KNOWLEDGE_OS_VAULT_KEY` existe só para CI e máquinas sem keyring — nunca a
|
|
226
|
+
ponha na config do MCP (`.mcp.json`) nem no ambiente do agente: quem a lê, com a pasta
|
|
227
|
+
`.secrets/`, abre todos os valores. Os arquivos `.enc` guardam só texto cifrado, cada valor
|
|
228
|
+
amarrado ao seu item. Se a chave some depois de criada, o servidor dá erro em vez de gerar outra
|
|
229
|
+
por cima.
|
|
230
|
+
|
|
231
|
+
No Windows, o `run` acha o comando só pelo PATH (nunca pela pasta do projeto, onde um `gh.cmd`
|
|
232
|
+
plantado receberia o token). Comandos `.cmd`/`.bat` (npm, az...) rodam pelo `cmd.exe`: o `run`
|
|
233
|
+
recusa argumentos com `" % & | < > ^ !` nesses casos. Valores com menos de 4 caracteres são
|
|
234
|
+
recusados (não daria para escondê-los na saída).
|
|
235
|
+
|
|
236
|
+
**Modelo de ameaça.** Protege o valor do contexto do modelo, do histórico das conversas, dos
|
|
237
|
+
itens e do repositório git. **Não** protege contra: um agente ou comando feito para vazar (quem
|
|
238
|
+
roda `knowledge-mcp run` pode escrever um filho que imprime o valor transformado de um jeito que
|
|
239
|
+
a redação não reconhece); malware rodando com o seu usuário (lê o keyring e chama a UI local); o
|
|
240
|
+
próprio comando gravar o valor em log ou arquivo. Segredo nunca expira sozinho.
|
|
241
|
+
|
|
242
|
+
Conteúdo com cara de segredo (chaves de nuvem, tokens, chaves privadas, `password=...`,
|
|
243
|
+
URLs com senha) em itens comuns é recusado sem eco do valor (a mensagem ensina o fluxo de
|
|
244
|
+
segredos acima).
|
|
245
|
+
|
|
246
|
+
## Desenvolvimento
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
uv pip install -e ".[dev]"
|
|
250
|
+
pytest -q # inclusive ponta a ponta via stdio
|
|
251
|
+
ruff check src tests
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Arquitetura: [docs/ARQUITETURA.md](docs/ARQUITETURA.md). O contrato da v2 está em
|
|
255
|
+
[docs/V2_MVP.md](docs/V2_MVP.md). Mudanças são conduzidas pelo Plumb (o plano de cada mudança
|
|
256
|
+
fica guardado no próprio cérebro).
|
|
257
|
+
|
|
258
|
+
## Licença
|
|
259
|
+
|
|
260
|
+
MIT
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "knowledge-os-mcp-server"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "MCP server: local knowledge base for Claude agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Kauã Leal", email = "kaualealdev@gmail.com"}
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
dependencies = [
|
|
17
|
+
# Faixas fechadas: o fastmcp 4 quebrou a API dos testes sem aviso (get_tools, call_tool).
|
|
18
|
+
"mcp>=2,<3",
|
|
19
|
+
"fastmcp>=4,<5",
|
|
20
|
+
"pydantic>=2.0,<3",
|
|
21
|
+
"python-dotenv>=1.0.0",
|
|
22
|
+
"fastapi>=0.110.0",
|
|
23
|
+
"uvicorn>=0.27.0",
|
|
24
|
+
"python-multipart>=0.0.9",
|
|
25
|
+
# Segredos: cifra Fernet e chave mestra no keyring do sistema.
|
|
26
|
+
"cryptography>=42",
|
|
27
|
+
"keyring>=24",
|
|
28
|
+
# Itens como arquivos Markdown com frontmatter YAML na pasta (git) de cada conexão.
|
|
29
|
+
"pyyaml>=6.0,<7",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/KauaLealz/knowledge-os-mcp-server"
|
|
34
|
+
Issues = "https://github.com/KauaLealz/knowledge-os-mcp-server/issues"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=7.0",
|
|
39
|
+
"pytest-asyncio>=0.21.0",
|
|
40
|
+
"pytest-cov>=4.0",
|
|
41
|
+
"httpx>=0.27.0",
|
|
42
|
+
"black>=23.0",
|
|
43
|
+
"ruff>=0.1.0",
|
|
44
|
+
"mypy>=1.0",
|
|
45
|
+
"types-PyYAML>=6.0",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.scripts]
|
|
49
|
+
knowledge-mcp = "knowledge_os.cli:main"
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["src"]
|
|
53
|
+
include = ["knowledge_os*"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.dynamic]
|
|
56
|
+
version = {attr = "knowledge_os.__version__"}
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.package-data]
|
|
59
|
+
"knowledge_os.mcp" = ["INSTRUCTIONS.md", "INSTRUCTIONS_AGENT.md"]
|
|
60
|
+
"knowledge_os.api" = ["static/**/*"]
|
|
61
|
+
|
|
62
|
+
[tool.black]
|
|
63
|
+
line-length = 100
|
|
64
|
+
target-version = ["py312"]
|
|
65
|
+
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
target-version = "py312"
|
|
68
|
+
line-length = 100
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = [
|
|
72
|
+
"E",
|
|
73
|
+
"F",
|
|
74
|
+
"W",
|
|
75
|
+
"I",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
python_version = "3.12"
|
|
80
|
+
warn_return_any = true
|
|
81
|
+
warn_unused_configs = true
|
|
82
|
+
disallow_untyped_defs = true
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
# Fixa o escopo padrão do loop de fixtures async (pytest-asyncio avisa quando não definido).
|
|
86
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
87
|
+
pythonpath = ["src"]
|