{"$schema":"https://wellknown.network/schemas/agent-record-v1.json","schemaVersion":"1","id":"ag_cfg9t8k4kkxy","handle":"af-jupyterlab-mcp","url":"https://wellknown.network/agents/af-jupyterlab-mcp","links":{"self":"https://wellknown.network/agents/af-jupyterlab-mcp/record.json","html":"https://wellknown.network/agents/af-jupyterlab-mcp","markdown":"https://wellknown.network/agents/af-jupyterlab-mcp/record.md","api":"https://wellknown.network/api/v1/agents/af-jupyterlab-mcp","status":"https://wellknown.network/api/v1/agents/af-jupyterlab-mcp/status","claim":"https://wellknown.network/agents/af-jupyterlab-mcp/claim","claimApi":"https://wellknown.network/api/v1/claims","claimDescriptor":"https://wellknown.network/agents/af-jupyterlab-mcp/claim.json","badge":"https://wellknown.network/agents/af-jupyterlab-mcp/badge.svg","openapi":"https://wellknown.network/openapi.json"},"ard":{"identifier":"urn:air::server:af-jupyterlab-mcp","type":"application/mcp-server-card+json"},"kind":"mcp_server","declared":{"name":"af-jupyterlab-mcp","summary":"MCP Server for per-user JupyterLab server management on the ATLAS AF Kubernetes cluster","description":"# af-jupyterlab-mcp\n\n<!-- --8<-- [start:intro] -->\n\nMCP server that lets AF users create, inspect, and delete their own per-user\nJupyterLab servers on the UChicago ATLAS Analysis Facility Kubernetes cluster —\nthe same notebooks [af-portal](https://github.com/maniaclab/af-portal) deploys\ntoday, exposed as tools for LLMs.\n<!-- --8<-- [end:intro] -->\n\n<!-- --8<-- [start:architecture] -->\n\n## Architecture\n\n```\nLLM <--MCP/HTTP--> af-jupyterlab-mcp <--k8s API--> notebook namespace (Pod/Service/Secret/Ingress)\n                         ^\n                         | Authorization: Bearer <broker-issued JWT>\n                         |\n              af-mcp-platform credential broker\n```\n\nPhase 1 (this repo, today) ships six tools that manage the Pod/Service/\nSecret/Ingress quadruple for a notebook, ported from af-portal's\n`portal/jupyterlab.py` and its four Jinja templates. Phase 2 (tracked, not yet\nbuilt) adds a typed proxy to the Datalayer `jupyter-mcp-server` running inside\nthe notebook itself — see\n[maniaclab/af-mcp-platform#189](https://github.com/maniaclab/af-mcp-platform/issues/189).\n<!-- --8<-- [end:architecture] -->\n\n## Project layout\n\n```\nsrc/af_jupyterlab_mcp/\n├── cli.py               # argparse: `af-jupyterlab-mcp serve` (HTTP only)\n├── config.py            # env-driven Settings: namespace, domain, image allowlist, quotas\n├── server.py            # FastMCP setup, lifespan (k8s client + broker verifier), tool registration\n├── auth/\n│   └── broker.py        # extract_bearer(), get_broker_claims() -- broker-issued JWT verification\n├── k8s/\n│   ├── errors.py         # GuardrailError, NameConflictError, NotFoundOrNotYoursError, ...\n│   ├── guardrails.py     # CPU/memory/duration range + image allowlist validation\n│   ├── names.py          # sanitize_k8s_pod_name, name availability, name generation\n│   ├── templates.py      # Jinja rendering of the four ported manifests\n│   ├── notebooks.py      # create/get/list/delete notebook (ported portal logic)\n│   ├── gpu.py      …","publisher":null,"homepage":"https://github.com/maniaclab/af-jupyterlab-mcp","repository":"https://github.com/maniaclab/af-jupyterlab-mcp/issues","version":"0.2.0","license":null,"protocols":["mcp"],"tags":["mcp"],"pricing":null,"endpoints":[{"url":"pypi:af-jupyterlab-mcp","type":"package_pypi","auth":null,"probeable":false}],"skills":null,"tools":null,"extra":null,"attribution":{"kind":"pypi","name":"pypi","repoUrl":"pypi","summary":"pypi","version":"pypi","description":"pypi","homepageUrl":"pypi"}},"derived":{"capabilities":[{"slug":"security.identity","name":"Identity & Access","confidence":0.825,"provenance":"derived"},{"slug":"infra.cloud","name":"Cloud Platforms","confidence":0.791,"provenance":"derived"},{"slug":"dev.version-control","name":"Version Control","confidence":0.779,"provenance":"derived"}],"categories":["dev","infra","security"],"language":"en"},"observed":{"status":"unknown","statusReason":"Distributed as a package to run locally; no network endpoint to check.","lastOkAt":null,"lastProbedAt":null,"statusComputedAt":null,"reliability30d":null,"latestObservations":[],"tools":null,"package":{"name":"af-jupyterlab-mcp","registry":"pypi","observedAt":"2026-09-09T08:22:25.527Z","publishedAt":"2026-08-21T15:31:16.060672Z","latestVersion":"0.2.0"}},"verification":{"claimed":false,"claimedAt":null,"proofs":[]},"provenance":{"sources":[{"source":"pypi","key":"af-jupyterlab-mcp","url":"https://pypi.org/project/af-jupyterlab-mcp/","firstSeenAt":"2026-09-09T08:20:40.925Z","fetchedAt":"2026-09-09T08:20:40.925Z","normalizedAt":"2026-09-09T08:20:40.925Z"}]},"firstSeenAt":"2026-09-09T08:20:40.925Z","updatedAt":"2026-09-09T08:22:25.527Z"}