[mKit](https://github.com/m9lk/mkit)
A cross-platform Swift 6 toolkit and Model Context Protocol (MCP) server/CLI. The repo targets macOS (Xcode 16, Swift 6) and Linux (Swift 6.0.1 Jammy), with both stdio and HTTP transports for MCP.
- morgueKitCore: core logic — configuration, logging, auth/token storage, Backtrace client, prompts/resources/tools.
- morgueKitMCPServer: MCP server — HTTP (SwiftNIO) and stdio entry points.
- morgueKitCLI: developer/ops CLI for interacting with the server.
- macOS: Xcode 16 (Swift 6)
- Linux: Swift 6.0.1 (e.g., docker image
swift:6.0.1-jammy)
swift build -v
swift test -vHTTP transport:
swift run morgueKitMCPServer --transport http --host 127.0.0.1 --port 8080Stdio transport:
swift run morgueKitMCPServer --transport stdioHealth/metrics (HTTP):
curl -sS http://127.0.0.1:8080/healthz
curl -sS http://127.0.0.1:8080/metricsMCP JSON POST (non-streaming):
curl -sS -X POST \
-H 'Content-Type: application/json' -H 'Accept: application/json' \
--data '{"jsonrpc":"2.0","id":"1","method":"initialize"}' \
http://127.0.0.1:8080/mcpMCP streaming via SSE:
curl -sS -N -X POST \
-H 'Content-Type: application/json' -H 'Accept: text/event-stream' \
--data '{"jsonrpc":"2.0","id":"1","method":"initialize"}' \
http://127.0.0.1:8080/mcpswift run morgueKitCLI --helpQuick Backtrace smoke (requires env):
export MORGUE_BASE_URL="https://<tenant>.sp.backtrace.io"
export MORGUE_API_TOKEN="<token>"
# List (limit 5)
swift run morgueKitCLI backtrace list --project <project> --limit 5
# Projection & grouping:
# - List with extra columns (projection)
swift run morgueKitCLI backtrace list \
--project "<PROJECT>" --limit 5 \
--columns application,error.type,hostname | jq .
# - Search with extra columns
swift run morgueKitCLI backtrace search \
--project "<PROJECT>" --class NullReferenceException \
--limit 5 --columns host,application.version | jq .
# - Group by error.type with count and order desc
swift run morgueKitCLI backtrace group \
--project "<PROJECT>" \
--group-by error.type --aggregate count --order count:desc --limit 5 | jq .
# Get object bytes (to file)
swift run morgueKitCLI backtrace get --project <project> --id <oid> --output out.bin
# Put object (json|minidump|symbols)
swift run morgueKitCLI backtrace put --project <project> --format json --file sample.json
# Symbolicate (stub in v0.10)
swift run morgueKitCLI backtrace symbolicate --project <project> --crash-id <id>Interact with the MCP dispatcher over HTTP or stdio:
# Start server
swift run morgueKitMCPServer --host 127.0.0.1 --port 8080 & S=$!; sleep 1
# Initialize
swift run morgueKitCLI mcp --http http://127.0.0.1:8080 init | jq .
# List tools
swift run morgueKitCLI mcp --http http://127.0.0.1:8080 tools | jq .
# Call backtrace.list (read-only; stubbed if default baseURL)
swift run morgueKitCLI mcp --http http://127.0.0.1:8080 call backtrace.list --args '{"project":"proj","limit":3}' | jq .
kill $Smake smoke-http # /healthz OK
make smoke-sse # SSE emits message + done
make smoke-mcpcli # JSON-RPC initialize/tools list via /mcp
make smoke-search # tools/call backtrace.search returns result
make demo-all # non-gating: list/search/group/get demo (requires MORGUE_*)For a complete end-to-end walkthrough (server + list/search/group/get with bounded output), see the “Run the full demo” section in Docs/STATUS.md.
See also: Demo flow (Run Script Phase + Source Editor command) in Docs/STATUS.md.
HTTP JSON-RPC
# Start server
swift run morgueKitMCPServer --transport http --host 127.0.0.1 --port 8080 & S=$!; sleep 1
# initialize → tools/list → tools/call backtrace.search
curl -sS -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"1","method":"initialize"}' http://127.0.0.1:8080/mcp | jq .
curl -sS -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"2","method":"tools/list"}' http://127.0.0.1:8080/mcp | jq .
curl -sS -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"3","method":"tools/call","params":{"name":"backtrace.search","arguments":{"project":"Unity","class":"NullReferenceException","limit":1}}}' http://127.0.0.1:8080/mcp | jq .
kill $SSTDIO (one-shot)
# Pipe a single JSON-RPC request into the stdio transport
printf '{"jsonrpc":"2.0","id":"1","method":"initialize"}\n' | swift run morgueKitMCPServer --transport stdio | sed -n '1,3p'Schemas: see Docs/MCP_CONTRACTS.md and the Contracts/ directory.
Stdio transport (server):
# Start an MCP stdio server (for local agents/clients that speak MCP stdio)
swift run morgueKitMCPServer --transport stdioNote: The morgueKitCLI mcp --stdio subcommand writes a single JSON-RPC envelope to stdout for piping into an MCP stdio server; response reading is omitted to avoid blocking interactive terminals.
Quick curl-based checks:
make smoke-http # /healthz OK
make smoke-sse # SSE emits message + done
make smoke-mcpcli # initialize + tools/list envelopes
make smoke-search # tools/call backtrace.search returns result
Search JSONL (one line per result). Pick a project from `swift run morgueKitCLI projects list`.
```bash
swift run morgueKitCLI backtrace search \
--project "<PROJECT>" --class "NullReferenceException" \
--limit 5 --jsonl | sed -n '1,5p'- Token: set
MORGUE_API_TOKEN(tests use a dummy token). On macOS, credentials are stored in Keychain. On Linux, aUserDefaultsfallback is used. - HTTP server host/port can be set via CLI flags or environment (e.g.,
PORT). - Outbound host allow-list, timeouts, and other security defaults live in
morgueKitCoreconfiguration.
- Use a Query token (capability
query:post), scoped to the target project. - Export envs in the same shell (pick a project via
morgueKitCLI projects list):export MORGUE_BASE_URL="https://<universe>.sp.backtrace.io"export MORGUE_UNIVERSE="<universe>"export MORGUE_API_TOKEN="<query_token>"
- Bootstrap (no external CLI): If you don’t have a project token yet, set
MORGUE_USERNAME/MORGUE_PASSWORDand run:swift run morgueKitCLI auth login --project <PROJECT>→ logs in, mints a per-projectquery:posttoken, and stores it in Keychain (last4 printed). On Linux, a UserDefaults fallback is used.- SSO tenants may not support password login; in that case, paste an existing token or use the MCP token tool (see below).
- Verify:
make diag-auth→auth: OK (morgue)orauth: FAIL (invalid token or scope) - Endpoint note: mKit calls only
/api/queryand/api/get(never UI routes/api/projects/...). Some tenants disable/api/get; in that case usebacktrace.get-uuidor the summarized OID path via/api/query. - Optional legacy fallback (tenant-specific):
MKIT_MORGUE_FALLBACK=1retries once with an Authorization header; not recommended for prod.
- mKit reads
MORGUE_API_TOKEN(env) or a stored scoped token for<host>/<universe>/<project>. - Bootstrap a scoped token:
- From env:
swift run morgueKitCLI auth bootstrap --project <PROJECT>→ stores env token scoped; printsauth: OK (stored scoped token ****). - From creds: set
MKIT_AUTH_AUTOCREATE=1withMORGUE_USERNAME/MORGUE_PASSWORD, then run bootstrap to mint/store a per‑projectquery:posttoken.
- From env:
- On 401/403, the client retries once by switching between env and scoped tokens and logs:
[mkit] auth-retry: primary token invalid → retrying with alternate.
- Some tenants don’t expose
uuidvia RLE and attachments may return HTML. Use the compact OID path:- CLI:
swift run morgueKitCLI backtrace get-oid --project <PROJECT> --id <OID> --age 180d | sed -n '1,20p' - MCP: tools/call
backtrace.get-oidwith{project,id,age}→ returns JSON containing:oid,timestamp,error.type,error.message,application.version,application.id,host, and optionallyuuid/guid/classifierswhen present. - Agents should call
get-oidwhenuuidis missing orresolveUuidyields “Not found”. - This works on tenants that omit object symbol tables: mKit resolves hex OIDs via the RLE
objectsindex runs and fetches the row by computed offset.
- CLI:
Quick CLI samples:
# Get compact details for hex OID (includes uuid/guid when projected)
swift run morgueKitCLI backtrace get-oid --project <P> --id e7 | jq .
# Resolve UUID/guid for a hex OID
swift run morgueKitCLI backtrace resolve-uuid --project <P> --id e7 | jq .Quick login & verify (Query token):
printf '%s' "$MORGUE_API_TOKEN" | swift run morgueKitCLI auth login --host '<host>' --universe '<universe>' --project '<PROJECT>'
swift run morgueKitCLI auth check --project '<PROJECT>'
MCP token helpers (optional):
- List tokens (masked): tool `morgue.tokens.list {project}`
- Create token (masked response; client stores full token): tool `morgue.tokens.create {project, capabilities:["query:post"]}`. 401/403 → bad_request: invalid_token_or_scope.See also the Auth notes in Docs/STATUS.md.
- Always build and test locally before committing.
- For local runs in constrained environments, consider using a writable module cache:
mkdir -p .build/ModuleCache .build/.cache export XDG_CACHE_HOME="$PWD/.build/.cache" swift build -v -Xswiftc -module-cache-path -Xswiftc .build/ModuleCache -Xcc -fmodules-cache-path=.build/ModuleCache swift test -v -Xswiftc -module-cache-path -Xswiftc .build/ModuleCache -Xcc -fmodules-cache-path=.build/ModuleCache
- Linux: GitHub Actions on
ubuntu-22.04using theswift:6.0.1-jammycontainer (SPM build/test + coverage export artifact). - macOS: GitHub Actions on macOS 15 with Xcode 16 (SPM build/test + coverage export artifact).
- Docs/ARCHITECTURE.md
- Docs/MCP_TOOLS.md
- Docs/BACKTRACE_API.md
- Docs/DEVELOPMENT.md
- Docs/SECURITY.md
- Docs/ROADMAP.md
Requirements:
MORGUE_BASE_URL(e.g., https://your.sp.backtrace.io)MORGUE_API_TOKEN(API token)MORGUE_UNIVERSE(Universe name)- Pick a project via
swift run morgueKitCLI projects listand pass it explicitly (no MORGUE_PROJECT default).
- Pick a project via
- an object id (OID)
Quick check with standalone harness:
OID=ca make smoke-backtrace
# writes .build/raw_ca.json and prints its headNotes:
- The client selects Morgue-style endpoints if MK_FORCE_MORGUE=1 or MK_USE_MORGUE_ENDPOINTS=true or both universe and token are present.
- Exact GET URL is printed to stderr during fetch for troubleshooting.
Done: HTTP server (/healthz, /metrics), MCP dispatcher at /mcp with read‑only tools (backtrace.list/get, attachments.list stub), CORS preflight, Linux/macOS builds & tests green, basic metrics export.
Todo: MCP Backtrace write tools (put/modify, attachment.add/delete), symbolicate, richer metrics, reports, full BacktraceClient parity, CLI parity, Xcode plugin UI.