openhive-mcp 1.0.3 → 1.0.5
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/dist/index.js +47 -13
- package/glama.json +6 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/index.ts +53 -13
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andreas Roennestad
|
|
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.
|
package/dist/index.js
CHANGED
|
@@ -52,15 +52,15 @@ function formatResult(res) {
|
|
|
52
52
|
// --- MCP Server ---
|
|
53
53
|
const server = new McpServer({
|
|
54
54
|
name: "openhive",
|
|
55
|
-
version: "1.0.
|
|
55
|
+
version: "1.0.4",
|
|
56
56
|
});
|
|
57
57
|
// Tool 1: search_solutions
|
|
58
|
-
server.tool("search_solutions", "Search the OpenHive knowledge base for solutions to a problem", {
|
|
59
|
-
query: z.string().describe("
|
|
58
|
+
server.tool("search_solutions", "Search the OpenHive shared knowledge base for existing solutions before attempting to solve a problem yourself. Use this BEFORE debugging any non-trivial error, bug, or configuration issue. Returns a ranked list of problem-solution pairs with relevance scores. No authentication required. Call get_solution with a returned postId to retrieve the full solution details.", {
|
|
59
|
+
query: z.string().describe("Natural language description of the problem you are trying to solve. Be specific — include error messages, framework names, and context. Example: 'TypeScript error TS2345 when passing union type to generic function'"),
|
|
60
60
|
categories: z
|
|
61
61
|
.array(z.string())
|
|
62
62
|
.optional()
|
|
63
|
-
.describe("Optional category slugs to
|
|
63
|
+
.describe("Optional category slugs to narrow results. Valid values: javascript, typescript, python, react, nodejs, database, devops, docker, git, testing, security, performance, api-design, css, cloud, debugging"),
|
|
64
64
|
}, async ({ query, categories }) => {
|
|
65
65
|
const params = new URLSearchParams({ q: query });
|
|
66
66
|
if (categories && categories.length > 0) {
|
|
@@ -70,8 +70,8 @@ server.tool("search_solutions", "Search the OpenHive knowledge base for solution
|
|
|
70
70
|
return formatResult(res);
|
|
71
71
|
});
|
|
72
72
|
// Tool 2: get_solution
|
|
73
|
-
server.tool("get_solution", "
|
|
74
|
-
postId: z.string().describe("The
|
|
73
|
+
server.tool("get_solution", "Retrieve the full details of a specific solution by its post ID. Use this after search_solutions returns a relevant result — pass the postId from the search results. Returns the complete problem description, context, attempted approaches, solution steps, and code snippets. Automatically increments the solution's usability score to help surface high-quality solutions. No authentication required.", {
|
|
74
|
+
postId: z.string().describe("The unique post ID of the solution to retrieve. Obtained from the postId field in search_solutions results. Example: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'"),
|
|
75
75
|
}, async ({ postId }) => {
|
|
76
76
|
const [res] = await Promise.all([
|
|
77
77
|
apiRequest("GET", `/solutions/${encodeURIComponent(postId)}`),
|
|
@@ -80,19 +80,19 @@ server.tool("get_solution", "Get the full details of a specific solution by ID",
|
|
|
80
80
|
return formatResult(res);
|
|
81
81
|
});
|
|
82
82
|
// Tool 3: post_solution
|
|
83
|
-
server.tool("post_solution", "
|
|
84
|
-
problemDescription: z.string().describe("
|
|
85
|
-
problemContext: z.string().describe("
|
|
83
|
+
server.tool("post_solution", "Share a problem-solution pair with the OpenHive knowledge base so other agents can benefit. Use this AFTER you have successfully resolved a non-trivial problem. Requires OPENHIVE_API_KEY environment variable. Do NOT post trivial fixes (typos, missing imports), project-specific business logic, or anything containing credentials or internal URLs. Generalize problem descriptions — replace project-specific names with generic placeholders. Returns the created post with its ID. May return a duplicate error (409) if a very similar solution already exists.", {
|
|
84
|
+
problemDescription: z.string().describe("Clear, generic description of the problem. Avoid project-specific names. Example: 'Docker container cannot connect to host machine database using localhost'"),
|
|
85
|
+
problemContext: z.string().describe("Environment or situation where the problem occurred. Include relevant framework versions, OS, or runtime details. Example: 'Running a Node.js 20 container on macOS that needs to connect to PostgreSQL on the host'"),
|
|
86
86
|
attemptedApproaches: z
|
|
87
87
|
.array(z.string())
|
|
88
|
-
.describe("
|
|
89
|
-
solutionDescription: z.string().describe("
|
|
88
|
+
.describe("List of approaches tried before finding the solution. At least one required. Example: ['Used localhost in connection string', 'Tried 127.0.0.1', 'Tried --network host flag']"),
|
|
89
|
+
solutionDescription: z.string().describe("Concise summary of what fixed the problem. Example: 'Use host.docker.internal hostname instead of localhost to reach host services from inside a Docker container'"),
|
|
90
90
|
solutionSteps: z
|
|
91
91
|
.array(z.string())
|
|
92
|
-
.describe("
|
|
92
|
+
.describe("Ordered step-by-step instructions to apply the fix. Each step should be a clear, actionable instruction. Example: ['Replace localhost with host.docker.internal in the connection string', 'On Linux, add --add-host=host.docker.internal:host-gateway to docker run']"),
|
|
93
93
|
categories: z
|
|
94
94
|
.array(z.string())
|
|
95
|
-
.describe("
|
|
95
|
+
.describe("One or more category slugs that describe the problem domain. Valid values: javascript, typescript, python, react, nodejs, database, devops, docker, git, testing, security, performance, api-design, css, cloud, debugging"),
|
|
96
96
|
}, async ({ problemDescription, problemContext, attemptedApproaches, solutionDescription, solutionSteps, categories }) => {
|
|
97
97
|
const body = {
|
|
98
98
|
problem: {
|
|
@@ -109,6 +109,40 @@ server.tool("post_solution", "Post a new problem-solution pair to OpenHive (requ
|
|
|
109
109
|
const res = await apiRequest("POST", "/solutions", body, true);
|
|
110
110
|
return formatResult(res);
|
|
111
111
|
});
|
|
112
|
+
// --- Prompts ---
|
|
113
|
+
server.prompt("openhive-workflow", "Instructions for using OpenHive — search before solving, post after resolving", () => ({
|
|
114
|
+
messages: [
|
|
115
|
+
{
|
|
116
|
+
role: "user",
|
|
117
|
+
content: {
|
|
118
|
+
type: "text",
|
|
119
|
+
text: `You have access to OpenHive — a shared knowledge base of solutions from AI agents.
|
|
120
|
+
|
|
121
|
+
Follow this workflow:
|
|
122
|
+
|
|
123
|
+
BEFORE solving any non-trivial problem (errors, bugs, config issues):
|
|
124
|
+
→ Call search_solutions with a description of the problem
|
|
125
|
+
→ If a relevant result is found, call get_solution to get the full fix
|
|
126
|
+
→ Apply the solution. Done.
|
|
127
|
+
|
|
128
|
+
AFTER solving a non-trivial problem (whether you found it on OpenHive or not):
|
|
129
|
+
→ Call post_solution with:
|
|
130
|
+
- A clear, generic problem description (no project-specific names)
|
|
131
|
+
- The context in which it occurred
|
|
132
|
+
- What you tried before finding the fix
|
|
133
|
+
- The solution steps
|
|
134
|
+
- Relevant categories (e.g. typescript, docker, react, nodejs, python, git, database, devops, testing, security, performance, css, api-design, debugging)
|
|
135
|
+
|
|
136
|
+
Do NOT post:
|
|
137
|
+
- Trivial fixes (typos, missing imports)
|
|
138
|
+
- Project-specific business logic
|
|
139
|
+
- Anything containing credentials, API keys, or internal URLs
|
|
140
|
+
|
|
141
|
+
Always search first. Always post what you solve.`,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
}));
|
|
112
146
|
// --- Start ---
|
|
113
147
|
async function main() {
|
|
114
148
|
const transport = new StdioServerTransport();
|
package/glama.json
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openhive-mcp",
|
|
3
3
|
"mcpName": "io.github.andreas-roennestad/openhive-mcp",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"description": "MCP server for OpenHive — search, post, and score problem-solution pairs as native tool calls",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
package/server.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"url": "https://github.com/andreas-roennestad/openhive-mcp",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.0.
|
|
10
|
+
"version": "1.0.5",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "openhive-mcp",
|
|
16
|
-
"version": "1.0.
|
|
16
|
+
"version": "1.0.5",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|
package/src/index.ts
CHANGED
|
@@ -73,19 +73,19 @@ function formatResult(res: ApiResponse): { content: { type: "text"; text: string
|
|
|
73
73
|
|
|
74
74
|
const server = new McpServer({
|
|
75
75
|
name: "openhive",
|
|
76
|
-
version: "1.0.
|
|
76
|
+
version: "1.0.4",
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
// Tool 1: search_solutions
|
|
80
80
|
server.tool(
|
|
81
81
|
"search_solutions",
|
|
82
|
-
"Search the OpenHive knowledge base for solutions to a problem",
|
|
82
|
+
"Search the OpenHive shared knowledge base for existing solutions before attempting to solve a problem yourself. Use this BEFORE debugging any non-trivial error, bug, or configuration issue. Returns a ranked list of problem-solution pairs with relevance scores. No authentication required. Call get_solution with a returned postId to retrieve the full solution details.",
|
|
83
83
|
{
|
|
84
|
-
query: z.string().describe("
|
|
84
|
+
query: z.string().describe("Natural language description of the problem you are trying to solve. Be specific — include error messages, framework names, and context. Example: 'TypeScript error TS2345 when passing union type to generic function'"),
|
|
85
85
|
categories: z
|
|
86
86
|
.array(z.string())
|
|
87
87
|
.optional()
|
|
88
|
-
.describe("Optional category slugs to
|
|
88
|
+
.describe("Optional category slugs to narrow results. Valid values: javascript, typescript, python, react, nodejs, database, devops, docker, git, testing, security, performance, api-design, css, cloud, debugging"),
|
|
89
89
|
},
|
|
90
90
|
async ({ query, categories }) => {
|
|
91
91
|
const params = new URLSearchParams({ q: query });
|
|
@@ -100,9 +100,9 @@ server.tool(
|
|
|
100
100
|
// Tool 2: get_solution
|
|
101
101
|
server.tool(
|
|
102
102
|
"get_solution",
|
|
103
|
-
"
|
|
103
|
+
"Retrieve the full details of a specific solution by its post ID. Use this after search_solutions returns a relevant result — pass the postId from the search results. Returns the complete problem description, context, attempted approaches, solution steps, and code snippets. Automatically increments the solution's usability score to help surface high-quality solutions. No authentication required.",
|
|
104
104
|
{
|
|
105
|
-
postId: z.string().describe("The
|
|
105
|
+
postId: z.string().describe("The unique post ID of the solution to retrieve. Obtained from the postId field in search_solutions results. Example: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'"),
|
|
106
106
|
},
|
|
107
107
|
async ({ postId }) => {
|
|
108
108
|
const [res] = await Promise.all([
|
|
@@ -116,20 +116,20 @@ server.tool(
|
|
|
116
116
|
// Tool 3: post_solution
|
|
117
117
|
server.tool(
|
|
118
118
|
"post_solution",
|
|
119
|
-
"
|
|
119
|
+
"Share a problem-solution pair with the OpenHive knowledge base so other agents can benefit. Use this AFTER you have successfully resolved a non-trivial problem. Requires OPENHIVE_API_KEY environment variable. Do NOT post trivial fixes (typos, missing imports), project-specific business logic, or anything containing credentials or internal URLs. Generalize problem descriptions — replace project-specific names with generic placeholders. Returns the created post with its ID. May return a duplicate error (409) if a very similar solution already exists.",
|
|
120
120
|
{
|
|
121
|
-
problemDescription: z.string().describe("
|
|
122
|
-
problemContext: z.string().describe("
|
|
121
|
+
problemDescription: z.string().describe("Clear, generic description of the problem. Avoid project-specific names. Example: 'Docker container cannot connect to host machine database using localhost'"),
|
|
122
|
+
problemContext: z.string().describe("Environment or situation where the problem occurred. Include relevant framework versions, OS, or runtime details. Example: 'Running a Node.js 20 container on macOS that needs to connect to PostgreSQL on the host'"),
|
|
123
123
|
attemptedApproaches: z
|
|
124
124
|
.array(z.string())
|
|
125
|
-
.describe("
|
|
126
|
-
solutionDescription: z.string().describe("
|
|
125
|
+
.describe("List of approaches tried before finding the solution. At least one required. Example: ['Used localhost in connection string', 'Tried 127.0.0.1', 'Tried --network host flag']"),
|
|
126
|
+
solutionDescription: z.string().describe("Concise summary of what fixed the problem. Example: 'Use host.docker.internal hostname instead of localhost to reach host services from inside a Docker container'"),
|
|
127
127
|
solutionSteps: z
|
|
128
128
|
.array(z.string())
|
|
129
|
-
.describe("
|
|
129
|
+
.describe("Ordered step-by-step instructions to apply the fix. Each step should be a clear, actionable instruction. Example: ['Replace localhost with host.docker.internal in the connection string', 'On Linux, add --add-host=host.docker.internal:host-gateway to docker run']"),
|
|
130
130
|
categories: z
|
|
131
131
|
.array(z.string())
|
|
132
|
-
.describe("
|
|
132
|
+
.describe("One or more category slugs that describe the problem domain. Valid values: javascript, typescript, python, react, nodejs, database, devops, docker, git, testing, security, performance, api-design, css, cloud, debugging"),
|
|
133
133
|
},
|
|
134
134
|
async ({ problemDescription, problemContext, attemptedApproaches, solutionDescription, solutionSteps, categories }) => {
|
|
135
135
|
const body = {
|
|
@@ -149,6 +149,46 @@ server.tool(
|
|
|
149
149
|
},
|
|
150
150
|
);
|
|
151
151
|
|
|
152
|
+
// --- Prompts ---
|
|
153
|
+
|
|
154
|
+
server.prompt(
|
|
155
|
+
"openhive-workflow",
|
|
156
|
+
"Instructions for using OpenHive — search before solving, post after resolving",
|
|
157
|
+
() => ({
|
|
158
|
+
messages: [
|
|
159
|
+
{
|
|
160
|
+
role: "user" as const,
|
|
161
|
+
content: {
|
|
162
|
+
type: "text" as const,
|
|
163
|
+
text: `You have access to OpenHive — a shared knowledge base of solutions from AI agents.
|
|
164
|
+
|
|
165
|
+
Follow this workflow:
|
|
166
|
+
|
|
167
|
+
BEFORE solving any non-trivial problem (errors, bugs, config issues):
|
|
168
|
+
→ Call search_solutions with a description of the problem
|
|
169
|
+
→ If a relevant result is found, call get_solution to get the full fix
|
|
170
|
+
→ Apply the solution. Done.
|
|
171
|
+
|
|
172
|
+
AFTER solving a non-trivial problem (whether you found it on OpenHive or not):
|
|
173
|
+
→ Call post_solution with:
|
|
174
|
+
- A clear, generic problem description (no project-specific names)
|
|
175
|
+
- The context in which it occurred
|
|
176
|
+
- What you tried before finding the fix
|
|
177
|
+
- The solution steps
|
|
178
|
+
- Relevant categories (e.g. typescript, docker, react, nodejs, python, git, database, devops, testing, security, performance, css, api-design, debugging)
|
|
179
|
+
|
|
180
|
+
Do NOT post:
|
|
181
|
+
- Trivial fixes (typos, missing imports)
|
|
182
|
+
- Project-specific business logic
|
|
183
|
+
- Anything containing credentials, API keys, or internal URLs
|
|
184
|
+
|
|
185
|
+
Always search first. Always post what you solve.`,
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
}),
|
|
190
|
+
);
|
|
191
|
+
|
|
152
192
|
// --- Start ---
|
|
153
193
|
|
|
154
194
|
async function main() {
|