feat(plugins): add MCP server + 4 new plugin bundles (Windsurf, Cline, Continue, VS Code)

MCP Server (semantica/mcp_server.py):
- Full stdio-based MCP server compatible with Claude Desktop, Windsurf,
  Cline, Continue, VS Code, Roo Code, and any MCP-aware tool
- 12 tools: extract_entities, extract_relations, record_decision,
  query_decisions, find_precedents, get_causal_chain, add_entity,
  add_relationship, run_reasoning, get_graph_analytics, export_graph,
  get_graph_summary
- 3 resources: semantica://graph/summary, semantica://decisions/list,
  semantica://schema/info
- Lazy graph session with optional SEMANTICA_KG_PATH env var
- JSON-RPC 2.0 over stdin/stdout; run with: python -m semantica.mcp_server

New plugin bundles (each: plugin.json + marketplace.json + README.md):
- plugins/.windsurf-plugin/ — Windsurf MCP config + 17 skills + 3 agents
- plugins/.cline-plugin/    — Cline MCP config + 17 skills + 3 agents
- plugins/.continue-plugin/ — Continue MCP config + 17 skills + 3 agents
- plugins/.vscode-plugin/   — VS Code MCP config + 17 skills + 3 agents

Updated plugins/.claude-plugin/README.md:
- Platform support table expanded to 9 tools
- Full MCP server section: per-tool config snippets for Claude Desktop,
  Windsurf, Cline, Continue, VS Code; tool/resource reference tables;
  environment variables

Updated README.md:
- Hero line updated to mention MCP server
- Visual grid: Windsurf/VS Code/Cline/Continue → 'MCP server + plugin';
  Claude Desktop → 'MCP server'
