SobroJuriBert / UPDATE_MCP_CONFIG.md
Sobro Inc
Fix permission errors and use simplified version
4786618

Обновление конфигурации MCP для SobroJuriBert

После развертывания SobroJuriBert, обнови конфигурацию MCP:

1. Обнови файл конфигурации

Отредактируй /mnt/c/Users/s7/AppData/Roaming/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\s7\\Documents",
        "C:\\sobro-mcp"
      ]
    },
    "memory": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-memory"
      ]
    },
    "sobrojuribert": {
      "command": "C:\\Users\\s7\\AppData\\Local\\Microsoft\\WindowsApps\\python.exe",
      "args": [
        "C:\\sobro-mcp\\sobrojuribert_mcp.py"
      ]
    }
  }
}

2. Создай новый MCP сервер

Создай файл C:\sobro-mcp\sobrojuribert_mcp.py:

#!/usr/bin/env python3
"""SobroJuriBert MCP Server"""

import asyncio
from typing import Any
import aiohttp
from mcp.server.models import InitializationOptions
from mcp.server import NotificationOptions, Server
import mcp.server.stdio
import mcp.types as types

API_URL = "https://sobroinc-sobrojuribert.hf.space"

async def run_server():
    server = Server("sobrojuribert-mcp")
    
    session = None
    
    @server.list_tools()
    async def handle_list_tools() -> list[types.Tool]:
        return [
            types.Tool(
                name="juribert_mask_fill",
                description="Fill [MASK] tokens in French legal text",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {"type": "string", "description": "Text with [MASK] tokens"},
                        "top_k": {"type": "integer", "default": 5}
                    },
                    "required": ["text"]
                }
            ),
            types.Tool(
                name="juribert_embeddings",
                description="Generate embeddings for French legal texts",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "texts": {"type": "array", "items": {"type": "string"}}
                    },
                    "required": ["texts"]
                }
            ),
            types.Tool(
                name="juribert_ner",
                description="Extract entities from French legal text",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {"type": "string"}
                    },
                    "required": ["text"]
                }
            ),
            types.Tool(
                name="juribert_classify",
                description="Classify French legal documents",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {"type": "string"}
                    },
                    "required": ["text"]
                }
            ),
            types.Tool(
                name="juribert_analyze_contract",
                description="Analyze French legal contracts",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {"type": "string"},
                        "contract_type": {"type": "string"}
                    },
                    "required": ["text"]
                }
            )
        ]
    
    @server.call_tool()
    async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
        nonlocal session
        
        if session is None:
            session = aiohttp.ClientSession()
        
        try:
            endpoint_map = {
                "juribert_mask_fill": "/mask-fill",
                "juribert_embeddings": "/embeddings",
                "juribert_ner": "/ner",
                "juribert_classify": "/classify",
                "juribert_analyze_contract": "/analyze-contract"
            }
            
            endpoint = endpoint_map.get(name)
            if not endpoint:
                return [types.TextContent(type="text", text=f"Unknown tool: {name}")]
            
            async with session.post(
                f"{API_URL}{endpoint}",
                json=arguments,
                timeout=aiohttp.ClientTimeout(total=30)
            ) as response:
                result = await response.json()
                
                # Format response based on tool
                if name == "juribert_mask_fill":
                    text = f"Predictions for: {result['input']}\n"
                    for pred in result['predictions']:
                        text += f"- {pred['sequence']} (score: {pred['score']:.3f})\n"
                
                elif name == "juribert_embeddings":
                    text = f"Generated {len(result['embeddings'])} embeddings "
                    text += f"(dimension: {result['dimension']})"
                
                elif name == "juribert_ner":
                    text = f"Found {len(result['entities'])} entities:\n"
                    for ent in result['entities']:
                        text += f"- {ent['text']} ({ent['type']})\n"
                
                elif name == "juribert_classify":
                    text = f"Document classification:\n"
                    text += f"Primary: {result['primary_category']}\n"
                    text += f"Confidence: {result['confidence']:.1%}\n"
                
                elif name == "juribert_analyze_contract":
                    text = f"Contract Analysis:\n"
                    text += f"Type: {result['contract_type']}\n"
                    text += f"Parties: {len(result['parties'])}\n"
                    text += f"Key clauses: {', '.join(result['key_clauses'])}\n"
                    if result['missing_clauses']:
                        text += f"Missing: {', '.join(result['missing_clauses'])}\n"
                
                return [types.TextContent(type="text", text=text)]
                
        except Exception as e:
            return [types.TextContent(type="text", text=f"Error: {str(e)}")]
    
    async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            InitializationOptions(
                server_name="sobrojuribert-mcp",
                server_version="1.0.0",
                capabilities=server.get_capabilities(
                    notification_options=NotificationOptions(),
                    experimental_capabilities={},
                ),
            ),
        )
    
    if session:
        await session.close()

def main():
    asyncio.run(run_server())

if __name__ == "__main__":
    main()

3. Перезапусти Claude Desktop

После обновления конфигурации, перезапусти Claude Desktop.

4. Используй новые команды

Используй juribert_mask_fill с текстом "Le contrat est signé entre les [MASK]"

Используй juribert_ner для извлечения сущностей из "Le Tribunal de Grande Instance de Paris"

Классифицируй документ с помощью juribert_classify

Проанализируй контракт с помощью juribert_analyze_contract