tokrepo-mcp-server 2.9.2 → 2.11.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.
Files changed (3) hide show
  1. package/README.md +7 -1
  2. package/bin/server.js +181 -1
  3. package/package.json +7 -3
package/README.md CHANGED
@@ -39,6 +39,7 @@ Once connected, your AI assistant can:
39
39
  - **Search** 200+ curated AI assets by keyword or category with agent fit signals
40
40
  - **Browse** trending assets, filter by type (MCP, Skill, Prompt, Agent, Script)
41
41
  - **Get details** — full documentation, install instructions, and metadata
42
+ - **Verify trust** — read-only content hash, install plan hash, permission envelope, policy, trust_score_v2, blockers, and warnings
42
43
  - **Plan before install** — get install plan v2 with policy decisions, rollback, and verification
43
44
  - **Safe Codex install** — dry-run by default; risky assets must be staged or explicitly approved
44
45
  - **Lifecycle control** — list, update, uninstall, and roll back managed Codex installs
@@ -53,6 +54,7 @@ Once connected, your AI assistant can:
53
54
  | `tokrepo_discover` | Planning-time capability discovery from a task, environment, and constraints |
54
55
  | `tokrepo_search` | Search assets by keyword/tag with `agent_fit` ranking |
55
56
  | `tokrepo_detail` | Get full asset details by UUID |
57
+ | `tokrepo_verify` | Verify trust, hashes, permissions, and policy before activation |
56
58
  | `tokrepo_install_plan` | Get agent-native install plan v2 |
57
59
  | `tokrepo_codex_install` | Dry-run, stage, or install a Codex skill safely |
58
60
  | `tokrepo_installed` | List TokRepo-managed Codex installs |
@@ -71,6 +73,7 @@ You: "What video assets should I install?"
71
73
  AI: [calls tokrepo_discover] → Finds relevant skills, checks fit and policy, then asks before installing
72
74
 
73
75
  You: "Install that cursor rules asset"
76
+ AI: [calls tokrepo_verify] → Checks trust_score_v2, permissions, blockers, and warnings
74
77
  AI: [calls tokrepo_install_plan] → Reviews policy and actions
75
78
  AI: [calls tokrepo_codex_install with dry_run=false, confirm=true] → Writes only after explicit confirmation
76
79
  AI: [calls tokrepo_rollback with dry_run=true] → Shows exactly what would be removed before rollback
