@cg3/prior-mcp 0.6.4 → 0.7.1
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/README.md +54 -25
- package/dist/client.d.ts +53 -6
- package/dist/client.js +515 -25
- package/dist/index.d.ts +5 -6
- package/dist/index.js +39 -14
- package/dist/ops-tools.d.ts +14 -0
- package/dist/ops-tools.js +169 -0
- package/dist/resources.d.ts +1 -1
- package/dist/resources.js +130 -122
- package/dist/tools.d.ts +2 -1
- package/dist/tools.js +19 -10
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { PriorApiClient } from "./client.js";
|
|
3
|
+
export declare const OPS_TOOL_NAMES: readonly ["ops_get_summary", "ops_list_attention", "ops_get_attention_item", "ops_get_recent_changes", "ops_get_runbook"];
|
|
4
|
+
export interface RegisterOpsToolsOptions {
|
|
5
|
+
client: PriorApiClient;
|
|
6
|
+
}
|
|
7
|
+
interface OpsToolRequest {
|
|
8
|
+
method: "GET";
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function isOpsToolsEnabled(value?: string | undefined): boolean;
|
|
12
|
+
export declare function buildOpsToolRequest(toolName: string, input?: Record<string, unknown>): OpsToolRequest;
|
|
13
|
+
export declare function registerOpsTools(server: McpServer, { client }: RegisterOpsToolsOptions): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.OPS_TOOL_NAMES = void 0;
|
|
37
|
+
exports.isOpsToolsEnabled = isOpsToolsEnabled;
|
|
38
|
+
exports.buildOpsToolRequest = buildOpsToolRequest;
|
|
39
|
+
exports.registerOpsTools = registerOpsTools;
|
|
40
|
+
const crypto = __importStar(require("node:crypto"));
|
|
41
|
+
const zod_1 = require("zod");
|
|
42
|
+
const utils_js_1 = require("./utils.js");
|
|
43
|
+
exports.OPS_TOOL_NAMES = Object.freeze([
|
|
44
|
+
"ops_get_summary",
|
|
45
|
+
"ops_list_attention",
|
|
46
|
+
"ops_get_attention_item",
|
|
47
|
+
"ops_get_recent_changes",
|
|
48
|
+
"ops_get_runbook",
|
|
49
|
+
]);
|
|
50
|
+
function appendQuery(path, params) {
|
|
51
|
+
const query = new URLSearchParams();
|
|
52
|
+
for (const [key, value] of Object.entries(params)) {
|
|
53
|
+
if (value !== undefined && value !== "")
|
|
54
|
+
query.set(key, String(value));
|
|
55
|
+
}
|
|
56
|
+
const queryString = query.toString();
|
|
57
|
+
return queryString ? `${path}?${queryString}` : path;
|
|
58
|
+
}
|
|
59
|
+
function isOpsToolsEnabled(value = process.env.PRIOR_MCP_ENABLE_OPS_TOOLS) {
|
|
60
|
+
return value === "1" || value?.toLowerCase() === "true";
|
|
61
|
+
}
|
|
62
|
+
function buildOpsToolRequest(toolName, input = {}) {
|
|
63
|
+
switch (toolName) {
|
|
64
|
+
case "ops_get_summary":
|
|
65
|
+
return {
|
|
66
|
+
method: "GET",
|
|
67
|
+
path: appendQuery("/v1/admin/ops/summary", {
|
|
68
|
+
window: typeof input.window === "string" ? input.window : undefined,
|
|
69
|
+
surface: typeof input.surface === "string" ? input.surface : undefined,
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
case "ops_list_attention":
|
|
73
|
+
return {
|
|
74
|
+
method: "GET",
|
|
75
|
+
path: appendQuery("/v1/admin/ops/attention", {
|
|
76
|
+
surface: typeof input.surface === "string" ? input.surface : undefined,
|
|
77
|
+
limit: typeof input.limit === "number" ? input.limit : undefined,
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
case "ops_get_attention_item":
|
|
81
|
+
if (typeof input.id !== "string" || !input.id)
|
|
82
|
+
throw new Error("ops_get_attention_item requires id");
|
|
83
|
+
return { method: "GET", path: `/v1/admin/ops/attention/${encodeURIComponent(input.id)}` };
|
|
84
|
+
case "ops_get_recent_changes":
|
|
85
|
+
return {
|
|
86
|
+
method: "GET",
|
|
87
|
+
path: appendQuery("/v1/admin/ops/recent-changes", {
|
|
88
|
+
window: typeof input.window === "string" ? input.window : undefined,
|
|
89
|
+
surface: typeof input.surface === "string" ? input.surface : undefined,
|
|
90
|
+
}),
|
|
91
|
+
};
|
|
92
|
+
case "ops_get_runbook":
|
|
93
|
+
if (typeof input.id !== "string" || !input.id)
|
|
94
|
+
throw new Error("ops_get_runbook requires id");
|
|
95
|
+
return { method: "GET", path: `/v1/admin/ops/runbooks/${encodeURIComponent(input.id)}` };
|
|
96
|
+
default:
|
|
97
|
+
throw new Error(`Unknown ops tool: ${toolName}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function makeOpsRequestId(toolName) {
|
|
101
|
+
return `ops-${toolName}-${crypto.randomUUID()}`;
|
|
102
|
+
}
|
|
103
|
+
async function callOpsApi(client, toolName, input) {
|
|
104
|
+
const request = buildOpsToolRequest(toolName, input);
|
|
105
|
+
const requestId = makeOpsRequestId(toolName);
|
|
106
|
+
const response = await client.request(request.method, request.path, undefined, undefined, requestId);
|
|
107
|
+
return {
|
|
108
|
+
structuredContent: {
|
|
109
|
+
requestId,
|
|
110
|
+
response,
|
|
111
|
+
},
|
|
112
|
+
content: [{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: `requestId: ${requestId}\n${(0, utils_js_1.formatResults)(response)}`,
|
|
115
|
+
}],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const opsOutputSchema = {
|
|
119
|
+
requestId: zod_1.z.string(),
|
|
120
|
+
response: zod_1.z.any(),
|
|
121
|
+
};
|
|
122
|
+
const windowSurfaceInput = {
|
|
123
|
+
window: zod_1.z.string().optional().describe("Window such as 24h, 7d, or 30d. Defaults to backend behavior when omitted."),
|
|
124
|
+
surface: zod_1.z.string().optional().describe("Optional ops surface filter such as business, auth, infrastructure, changes, or equip.release."),
|
|
125
|
+
};
|
|
126
|
+
function registerOpsTools(server, { client }) {
|
|
127
|
+
server.registerTool("ops_get_summary", {
|
|
128
|
+
title: "Get CG3 Ops Summary",
|
|
129
|
+
description: "Read-only admin operator summary. Requires opt-in local ops tools and an admin-capable Prior session/API key.",
|
|
130
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
131
|
+
inputSchema: windowSurfaceInput,
|
|
132
|
+
outputSchema: opsOutputSchema,
|
|
133
|
+
}, async (input) => callOpsApi(client, "ops_get_summary", input));
|
|
134
|
+
server.registerTool("ops_list_attention", {
|
|
135
|
+
title: "List CG3 Ops Attention Items",
|
|
136
|
+
description: "Read-only admin attention list for CG3 operator surfaces. Requires admin-capable Prior auth.",
|
|
137
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
138
|
+
inputSchema: {
|
|
139
|
+
surface: zod_1.z.string().optional().describe("Optional ops surface filter."),
|
|
140
|
+
limit: zod_1.z.number().optional().describe("Maximum number of items. Backend bounds the value."),
|
|
141
|
+
},
|
|
142
|
+
outputSchema: opsOutputSchema,
|
|
143
|
+
}, async (input) => callOpsApi(client, "ops_list_attention", input));
|
|
144
|
+
server.registerTool("ops_get_attention_item", {
|
|
145
|
+
title: "Get CG3 Ops Attention Item",
|
|
146
|
+
description: "Read-only admin detail for one ops attention item. Requires admin-capable Prior auth.",
|
|
147
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
148
|
+
inputSchema: {
|
|
149
|
+
id: zod_1.z.string().describe("Stable attention item ID."),
|
|
150
|
+
},
|
|
151
|
+
outputSchema: opsOutputSchema,
|
|
152
|
+
}, async (input) => callOpsApi(client, "ops_get_attention_item", input));
|
|
153
|
+
server.registerTool("ops_get_recent_changes", {
|
|
154
|
+
title: "Get CG3 Ops Recent Changes",
|
|
155
|
+
description: "Read-only admin recent-change projection with evidence links. Requires admin-capable Prior auth.",
|
|
156
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
157
|
+
inputSchema: windowSurfaceInput,
|
|
158
|
+
outputSchema: opsOutputSchema,
|
|
159
|
+
}, async (input) => callOpsApi(client, "ops_get_recent_changes", input));
|
|
160
|
+
server.registerTool("ops_get_runbook", {
|
|
161
|
+
title: "Get CG3 Ops Runbook",
|
|
162
|
+
description: "Read-only admin runbook lookup for an ops attention item or surface. Requires admin-capable Prior auth.",
|
|
163
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
164
|
+
inputSchema: {
|
|
165
|
+
id: zod_1.z.string().describe("Stable runbook ID, e.g. rb-equip-channel-bad-release."),
|
|
166
|
+
},
|
|
167
|
+
outputSchema: opsOutputSchema,
|
|
168
|
+
}, async (input) => callOpsApi(client, "ops_get_runbook", input));
|
|
169
|
+
}
|
package/dist/resources.d.ts
CHANGED
package/dist/resources.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Prior MCP resources
|
|
3
|
+
* Prior MCP resources shared between local and remote MCP servers.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* import { registerResources } from "@cg3/prior-mcp/resources";
|
|
@@ -9,151 +9,170 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.registerResources = registerResources;
|
|
11
11
|
function registerResources(server, { client }) {
|
|
12
|
-
// ── Dynamic: Agent Status ───────────────────────────────────────────
|
|
13
12
|
server.registerResource("agent-status", "prior://agent/status", {
|
|
14
|
-
description: "Your current Prior
|
|
13
|
+
description: "Your current Prior auth status: auth mode, credits, tier, and profile summary.",
|
|
15
14
|
mimeType: "application/json",
|
|
16
15
|
annotations: { audience: ["assistant"], priority: 0.4 },
|
|
17
16
|
}, async () => {
|
|
18
17
|
try {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const status = await client.getStatus();
|
|
19
|
+
return {
|
|
20
|
+
contents: [{
|
|
21
|
+
uri: "prior://agent/status",
|
|
22
|
+
mimeType: "application/json",
|
|
22
23
|
text: JSON.stringify({
|
|
23
|
-
id:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
id: status.id,
|
|
25
|
+
authType: status.authType,
|
|
26
|
+
credits: status.credits,
|
|
27
|
+
tier: status.tier,
|
|
28
|
+
contributions: status.contributions,
|
|
29
|
+
displayName: status.displayName,
|
|
30
|
+
}, null, 2),
|
|
31
|
+
}],
|
|
32
|
+
};
|
|
29
33
|
}
|
|
30
34
|
catch (err) {
|
|
31
|
-
return {
|
|
32
|
-
|
|
35
|
+
return {
|
|
36
|
+
contents: [{
|
|
37
|
+
uri: "prior://agent/status",
|
|
38
|
+
mimeType: "application/json",
|
|
39
|
+
text: JSON.stringify({ error: err.message }),
|
|
40
|
+
}],
|
|
41
|
+
};
|
|
33
42
|
}
|
|
34
43
|
});
|
|
35
|
-
// ── Static: Search Tips ─────────────────────────────────────────────
|
|
36
44
|
server.registerResource("search-tips", "prior://docs/search-tips", {
|
|
37
|
-
description: "How to search Prior effectively
|
|
45
|
+
description: "How to search Prior effectively: query formulation, when to search, interpreting results, and giving feedback.",
|
|
38
46
|
mimeType: "text/markdown",
|
|
39
47
|
annotations: { audience: ["assistant"], priority: 0.9 },
|
|
40
48
|
}, async () => ({
|
|
41
49
|
contents: [{ uri: "prior://docs/search-tips", mimeType: "text/markdown", text: SEARCH_TIPS }],
|
|
42
50
|
}));
|
|
43
|
-
// ── Static: Contributing Guide ──────────────────────────────────────
|
|
44
51
|
server.registerResource("contributing-guide", "prior://docs/contributing", {
|
|
45
|
-
description: "How to write high-value Prior contributions
|
|
52
|
+
description: "How to write high-value Prior contributions: structured fields, PII rules, and title guidance.",
|
|
46
53
|
mimeType: "text/markdown",
|
|
47
54
|
annotations: { audience: ["assistant"], priority: 0.6 },
|
|
48
55
|
}, async () => ({
|
|
49
56
|
contents: [{ uri: "prior://docs/contributing", mimeType: "text/markdown", text: CONTRIBUTING_GUIDE }],
|
|
50
57
|
}));
|
|
51
|
-
// ── Static: API Keys Guide ──────────────────────────────────────────
|
|
52
58
|
server.registerResource("api-keys-guide", "prior://docs/api-keys", {
|
|
53
|
-
description: "API key setup
|
|
59
|
+
description: "API key setup, local browser login guidance, and client-specific config examples.",
|
|
54
60
|
mimeType: "text/markdown",
|
|
55
61
|
annotations: { audience: ["assistant", "user"], priority: 0.7 },
|
|
56
62
|
}, async () => ({
|
|
57
63
|
contents: [{ uri: "prior://docs/api-keys", mimeType: "text/markdown", text: API_KEYS_GUIDE }],
|
|
58
64
|
}));
|
|
59
|
-
// ── Static: Getting Started Guide ───────────────────────────────────
|
|
60
65
|
server.registerResource("getting-started", "prior://docs/getting-started", {
|
|
61
|
-
description: "How to
|
|
66
|
+
description: "How to create your Prior account and choose local OIDC or API-key auth.",
|
|
62
67
|
mimeType: "text/markdown",
|
|
63
68
|
annotations: { audience: ["assistant", "user"], priority: 0.5 },
|
|
64
69
|
}, async () => ({
|
|
65
70
|
contents: [{ uri: "prior://docs/getting-started", mimeType: "text/markdown", text: GETTING_STARTED_GUIDE }],
|
|
66
71
|
}));
|
|
67
|
-
// ── Static: Agent Guide (comprehensive) ─────────────────────────────
|
|
68
72
|
server.registerResource("agent-guide", "prior://docs/agent-guide", {
|
|
69
|
-
description: "Complete Prior integration guide
|
|
73
|
+
description: "Complete Prior integration guide with the full workflow and best practices.",
|
|
70
74
|
mimeType: "text/markdown",
|
|
71
75
|
annotations: { audience: ["assistant"], priority: 0.4 },
|
|
72
76
|
}, async () => ({
|
|
73
77
|
contents: [{ uri: "prior://docs/agent-guide", mimeType: "text/markdown", text: AGENT_GUIDE }],
|
|
74
78
|
}));
|
|
75
79
|
}
|
|
76
|
-
// ── Resource Content ────────────────────────────────────────────────────
|
|
77
|
-
// Highest-value, most actionable content first in each resource.
|
|
78
80
|
const SEARCH_TIPS = `# Prior Search Tips
|
|
79
81
|
|
|
80
82
|
## Quick Reference
|
|
81
|
-
- Search the **
|
|
82
|
-
- Include framework
|
|
83
|
-
- Paste
|
|
84
|
-
- \`relevanceScore > 0.5\`
|
|
85
|
-
- \`failedApproaches\`
|
|
83
|
+
- Search the **error**, not the goal: "ECONNREFUSED localhost:5432" not "how to connect to postgres"
|
|
84
|
+
- Include framework or version details when they matter
|
|
85
|
+
- Paste exact error strings for the best matches
|
|
86
|
+
- \`relevanceScore > 0.5\` is usually worth trying first
|
|
87
|
+
- Read \`failedApproaches\` before you try a result
|
|
86
88
|
|
|
87
89
|
## When to Search
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
- 2+ fixes tried, none worked → definitely search
|
|
90
|
+
- Search immediately when you hit an unfamiliar error
|
|
91
|
+
- Search before trial-and-error on new frameworks, tools, or config
|
|
92
|
+
- Search again if you have already tried a couple of fixes and none worked
|
|
92
93
|
|
|
93
94
|
## Giving Feedback
|
|
94
|
-
After trying a search result, use the \`feedbackActions\` from the result to call prior_feedback
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
95
|
+
After trying a search result, use the \`feedbackActions\` from the result to call \`prior_feedback\`:
|
|
96
|
+
- \`useful\`: you tried it and it solved the problem
|
|
97
|
+
- \`not_useful\`: you tried it and it failed; explain what you tried
|
|
98
|
+
- \`irrelevant\`: the result did not match your problem
|
|
98
99
|
|
|
99
|
-
Feedback
|
|
100
|
+
Feedback improves future search quality and refunds the search credit.
|
|
100
101
|
|
|
101
102
|
## Interpreting Scores
|
|
102
|
-
- \`relevanceScore > 0.5
|
|
103
|
-
- \`relevanceScore 0.3
|
|
104
|
-
- \`relevanceScore < 0.3
|
|
105
|
-
- \`qualityScore
|
|
106
|
-
`;
|
|
103
|
+
- \`relevanceScore > 0.5\`: strong match
|
|
104
|
+
- \`relevanceScore 0.3-0.5\`: partial match, worth skimming
|
|
105
|
+
- \`relevanceScore < 0.3\`: weak match
|
|
106
|
+
- \`qualityScore\`: community-verified quality`;
|
|
107
107
|
const CONTRIBUTING_GUIDE = `# Prior Contributing Guide
|
|
108
108
|
|
|
109
109
|
## When to Contribute
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
- You thought "this should have been easier"
|
|
110
|
+
- The fix was not obvious from the error message
|
|
111
|
+
- It took multiple attempts to figure out
|
|
112
|
+
- You had to read source code or obscure docs
|
|
113
|
+
- The issue depended on a specific version or tool combination
|
|
115
114
|
|
|
116
115
|
## Writing Titles
|
|
117
|
-
Describe
|
|
118
|
-
-
|
|
119
|
-
-
|
|
116
|
+
Describe symptoms, not diagnoses:
|
|
117
|
+
- Bad: "Duplicate route handlers shadow each other"
|
|
118
|
+
- Good: "Route handler returns wrong response despite correct source code"
|
|
120
119
|
|
|
121
|
-
Ask:
|
|
120
|
+
Ask yourself: what would I have searched before I knew the answer?
|
|
122
121
|
|
|
123
122
|
## Required Fields
|
|
124
|
-
- **title
|
|
125
|
-
- **content
|
|
123
|
+
- **title**: concise symptom description
|
|
124
|
+
- **content**: the full markdown write-up with context, what happened, and the fix
|
|
126
125
|
|
|
127
126
|
## Optional Structured Fields
|
|
128
|
-
|
|
129
|
-
- **
|
|
130
|
-
- **
|
|
131
|
-
- **
|
|
132
|
-
- **
|
|
133
|
-
- **environment** — Language, framework, runtime versions
|
|
127
|
+
- **problem**: short symptom summary
|
|
128
|
+
- **solution**: short fix summary
|
|
129
|
+
- **errorMessages**: exact error text
|
|
130
|
+
- **failedApproaches**: what did not work
|
|
131
|
+
- **environment**: language, framework, runtime versions
|
|
134
132
|
|
|
135
133
|
## PII Rules
|
|
136
|
-
|
|
137
|
-
Use generic
|
|
134
|
+
Never include real file paths, usernames, emails, API keys, IPs, or internal hostnames.
|
|
135
|
+
Use generic placeholders like \`/project/src/...\`.
|
|
138
136
|
|
|
139
|
-
## Generalizing
|
|
140
|
-
Prior is a
|
|
141
|
-
- Replace project-specific class/table/service names with generic equivalents
|
|
142
|
-
- Describe the **pattern**, not your architecture (e.g., "two DB rows shared the same key hash" not "our SubscriptionService left duplicates in the agents table")
|
|
143
|
-
- Test: would a developer on a completely different stack find this useful?
|
|
144
|
-
- If it reads like an internal postmortem, it's too specific — abstract it
|
|
137
|
+
## Generalizing
|
|
138
|
+
Prior is a public knowledge base. Replace project-specific names with generic patterns and write for someone on a different codebase.
|
|
145
139
|
|
|
146
140
|
## Effort Tracking
|
|
147
|
-
Include \`effort.tokensUsed\`
|
|
148
|
-
|
|
149
|
-
const API_KEYS_GUIDE = `# Prior API Key Setup
|
|
141
|
+
Include \`effort.tokensUsed\` when you can estimate it.`;
|
|
142
|
+
const API_KEYS_GUIDE = `# Prior Auth Setup
|
|
150
143
|
|
|
151
144
|
## Quick Start
|
|
152
|
-
Get your API key at https://prior.cg3.io/account, then
|
|
145
|
+
Get your API key at https://prior.cg3.io/account, then choose the auth mode that fits the client:
|
|
146
|
+
|
|
147
|
+
- Human local MCP session: run \`prior-mcp --login\` once and let the local stdio server use browser OIDC
|
|
148
|
+
- Durable machine workflow: set \`PRIOR_API_KEY\`
|
|
149
|
+
- OAuth-capable remote MCP client: connect to the hosted MCP server and follow the browser prompt
|
|
150
|
+
|
|
151
|
+
API keys remain the right choice for unattended or durable machine workflows.
|
|
152
|
+
|
|
153
|
+
## Environment Variables
|
|
154
|
+
\`\`\`bash
|
|
155
|
+
export PRIOR_API_KEY=ask_your_key_here
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
Optional token-based overrides for advanced setups:
|
|
159
|
+
|
|
160
|
+
\`\`\`bash
|
|
161
|
+
export PRIOR_IDENTITY_ACCESS_TOKEN=eyJ...
|
|
162
|
+
export PRIOR_REFRESH_TOKEN=rt_...
|
|
163
|
+
\`\`\`
|
|
164
|
+
|
|
165
|
+
\`PRIOR_IDENTITY_ACCESS_TOKEN\` is a delegated OIDC access token issued by Prior Identity. It is not a durable API key and not a generic Prior Knowledge credential; its JWT audience and scopes define which resource server can accept it and what it can do.
|
|
166
|
+
|
|
167
|
+
## Local Browser Login
|
|
168
|
+
\`\`\`bash
|
|
169
|
+
npx -y @cg3/prior-mcp --login
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
To clear the stored browser session and keep any saved API key config:
|
|
153
173
|
|
|
154
|
-
## Environment Variable (overrides config file)
|
|
155
174
|
\`\`\`bash
|
|
156
|
-
|
|
175
|
+
npx -y @cg3/prior-mcp --logout
|
|
157
176
|
\`\`\`
|
|
158
177
|
|
|
159
178
|
## Client Setup
|
|
@@ -166,7 +185,7 @@ In \`claude_code_config.json\` or project \`.mcp.json\`:
|
|
|
166
185
|
"prior": {
|
|
167
186
|
"command": "npx",
|
|
168
187
|
"args": ["-y", "@cg3/prior-mcp"],
|
|
169
|
-
"env": { "PRIOR_API_KEY": "
|
|
188
|
+
"env": { "PRIOR_API_KEY": "ask_your_key_here" }
|
|
170
189
|
}
|
|
171
190
|
}
|
|
172
191
|
}
|
|
@@ -180,7 +199,7 @@ In \`.cursor/mcp.json\`:
|
|
|
180
199
|
"prior": {
|
|
181
200
|
"command": "npx",
|
|
182
201
|
"args": ["-y", "@cg3/prior-mcp"],
|
|
183
|
-
"env": { "PRIOR_API_KEY": "
|
|
202
|
+
"env": { "PRIOR_API_KEY": "ask_your_key_here" }
|
|
184
203
|
}
|
|
185
204
|
}
|
|
186
205
|
}
|
|
@@ -195,7 +214,7 @@ In MCP settings:
|
|
|
195
214
|
"prior": {
|
|
196
215
|
"command": "npx",
|
|
197
216
|
"args": ["-y", "@cg3/prior-mcp"],
|
|
198
|
-
"env": { "PRIOR_API_KEY": "
|
|
217
|
+
"env": { "PRIOR_API_KEY": "ask_your_key_here" }
|
|
199
218
|
}
|
|
200
219
|
}
|
|
201
220
|
}
|
|
@@ -206,67 +225,56 @@ In MCP settings:
|
|
|
206
225
|
Command: \`npx -y @cg3/prior-mcp\`
|
|
207
226
|
Or install globally: \`npm install -g @cg3/prior-mcp\` then run \`prior-mcp\`
|
|
208
227
|
|
|
209
|
-
##
|
|
210
|
-
Sign into https://prior.cg3.io/account
|
|
211
|
-
|
|
212
|
-
## Team Tier: Sub-Keys
|
|
213
|
-
Subscribers can create sub-keys at https://prior.cg3.io/account/keys.
|
|
214
|
-
`;
|
|
228
|
+
## Recovery
|
|
229
|
+
Sign into https://prior.cg3.io/account to manage API keys and account settings.`;
|
|
215
230
|
const GETTING_STARTED_GUIDE = `# Getting Started with Prior
|
|
216
231
|
|
|
217
232
|
## Create Your Account
|
|
218
233
|
Sign up at https://prior.cg3.io/register with GitHub or Google.
|
|
219
|
-
This creates your account and
|
|
234
|
+
This creates your Prior account. API keys are available in account settings, and local OIDC login is available from the CLI.
|
|
235
|
+
|
|
236
|
+
## Authentication Paths
|
|
237
|
+
- **Local browser login**: run \`npx -y @cg3/prior-mcp --login\` for a first-party OIDC session
|
|
238
|
+
- **API key**: set \`PRIOR_API_KEY\` for unattended or durable machine use
|
|
239
|
+
- **Remote MCP**: OAuth-capable clients handle browser auth automatically
|
|
220
240
|
|
|
221
|
-
##
|
|
222
|
-
|
|
223
|
-
- **Remote MCP**: Clients with OAuth support (Claude Desktop, etc.) handle authentication automatically via browser
|
|
241
|
+
## Status Reads
|
|
242
|
+
The local OIDC flow reads account and product profile state from the standard OIDC-aligned account surface, not the old \`/v1/agents/me\` bootstrap path.
|
|
224
243
|
|
|
225
244
|
## Dashboard
|
|
226
|
-
Visit https://prior.cg3.io/account to manage your
|
|
227
|
-
|
|
228
|
-
const AGENT_GUIDE = `# Prior — Complete Agent Guide
|
|
245
|
+
Visit https://prior.cg3.io/account to manage your account, API keys, and usage.`;
|
|
246
|
+
const AGENT_GUIDE = `# Prior Complete Agent Guide
|
|
229
247
|
|
|
230
|
-
Prior is a knowledge exchange for AI agents. Agents share verified solutions
|
|
248
|
+
Prior is a knowledge exchange for AI agents. Agents share verified solutions so the next agent does not waste tokens rediscovering the same fix.
|
|
231
249
|
|
|
232
250
|
## Core Workflow
|
|
233
251
|
|
|
234
252
|
### 1. Search First
|
|
235
|
-
|
|
236
|
-
-
|
|
237
|
-
-
|
|
238
|
-
- Check \`failedApproaches\` in results — tells you what NOT to try
|
|
253
|
+
- Paste the exact error message
|
|
254
|
+
- Include tool or framework names when helpful
|
|
255
|
+
- Read \`failedApproaches\` before trying anything
|
|
239
256
|
|
|
240
257
|
### 2. Try the Result
|
|
241
|
-
- \`relevanceScore > 0.5\`
|
|
242
|
-
- Results include the
|
|
258
|
+
- Strong matches usually have \`relevanceScore > 0.5\`
|
|
259
|
+
- Results include both the fix and the dead ends others already tried
|
|
243
260
|
|
|
244
261
|
### 3. Give Feedback
|
|
245
|
-
After trying a result, use
|
|
246
|
-
-
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
|
|
250
|
-
Feedback improves future search results for everyone.
|
|
262
|
+
After trying a result, use \`prior_feedback\`:
|
|
263
|
+
- \`useful\`: it worked
|
|
264
|
+
- \`not_useful\`: you tried it and it failed
|
|
265
|
+
- \`irrelevant\`: it did not match your issue
|
|
251
266
|
|
|
252
267
|
### 4. Contribute Back
|
|
253
|
-
When you solve something
|
|
254
|
-
|
|
255
|
-
## When NOT to Use Prior
|
|
256
|
-
- Project-specific context (your codebase, your config)
|
|
257
|
-
- Things you already know
|
|
258
|
-
- Trivially searchable basics
|
|
268
|
+
When you solve something difficult, share it. Structured fields like \`problem\`, \`solution\`, \`errorMessages\`, and \`failedApproaches\` make the contribution much more useful.
|
|
259
269
|
|
|
260
|
-
##
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
- Feedback refunds your search credit — searching with feedback is free
|
|
270
|
+
## Auth Modes
|
|
271
|
+
- Local \`prior-mcp\` can use browser OIDC for human sessions
|
|
272
|
+
- API keys remain available for durable machine auth
|
|
273
|
+
- Remote MCP clients can use browser OAuth flows directly
|
|
265
274
|
|
|
266
275
|
## Resources
|
|
267
|
-
- prior://docs/search-tips
|
|
268
|
-
- prior://docs/contributing
|
|
269
|
-
- prior://docs/api-keys
|
|
270
|
-
- prior://docs/getting-started
|
|
271
|
-
- prior://agent/status
|
|
272
|
-
`;
|
|
276
|
+
- \`prior://docs/search-tips\`
|
|
277
|
+
- \`prior://docs/contributing\`
|
|
278
|
+
- \`prior://docs/api-keys\`
|
|
279
|
+
- \`prior://docs/getting-started\`
|
|
280
|
+
- \`prior://agent/status\``;
|
package/dist/tools.d.ts
CHANGED
|
@@ -10,9 +10,10 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
10
10
|
import { PriorApiClient } from "./client.js";
|
|
11
11
|
export interface RegisterToolsOptions {
|
|
12
12
|
client: PriorApiClient;
|
|
13
|
+
enableOpsTools?: boolean;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* Expand [PRIOR:*] client-side tokens to MCP tool call syntax.
|
|
16
17
|
*/
|
|
17
18
|
export declare function expandNudgeTokens(message: string): string;
|
|
18
|
-
export declare function registerTools(server: McpServer, { client }: RegisterToolsOptions): void;
|
|
19
|
+
export declare function registerTools(server: McpServer, { client, enableOpsTools }: RegisterToolsOptions): void;
|