Local development
Running the MCP (Model Context Protocol) Services from source against a local OctoMesh stack on your own machine.
Prerequisites
- .NET 10 SDK
- The OctoMesh backend services running locally — see Developer Guide → Getting started and Developer PowerShell for the
Start-Octoworkflow - MongoDB reachable (the default
Start-Octoinfrastructure exposes it onlocalhost:27017) octo-cliavailable — used during one-time tenant bootstrap and as the reference behaviour for new tools
Start the backend services first
The MCP Services calls Identity / Asset / Communication / Bot / Reporting / AdminPanel over HTTP. The Start-Octo PowerShell cmdlet starts them natively on the dev machine:
Start-Octo -nonInteractive $true
The ports each service binds locally (used by appsettings.json defaults — see Configuration):
| Service | HTTPS |
|---|---|
| Asset | https://localhost:5001/ |
| Identity | https://localhost:5003/ |
| Communication | https://localhost:5005/ |
| Bot | https://localhost:5007/ |
| Reporting | https://localhost:5009/ |
| AdminPanel | https://localhost:5011/ |
Stop them with Stop-Octo when you're done.
Run the MCP Services from source
cd octo-mcp-service/src/McpServices
dotnet run --environment Development
In Development mode the server reads appsettings.json + appsettings.Development.json and exposes both transports:
| Transport | URL |
|---|---|
| HTTP | http://localhost:5016/mcp |
| HTTPS | https://localhost:5017/mcp |
The HTTPS port uses the local dev certificate (dotnet dev-certs https --trust if your OS doesn't trust it yet).
The dev server enumerates roughly 187 tool methods at startup. Tail the output to confirm a clean boot — startup errors surface as logged exceptions before the host begins listening.
Register your local server with Claude Code
# HTTP (most common — no cert hassle)
claude mcp add --transport http --scope local octomesh-local http://localhost:5016/mcp
# HTTPS (only if your dev profile binds HTTPS and you trust the dev cert)
claude mcp add --transport http --scope local octomesh-local https://localhost:5017/mcp
// Claude Desktop — claude_desktop_config.json
{
"mcpServers": {
"octomesh-local": {
"type": "http",
"url": "http://localhost:5016/mcp"
}
}
}
Verify:
claude mcp list
# octomesh-local: http://localhost:5016/mcp (HTTP) - ✓ Connected
Restart Claude Code so the tool catalogue is enumerated. First tool call against the local server should be authenticate(tenantId="<your local tenant>") to start the OAuth Device Flow against the locally-running Identity service.
Earlier versions shipped src/mcp-bridge.js, a Node-based stdio→HTTPS shim required by older Claude Code releases. That shim has been removed. Direct HTTP registration is simpler, supports per-call tenant routing, and avoids NODE_TLS_REJECT_UNAUTHORIZED=0.
Running the test suite
# Full suite (~400 tests, ~250 ms)
dotnet test Octo.McpServices.sln -c DebugL
# Filter to a single tool class
dotnet test --filter "FullyQualifiedName~TenantManagementToolsTests"
# CI parity (uses Release + private NuGet feed)
dotnet test Octo.McpServices.sln -c Release
The CI build runs in Release against the private NuGet feed ($(nugetPrivateServer)), not DebugL. Mirror this locally when you suspect a config-sensitive failure.
Pitfalls during local-dev
CkTypeIdformat isName-VersionUint, not SemVer.new CkTypeId("MyType-1")works;new CkTypeId("MyType-1.0.0")throws because the SDK parses the version asuint.OctoObjectIdmust be a 24-character hex string. Use realistic values like"507f1f77bcf86cd799439011"in tests.- Don't reuse SDK clients across requests. The SDK clients cache
ServiceUrion first use; sharing one across tenants routes the second call to the wrong tenant. Always go throughIOctoServiceClientFactory.Create*Client(tenantId, accessToken)— the*ClientContext.TryBuildhelpers do this for you. TreatWarningsAsErrorsis on. Missing XML doc on a public member (CS1591) fails the build.
For the full conventions catalogue (response envelope, optimistic locking, file-transfer architecture, aggregation mapper) see CLAUDE.md in the repository.