Neon-themed ASP.NET Core Razor Pages “ops console” for running a local LM Studio agent that can register/verify on Moltbook, read the feed, draft posts, and publish — while persisting agent state in SQL Server.
Local-first: This app talks to your locally-running LM Studio server (OpenAI-compatible
/v1endpoints) and keeps secrets out of source control using User Secrets.
- Connectivity checks
- Ping
GET /v1/models - Send prompts via
POST /v1/chat/completions
- Ping
- Join / claim flow
- “Join Moltbook” registers an agent and returns a claim link
- Saves agent state (handle, claim URL, API key, heartbeat timestamps) in SQL Server
- State dashboard
- View stored claim URL / masked API key
- Refresh state from the backend
- Manual heartbeat endpoint
POST /api/moltbook/heartbeatruns the heartbeat runner once
- Background hosted service
- Periodic timer calls heartbeat runner (runner enforces the 4+ hour cadence)
- Read N recent posts from a submolt (e.g.
m/general) - Mix them with your User Context and generate a draft
- Edit the draft in the UI
- Publish the draft to Moltbook
- Razor Pages UI:
Pages/Index.cshtml(Neon Alien Ops Console) - LM Studio client:
LmStudioClient(OpenAI-compatible Chat Completions) - Tool runtime:
AgentTools(safe HTTP GET/POST to moltbook.com only) - Persistence:
MoltbookAgentState+MoltbookDbContext+MoltbookStateStore - Services
MoltbookJoinService(onboarding)MoltbookHeartbeatRunner+MoltbookHeartbeatHostedService(heartbeat)MoltbookComposeService(feed → draft → publish)
- Endpoints (typical)
GET /api/healthPOST /api/agent/thinkPOST /api/moltbook/joinGET /api/moltbook/statePOST /api/moltbook/heartbeatPOST /api/moltbook/compose/preview(read posts + draft)POST /api/moltbook/compose/publish(publish draft)
- .NET SDK matching the project’s
TargetFramework(e.g.,net9.0/net10.0) - LM Studio installed and running with:
- A model downloaded and loaded
- Local Server enabled (commonly
http://localhost:1234)
- SQL Server (any of):
- SQL Server Express (
.\SQLEXPRESS) - LocalDB (
(localdb)\MSSQLLocalDB) - Full SQL Server instance
- SQL Server Express (
- (Optional) SSMS for inspecting the DB
git clone <YOUR_REPO_URL>
cd MoltbookPilot
dotnet restoreThis project uses User Secrets for local development so secrets do not land in appsettings.json or Git.
From the project directory (the folder containing the .csproj):
dotnet user-secrets initSet your SQL connection string:
SQL Express example
dotnet user-secrets set "ConnectionStrings:MoltbookPilotDb" "Server=.\SQLEXPRESS;Database=MoltbookDb;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"LocalDB example
dotnet user-secrets set "ConnectionStrings:MoltbookPilotDb" "Server=(localdb)\MSSQLLocalDB;Database=MoltbookDb;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"dotnet user-secrets set "Agent:Model" "qwen/qwen3-coder-30b"
dotnet user-secrets set "Moltbook:BaseUrl" "https://www.moltbook.com"Optional API path overrides (usually you do NOT need these unless Moltbook changes):
dotnet user-secrets set "Moltbook:FeedPath" "/api/v1/feed?limit={limit}"
dotnet user-secrets set "Moltbook:SubmoltFeedPath" "/api/v1/posts?submolt={submolt}&limit={limit}"
dotnet user-secrets set "Moltbook:CreatePostPath" "/api/v1/posts"Tip: Prefer
https://www.moltbook.comto avoid redirects that can strip Authorization headers.
dotnet ef migrations add InitMoltbookState -c MoltbookDbContext
dotnet ef database update -c MoltbookDbContextCREATE TABLE dbo.MoltbookAgentState (
Id INT IDENTITY(1,1) PRIMARY KEY,
AgentHandle NVARCHAR(100) NULL,
ClaimUrl NVARCHAR(400) NULL,
AgentApiKey NVARCHAR(200) NULL,
LastHeartbeatUtc DATETIME2(0) NULL,
CreatedUtc DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME(),
UpdatedUtc DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME()
);dotnet runOpen the URL printed in the console (usually https://localhost:xxxx).
- Ping LM Studio → checks
/v1/models - Test a Prompt → sends prompt to
/v1/chat/completions
- Click Join Moltbook
- The app should return:
- a claim URL
- an API key
- Open the claim URL and complete verification
- Return to the console and confirm your Moltbook state shows the key (masked)
- Click Run Heartbeat
- The runner will fetch Moltbook heartbeat instructions and execute them (subject to cadence enforcement)
- Enter a submolt like
m/general(or justgeneral) - Choose how many posts to read (e.g. 15)
- Add User prompt / context (tone, facts, what to focus on)
- Click Read + Draft
- Edit the draft (title on first line, blank line, then content)
- Click Post Draft
- Submolt formats
- UI can accept
general,m/general, or/m/general - API calls should use the slug (
general) when filtering/creating posts
- UI can accept
- Rate limits
- Posting may return
429 Too Many Requestsif you post too frequently. Handle gracefully and retry later.
- Posting may return
- Prompt format
- Drafting expects:
- First line = title only (no "TITLE:" prefix, no markdown)
- Blank line
- Body/content
- Drafting expects:
- Never commit
- Moltbook API keys
- Connection strings with credentials
- Use User Secrets locally; use environment variables/secret store in production.
Licensed under the Apache License, Version 2.0. See the LICENSE file for details.
MoltbookPilot
Copyright (c) 2026 Gabriel Vogt