Skip to content

Commit c786c3c

Browse files
committed
init
1 parent c68a6cf commit c786c3c

File tree

8 files changed

+972
-2
lines changed

8 files changed

+972
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ celerybeat.pid
128128
*.sage.py
129129

130130
# Environments
131-
.env
131+
.env*
132132
.venv
133133
env/
134134
venv/

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10

README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,51 @@
11
# mcp-server-python
2-
Inkeep MCP Server
2+
Inkeep MCP Server for your docs!
3+
4+
### Dependencies
5+
6+
- An account on [Inkeep](https://inkeep.com)
7+
- [`uv`](https://github.com/astral-sh/uv)
8+
9+
### Setup
10+
11+
```
12+
git clone [email protected]:inkeep/mcp-server-python.git
13+
cd mcp-server-python
14+
uv venv
15+
uv pip install -r pyproject.toml
16+
```
17+
18+
You'll need these environment variables:
19+
```
20+
INKEEP_API_BASE_URL=https://api.inkeep.com/v1
21+
INKEEP_API_KEY=
22+
INKEEP_API_MODEL=inkeep-rag-20250310
23+
```
24+
To get an API key, go to the Inkeep Portal and create an API Integration.
25+
26+
27+
### `claude_desktop_config.json`
28+
29+
```
30+
{
31+
"mcpServers": {
32+
"your-docs-by-inkeep-mcp-server": {
33+
"command": "uv",
34+
"args": [
35+
"--directory",
36+
"/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-server-python",
37+
"run",
38+
"-m",
39+
"inkeep_mcp_server"
40+
],
41+
"env": {
42+
"INKEEP_API_BASE_URL": "https://api.inkeep.com/v1",
43+
"INKEEP_API_KEY": "YOUR_INKEEP_API_KEY",
44+
"INKEEP_API_MODEL": "inkeep-rag-20250310"
45+
}
46+
},
47+
}
48+
}
49+
```
50+
51+
You may need to put the full path to the `uv` executable in the command field. You can get this by running `which uv` on MacOS/Linux or `where uv` on Windows.

inkeep_mcp_server/__main__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from inkeep_mcp_server.server import mcp
2+
3+
if __name__ == "__main__":
4+
mcp.run(transport="stdio")

inkeep_mcp_server/server.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import typing as T
2+
3+
import openai
4+
from mcp.server.fastmcp import FastMCP
5+
from pydantic import BaseModel
6+
7+
from inkeep_mcp_server.settings import inkeep_settings
8+
9+
# Initialize FastMCP server
10+
mcp = FastMCP("inkeep-mcp-server")
11+
12+
13+
# https://docs.anthropic.com/en/docs/build-with-claude/citations#plain-text-documents
14+
class InkeepRAGDocument(BaseModel):
15+
# anthropic fields citation types
16+
type: str
17+
source: T.Dict
18+
title: T.Optional[str] = None
19+
context: T.Optional[str] = None
20+
# inkeep specific fields
21+
source_type: T.Optional[str] = None
22+
url: T.Optional[str] = None
23+
24+
25+
class InkeepRAGResponse(BaseModel):
26+
content: T.List[InkeepRAGDocument] = []
27+
28+
29+
async def make_inkeep_rag_request(query: str) -> InkeepRAGResponse:
30+
async with openai.AsyncOpenAI(
31+
base_url=inkeep_settings.INKEEP_API_BASE_URL,
32+
api_key=inkeep_settings.INKEEP_API_KEY,
33+
) as openai_client:
34+
# https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat
35+
inkeep_rag_response = await openai_client.beta.chat.completions.parse(
36+
model=inkeep_settings.INKEEP_API_MODEL,
37+
messages=[
38+
{"role": "user", "content": query},
39+
],
40+
response_format=InkeepRAGResponse,
41+
)
42+
43+
inkeep_rag_response_parsed = inkeep_rag_response.choices[0].message.parsed
44+
if inkeep_rag_response_parsed:
45+
return inkeep_rag_response_parsed
46+
else:
47+
return InkeepRAGResponse()
48+
49+
50+
@mcp.tool(
51+
name="rag-search",
52+
description="Search for relevant docs for a query using Inkeep's RAG API.",
53+
)
54+
async def rag_search(query: str) -> InkeepRAGResponse:
55+
return await make_inkeep_rag_request(query)

inkeep_mcp_server/settings.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from pydantic_settings import BaseSettings, SettingsConfigDict
2+
3+
4+
class InkeepSettings(BaseSettings):
5+
INKEEP_API_BASE_URL: str
6+
INKEEP_API_KEY: str
7+
INKEEP_API_MODEL: str
8+
9+
model_config = SettingsConfigDict()
10+
11+
12+
inkeep_settings = InkeepSettings() # type: ignore

pyproject.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[project]
2+
name = "inkeep-mcp-server"
3+
version = "0.1.0"
4+
description = "Inkeep MCP Server"
5+
readme = "README.md"
6+
requires-python = ">=3.10"
7+
dependencies = [
8+
"mcp[cli]>=1.3.0",
9+
"openai>=1.66.3",
10+
"pydantic-settings>=2.8.1",
11+
]
12+
13+
[dependency-groups]
14+
dev = [
15+
"black>=25.1.0",
16+
"ipython>=8.34.0",
17+
"isort>=6.0.1",
18+
]

uv.lock

Lines changed: 831 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)