@@ -95,6 +98,9 @@ Registries and agents can discover this server through:
95
98
  - Portable agent manifest: [tokrepo.com/.well-known/agent.json](https://tokrepo.com/.well-known/agent.json)
96
99
  - A2A agent card: [tokrepo.com/.well-known/agent-card.json](https://tokrepo.com/.well-known/agent-card.json)
97
100
  - Tool catalog: [tokrepo.com/.well-known/tool-catalog.json](https://tokrepo.com/.well-known/tool-catalog.json)
101
+ - Trust manifest: [tokrepo.com/.well-known/tokrepo-trust.json](https://tokrepo.com/.well-known/tokrepo-trust.json)
102
+ - Default agent policy pack: [tokrepo.com/policy-packs/default-agent-policy.json](https://tokrepo.com/policy-packs/default-agent-policy.json)
103
+ - Eval evidence: [tokrepo.com/evals/agent-discovery.json](https://tokrepo.com/evals/agent-discovery.json)
98
104
  - Agent text entry: [tokrepo.com/agents.txt](https://tokrepo.com/agents.txt)
99
105
  - Agent instructions: [tokrepo.com/agent-instructions/tokrepo.md](https://tokrepo.com/agent-instructions/tokrepo.md)
100
106
  - Agent ecosystem distribution pack: [tokrepo.com/agent-ecosystem.json](https://tokrepo.com/agent-ecosystem.json)
@@ -102,7 +108,7 @@ Registries and agents can discover this server through:
102
108
 
103
109
  Use `https://tokrepo.com/agent-ecosystem.json` for agent marketplace submissions, starter templates, README snippets, install guides, and example projects. It contains canonical listing copy, ecosystem channels, target project-memory files, and verification commands.
104
110
 
105
- TokRepo emits anonymous aggregate funnel events for `tokrepo_discover`, `tokrepo_install_plan`, install dry-runs, installs, handoffs, and pushes. It does not send task text or file contents. Disable with `TOKREPO_TELEMETRY=0`.
111
+ TokRepo emits anonymous aggregate funnel events for `tokrepo_discover`, `tokrepo_verify`, `tokrepo_install_plan`, install dry-runs, installs, handoffs, and pushes. It does not send task text or file contents. Disable with `TOKREPO_TELEMETRY=0`.
106
112
 
107
113
  ## Why TokRepo?
108
114
 
package/bin/server.js CHANGED
@@ -20,7 +20,7 @@ const API_BASE = process.env.TOKREPO_API || 'https://api.tokrepo.com';
20
20
  const TOKREPO_URL = 'https://tokrepo.com';
21
21
  const TOKREPO_TOKEN = process.env.TOKREPO_TOKEN || '';
22
22
  const TOKREPO_CLI = process.env.TOKREPO_CLI || '';
23
- const SERVER_VERSION = '2.9.2';
23
+ const SERVER_VERSION = '2.11.0';
24
24
 
25
25
  // ─── MCP Protocol (JSON-RPC over stdio) ───
26
26
 
@@ -155,6 +155,36 @@ const TOOLS = [
155
155
  required: ['uuid'],
156
156
  },
157
157
  },
158
+ {
159
+ name: 'tokrepo_verify',
160
+ description: 'Read-only asset trust verification for agents. Produces content hash, install plan hash, policy decision, permission envelope, trust_score_v2, blockers, warnings, schemas, and safe next actions before activation.',
161
+ inputSchema: {
162
+ type: 'object',
163
+ properties: {
164
+ uuid: {
165
+ type: 'string',
166
+ description: 'Asset UUID, workflow URL slug, or workflow UUID from search/detail results. Ignored when offline=true.',
167
+ },
168
+ target: {
169
+ type: 'string',
170
+ description: 'Verification target adapter.',
171
+ enum: ['codex'],
172
+ default: 'codex',
173
+ },
174
+ strict: {
175
+ type: 'boolean',
176
+ description: 'When true, warnings fail the verification report.',
177
+ default: false,
178
+ },
179
+ offline: {
180
+ type: 'boolean',
181
+ description: 'Use the bundled offline fixture. Intended for agent/toolchain self-tests.',
182
+ default: false,
183
+ },
184
+ },
185
+ required: ['uuid'],
186
+ },
187
+ },
158
188
  {
159
189
  name: 'tokrepo_codex_install',
160
190
  description: 'Safely install a TokRepo asset into local Codex. Defaults to dry_run=true. To write files, set dry_run=false and confirm=true. Risky assets require stage=true or approve_risk=true.',
@@ -436,6 +466,7 @@ const EXPOSED_TOOL_NAMES = new Set([
436
466
  'tokrepo_search',
437
467
  'tokrepo_detail',
438
468
  'tokrepo_install_plan',
469
+ 'tokrepo_verify',
439
470
  'tokrepo_codex_install',
440
471
  'tokrepo_installed',
441
472
  'tokrepo_update',
@@ -473,6 +504,13 @@ const TOOL_ANNOTATIONS = {
473
504
  idempotentHint: true,
474
505
  openWorldHint: true,
475
506
  },
507
+ tokrepo_verify: {
508
+ title: 'Verify asset trust, hashes, permissions, and policy before activation',
509
+ readOnlyHint: true,
510
+ destructiveHint: false,
511
+ idempotentHint: true,
512
+ openWorldHint: true,
513
+ },
476
514
  tokrepo_codex_install: {
477
515
  title: 'Dry-run, stage, or install an asset for Codex',
478
516
  readOnlyHint: false,
@@ -613,6 +651,7 @@ function eventForTool(name, args = {}) {
613
651
  if (name === 'tokrepo_search') return 'mcp_search';
614
652
  if (name === 'tokrepo_detail') return 'mcp_detail';
615
653
  if (name === 'tokrepo_install_plan') return 'install_plan';
654
+ if (name === 'tokrepo_verify') return 'verify_asset';
616
655
  if (name === 'tokrepo_codex_install') return args.dry_run === false ? 'install_apply' : 'install_dry_run';
617
656
  if (name === 'tokrepo_push') return 'push';
618
657
  return '';
@@ -846,6 +885,112 @@ function buildDiscoveryQuery(task, environment, constraints) {
846
885
  return compactText([...new Set(parts)].join(' '), 100);
847
886
  }
848
887
 
888
+ function inferAgentCapabilityAnalysis(task, target = 'any', constraints = {}, environment = {}) {
889
+ const text = [
890
+ task,
891
+ constraints.kind,
892
+ constraints.policy,
893
+ environment.project_type,
894
+ environment.language,
895
+ ...asArray(environment.frameworks),
896
+ ].filter(Boolean).join(' ').toLowerCase();
897
+ const normalizeKind = (value) => String(value || '').toLowerCase().replace(/[-\s]+/g, '_');
898
+ const rules = [
899
+ {
900
+ name: 'domain_or_workflow_skill',
901
+ kind: 'skill',
902
+ evidence: ['skill', 'rule', 'guideline', 'review', 'audit', 'seo', 'design', 'frontend', 'backend', 'security', 'test', 'deploy', 'video', 'writing'],
903
+ why: 'The task likely benefits from reusable instructions, domain rules, or a repeatable agent workflow.',
904
+ },
905
+ {
906
+ name: 'agent_tool_or_mcp_integration',
907
+ kind: 'mcp_config',
908
+ evidence: ['mcp', 'tool', 'api', 'integration', 'github', 'browser', 'calendar', 'email', 'gmail', 'slack', 'notion', 'database', 'vercel'],
909
+ why: 'The task may require a callable tool surface instead of hand-written one-off glue code.',
910
+ },
911
+ {
912
+ name: 'automation_script',
913
+ kind: 'script',
914
+ evidence: ['script', 'cli', 'batch', 'cron', 'automation', 'generate', 'convert', 'migrate', 'lint', 'check'],
915
+ why: 'The task may reuse a tested script or command wrapper.',
916
+ },
917
+ {
918
+ name: 'prompt_or_reasoning_template',
919
+ kind: 'prompt',
920
+ evidence: ['prompt', 'copy', 'research', 'analysis', 'summarize', 'translate', 'plan', 'brainstorm'],
921
+ why: 'The task may reuse a prompt template or reasoning checklist.',
922
+ },
923
+ {
924
+ name: 'knowledge_or_policy_pack',
925
+ kind: 'knowledge',
926
+ evidence: ['policy', 'standard', 'compliance', 'docs', 'documentation', 'architecture', 'best practice', 'trust'],
927
+ why: 'The task may need reusable reference knowledge or policy constraints.',
928
+ },
929
+ ];
930
+ const inferred = [];
931
+ for (const rule of rules) {
932
+ const matches = rule.evidence.filter(term => text.includes(term));
933
+ if (constraints.kind && normalizeKind(constraints.kind) === normalizeKind(rule.kind)) matches.push(`requested kind ${rule.kind}`);
934
+ if (!matches.length) continue;
935
+ inferred.push({
936
+ name: rule.name,
937
+ asset_kind: rule.kind,
938
+ confidence: Math.min(0.95, 0.55 + matches.length * 0.08),
939
+ evidence: Array.from(new Set(matches)).slice(0, 6),
940
+ why: rule.why,
941
+ });
942
+ }
943
+ if (!inferred.length) {
944
+ inferred.push({
945
+ name: 'general_reusable_agent_capability',
946
+ asset_kind: constraints.kind || 'skill',
947
+ confidence: 0.5,
948
+ evidence: ['new task capability gap'],
949
+ why: 'Before creating local one-off work, the agent should check whether TokRepo already has a reusable asset.',
950
+ });
951
+ }
952
+ const preferredAssetKinds = Array.from(new Set([
953
+ constraints.kind,
954
+ ...inferred.map(item => item.asset_kind),
955
+ 'skill',
956
+ 'prompt',
957
+ 'mcp_config',
958
+ 'script',
959
+ 'workflow',
960
+ 'knowledge',
961
+ ].filter(Boolean))).slice(0, 6);
962
+ const taskTerms = extractSearchTerms(task, 6);
963
+ return {
964
+ schema_version: 1,
965
+ decision: 'discover_before_build',
966
+ target,
967
+ trigger: 'planning_time_capability_gap',
968
+ inferred_capabilities: inferred,
969
+ preferred_asset_kinds: preferredAssetKinds,
970
+ search_queries: Array.from(new Set([
971
+ buildDiscoveryQuery(task, environment, constraints),
972
+ compactText(taskTerms.slice(0, 4).join(' '), 100),
973
+ ...preferredAssetKinds.map(kind => compactText(`${taskTerms.slice(0, 3).join(' ')} ${kind}`, 100)),
974
+ ].filter(Boolean))).slice(0, 6),
975
+ required_mcp_sequence: [
976
+ 'tokrepo_discover',
977
+ 'tokrepo_detail',
978
+ 'tokrepo_verify',
979
+ 'tokrepo_install_plan',
980
+ ],
981
+ acceptance_criteria: [
982
+ 'Do not require the human to browse the TokRepo GUI before discovery.',
983
+ 'Use a candidate only when fit, policy, trust, and permission envelope match the active subtask.',
984
+ 'Prefer dry-run or stage-only before writes, execution, secrets, network access, or global config changes.',
985
+ 'After completing the task, run tokrepo agent-handoff --json to preserve reusable improvements.',
986
+ ],
987
+ empty_state_strategy: [
988
+ 'Try broader capability terms from search_queries.',
989
+ 'If still empty, build locally and package the reusable part with tokrepo agent-handoff.',
990
+ ],
991
+ };
992
+ }
993
+
849
994
  function scoreDiscoveryCandidate(item, task, target, constraints = {}) {
850
995
  const metadata = itemAgentMetadata(item);
851
996
  const fit = itemAgentFit(item);
@@ -935,10 +1080,13 @@ function buildCandidate(item, target, ranking = {}) {
935
1080
  ranking,
936
1081
  next_mcp_calls: [
937
1082
  { tool: 'tokrepo_detail', arguments: { uuid } },
1083
+ { tool: 'tokrepo_verify', arguments: { uuid, target: planTarget } },
938
1084
  { tool: 'tokrepo_install_plan', arguments: { uuid, target: planTarget } },
939
1085
  ],
940
1086
  commands: {
941
1087
  inspect: `npx tokrepo detail ${uuid} --json`,
1088
+ audit: `npx tokrepo audit ${uuid} --target ${planTarget} --json`,
1089
+ verify: `npx tokrepo verify ${uuid} --target ${planTarget} --json`,
942
1090
  dry_run_install: planTarget === 'codex'
943
1091
  ? `npx tokrepo install ${uuid} --dry-run --json`
944
1092
  : `npx tokrepo install ${uuid} --target ${planTarget} --dry-run --json`,
@@ -946,6 +1094,8 @@ function buildCandidate(item, target, ranking = {}) {
946
1094
  agent_use_contract: [
947
1095
  'Use only if the capability matches the current subtask.',
948
1096
  'Call tokrepo_detail before install to inspect content and metadata.',
1097
+ 'Call tokrepo_verify to inspect hashes, permissions, trust_score_v2, blockers, and warnings.',
1098
+ 'Call tokrepo audit if future agents need a persistent trust-history snapshot.',
949
1099
  'Call tokrepo_install_plan and respect policy_decision before writing files.',
950
1100
  'Prefer dry-run or stage-only when risk or fit is uncertain.',
951
1101
  'After using it, verify the original task outcome and record failures.',
@@ -1022,10 +1172,12 @@ async function handleDiscover(args) {
1022
1172
  environment,
1023
1173
  constraints,
1024
1174
  },
1175
+ capability_analysis: inferAgentCapabilityAnalysis(task, target, constraints, environment),
1025
1176
  recommended_flow: [
1026
1177
  'During planning, call tokrepo_discover when the task exposes a capability gap.',
1027
1178
  'Rank candidates by fit, policy, trust, and whether the entrypoint matches the active agent runtime.',
1028
1179
  'Call tokrepo_detail for the top candidate before installation or use.',
1180
+ 'Call tokrepo audit if the chosen asset materially affects the task and future agents need a trust-history snapshot.',
1029
1181
  'Call tokrepo_install_plan and respect policy_decision, rollback, and verification steps.',
1030
1182
  'Dry-run or stage when the asset may write files, execute code, require secrets, or change global config.',
1031
1183
  'Use the installed capability only for the matching subtask, then verify the user goal.',
@@ -1179,6 +1331,33 @@ async function handleInstallPlan(args) {
1179
1331
  };
1180
1332
  }
1181
1333
 
1334
+ async function handleVerify(args) {
1335
+ const {
1336
+ uuid = '00000000-0000-4000-8000-000000000001',
1337
+ target = 'codex',
1338
+ strict = false,
1339
+ offline = false,
1340
+ } = args || {};
1341
+ const cliArgs = ['verify', uuid, '--target', target, '--json'];
1342
+ if (strict) cliArgs.push('--strict');
1343
+ if (offline) cliArgs.push('--offline');
1344
+ const { stdout, stderr } = await runTokrepoCli(cliArgs);
1345
+ let data;
1346
+ try {
1347
+ data = JSON.parse(stdout);
1348
+ } catch {
1349
+ data = { stdout, stderr };
1350
+ }
1351
+ const status = data?.status || 'unknown';
1352
+ return {
1353
+ isError: status === 'fail',
1354
+ content: [{
1355
+ type: 'text',
1356
+ text: jsonText(`TokRepo asset verification (${status})`, data),
1357
+ }],
1358
+ };
1359
+ }
1360
+
1182
1361
  async function handleCodexInstall(args) {
1183
1362
  const {
1184
1363
  uuid,
@@ -1552,6 +1731,7 @@ async function handleRequest(msg) {
1552
1731
  case 'tokrepo_detail': result = await handleDetail(args || {}); break;
1553
1732
  case 'tokrepo_install': result = await handleInstall(args || {}); break;
1554
1733
  case 'tokrepo_install_plan': result = await handleInstallPlan(args || {}); break;
1734
+ case 'tokrepo_verify': result = await handleVerify(args || {}); break;
1555
1735
  case 'tokrepo_codex_install': result = await handleCodexInstall(args || {}); break;
1556
1736
  case 'tokrepo_clone_plan': result = await handleClonePlan(args || {}); break;
1557
1737
  case 'tokrepo_installed': result = await handleInstalled(args || {}); break;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tokrepo-mcp-server",
3
- "version": "2.9.2",
4
- "description": "Agent-native MCP server for TokRepo search, plan, safely install, and push AI assets from MCP clients.",
3
+ "version": "2.11.0",
4
+ "description": "Agent-native MCP server for TokRepo - discover, verify, plan, safely install, and push AI assets from MCP clients.",
5
5
  "mcpName": "io.github.henu-wang/tokrepo-mcp-server",
6
6
  "bin": {
7
7
  "tokrepo-mcp-server": "bin/server.js"
@@ -37,10 +37,14 @@
37
37
  "claude-code",
38
38
  "openai-codex",
39
39
  "mcp-registry",
40
+ "hosted-mcp",
40
41
  "agent-manifest",
41
42
  "a2a-agent-card",
42
43
  "tool-discovery",
43
- "llms-txt"
44
+ "llms-txt",
45
+ "trust-verification",
46
+ "agent-audit",
47
+ "agent-evals"
44
48
  ],
45
49
  "engines": {
46
50
  "node": ">=18"