Skip to content

Commit 0899463

Browse files
authored
Merge pull request #23 from sensein/claude/schema-registry-meta-model-2upt56
Add HTTP/SSE transport for Smithery; fix NWB Container parse error
2 parents fd537e3 + 1d01446 commit 0899463

4 files changed

Lines changed: 44 additions & 5 deletions

File tree

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: MCP_TRANSPORT=sse PORT=$PORT python -m neuro_ghost.mcp_server

neuro_ghost/ingest_linkml.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,38 @@ def parse_linkml(path: Path) -> dict[str, Any]:
248248
slots: dict[str, dict] = {}
249249

250250
for cls_name in sv.all_classes():
251-
cls_def = sv.get_class(cls_name)
252-
induced_slots = sv.class_induced_slots(cls_name)
251+
cls_def = sv.get_class(cls_name)
252+
253+
try:
254+
induced_slots = sv.class_induced_slots(cls_name)
255+
except (ValueError, KeyError):
256+
# is_a points to a class outside this schema (e.g. NWB's "Container")
257+
# Fall back to directly-declared slots only.
258+
induced_slots = list(cls_def.attributes.values())
259+
for sname in (cls_def.slots or []):
260+
try:
261+
s = sv.get_slot(sname)
262+
if s:
263+
induced_slots.append(s)
264+
except Exception:
265+
pass
253266

254267
class_uri = cls_def.class_uri or ""
255268
resolved_iri = resolve_prefix(class_uri, prefixes) if class_uri else ""
256269

270+
# Strip is_a if the parent class isn't in this schema — build_registry_entities
271+
# already handles None gracefully; leaving a dangling name would be misleading.
272+
is_a = cls_def.is_a
273+
if is_a:
274+
try:
275+
sv.get_class(is_a)
276+
except (ValueError, KeyError):
277+
is_a = None
278+
257279
classes[cls_name] = {
258280
"iri": resolved_iri,
259281
"definition": cls_def.description or "",
260-
"is_a": cls_def.is_a,
282+
"is_a": is_a,
261283
"is_abstract": bool(cls_def.abstract),
262284
"slots": [slot.name for slot in induced_slots],
263285
}

neuro_ghost/mcp_server.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,18 @@ def ingest_schema(
428428
# ---------------------------------------------------------------------------
429429

430430
def main() -> None:
431-
"""Entry point for the `neuroghost-mcp` console script."""
432-
mcp.run()
431+
"""Entry point for the `neuroghost-mcp` console script.
432+
433+
Transport is selected by the MCP_TRANSPORT env var:
434+
stdio (default) — for Claude Desktop / Cursor / local use
435+
sse — HTTP+SSE for Smithery and other hosted platforms
436+
"""
437+
transport = os.environ.get("MCP_TRANSPORT", "stdio")
438+
if transport == "sse":
439+
port = int(os.environ.get("PORT", "8000"))
440+
mcp.run(transport="sse", host="0.0.0.0", port=port)
441+
else:
442+
mcp.run()
433443

434444

435445
if __name__ == "__main__":

railway.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[build]
2+
builder = "nixpacks"
3+
4+
[deploy]
5+
startCommand = "MCP_TRANSPORT=sse python -m neuro_ghost.mcp_server"
6+
restartPolicyType = "on_failure"

0 commit comments

Comments
 (0)