push-oynptmmzrplt #2
23
Dockerfile
23
Dockerfile
@@ -38,23 +38,36 @@ RUN curl -fsSL https://opencode.ai/install | bash && \
|
|||||||
|
|
||||||
ENV GOPATH=/usr/local/go
|
ENV GOPATH=/usr/local/go
|
||||||
ENV GOBIN=/usr/local/go/bin
|
ENV GOBIN=/usr/local/go/bin
|
||||||
RUN go install golang.org/x/tools/gopls@latest
|
RUN go install golang.org/x/tools/gopls@latest \
|
||||||
RUN go install github.com/isaacphi/mcp-language-server@latest
|
&& go install github.com/isaacphi/mcp-language-server@latest \
|
||||||
|
&& go install github.com/dorcha-inc/orla/cmd/orla@latest
|
||||||
|
|
||||||
|
RUN mkdir -p /etc/bash_completion.d \
|
||||||
|
&& orla completion bash > /etc/bash_completion.d/orla \
|
||||||
|
&& jj util completion bash > /etc/bash_completion.d/jj
|
||||||
|
|
||||||
|
RUN rustup component add rust-analyzer --toolchain nightly
|
||||||
|
|
||||||
ARG USERNAME=devuser
|
ARG USERNAME=devuser
|
||||||
ARG USER_UID=1000
|
ARG USER_UID=1000
|
||||||
ARG USER_GID=1000
|
ARG USER_GID=1000
|
||||||
RUN groupadd --gid $USER_GID $USERNAME && \
|
RUN groupadd --gid $USER_GID $USERNAME && \
|
||||||
useradd --uid $USER_UID \
|
useradd --uid $USER_UID \
|
||||||
--gid $USER_GID \
|
--gid $USER_GID \
|
||||||
-m $USERNAME \
|
-m $USERNAME \
|
||||||
--shell /bin/bash
|
--shell /bin/bash && \
|
||||||
|
echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME && \
|
||||||
|
chmod 440 /etc/sudoers.d/$USERNAME
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh
|
COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||||
|
RUN mkdir -p /home/${USERNAME}/.config \
|
||||||
|
&& chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.config
|
||||||
|
COPY --chown=${USERNAME}:${USERNAME} opencode /home/${USERNAME}/.config/opencode
|
||||||
|
|
||||||
USER $USERNAME
|
USER $USERNAME
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
CMD ["/bin/bash"]
|
CMD ["/bin/bash"]
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
|
|
||||||
export USERNAME=${USERNAME:-devuser}
|
export USERNAME=${USERNAME:-devuser}
|
||||||
|
|
||||||
|
export WORKSPACE=${WORKSPACE:-/workspace}
|
||||||
export LOCAL_LLM_API=${LOCAL_LLM_API:-http://host.docker.internal:1248/v1}
|
export LOCAL_LLM_API=${LOCAL_LLM_API:-http://host.docker.internal:1248/v1}
|
||||||
|
export LLM_MODEL=${LLM_MODEL:-'ollama:qwen/qwen3-coder-next@4bit'}
|
||||||
|
export ORLA_OLLAMA_HOST=$(sed -E 's@(https?://[^/]+).*$@\1@' <<< $LOCAL_LLM_API)
|
||||||
export MAXTOKEN=${MAXTOKEN:-4096}
|
export MAXTOKEN=${MAXTOKEN:-4096}
|
||||||
export NUM_CTX=${NUM_CTX:-32768}
|
export NUM_CTX=${NUM_CTX:-32768}
|
||||||
export REPEAT_PENALTY=${REPEAT_PENALTY:-1.3}
|
export REPEAT_PENALTY=${REPEAT_PENALTY:-1.3}
|
||||||
@@ -23,6 +26,8 @@ fi
|
|||||||
if [ -n "$LOCAL_LLM_API" ]; then
|
if [ -n "$LOCAL_LLM_API" ]; then
|
||||||
if ! grep -q "LOCAL_LLM_API" /home/${USERNAME}/.bashrc; then
|
if ! grep -q "LOCAL_LLM_API" /home/${USERNAME}/.bashrc; then
|
||||||
echo "export LOCAL_LLM_API=$LOCAL_LLM_API" >> /home/${USERNAME}/.bashrc
|
echo "export LOCAL_LLM_API=$LOCAL_LLM_API" >> /home/${USERNAME}/.bashrc
|
||||||
|
echo "export ORLA_OLLAMA_HOST=$ORLA_OLLAMA_HOST" >> /home/${USERNAME}/.bashrc
|
||||||
|
echo "export ORLA_MODEL='${LLM_MODEL}'" >> /home/${USERNAME}/.bashrc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /home/${USERNAME}/.config/opencode
|
mkdir -p /home/${USERNAME}/.config/opencode
|
||||||
@@ -31,6 +36,45 @@ if [ -n "$LOCAL_LLM_API" ]; then
|
|||||||
cat > $CONFIG_FILE <<EOF
|
cat > $CONFIG_FILE <<EOF
|
||||||
{
|
{
|
||||||
"\$schema": "https://opencode.ai/config.json",
|
"\$schema": "https://opencode.ai/config.json",
|
||||||
|
"mcp": {
|
||||||
|
"go-lsp-tools": {
|
||||||
|
"type": "local",
|
||||||
|
"command": ["mcp-language-server",
|
||||||
|
"--workspace", "$WORKSPACE",
|
||||||
|
"--lsp", "gopls"
|
||||||
|
],
|
||||||
|
"enabled": true,
|
||||||
|
"environment": {
|
||||||
|
"GOPATH": "$GOPATH"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"python-lsp-tools": {
|
||||||
|
"type": "local",
|
||||||
|
"command": ["mcp-language-server",
|
||||||
|
"--workspace", "$WORKSPACE",
|
||||||
|
"--lsp", "pyright-langserver",
|
||||||
|
"--", "--stdio"
|
||||||
|
],
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"rust-lsp-tools": {
|
||||||
|
"type": "local",
|
||||||
|
"command": ["mcp-language-server",
|
||||||
|
"--workspace", "$WORKSPACE",
|
||||||
|
"--lsp", "$(find /usr/local/rustup/toolchains -type f -name rust-analyzer)"
|
||||||
|
],
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"typescript-lsp-tools": {
|
||||||
|
"type": "local",
|
||||||
|
"command": ["mcp-language-server",
|
||||||
|
"--workspace", "$WORKSPACE",
|
||||||
|
"--lsp", "typescript-language-server",
|
||||||
|
"--", "--stdio"
|
||||||
|
],
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"lmstudio": {
|
"lmstudio": {
|
||||||
"npm": "@ai-sdk/openai-compatible",
|
"npm": "@ai-sdk/openai-compatible",
|
||||||
@@ -75,44 +119,13 @@ if [ -n "$LOCAL_LLM_API" ]; then
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"model": "lmstudio/qwen/qwen3-coder-next@4bit"
|
"model": "${LLM_MODEL}"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chown ${USERNAME}:${USERNAME} ${CONFIG_FILE}
|
chown ${USERNAME}:${USERNAME} ${CONFIG_FILE}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Install MCP Language Server ---
|
|
||||||
if command -v mcp-language-server &> /dev/null; then
|
|
||||||
mkdir -p /home/${USERNAME}/.config/opencode
|
|
||||||
MCP_CONFIG=/home/${USERNAME}/.config/opencode/mcp_servers.json
|
|
||||||
|
|
||||||
cat > $MCP_CONFIG <<EOF
|
|
||||||
{
|
|
||||||
"mcpServers": {
|
|
||||||
"language-server": {
|
|
||||||
"command": "mcp-language-server",
|
|
||||||
"args": [
|
|
||||||
"--workspace",
|
|
||||||
"/workspace",
|
|
||||||
"--lsp",
|
|
||||||
"gopls"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"PATH": "/usr/local/go/bin:/usr/local/cargo/bin:/usr/local/bin:$PATH",
|
|
||||||
"GOPATH": "/home/${USERNAME}/go",
|
|
||||||
"GOCACHE": "/home/${USERNAME}/.cache/go-build",
|
|
||||||
"GOMODCACHE": "/home/${USERNAME}/go/pkg/mod"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chown ${USERNAME}:${USERNAME} $MCP_CONFIG
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# --- Force Bash comme shell par défaut ---
|
# --- Force Bash comme shell par défaut ---
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ]; then
|
||||||
exec /bin/bash
|
exec /bin/bash
|
||||||
|
|||||||
49
opencode/AGENTs.md
Normal file
49
opencode/AGENTs.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# AGENTS.md - Development Guidelines
|
||||||
|
|
||||||
|
## Code Style Guidelines
|
||||||
|
|
||||||
|
### General Principles
|
||||||
|
- Use relative paths only (never absolute paths)
|
||||||
|
- Operate strictly on explicitly mentioned files
|
||||||
|
- Generate minimal, single implementations
|
||||||
|
- Avoid speculation about missing files
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
- Use structured error messages
|
||||||
|
- Avoid verbose stack traces in user-facing output
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
- Variables/functions: `snake_case`
|
||||||
|
- Types/interfaces: `PascalCase`
|
||||||
|
- Constants: `UPPER_SNAKE_CASE`
|
||||||
|
|
||||||
|
## CRITICAL Security Rules
|
||||||
|
|
||||||
|
### File Operations
|
||||||
|
- **NEVER** delete files without explicit human authorization
|
||||||
|
- **NEVER** modify files outside the scope of the requested task
|
||||||
|
- Always use relative paths (never absolute paths)
|
||||||
|
|
||||||
|
### Version Control with `jj`
|
||||||
|
- Projects are managed with `jj` (Jujutsu), NOT Git
|
||||||
|
- **Before starting modifications to respond to a user prompt**, run `jj new` to create a commit
|
||||||
|
- This creates a baseline to revert all changes from that prompt if needed
|
||||||
|
- Do NOT run `jj new` for every individual file change—only once at the start of a prompt response
|
||||||
|
|
||||||
|
## File Generation Rules
|
||||||
|
- Output only requested files
|
||||||
|
- Do not modify unrelated files
|
||||||
|
- Valid JSON without comments when requested
|
||||||
|
- Assume no knowledge of other files unless provided
|
||||||
|
|
||||||
|
## MCP Tools
|
||||||
|
- Located in `/opt/dev-tools/`
|
||||||
|
- Use SQLite for graph storage (`.ai_index/graph.db`)
|
||||||
|
- Embeddings stored in `.ai_index/embeddings/`
|
||||||
|
- AST data in `.ai_index/ast/`
|
||||||
|
|
||||||
|
## LM Studio Integration
|
||||||
|
- Local LLM API: `http://host.docker.internal:1248`
|
||||||
|
- Model: `qwen/qwen3-coder-next@4bit`
|
||||||
|
- Context window: 32768 tokens
|
||||||
|
- Max output: 65536 tokens
|
||||||
33
pyproject.toml
Normal file
33
pyproject.toml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[project]
|
||||||
|
name = "pmocrazykoder"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A crazy MCP server"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"crazy-mcp>=0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"ruff",
|
||||||
|
"black",
|
||||||
|
"mypy",
|
||||||
|
"isort",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = ["E", "F", "I", "N", "W"]
|
||||||
|
ignore = []
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
target-version = ["py310"]
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
python_version = "3.10"
|
||||||
37
src/PMOCrazyCoder.py
Normal file
37
src/PMOCrazyCoder.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from crazy_mcp import Context, mcp
|
||||||
|
from crazy_mcp.tools import *
|
||||||
|
|
||||||
|
|
||||||
|
# Déclaration d'un outil
|
||||||
|
@mcp.tool(description="Renvoie le texte reçu")
|
||||||
|
def echo_texte(texte: str) -> str:
|
||||||
|
return f"Écho du serveur : {texte} mec"
|
||||||
|
|
||||||
|
|
||||||
|
# Déclaration d'un second outil pour démonstration
|
||||||
|
@mcp.tool(description="Renvoie le texte en majuscules")
|
||||||
|
def shout_texte(texte: str) -> str:
|
||||||
|
return texte.upper()
|
||||||
|
|
||||||
|
|
||||||
|
# Déclaration d'un outil pour additionner deux nombres
|
||||||
|
@mcp.tool(description="Additionne deux nombres")
|
||||||
|
def additionner(a: float, b: float) -> float:
|
||||||
|
return a + b
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.tool
|
||||||
|
async def increment(ctx: Context) -> tuple[int, str]:
|
||||||
|
count = ctx.get_state("count") or 0
|
||||||
|
ctx.set_state("count", count + 1)
|
||||||
|
return count + 1, ctx.session_id
|
||||||
|
|
||||||
|
|
||||||
|
# Lancement du serveur MCP
|
||||||
|
if __name__ == "__main__":
|
||||||
|
mcp.run(
|
||||||
|
transport="http", # Transport réseau HTTP
|
||||||
|
host="0.0.0.0", # Adresse d’écoute
|
||||||
|
port=7860, # Port TCP
|
||||||
|
path="/mcp", # Chemin MCP (par défaut /mcp)
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user