- Plugin Bundles section: expanded table listing all 7 bundles with dirs
- New MCP Server section with quick-start snippet and tool/resource list
- Detailed integrations table: corrected connection types and config paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
KaifAhmad1
2026-04-13 16:59:45 +05:30
co-authored by Claude Sonnet 4.6
parent f2eb3e1608
commit ab93ec3e8f
15 changed files with 1108 additions and 24 deletions
+51 -14
View File
@@ -55,7 +55,7 @@ pip install semantica
## 🔌 Works With Every AI Tool ## 🔌 Works With Every AI Tool
Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex and connects to any other tool via its **REST API** (FastAPI server, port 8000) or as an **MCP data source** you can pull from. Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex, an **MCP server** (`python -m semantica.mcp_server`) for Windsurf, Cline, Continue, VS Code, and Claude Desktop, and a **REST API** (FastAPI, port 8000) for any other tool.
<table> <table>
<tr> <tr>
@@ -77,17 +77,17 @@ Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex —
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://windsurf.com"><img src="https://exafunction.github.io/public/brand/windsurf-black-symbol.svg" alt="Windsurf" width="48" height="48" /></a><br/> <a href="https://windsurf.com"><img src="https://exafunction.github.io/public/brand/windsurf-black-symbol.svg" alt="Windsurf" width="48" height="48" /></a><br/>
<strong>Windsurf</strong><br/> <strong>Windsurf</strong><br/>
<sub>REST API</sub> <sub>MCP server + plugin</sub>
</td> </td>
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://claude.ai/download"><img src="https://github.com/anthropics.png?size=120" alt="Claude Desktop" width="48" height="48" /></a><br/> <a href="https://claude.ai/download"><img src="https://github.com/anthropics.png?size=120" alt="Claude Desktop" width="48" height="48" /></a><br/>
<strong>Claude Desktop</strong><br/> <strong>Claude Desktop</strong><br/>
<sub>REST API</sub> <sub>MCP server</sub>
</td> </td>
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://github.com/microsoft/vscode"><img src="https://github.com/microsoft.png?size=120" alt="VS Code" width="48" height="48" /></a><br/> <a href="https://github.com/microsoft/vscode"><img src="https://github.com/microsoft.png?size=120" alt="VS Code" width="48" height="48" /></a><br/>
<strong>VS Code</strong><br/> <strong>VS Code</strong><br/>
<sub>REST API</sub> <sub>MCP server + plugin</sub>
</td> </td>
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://github.com/features/copilot"><img src="https://github.com/github.png?size=120" alt="GitHub Copilot" width="48" height="48" /></a><br/> <a href="https://github.com/features/copilot"><img src="https://github.com/github.png?size=120" alt="GitHub Copilot" width="48" height="48" /></a><br/>
@@ -97,7 +97,7 @@ Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex —
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://github.com/cline/cline"><img src="https://github.com/cline.png?size=120" alt="Cline" width="48" height="48" /></a><br/> <a href="https://github.com/cline/cline"><img src="https://github.com/cline.png?size=120" alt="Cline" width="48" height="48" /></a><br/>
<strong>Cline</strong><br/> <strong>Cline</strong><br/>
<sub>REST API</sub> <sub>MCP server + plugin</sub>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -109,7 +109,7 @@ Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex —
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://github.com/continuedev/continue"><img src="https://github.com/continuedev.png?size=120" alt="Continue" width="48" height="48" /></a><br/> <a href="https://github.com/continuedev/continue"><img src="https://github.com/continuedev.png?size=120" alt="Continue" width="48" height="48" /></a><br/>
<strong>Continue</strong><br/> <strong>Continue</strong><br/>
<sub>REST API</sub> <sub>MCP server + plugin</sub>
</td> </td>
<td align="center" width="12.5%"> <td align="center" width="12.5%">
<a href="https://github.com/block/goose"><img src="https://github.com/block.png?size=120" alt="Goose" width="48" height="48" /></a><br/> <a href="https://github.com/block/goose"><img src="https://github.com/block.png?size=120" alt="Goose" width="48" height="48" /></a><br/>
@@ -146,7 +146,17 @@ Semantica ships **native plugin bundles** for Claude Code, Cursor, and Codex —
### Plugin Bundles (Claude Code · Cursor · Codex) ### Plugin Bundles (Claude Code · Cursor · Codex)
Native plugin bundles live under [`plugins/`](plugins/) — install once, works across all three tools. Native plugin bundles live under [`plugins/`](plugins/). Each directory contains a `plugin.json`, `marketplace.json`, and `README.md`.
| Bundle | Directory | Tools |
|---|---|---|
| Claude Code | [`plugins/.claude-plugin/`](plugins/.claude-plugin/) | 17 skills · 3 agents · hooks |
| Cursor | [`plugins/.cursor-plugin/`](plugins/.cursor-plugin/) | 17 skills · 3 agents · hooks |
| Codex CLI | [`plugins/.codex-plugin/`](plugins/.codex-plugin/) | 17 skills · 3 agents |
| Windsurf | [`plugins/.windsurf-plugin/`](plugins/.windsurf-plugin/) | 17 skills · 3 agents · MCP config |
| Cline | [`plugins/.cline-plugin/`](plugins/.cline-plugin/) | 17 skills · 3 agents · MCP config |
| Continue | [`plugins/.continue-plugin/`](plugins/.continue-plugin/) | 17 skills · 3 agents · MCP config |
| VS Code | [`plugins/.vscode-plugin/`](plugins/.vscode-plugin/) | 17 skills · 3 agents · MCP config |
**17 domain skills:** **17 domain skills:**
@@ -182,9 +192,36 @@ Native plugin bundles live under [`plugins/`](plugins/) — install once, works
→ [`plugins/.claude-plugin/README.md`](plugins/.claude-plugin/README.md) → [`plugins/.claude-plugin/README.md`](plugins/.claude-plugin/README.md)
### MCP Server (expose Semantica to any MCP-aware tool)
Semantica ships a full **MCP server** (`semantica/mcp_server.py`) — run it once and any MCP-compatible tool connects automatically:
```bash
python -m semantica.mcp_server
```
Add to your tool's config (Claude Desktop, Windsurf, Cline, Continue, VS Code, Roo Code):
```json
{
"mcpServers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
**12 tools exposed:** `extract_entities`, `extract_relations`, `record_decision`, `query_decisions`, `find_precedents`, `get_causal_chain`, `add_entity`, `add_relationship`, `run_reasoning`, `get_graph_analytics`, `export_graph`, `get_graph_summary`
**3 resources:** `semantica://graph/summary`, `semantica://decisions/list`, `semantica://schema/info`
See [`plugins/.claude-plugin/README.md`](plugins/.claude-plugin/README.md) for per-tool config snippets.
### MCP Client (Ingest from MCP Servers) ### MCP Client (Ingest from MCP Servers)
Semantica includes an **MCP client** (`semantica/ingest/mcp_client.py`) that lets you pull data from any Python/FastMCP server into a knowledge graph: Semantica also includes an **MCP client** (`semantica/ingest/mcp_client.py`) that lets you pull data from any Python/FastMCP server into a knowledge graph:
```python ```python
from semantica.ingest import MCPClient from semantica.ingest import MCPClient
@@ -825,13 +862,13 @@ Start the Semantica server (`python -m semantica.server`, port 8000) and point a
| [Claude Code](https://claude.com/product/claude-code) | **Native plugin** | `plugins/.claude-plugin/` — 17 skills, 3 agents, `hooks.json` | | [Claude Code](https://claude.com/product/claude-code) | **Native plugin** | `plugins/.claude-plugin/` — 17 skills, 3 agents, `hooks.json` |
| [Cursor](https://cursor.com) | **Native plugin** | `plugins/.cursor-plugin/` — same 17 skills + 3 agents | | [Cursor](https://cursor.com) | **Native plugin** | `plugins/.cursor-plugin/` — same 17 skills + 3 agents |
| [Codex CLI](https://github.com/openai/codex) | **Native plugin** | `plugins/.codex-plugin/` — same 17 skills + 3 agents | | [Codex CLI](https://github.com/openai/codex) | **Native plugin** | `plugins/.codex-plugin/` — same 17 skills + 3 agents |
| [Windsurf](https://windsurf.com) | REST API | Point at `http://localhost:8000/api` | | [Windsurf](https://windsurf.com) | **MCP server** + plugin | `plugins/.windsurf-plugin/` · add `python -m semantica.mcp_server` to `~/.codeium/windsurf/mcp_config.json` |
| [Claude Desktop](https://claude.ai/download) | REST API | Point at `http://localhost:8000/api` | | [Claude Desktop](https://claude.ai/download) | **MCP server** | Add `python -m semantica.mcp_server` to `claude_desktop_config.json` |
| [VS Code](https://github.com/microsoft/vscode) | REST API | Use any REST client extension | | [VS Code](https://github.com/microsoft/vscode) | **MCP server** + plugin | `plugins/.vscode-plugin/` · add to `settings.json` under `mcp.servers` |
| [GitHub Copilot](https://github.com/features/copilot) | REST API | Use via Copilot Chat custom tools | | [GitHub Copilot](https://github.com/features/copilot) | REST API | Use via Copilot Chat custom tools |
| [Cline](https://github.com/cline/cline) | REST API | Add as a custom tool endpoint | | [Cline](https://github.com/cline/cline) | **MCP server** + plugin | `plugins/.cline-plugin/` · add server in Cline MCP settings panel |
| [Roo Code](https://github.com/RooCodeInc/Roo-Code) | REST API | Add as a custom tool endpoint | | [Roo Code](https://github.com/RooCodeInc/Roo-Code) | **MCP server** | Add `python -m semantica.mcp_server` in Roo Code MCP settings |
| [Continue](https://github.com/continuedev/continue) | REST API | Add to `~/.continue/config.json` as context provider | | [Continue](https://github.com/continuedev/continue) | **MCP server** + plugin | `plugins/.continue-plugin/` · add to `~/.continue/config.json` under `mcpServers` |
| [Goose](https://github.com/block/goose) | REST API | Add to Goose toolset config | | [Goose](https://github.com/block/goose) | REST API | Add to Goose toolset config |
| [Kilo Code](https://github.com/Kilo-Org/kilocode) | REST API | Add as custom REST tool | | [Kilo Code](https://github.com/Kilo-Org/kilocode) | REST API | Add as custom REST tool |
| [Aider](https://github.com/Aider-AI/aider) | REST API | Pass context from the API into prompts | | [Aider](https://github.com/Aider-AI/aider) | REST API | Pass context from the API into prompts |
+130 -10
View File
@@ -2,13 +2,21 @@
Semantica ships a shared plugin bundle under `plugins/` with skills, agents, and hooks for knowledge graphs, context graphs, decision intelligence, reasoning, explainability, provenance, ontology, and export workflows. Semantica ships a shared plugin bundle under `plugins/` with skills, agents, and hooks for knowledge graphs, context graphs, decision intelligence, reasoning, explainability, provenance, ontology, and export workflows.
This README is for community users who want to install or reuse the plugin package across Claude, Cursor, and Codex. This README covers installation across every supported platform.
## Supported Platforms ## Supported Platforms
- Claude Code | Platform | Method | Config file |
- Cursor |---|---|---|
- Codex | Claude Code | Native plugin bundle | `plugins/.claude-plugin/plugin.json` |
| Cursor | Native plugin bundle | `plugins/.cursor-plugin/plugin.json` |
| Codex CLI | Native plugin bundle | `plugins/.codex-plugin/plugin.json` |
| Windsurf | MCP server + plugin bundle | `plugins/.windsurf-plugin/plugin.json` |
| Cline (VS Code) | MCP server + plugin bundle | `plugins/.cline-plugin/plugin.json` |
| Continue | MCP server | `plugins/.continue-plugin/plugin.json` |
| VS Code | MCP server | `plugins/.vscode-plugin/plugin.json` |
| Claude Desktop | MCP server | — (see MCP section below) |
| Any MCP client | MCP server | `python -m semantica.mcp_server` |
## Prerequisites ## Prerequisites
@@ -23,12 +31,16 @@ cd semantica
```text ```text
plugins/ plugins/
skills/ skills/ ← 17 domain skills
agents/ agents/ ← 3 specialized agents
hooks/ hooks/ ← hooks.json
.claude-plugin/ .claude-plugin/ ← Claude Code manifest
.cursor-plugin/ .cursor-plugin/ ← Cursor manifest
.codex-plugin/ .codex-plugin/ ← Codex CLI manifest
.windsurf-plugin/← Windsurf manifest + MCP config
.cline-plugin/ ← Cline manifest + MCP config
.continue-plugin/← Continue manifest + MCP config
.vscode-plugin/ ← VS Code manifest + MCP config
``` ```
## Plugin Contents ## Plugin Contents
@@ -128,6 +140,114 @@ After installing on any platform, these are good smoke tests:
4. `/semantica:explain decision <decision_id>` 4. `/semantica:explain decision <decision_id>`
5. `/semantica:validate graph` 5. `/semantica:validate graph`
## MCP Server (Windsurf · Cline · Continue · VS Code · Claude Desktop · Any tool)
Semantica includes a full MCP server (`semantica/mcp_server.py`) that exposes 12 tools and 3 resources over stdio — compatible with any MCP-aware tool.
### Start the server
```bash
python -m semantica.mcp_server
```
### Configure in your tool
**Claude Desktop**`~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
**Windsurf**`~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
**Cline** — Cline MCP settings panel → Add server:
```json
{
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
```
**Continue**`~/.continue/config.json`:
```json
{
"mcpServers": [
{
"name": "semantica",
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
]
}
```
**VS Code**`settings.json`:
```json
{
"mcp.servers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
### Available MCP tools
| Tool | Description |
|---|---|
| `extract_entities` | Named entity recognition from text |
| `extract_relations` | Relation and triplet extraction from text |
| `record_decision` | Record a decision with full context and metadata |
| `query_decisions` | Query recorded decisions by natural language or category |
| `find_precedents` | Find past decisions similar to a scenario |
| `get_causal_chain` | Trace upstream/downstream causal chain from a decision |
| `add_entity` | Add a node/entity to the knowledge graph |
| `add_relationship` | Add a directed edge between two entities |
| `run_reasoning` | Run IF/THEN rules over facts to derive new facts |
| `get_graph_analytics` | PageRank centrality and community detection |
| `export_graph` | Export graph as Turtle, JSON-LD, N-Triples, or JSON |
| `get_graph_summary` | Node count, decision count, graph status |
### Available MCP resources
| URI | Description |
|---|---|
| `semantica://graph/summary` | High-level graph statistics |
| `semantica://decisions/list` | All recorded decisions |
| `semantica://schema/info` | Server info and capability list |
### Environment variables
| Variable | Description |
|---|---|
| `SEMANTICA_KG_PATH` | Path to a persisted graph to load on start |
| `SEMANTICA_LOG_LEVEL` | Log level: DEBUG, INFO, WARNING (default: WARNING) |
## Community Notes ## Community Notes
- Keep plugin name/version/keywords updated in each manifest before publishing. - Keep plugin name/version/keywords updated in each manifest before publishing.
+24
View File
@@ -0,0 +1,24 @@
# Semantica — Cline Plugin
Adds all 17 Semantica skills, 3 agents, and hook configuration to Cline (VS Code extension).
## MCP Server Setup (recommended)
In Cline settings, add a new MCP server:
```json
{
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"],
"env": {}
}
}
```
Cline will discover all 12 Semantica tools automatically on connection.
## Requirements
- Python 3.8+
- `pip install semantica`
+17
View File
@@ -0,0 +1,17 @@
{
"name": "semantica-cline",
"plugins": [
{
"name": "semantica",
"description": "Semantica plugin for Cline: knowledge graph skills, reasoning, extraction, and visualization.",
"source": "./",
"category": "Productivity",
"tags": [
"knowledge-graph",
"reasoning",
"semantica",
"cline"
]
}
]
}
+35
View File
@@ -0,0 +1,35 @@
{
"name": "semantica-cline",
"displayName": "Semantica Cline Plugin",
"description": "Semantica plugin for Cline: knowledge graph skills, decision intelligence, reasoning, extraction, and visualization.",
"version": "0.1.0",
"author": {
"name": "Semantica Contributors"
},
"homepage": "https://github.com/Hawksight-AI/semantica",
"repository": "https://github.com/Hawksight-AI/semantica",
"license": "MIT",
"keywords": [
"semantica",
"knowledge graph",
"cline",
"context graphs",
"decision intelligence",
"explainability",
"causal analysis",
"provenance",
"ontology",
"graph analytics",
"semantic extraction",
"visualization",
"reasoning",
"mcp"
],
"skills": "../skills",
"agents": "../agents",
"hooks": "../hooks/hooks.json",
"mcp": {
"server": "python -m semantica.mcp_server",
"transport": "stdio"
}
}
+26
View File
@@ -0,0 +1,26 @@
# Semantica — Continue Plugin
Adds Semantica as an MCP server and context provider to [Continue.dev](https://continue.dev).
## MCP Server Setup
Add to `~/.continue/config.json`:
```json
{
"mcpServers": [
{
"name": "semantica",
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
]
}
```
Continue will show all Semantica tools in the `@semantica` context provider dropdown.
## Requirements
- Python 3.8+
- `pip install semantica`
+17
View File
@@ -0,0 +1,17 @@
{
"name": "semantica-continue",
"plugins": [
{
"name": "semantica",
"description": "Semantica plugin for Continue.dev: knowledge graph context provider, reasoning, and extraction.",
"source": "./",
"category": "Productivity",
"tags": [
"knowledge-graph",
"reasoning",
"semantica",
"continue"
]
}
]
}
+33
View File
@@ -0,0 +1,33 @@
{
"name": "semantica-continue",
"displayName": "Semantica Continue Plugin",
"description": "Semantica plugin for Continue.dev: knowledge graph context provider, decision intelligence, reasoning, and semantic extraction.",
"version": "0.1.0",
"author": {
"name": "Semantica Contributors"
},
"homepage": "https://github.com/Hawksight-AI/semantica",
"repository": "https://github.com/Hawksight-AI/semantica",
"license": "MIT",
"keywords": [
"semantica",
"knowledge graph",
"continue",
"context provider",
"decision intelligence",
"explainability",
"causal analysis",
"provenance",
"ontology",
"semantic extraction",
"reasoning",
"mcp"
],
"skills": "../skills",
"agents": "../agents",
"hooks": "../hooks/hooks.json",
"mcp": {
"server": "python -m semantica.mcp_server",
"transport": "stdio"
}
}
+36
View File
@@ -0,0 +1,36 @@
# Semantica — VS Code Plugin
Adds Semantica as an MCP server to VS Code (via GitHub Copilot Chat or any MCP-aware extension).
## MCP Server Setup
Add to your VS Code `settings.json`:
```json
{
"github.copilot.chat.mcp.servers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
Or if using the VS Code MCP extension directly:
```json
{
"mcp.servers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
## Requirements
- Python 3.8+
- `pip install semantica`
+17
View File
@@ -0,0 +1,17 @@
{
"name": "semantica-vscode",
"plugins": [
{
"name": "semantica",
"description": "Semantica plugin for VS Code: knowledge graph skills, reasoning, extraction, and visualization.",
"source": "./",
"category": "Productivity",
"tags": [
"knowledge-graph",
"reasoning",
"semantica",
"vscode"
]
}
]
}
+35
View File
@@ -0,0 +1,35 @@
{
"name": "semantica-vscode",
"displayName": "Semantica VS Code Plugin",
"description": "Semantica plugin for VS Code: knowledge graph skills, decision intelligence, reasoning, extraction, and visualization via MCP server.",
"version": "0.1.0",
"author": {
"name": "Semantica Contributors"
},
"homepage": "https://github.com/Hawksight-AI/semantica",
"repository": "https://github.com/Hawksight-AI/semantica",
"license": "MIT",
"keywords": [
"semantica",
"knowledge graph",
"vscode",
"context graphs",
"decision intelligence",
"explainability",
"causal analysis",
"provenance",
"ontology",
"graph analytics",
"semantic extraction",
"visualization",
"reasoning",
"mcp"
],
"skills": "../skills",
"agents": "../agents",
"hooks": "../hooks/hooks.json",
"mcp": {
"server": "python -m semantica.mcp_server",
"transport": "stdio"
}
}
+29
View File
@@ -0,0 +1,29 @@
# Semantica — Windsurf Plugin
Adds all 17 Semantica skills, 3 agents, and hook configuration to Windsurf.
## MCP Server Setup (recommended)
Add to your Windsurf MCP config (`~/.codeium/windsurf/mcp_config.json`):
```json
{
"mcpServers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
```
Windsurf will then have access to all 12 Semantica tools (extract, record_decision, query_decisions, find_precedents, get_causal_chain, add_entity, add_relationship, run_reasoning, get_graph_analytics, export_graph, and more) directly in the AI panel.
## Skills
All 17 skills under `plugins/skills/` are available as slash commands once the plugin is loaded.
## Requirements
- Python 3.8+
- `pip install semantica`
+17
View File
@@ -0,0 +1,17 @@
{
"name": "semantica-windsurf",
"plugins": [
{
"name": "semantica",
"description": "Semantica plugin for Windsurf: knowledge graph skills, reasoning, extraction, and visualization.",
"source": "./",
"category": "Productivity",
"tags": [
"knowledge-graph",
"reasoning",
"semantica",
"windsurf"
]
}
]
}
+35
View File
@@ -0,0 +1,35 @@
{
"name": "semantica-windsurf",
"displayName": "Semantica Windsurf Plugin",
"description": "Semantica plugin for Windsurf: knowledge graph skills, decision intelligence, reasoning, extraction, and visualization.",
"version": "0.1.0",
"author": {
"name": "Semantica Contributors"
},
"homepage": "https://github.com/Hawksight-AI/semantica",
"repository": "https://github.com/Hawksight-AI/semantica",
"license": "MIT",
"keywords": [
"semantica",
"knowledge graph",
"windsurf",
"context graphs",
"decision intelligence",
"explainability",
"causal analysis",
"provenance",
"ontology",
"graph analytics",
"semantic extraction",
"visualization",
"reasoning",
"mcp"
],
"skills": "../skills",
"agents": "../agents",
"hooks": "../hooks/hooks.json",
"mcp": {
"server": "python -m semantica.mcp_server",
"transport": "stdio"
}
}
+606
View File
@@ -0,0 +1,606 @@
"""
Semantica MCP Server
Exposes Semantica's knowledge graph, decision intelligence, semantic extraction,
reasoning, and analytics capabilities as an MCP (Model Context Protocol) server
over stdio — compatible with Claude Desktop, Windsurf, Cline, Continue, VS Code,
Roo Code, and any other MCP-aware tool.
Usage
-----
Configure in your tool's MCP settings:
Claude Desktop / Windsurf / Cline / Continue / VS Code:
{
"mcpServers": {
"semantica": {
"command": "python",
"args": ["-m", "semantica.mcp_server"]
}
}
}
Run directly:
python -m semantica.mcp_server
Environment variables:
SEMANTICA_KG_PATH — path to a persisted graph to load on start (optional)
SEMANTICA_LOG_LEVEL — log level: DEBUG, INFO, WARNING (default: WARNING)
"""
from __future__ import annotations
import json
import logging
import os
import sys
from typing import Any
# ── logging ────────────────────────────────────────────────────────────────
_log_level = getattr(logging, os.environ.get("SEMANTICA_LOG_LEVEL", "WARNING").upper(), logging.WARNING)
logging.basicConfig(stream=sys.stderr, level=_log_level,
format="%(asctime)s [semantica-mcp] %(levelname)s %(message)s")
log = logging.getLogger("semantica.mcp_server")
# ── lazy graph session ──────────────────────────────────────────────────────
_graph: Any = None
def _get_graph():
global _graph
if _graph is None:
from semantica.context import ContextGraph
_graph = ContextGraph(advanced_analytics=True)
kg_path = os.environ.get("SEMANTICA_KG_PATH")
if kg_path and os.path.exists(kg_path):
try:
_graph.load(kg_path)
log.info("Loaded graph from %s", kg_path)
except Exception as exc:
log.warning("Could not load graph from %s: %s", kg_path, exc)
return _graph
# ══════════════════════════════════════════════════════════════════════════════
# Tool implementations
# ══════════════════════════════════════════════════════════════════════════════
def _tool_extract_entities(args: dict) -> dict:
"""Extract named entities from text."""
text = args.get("text", "")
if not text:
return {"error": "text is required"}
from semantica.semantic_extract import NamedEntityRecognizer
from semantica.semantic_extract.cache import _result_cache
_result_cache.clear()
entities = NamedEntityRecognizer().extract(text)
return {
"entities": [
{"label": getattr(e, "label", str(e)),
"type": getattr(e, "type", None),
"start": getattr(e, "start", None),
"end": getattr(e, "end", None)}
for e in (entities or [])
]
}
def _tool_extract_relations(args: dict) -> dict:
"""Extract relations and triplets from text."""
text = args.get("text", "")
if not text:
return {"error": "text is required"}
from semantica.semantic_extract import RelationExtractor, TripletExtractor
from semantica.semantic_extract.cache import _result_cache
_result_cache.clear()
relations = RelationExtractor().extract(text)
triplets = TripletExtractor().extract(text)
return {
"relations": [
{"source": getattr(r, "source", None),
"type": getattr(r, "type", None),
"target": getattr(r, "target", None)}
for r in (relations or [])
],
"triplets": [
{"subject": getattr(t, "subject", None),
"predicate": getattr(t, "predicate", None),
"object": getattr(t, "object", None)}
for t in (triplets or [])
],
}
def _tool_record_decision(args: dict) -> dict:
"""Record a decision with full context into the graph."""
required = ["category", "scenario", "reasoning", "outcome", "confidence"]
for field in required:
if field not in args:
return {"error": f"missing required field: {field}"}
graph = _get_graph()
decision_id = graph.record_decision(
category=args["category"],
scenario=args["scenario"],
reasoning=args["reasoning"],
outcome=args["outcome"],
confidence=float(args["confidence"]),
entities=args.get("entities", []),
decision_maker=args.get("decision_maker", "mcp_client"),
valid_from=args.get("valid_from"),
valid_until=args.get("valid_until"),
)
return {"decision_id": decision_id, "status": "recorded"}
def _tool_query_decisions(args: dict) -> dict:
"""Query decisions by natural language or structured filters."""
query = args.get("query", "")
category = args.get("category")
limit = int(args.get("limit", 10))
graph = _get_graph()
try:
if query:
results = graph.find_similar_decisions(query, max_results=limit)
elif category:
nodes = graph.find_nodes(node_type="decision")
results = [n for n in nodes if n.get("category") == category][:limit]
else:
results = graph.find_nodes(node_type="decision")[:limit]
return {"decisions": results if isinstance(results, list) else list(results)}
except Exception as exc:
return {"error": str(exc), "decisions": []}
def _tool_find_precedents(args: dict) -> dict:
"""Find past decisions similar to a given scenario."""
scenario = args.get("scenario", "")
if not scenario:
return {"error": "scenario is required"}
max_results = int(args.get("max_results", 5))
graph = _get_graph()
try:
precedents = graph.find_similar_decisions(scenario, max_results=max_results)
return {"precedents": precedents if isinstance(precedents, list) else list(precedents)}
except Exception as exc:
return {"error": str(exc), "precedents": []}
def _tool_get_causal_chain(args: dict) -> dict:
"""Get the causal chain for a decision."""
decision_id = args.get("decision_id", "")
if not decision_id:
return {"error": "decision_id is required"}
direction = args.get("direction", "downstream")
max_depth = int(args.get("max_depth", 5))
graph = _get_graph()
try:
from semantica.context.causal_analyzer import CausalChainAnalyzer
analyzer = CausalChainAnalyzer(graph_store=graph)
chain = analyzer.get_causal_chain(decision_id, direction=direction, max_depth=max_depth)
return {"chain": chain if isinstance(chain, list) else list(chain)}
except Exception as exc:
return {"error": str(exc), "chain": []}
def _tool_add_entity(args: dict) -> dict:
"""Add a node/entity to the knowledge graph."""
node_id = args.get("id", "")
label = args.get("label", node_id)
node_type = args.get("type", "Entity")
if not node_id:
return {"error": "id is required"}
graph = _get_graph()
graph.add_node(node_id=node_id, label=label, node_type=node_type,
metadata=args.get("metadata", {}))
return {"status": "added", "id": node_id}
def _tool_add_relationship(args: dict) -> dict:
"""Add a relationship (edge) between two entities."""
source = args.get("source", "")
target = args.get("target", "")
rel_type = args.get("type", "RELATED_TO")
if not source or not target:
return {"error": "source and target are required"}
graph = _get_graph()
graph.add_edge(source_id=source, target_id=target, edge_type=rel_type,
metadata=args.get("metadata", {}))
return {"status": "added", "source": source, "target": target, "type": rel_type}
def _tool_run_reasoning(args: dict) -> dict:
"""Run forward-chaining reasoning rules over a set of facts."""
facts = args.get("facts", [])
rules = args.get("rules", [])
if not facts or not rules:
return {"error": "facts and rules are required"}
from semantica.reasoning import Reasoner
reasoner = Reasoner()
for rule in rules:
reasoner.add_rule(rule)
derived = reasoner.infer_facts(facts)
return {"derived_facts": derived if isinstance(derived, list) else list(derived)}
def _tool_get_graph_analytics(args: dict) -> dict:
"""Compute graph analytics: centrality, community detection, metrics."""
graph = _get_graph()
try:
from semantica.kg import CentralityCalculator, CommunityDetector
centrality = CentralityCalculator().calculate_pagerank(graph)
communities = CommunityDetector().detect_communities(graph)
node_count = len(list(graph.find_nodes()))
edge_count = getattr(graph, "edge_count", lambda: 0)()
return {
"node_count": node_count,
"edge_count": edge_count,
"top_nodes_by_pagerank": sorted(
centrality.items() if hasattr(centrality, "items") else [],
key=lambda x: x[1], reverse=True
)[:10],
"community_count": len(communities) if isinstance(communities, (list, dict)) else 0,
}
except Exception as exc:
return {"error": str(exc)}
def _tool_export_graph(args: dict) -> dict:
"""Export the current knowledge graph to a serialised format."""
fmt = args.get("format", "json-ld")
graph = _get_graph()
try:
from semantica.export import RDFExporter, JSONExporter
if fmt in ("turtle", "ttl", "nt", "xml", "json-ld"):
result = RDFExporter().export_to_rdf(graph, format=fmt)
else:
result = JSONExporter().export(graph)
return {"format": fmt, "data": result}
except Exception as exc:
return {"error": str(exc)}
def _tool_get_graph_summary(args: dict) -> dict:
"""Return a high-level summary of the current graph."""
graph = _get_graph()
try:
node_count = len(list(graph.find_nodes()))
decisions = graph.find_nodes(node_type="decision")
return {
"node_count": node_count,
"decision_count": len(list(decisions)),
"graph_ready": True,
}
except Exception as exc:
return {"error": str(exc), "graph_ready": False}
# ══════════════════════════════════════════════════════════════════════════════
# MCP protocol tables
# ══════════════════════════════════════════════════════════════════════════════
TOOLS = [
{
"name": "extract_entities",
"description": "Extract named entities (people, places, organisations, concepts) from text using Semantica NER.",
"inputSchema": {
"type": "object",
"properties": {
"text": {"type": "string", "description": "Input text to extract entities from"}
},
"required": ["text"],
},
"_handler": _tool_extract_entities,
},
{
"name": "extract_relations",
"description": "Extract relations and (subject, predicate, object) triplets from text.",
"inputSchema": {
"type": "object",
"properties": {
"text": {"type": "string", "description": "Input text to extract relations from"}
},
"required": ["text"],
},
"_handler": _tool_extract_relations,
},
{
"name": "record_decision",
"description": "Record a decision into the Semantica knowledge graph with full context, causal links, and metadata.",
"inputSchema": {
"type": "object",
"properties": {
"category": {"type": "string", "description": "Decision category, e.g. 'loan_approval'"},
"scenario": {"type": "string", "description": "Natural-language situation description"},
"reasoning": {"type": "string", "description": "Why this decision was made"},
"outcome": {"type": "string", "description": "Decision outcome, e.g. 'approved'"},
"confidence": {"type": "number", "description": "Confidence score 01"},
"decision_maker":{"type": "string", "description": "Who/what made the decision"},
"valid_from": {"type": "string", "description": "ISO date validity start (optional)"},
"valid_until": {"type": "string", "description": "ISO date validity end (optional)"},
},
"required": ["category", "scenario", "reasoning", "outcome", "confidence"],
},
"_handler": _tool_record_decision,
},
{
"name": "query_decisions",
"description": "Query recorded decisions by natural language, category, or get all recent decisions.",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Natural language query (optional)"},
"category": {"type": "string", "description": "Filter by category (optional)"},
"limit": {"type": "integer", "description": "Max results (default 10)"},
},
},
"_handler": _tool_query_decisions,
},
{
"name": "find_precedents",
"description": "Find past decisions similar to a given scenario using hybrid similarity search.",
"inputSchema": {
"type": "object",
"properties": {
"scenario": {"type": "string", "description": "Scenario description to find precedents for"},
"max_results": {"type": "integer", "description": "Max results (default 5)"},
},
"required": ["scenario"],
},
"_handler": _tool_find_precedents,
},
{
"name": "get_causal_chain",
"description": "Trace the causal chain upstream or downstream from a decision.",
"inputSchema": {
"type": "object",
"properties": {
"decision_id": {"type": "string", "description": "Decision ID to trace"},
"direction": {"type": "string", "enum": ["upstream", "downstream"], "description": "Trace direction"},
"max_depth": {"type": "integer", "description": "Max chain depth (default 5)"},
},
"required": ["decision_id"],
},
"_handler": _tool_get_causal_chain,
},
{
"name": "add_entity",
"description": "Add a node/entity to the Semantica knowledge graph.",
"inputSchema": {
"type": "object",
"properties": {
"id": {"type": "string", "description": "Unique node ID"},
"label": {"type": "string", "description": "Human-readable label"},
"type": {"type": "string", "description": "Node type, e.g. 'Person', 'Organisation'"},
"metadata": {"type": "object", "description": "Additional properties"},
},
"required": ["id"],
},
"_handler": _tool_add_entity,
},
{
"name": "add_relationship",
"description": "Add a directed relationship (edge) between two entities in the knowledge graph.",
"inputSchema": {
"type": "object",
"properties": {
"source": {"type": "string", "description": "Source node ID"},
"target": {"type": "string", "description": "Target node ID"},
"type": {"type": "string", "description": "Relationship type, e.g. 'WORKS_AT'"},
"metadata": {"type": "object", "description": "Additional edge properties"},
},
"required": ["source", "target"],
},
"_handler": _tool_add_relationship,
},
{
"name": "run_reasoning",
"description": "Run forward-chaining IF/THEN rules over a set of facts to derive new facts.",
"inputSchema": {
"type": "object",
"properties": {
"facts": {
"type": "array", "items": {"type": "string"},
"description": "List of fact strings, e.g. ['Person(John)', 'Employee(John)']",
},
"rules": {
"type": "array", "items": {"type": "string"},
"description": "IF/THEN rule strings, e.g. ['IF Employee(?x) THEN WorkerBee(?x)']",
},
},
"required": ["facts", "rules"],
},
"_handler": _tool_run_reasoning,
},
{
"name": "get_graph_analytics",
"description": "Compute PageRank centrality and community detection over the knowledge graph.",
"inputSchema": {"type": "object", "properties": {}},
"_handler": _tool_get_graph_analytics,
},
{
"name": "export_graph",
"description": "Export the current knowledge graph. Formats: turtle, ttl, nt, xml, json-ld, json.",
"inputSchema": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": ["turtle", "ttl", "nt", "xml", "json-ld", "json"],
"description": "Export format (default: json-ld)",
}
},
},
"_handler": _tool_export_graph,
},
{
"name": "get_graph_summary",
"description": "Return a high-level summary of the current knowledge graph: node count, decision count, status.",
"inputSchema": {"type": "object", "properties": {}},
"_handler": _tool_get_graph_summary,
},
]
RESOURCES = [
{
"uri": "semantica://graph/summary",
"name": "Graph Summary",
"description": "High-level statistics about the current knowledge graph",
"mimeType": "application/json",
},
{
"uri": "semantica://decisions/list",
"name": "Decisions",
"description": "List of all recorded decisions in the graph",
"mimeType": "application/json",
},
{
"uri": "semantica://schema/info",
"name": "Schema Info",
"description": "Semantica server info and available capabilities",
"mimeType": "application/json",
},
]
def _read_resource(uri: str) -> dict:
if uri == "semantica://graph/summary":
return _tool_get_graph_summary({})
if uri == "semantica://decisions/list":
return _tool_query_decisions({"limit": 50})
if uri == "semantica://schema/info":
return {
"name": "Semantica",
"version": "0.4.0",
"tools": [t["name"] for t in TOOLS],
"resources": [r["uri"] for r in RESOURCES],
}
return {"error": f"Unknown resource URI: {uri}"}
# ══════════════════════════════════════════════════════════════════════════════
# JSON-RPC / MCP protocol handler
# ══════════════════════════════════════════════════════════════════════════════
SERVER_INFO = {
"name": "semantica",
"version": "0.4.0",
}
CAPABILITIES = {
"tools": {"listChanged": False},
"resources": {"listChanged": False, "subscribe": False},
}
def _handle(req: dict) -> dict | None:
"""Dispatch a single JSON-RPC request; return None for notifications."""
method = req.get("method", "")
params = req.get("params") or {}
req_id = req.get("id")
def ok(result):
return {"jsonrpc": "2.0", "id": req_id, "result": result}
def err(code, message):
return {"jsonrpc": "2.0", "id": req_id, "error": {"code": code, "message": message}}
# Notifications (no id) — acknowledge silently
if req_id is None and method.startswith("notifications/"):
return None
if method == "initialize":
return ok({
"protocolVersion": "2024-11-05",
"capabilities": CAPABILITIES,
"serverInfo": SERVER_INFO,
})
if method == "notifications/initialized":
return None
if method == "ping":
return ok({})
if method == "tools/list":
tools_out = [
{"name": t["name"], "description": t["description"], "inputSchema": t["inputSchema"]}
for t in TOOLS
]
return ok({"tools": tools_out})
if method == "tools/call":
name = params.get("name", "")
arguments = params.get("arguments") or {}
handler = next((t["_handler"] for t in TOOLS if t["name"] == name), None)
if handler is None:
return err(-32601, f"Unknown tool: {name}")
try:
result = handler(arguments)
text = json.dumps(result, ensure_ascii=False, indent=2)
return ok({"content": [{"type": "text", "text": text}]})
except Exception as exc:
log.exception("Tool %s raised", name)
return err(-32603, str(exc))
if method == "resources/list":
return ok({"resources": RESOURCES})
if method == "resources/read":
uri = params.get("uri", "")
data = _read_resource(uri)
text = json.dumps(data, ensure_ascii=False, indent=2)
return ok({"contents": [{"uri": uri, "mimeType": "application/json", "text": text}]})
if method == "prompts/list":
return ok({"prompts": []})
return err(-32601, f"Method not found: {method}")
# ══════════════════════════════════════════════════════════════════════════════
# stdio event loop
# ══════════════════════════════════════════════════════════════════════════════
def _run_stdio():
log.info("Semantica MCP server starting on stdio")
# Use binary stdin/stdout for reliable newline handling on Windows
stdin = sys.stdin.buffer
stdout = sys.stdout.buffer
while True:
try:
line = stdin.readline()
if not line:
break
line = line.strip()
if not line:
continue
try:
req = json.loads(line)
except json.JSONDecodeError as exc:
resp = {"jsonrpc": "2.0", "id": None,
"error": {"code": -32700, "message": f"Parse error: {exc}"}}
stdout.write(json.dumps(resp).encode() + b"\n")
stdout.flush()
continue
resp = _handle(req)
if resp is not None:
stdout.write(json.dumps(resp, ensure_ascii=False).encode() + b"\n")
stdout.flush()
except EOFError:
break
except KeyboardInterrupt:
break
except Exception as exc:
log.exception("Unhandled error in MCP loop: %s", exc)
log.info("Semantica MCP server stopped")
def main():
_run_stdio()
if __name__ == "__main__":
main()