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 GOBIN=/usr/local/go/bin
|
||||
RUN go install golang.org/x/tools/gopls@latest
|
||||
RUN go install github.com/isaacphi/mcp-language-server@latest
|
||||
RUN go install golang.org/x/tools/gopls@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 USER_UID=1000
|
||||
ARG USER_GID=1000
|
||||
RUN groupadd --gid $USER_GID $USERNAME && \
|
||||
useradd --uid $USER_UID \
|
||||
--gid $USER_GID \
|
||||
-m $USERNAME \
|
||||
--shell /bin/bash
|
||||
--gid $USER_GID \
|
||||
-m $USERNAME \
|
||||
--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
|
||||
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
|
||||
WORKDIR /workspace
|
||||
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
export USERNAME=${USERNAME:-devuser}
|
||||
|
||||
export WORKSPACE=${WORKSPACE:-/workspace}
|
||||
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 NUM_CTX=${NUM_CTX:-32768}
|
||||
export REPEAT_PENALTY=${REPEAT_PENALTY:-1.3}
|
||||
@@ -23,6 +26,8 @@ fi
|
||||
if [ -n "$LOCAL_LLM_API" ]; then
|
||||
if ! grep -q "LOCAL_LLM_API" /home/${USERNAME}/.bashrc; then
|
||||
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
|
||||
|
||||
mkdir -p /home/${USERNAME}/.config/opencode
|
||||
@@ -31,6 +36,45 @@ if [ -n "$LOCAL_LLM_API" ]; then
|
||||
cat > $CONFIG_FILE <<EOF
|
||||
{
|
||||
"\$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": {
|
||||
"lmstudio": {
|
||||
"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
|
||||
|
||||
chown ${USERNAME}:${USERNAME} ${CONFIG_FILE}
|
||||
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 ---
|
||||
if [ -z "$1" ]; then
|
||||
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