@chnxthr/knowledge-mcp 0.0.0-stage → 0.3.0
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.
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/dist/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +18 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/auth.d.ts +38 -0
- package/dist/core/auth.js +93 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/config.d.ts +259 -0
- package/dist/core/config.js +172 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +25 -0
- package/dist/core/context.js +37 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/env.d.ts +2 -0
- package/dist/core/env.js +5 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/log_mask.d.ts +10 -0
- package/dist/core/log_mask.js +88 -0
- package/dist/core/log_mask.js.map +1 -0
- package/dist/core/oauth.d.ts +46 -0
- package/dist/core/oauth.js +507 -0
- package/dist/core/oauth.js.map +1 -0
- package/dist/core/paths.d.ts +5 -0
- package/dist/core/paths.js +47 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/scope.d.ts +28 -0
- package/dist/core/scope.js +54 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/upstream.d.ts +30 -0
- package/dist/core/upstream.js +164 -0
- package/dist/core/upstream.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/define.d.ts +144 -0
- package/dist/plugin/define.js +44 -0
- package/dist/plugin/define.js.map +1 -0
- package/dist/plugin/load.d.ts +2 -0
- package/dist/plugin/load.js +41 -0
- package/dist/plugin/load.js.map +1 -0
- package/dist/plugin/ping.d.ts +9 -0
- package/dist/plugin/ping.js +29 -0
- package/dist/plugin/ping.js.map +1 -0
- package/dist/plugin/registry.d.ts +62 -0
- package/dist/plugin/registry.js +248 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/result.d.ts +20 -0
- package/dist/plugin/result.js +59 -0
- package/dist/plugin/result.js.map +1 -0
- package/dist/plugins/drive/chunker.d.ts +28 -0
- package/dist/plugins/drive/chunker.js +356 -0
- package/dist/plugins/drive/chunker.js.map +1 -0
- package/dist/plugins/drive/clean_text.d.ts +13 -0
- package/dist/plugins/drive/clean_text.js +31 -0
- package/dist/plugins/drive/clean_text.js.map +1 -0
- package/dist/plugins/drive/client.d.ts +25 -0
- package/dist/plugins/drive/client.js +62 -0
- package/dist/plugins/drive/client.js.map +1 -0
- package/dist/plugins/drive/embeddings.d.ts +15 -0
- package/dist/plugins/drive/embeddings.js +118 -0
- package/dist/plugins/drive/embeddings.js.map +1 -0
- package/dist/plugins/drive/exclude.d.ts +11 -0
- package/dist/plugins/drive/exclude.js +36 -0
- package/dist/plugins/drive/exclude.js.map +1 -0
- package/dist/plugins/drive/extract_text.d.ts +26 -0
- package/dist/plugins/drive/extract_text.js +108 -0
- package/dist/plugins/drive/extract_text.js.map +1 -0
- package/dist/plugins/drive/get_token.d.ts +5 -0
- package/dist/plugins/drive/get_token.js +113 -0
- package/dist/plugins/drive/get_token.js.map +1 -0
- package/dist/plugins/drive/index.d.ts +5 -0
- package/dist/plugins/drive/index.js +72 -0
- package/dist/plugins/drive/index.js.map +1 -0
- package/dist/plugins/drive/indexer.d.ts +69 -0
- package/dist/plugins/drive/indexer.js +204 -0
- package/dist/plugins/drive/indexer.js.map +1 -0
- package/dist/plugins/drive/mathpix.d.ts +4 -0
- package/dist/plugins/drive/mathpix.js +102 -0
- package/dist/plugins/drive/mathpix.js.map +1 -0
- package/dist/plugins/drive/path.d.ts +40 -0
- package/dist/plugins/drive/path.js +87 -0
- package/dist/plugins/drive/path.js.map +1 -0
- package/dist/plugins/drive/qdrant.d.ts +50 -0
- package/dist/plugins/drive/qdrant.js +61 -0
- package/dist/plugins/drive/qdrant.js.map +1 -0
- package/dist/plugins/drive/reindex.d.ts +2 -0
- package/dist/plugins/drive/reindex.js +263 -0
- package/dist/plugins/drive/reindex.js.map +1 -0
- package/dist/plugins/drive/settings.d.ts +11 -0
- package/dist/plugins/drive/settings.js +13 -0
- package/dist/plugins/drive/settings.js.map +1 -0
- package/dist/plugins/drive/sync.d.ts +16 -0
- package/dist/plugins/drive/sync.js +139 -0
- package/dist/plugins/drive/sync.js.map +1 -0
- package/dist/plugins/drive/sync_state.d.ts +3 -0
- package/dist/plugins/drive/sync_state.js +26 -0
- package/dist/plugins/drive/sync_state.js.map +1 -0
- package/dist/plugins/drive/tools/list_drive_folder.d.ts +104 -0
- package/dist/plugins/drive/tools/list_drive_folder.js +221 -0
- package/dist/plugins/drive/tools/list_drive_folder.js.map +1 -0
- package/dist/plugins/drive/tools/read_drive_file.d.ts +66 -0
- package/dist/plugins/drive/tools/read_drive_file.js +206 -0
- package/dist/plugins/drive/tools/read_drive_file.js.map +1 -0
- package/dist/plugins/drive/tools/search_drive.d.ts +52 -0
- package/dist/plugins/drive/tools/search_drive.js +78 -0
- package/dist/plugins/drive/tools/search_drive.js.map +1 -0
- package/dist/plugins/drive/tools/semantic_search_drive.d.ts +109 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js +228 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js.map +1 -0
- package/dist/plugins/github/index.d.ts +1 -0
- package/dist/plugins/github/index.js +27 -0
- package/dist/plugins/github/index.js.map +1 -0
- package/dist/plugins/github/repo_tree.d.ts +57 -0
- package/dist/plugins/github/repo_tree.js +123 -0
- package/dist/plugins/github/repo_tree.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.js +7 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/railway/index.d.ts +1 -0
- package/dist/plugins/railway/index.js +21 -0
- package/dist/plugins/railway/index.js.map +1 -0
- package/dist/plugins/railway/tools.d.ts +114 -0
- package/dist/plugins/railway/tools.js +165 -0
- package/dist/plugins/railway/tools.js.map +1 -0
- package/dist/plugins/slack/api.d.ts +63 -0
- package/dist/plugins/slack/api.js +280 -0
- package/dist/plugins/slack/api.js.map +1 -0
- package/dist/plugins/slack/index.d.ts +1 -0
- package/dist/plugins/slack/index.js +80 -0
- package/dist/plugins/slack/index.js.map +1 -0
- package/dist/plugins/slack/tools/slack_files.d.ts +87 -0
- package/dist/plugins/slack/tools/slack_files.js +204 -0
- package/dist/plugins/slack/tools/slack_files.js.map +1 -0
- package/dist/plugins/slack/tools/slack_list_channels.d.ts +46 -0
- package/dist/plugins/slack/tools/slack_list_channels.js +197 -0
- package/dist/plugins/slack/tools/slack_list_channels.js.map +1 -0
- package/dist/plugins/slack/tools/slack_read_channel.d.ts +56 -0
- package/dist/plugins/slack/tools/slack_read_channel.js +150 -0
- package/dist/plugins/slack/tools/slack_read_channel.js.map +1 -0
- package/dist/plugins/slack/tools/slack_search.d.ts +53 -0
- package/dist/plugins/slack/tools/slack_search.js +132 -0
- package/dist/plugins/slack/tools/slack_search.js.map +1 -0
- package/dist/run.d.ts +8 -0
- package/dist/run.js +270 -0
- package/dist/run.js.map +1 -0
- package/dist/server/http.d.ts +5 -0
- package/dist/server/http.js +406 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/identity.d.ts +17 -0
- package/dist/server/identity.js +47 -0
- package/dist/server/identity.js.map +1 -0
- package/dist/server/mcp.d.ts +7 -0
- package/dist/server/mcp.js +55 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/stdio.d.ts +2 -0
- package/dist/server/stdio.js +40 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/store/index.d.ts +11 -0
- package/dist/store/index.js +31 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/keys.d.ts +9 -0
- package/dist/store/keys.js +32 -0
- package/dist/store/keys.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.js +316 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/supabase.d.ts +35 -0
- package/dist/store/supabase.js +269 -0
- package/dist/store/supabase.js.map +1 -0
- package/dist/store/supabase_client.d.ts +10 -0
- package/dist/store/supabase_client.js +31 -0
- package/dist/store/supabase_client.js.map +1 -0
- package/dist/store/tool_log.d.ts +12 -0
- package/dist/store/tool_log.js +8 -0
- package/dist/store/tool_log.js.map +1 -0
- package/dist/store/types.d.ts +96 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -4
- package/sql/supabase.sql +185 -0
package/sql/supabase.sql
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
-- Knowledge MCP — Supabase setup (only for MCP_STORE=supabase; the default SQLite store needs nothing)
|
|
2
|
+
--
|
|
3
|
+
-- Run this in your Supabase project (SQL editor or `supabase db`). Run it again after every upgrade: every
|
|
4
|
+
-- statement is idempotent, and re-running it on an existing install applies the fixes below. It creates:
|
|
5
|
+
-- - mcp_keys + validate_mcp_key() : API-key auth for http/prod
|
|
6
|
+
-- - app_users : per-user role + resource scopes (RBAC)
|
|
7
|
+
-- - mcp_oauth_clients : DCR client persistence (only if you enable OAuth)
|
|
8
|
+
-- - mcp_refresh_tokens : OAuth refresh rotation / revocation
|
|
9
|
+
-- - mcp_plugin_state : plugin key-value state (Drive sync token, your plugins' ctx.state)
|
|
10
|
+
-- - mcp_sync_state : pre-0.3 Drive sync token (copied into mcp_plugin_state, then unused)
|
|
11
|
+
-- - mcp_tool_calls : tool-call audit log
|
|
12
|
+
-- - slack_channels : Slack channel purpose map (slack_list_channels)
|
|
13
|
+
-- and then locks every table and the key function down to the server's service-role key.
|
|
14
|
+
--
|
|
15
|
+
-- Requires Postgres 13+ (gen_random_uuid and sha256 are built in; no extension needed).
|
|
16
|
+
--
|
|
17
|
+
-- NOTE ON SCHEMA: state tables are read via config.data.schema (default "public"). validate_mcp_key
|
|
18
|
+
-- is called without a schema qualifier, so keep it (and mcp_keys) in "public". If you set
|
|
19
|
+
-- config.data.schema to something other than "public", create the state tables in that schema, add that
|
|
20
|
+
-- schema to "Exposed schemas" in Supabase API settings, and apply the lock-down section to it as well.
|
|
21
|
+
|
|
22
|
+
-- ── API keys ───────────────────────────────────────────────────────────────
|
|
23
|
+
-- Store only a SHA-256 hash of each key. Hand the raw key to the client once.
|
|
24
|
+
-- Use a long random key (e.g. `openssl rand -hex 32`); the hash is unsalted.
|
|
25
|
+
create table if not exists public.mcp_keys (
|
|
26
|
+
id uuid primary key default gen_random_uuid(),
|
|
27
|
+
key_hash text not null unique, -- encode(sha256(convert_to(raw_key,'UTF8')),'hex')
|
|
28
|
+
org_id text not null default 'org',
|
|
29
|
+
role text not null default 'member', -- admin | member | viewer (used only when email is null)
|
|
30
|
+
email text, -- set => role and scopes come from app_users
|
|
31
|
+
label text,
|
|
32
|
+
active boolean not null default true,
|
|
33
|
+
expires_at timestamptz,
|
|
34
|
+
created_at timestamptz not null default now()
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
-- 0.3: label column, 'member' replaces 'engineer' (old rows keep working; the server reads engineer as member).
|
|
38
|
+
alter table public.mcp_keys add column if not exists label text;
|
|
39
|
+
alter table public.mcp_keys alter column role set default 'member';
|
|
40
|
+
|
|
41
|
+
-- Provision keys with the CLI instead of SQL (it hashes the key and prints it once):
|
|
42
|
+
-- MCP_STORE=supabase knowledge-mcp users add you@acme.com --role admin
|
|
43
|
+
-- MCP_STORE=supabase knowledge-mcp keys create --email you@acme.com
|
|
44
|
+
|
|
45
|
+
-- sha256() over the UTF-8 bytes gives the same hash as the older digest(text,'sha256'), so existing keys
|
|
46
|
+
-- keep working. It avoids pgcrypto, which Supabase installs in the "extensions" schema where a function
|
|
47
|
+
-- pinned to search_path=public cannot see it.
|
|
48
|
+
create or replace function public.validate_mcp_key(p_key text)
|
|
49
|
+
returns table (ok boolean, org_id text, role text, email text, key_id text, reason text)
|
|
50
|
+
language plpgsql
|
|
51
|
+
security definer
|
|
52
|
+
set search_path = public
|
|
53
|
+
as $$
|
|
54
|
+
declare r public.mcp_keys%rowtype;
|
|
55
|
+
begin
|
|
56
|
+
select * into r from public.mcp_keys
|
|
57
|
+
where key_hash = encode(sha256(convert_to(p_key, 'UTF8')), 'hex')
|
|
58
|
+
limit 1;
|
|
59
|
+
if not found then
|
|
60
|
+
return query select false, null::text, null::text, null::text, null::text, 'key not found'; return;
|
|
61
|
+
end if;
|
|
62
|
+
if not r.active then
|
|
63
|
+
return query select false, null::text, null::text, null::text, null::text, 'key inactive'; return;
|
|
64
|
+
end if;
|
|
65
|
+
if r.expires_at is not null and r.expires_at < now() then
|
|
66
|
+
return query select false, null::text, null::text, null::text, null::text, 'key expired'; return;
|
|
67
|
+
end if;
|
|
68
|
+
return query select true, r.org_id, r.role, r.email, r.id::text, null::text;
|
|
69
|
+
end $$;
|
|
70
|
+
|
|
71
|
+
-- ── Users (RBAC) ─────────────────────────────────────────────────────────────
|
|
72
|
+
-- role 'admin' => admin (every tool). Any other value => member (limited by the allowed_* columns).
|
|
73
|
+
-- A signed-in email with no row here is a viewer: only `ping`, unless config access.viewerTools opens groups.
|
|
74
|
+
create table if not exists public.app_users (
|
|
75
|
+
email text primary key,
|
|
76
|
+
role text not null default 'member',
|
|
77
|
+
name text,
|
|
78
|
+
allowed_slack_channels text[], -- null/empty = all channels the bot is in
|
|
79
|
+
allowed_drive_folders text[], -- null/empty = all (path prefixes under the Drive roots)
|
|
80
|
+
allowed_tools text[], -- null/empty = all (groups = plugin ids: drive, slack, github, railway, yours)
|
|
81
|
+
created_at timestamptz not null default now()
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
-- ── OAuth (only needed if you enable OAuth 2.1) ──────────────────────────────
|
|
85
|
+
create table if not exists public.mcp_oauth_clients (
|
|
86
|
+
client_id text primary key,
|
|
87
|
+
client_data jsonb not null,
|
|
88
|
+
client_name text,
|
|
89
|
+
created_at timestamptz not null default now(),
|
|
90
|
+
last_used_at timestamptz
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
create table if not exists public.mcp_refresh_tokens (
|
|
94
|
+
jti text primary key,
|
|
95
|
+
email text not null,
|
|
96
|
+
client_id text not null,
|
|
97
|
+
expires_at timestamptz not null,
|
|
98
|
+
revoked_at timestamptz,
|
|
99
|
+
rotated_to text,
|
|
100
|
+
created_at timestamptz not null default now()
|
|
101
|
+
);
|
|
102
|
+
create index if not exists mcp_refresh_tokens_email_idx on public.mcp_refresh_tokens (email);
|
|
103
|
+
|
|
104
|
+
-- ── Drive incremental sync state ─────────────────────────────────────────────
|
|
105
|
+
create table if not exists public.mcp_sync_state (
|
|
106
|
+
key text primary key,
|
|
107
|
+
page_token text,
|
|
108
|
+
updated_at timestamptz not null default now()
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
-- ── Plugin state (ctx.state) ────────────────────────────────────────────────
|
|
112
|
+
create table if not exists public.mcp_plugin_state (
|
|
113
|
+
namespace text not null,
|
|
114
|
+
key text not null,
|
|
115
|
+
value jsonb,
|
|
116
|
+
updated_at timestamptz not null default now(),
|
|
117
|
+
primary key (namespace, key)
|
|
118
|
+
);
|
|
119
|
+
-- Carry the pre-0.3 Drive sync token over, so the first sync after the upgrade continues where it stopped.
|
|
120
|
+
insert into public.mcp_plugin_state (namespace, key, value)
|
|
121
|
+
select 'drive', 'pageToken', to_jsonb(page_token) from public.mcp_sync_state
|
|
122
|
+
where key = 'drive' and page_token is not null
|
|
123
|
+
on conflict (namespace, key) do nothing;
|
|
124
|
+
|
|
125
|
+
-- ── Tool-call audit log ──────────────────────────────────────────────────────
|
|
126
|
+
create table if not exists public.mcp_tool_calls (
|
|
127
|
+
id bigserial primary key,
|
|
128
|
+
tool text not null,
|
|
129
|
+
email text,
|
|
130
|
+
role text,
|
|
131
|
+
ok boolean not null,
|
|
132
|
+
error text,
|
|
133
|
+
duration_ms integer,
|
|
134
|
+
source text,
|
|
135
|
+
created_at timestamptz not null default now()
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
-- ── Slack channel purpose map (slack_list_channels) ──────────────────────────
|
|
139
|
+
-- New channels are added automatically with enabled=false. Fill in `purpose` and set enabled=true to list them.
|
|
140
|
+
create table if not exists public.slack_channels (
|
|
141
|
+
id uuid primary key default gen_random_uuid(),
|
|
142
|
+
channel_name text not null,
|
|
143
|
+
channel_id text unique,
|
|
144
|
+
purpose text not null default '',
|
|
145
|
+
category text,
|
|
146
|
+
enabled boolean not null default false,
|
|
147
|
+
sort_order integer not null default 100,
|
|
148
|
+
created_at timestamptz not null default now()
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
-- ── Lock down ────────────────────────────────────────────────────────────────
|
|
152
|
+
-- Only the server touches these, with the service-role key (which bypasses RLS).
|
|
153
|
+
-- Supabase grants new tables, sequences and functions in "public" to the anon and authenticated roles by
|
|
154
|
+
-- default, and tables created from SQL start with RLS off. Without this section anyone holding the
|
|
155
|
+
-- project's public anon key could, through the REST API, insert an admin API key, read OAuth client
|
|
156
|
+
-- secrets, un-revoke refresh tokens, or call validate_mcp_key to guess keys without any rate limit.
|
|
157
|
+
alter table public.mcp_keys enable row level security;
|
|
158
|
+
alter table public.app_users enable row level security;
|
|
159
|
+
alter table public.mcp_oauth_clients enable row level security;
|
|
160
|
+
alter table public.mcp_refresh_tokens enable row level security;
|
|
161
|
+
alter table public.mcp_sync_state enable row level security;
|
|
162
|
+
alter table public.mcp_plugin_state enable row level security;
|
|
163
|
+
alter table public.mcp_tool_calls enable row level security;
|
|
164
|
+
alter table public.slack_channels enable row level security;
|
|
165
|
+
|
|
166
|
+
revoke all on function public.validate_mcp_key(text) from public;
|
|
167
|
+
|
|
168
|
+
do $$
|
|
169
|
+
declare
|
|
170
|
+
t text;
|
|
171
|
+
r text;
|
|
172
|
+
begin
|
|
173
|
+
foreach r in array array['anon', 'authenticated'] loop
|
|
174
|
+
continue when not exists (select 1 from pg_roles where rolname = r);
|
|
175
|
+
foreach t in array array['mcp_keys', 'app_users', 'mcp_oauth_clients', 'mcp_refresh_tokens',
|
|
176
|
+
'mcp_sync_state', 'mcp_plugin_state', 'mcp_tool_calls', 'slack_channels'] loop
|
|
177
|
+
execute format('revoke all on table public.%I from %I', t, r);
|
|
178
|
+
end loop;
|
|
179
|
+
execute format('revoke all on sequence public.mcp_tool_calls_id_seq from %I', r);
|
|
180
|
+
execute format('revoke all on function public.validate_mcp_key(text) from %I', r);
|
|
181
|
+
end loop;
|
|
182
|
+
if exists (select 1 from pg_roles where rolname = 'service_role') then
|
|
183
|
+
grant execute on function public.validate_mcp_key(text) to service_role;
|
|
184
|
+
end if;
|
|
185
|
+
end $$;
|