Auto-generate a Model Context Protocol (MCP) server from your ABP Framework application. One NuGet, one line, and every
[McpTool]-tagged Application Service is reachable by Claude, Cursor, and every MCP-compatible agent. In-process. Permission-aware. Tenancy-aware β agent calls flow through ABP's normalICurrentTenantpipeline, so a token issued for a tenant calls into that tenant's data.
sequenceDiagram
autonumber
participant Agent as π€ Claude / Cursor / any MCP client
participant MCP as /mcp endpoint<br/>(in-process)
participant Service as Your <code>IApplicationService</code><br/>(BookAppService, etc.)
participant DB as πΎ EF Core / your data store
Agent->>MCP: tools/list
MCP->>MCP: filter by ABP permissions<br/>of the bearer token
MCP-->>Agent: only the tools this user can call
Agent->>MCP: tools/call Loan_CheckOut(memberId, editionId)
MCP->>MCP: re-check permission +<br/>map JSON args to DTO
MCP->>Service: CheckOutAsync(input)
Service->>DB: INSERT INTO Loans
DB-->>Service: ok
Service-->>MCP: LoanDto
MCP-->>Agent: structured result + content blocks
A 30-second screen recording of this flow against the bundled Library sample is tracked as #18. PRs welcome.
Status: pre-alpha (v0.1). Phase 1 scaffolding in place. Not yet published to NuGet.
Every ABP app already declares its business logic as IApplicationService with typed DTOs, permission attributes, XML docs, and multi-tenancy awareness. That is richer metadata than any OpenAPI spec. Generic OpenAPI β MCP converters produce low-quality servers that confuse agents. abp-mcp skips the OpenAPI middleman entirely and generates from ABP's own API description pipeline β the same one that powers ABP's TS/C# proxy generators.
Install the NuGet (pre-release):
dotnet add package AbpMcp --prereleaseAdd AbpMcpModule to your application module's [DependsOn(...)], then register the assembly that holds your application services:
[DependsOn(
typeof(AbpAspNetCoreMvcModule),
typeof(AbpMcpModule),
/* your other modules */)]
public class MyAppHttpApiHostModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// One call wires both ABP's ConventionalControllers (so the api-definition
// provider sees the assembly's app services) and abp-mcp's ExposedAssemblies
// filter (so the MCP scan scopes to it).
context.Services.AddAbpMcpAssembly(typeof(MyAppApplicationModule).Assembly);
Configure<AbpMcpOptions>(opts =>
{
opts.Path = "/mcp";
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseRouting();
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapAbpMcp();
});
}
}Tag the services you want agent-accessible:
[McpTool]
public class ProductAppService : ApplicationService, IProductAppService
{
[Authorize("Products.Create")]
public Task<ProductDto> CreateAsync(CreateProductDto input) => /* ... */;
}Point Claude (or any MCP client) at https://your-host/mcp with a bearer token from your ABP identity server, and the agent calls every exposed tool with the same permissions as a regular user.
Not in an
AbpModule? The rawbuilder.Services.AddAbpMcp(...)+app.MapAbpMcp()path works too. The module-style example above is the one most ABP solutions reach for first.
The repo ships with a runnable ABP host that demonstrates the full surface against a small library domain (Titles, Editions, Members, Loans) seeded with classic books.
dotnet run --project samples/AbpMcp.SampleThen in another terminal:
# What tools are live?
curl http://localhost:5000/mcp/_discover | jq '.tools[].name'
# β Catalog_SearchTitles, Catalog_GetTitle, Catalog_AddTitle,
# Catalog_AddEdition, Catalog_ListAvailableEditions,
# Loan_CheckOut, Loan_Return, Loan_Renew, Loan_ListForMember,
# Loan_ListOverdue, Member_Register, Member_Get, Member_List,
# Member_Suspend, Member_Reinstate
# Why isn't a particular service showing up?
curl 'http://localhost:5000/mcp/_explain?service=Loan'Point Claude Desktop at http://localhost:5000/mcp by adding this to your
claude_desktop_config.json (%APPDATA%\Claude\claude_desktop_config.json on
Windows, ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
Restart Claude Desktop. The agent can now search the catalog, register members,
and check books out β every call hitting a real IApplicationService and
persisting through EF Core.
The MCP endpoint is mounted on the host's normal request pipeline, so ABP's
ICurrentTenant resolution flows through unchanged. A bearer token issued for
tenant T (with the __tenant claim set, the way ABP's identity server issues
them) calls into tenant T's data β no extra wiring. Host-level tenancy
resolvers (header, cookie, route) work the same way they do for any ABP HTTP
endpoint. Cross-tenant impersonation is intentionally not supported in v0.1.
See DESIGN.md for the full design document:
- Problem statement and premises
- Approaches considered (reflection runtime, source generator, LLM-enhanced descriptions)
- Test plan
- Distribution plan
abp-mcp/
βββ src/
β βββ AbpMcp/ # the library
β βββ AbpMcpModule.cs # ABP module
β βββ AbpMcpBuilderExtensions.cs # AddAbpMcp / MapAbpMcp
β βββ AbpMcpOptions.cs
β βββ Attributes/ # [McpTool], [McpIgnore]
β βββ Metadata/ # ApiDefinitionReader, ToolDescriptorBuilder
β βββ Registration/ # DynamicMcpToolRegistry
β βββ Dispatch/ # AbpMcpDispatcher
βββ samples/
β βββ AbpMcp.Sample/ # runnable Library host (15 [McpTool] methods, seeded)
βββ test/
β βββ AbpMcp.Tests/ # unit tests (schema mapping, naming, options shape)
β βββ AbpMcp.IntegrationTests/ # seed-DB β invoke-tool β verify-DB integration tests
βββ .github/
β βββ workflows/ # CI build+test, release-on-tag (signs + publishes)
β βββ ISSUE_TEMPLATE/ # bug + feature forms
β βββ PULL_REQUEST_TEMPLATE.md
βββ DESIGN.md # premises, alternatives, scope decisions
βββ CHANGELOG.md # release notes
βββ CONTRIBUTING.md # setup + design rules + PR process
βββ SECURITY.md # private vulnerability reporting
βββ CLAUDE.md # project guidance for agents & humans
βββ LICENSE # MIT
βββ README.md
Pre-alpha. Direct PRs welcome β please skim CONTRIBUTING.md before opening anything non-trivial. The non-negotiable design rules and the regression-test requirement are in there.
Open invitations:
- JSON Schema mapping for complex DTOs (recursion handling, polymorphism)
- Streamable HTTP transport config refinements
- Sample host integration against eShopOnAbp
Every bug fix lands with a regression test. No exceptions.
- DESIGN.md β premises, alternatives considered, scope decisions
- CHANGELOG.md β what shipped when
- CONTRIBUTING.md β setup, design rules, PR process
- SECURITY.md β vulnerability reporting (do NOT open a public issue for security)
- CLAUDE.md β project guidance for Claude Code & humans
MIT.
{ "mcpServers": { "abp-mcp-sample": { "type": "streamable-http", "url": "http://localhost:5000/mcp" } } }