How to Create MCP Server Desktop Extension in TypeScript
目次
About two weeks ago, Anthropic announced MCP Server Desktop Extension (DXT), which “makes installing MCP servers as easy as clicking a button.”
Claude Desktop Extensions: One-click MCP server installation for Claude Desktop \ Anthropic
It looks fun, so I developed a small DXT in TypeScript last week. The project is small and the documentation is good enough, and it actually took me only a day or two. However, there are a few points not covered in the documentation, so I decided to write this blog post.
Overview
Target audience
This post requires you to have basic knowledge of MCP and JavaScript/TypeScript.
What to implement
We have a product called WP RAG, which is a solution that consists of a WordPress plugin and a backend API with a vector database. It imports content from the customer’s WordPress site, generates embeddings in the vector database, and offers search/RAG capabilities. See the following pages for more details:
- WP RAG – Build RAG Systems with WordPress Content
- WP RAG – Enhance Your WordPress Site with AI-Powered RAG Capabilities – もばらぶん
What I developed is an MCP server that works as a bridge between MCP clients (e.g., Claude Desktop) and WP RAG API, and offers an MCP “tool” that searches through WordPress content.
Below is the source code:
mobalab/wp-rag-mcp-server-dxt
Resources to check out
Before proceeding, I would like you to go through the following online resources if you haven’t yet:
- Blog post by Anthropic: Claude Desktop Extensions: One-click MCP server installation for Claude Desktop \ Anthropic
- Repo for the CLI tool with some sample programs: anthropics/dxt: Desktop Extensions: One-click local MCP server installation in desktop apps

Implementation
Now that you have a basic understanding of the background and DXT, let’s start implementing a DXT.
Create the manifest file
First, run npx @anthropic-ai/dxt init
to initialize manifest.json
. Below is my case. You can change the file later, so if you’re not sure what to enter, put anything for now:
$ npx @anthropic-ai/dxt init
This utility will help you create a manifest.json file for your DXT extension.
Press ^C at any time to quit.
✔ Extension name: wp-rag-mcp-server-dxt
✔ Author name: Mobalab, KK
✔ Display name (optional): WP RAG MCP Server Desktop Extension
✔ Version: 0.0.1
✔ Description: Model Context Protocol (MCP) server as part of the "WP RAG" WordPress plugin ecosystem
✔ Add a detailed long description? no
✔ Author email (optional): info@mobalab.net
✔ Author URL (optional): https://mobalab.net
✔ Homepage URL (optional): https://services.mobalab.net/wp-rag/
✔ Documentation URL (optional):
✔ Support URL (optional):
✔ Icon file path (optional, relative to manifest):
✔ Add screenshots? no
✔ Server type: Node.js
✔ Entry point: server/index.js
✔ Does your MCP Server provide tools you want to advertise (optional)? yes
✔ Tool name: search_posts
✔ Tool description (optional): Semantic search with score thresholds
✔ Add another tool? no
✔ Does your server generate additional tools at runtime? no
✔ Does your MCP Server provide prompts you want to advertise (optional)? no
✔ Add compatibility constraints? no
✔ Add user-configurable options? yes
✔ Configuration option key (unique identifier): api_key
✔ Option type: String
✔ Option title (human-readable name): WP RAG API Key
✔ Option description: WP RAG API Key
✔ Is this option required? yes
✔ Is this option sensitive (like a password)? yes
✔ Add another configuration option? yes
✔ Configuration option key (unique identifier): site_id
✔ Option type: Number
✔ Option title (human-readable name): Site ID on WP RAG
✔ Option description: Site ID on WP RAG
✔ Is this option required? yes
✔ Is this option sensitive (like a password)? no
✔ Add min/max constraints? no
✔ Add another configuration option? no
✔ Keywords (comma-separated, optional): WordPress,RAG,vector database
✔ License: MIT
✔ Add repository information? yes
✔ Repository URL: https://github.com/mobalab/wp-rag-mcp-server-dxt
Created manifest.json at /Users/kashima/Documents/workspace/rag/wp-rag-mcp-server-dxt/manifest.json
Next steps:
1. Ensure all your production dependencies are in this directory
2. Run 'dxt pack' to create your .dxt file
Set up a TypeScript project
We’ll build a DXT in TypeScript, so we need to set up the project for that. I’m not that familiar with the JavaScript/TypeScript ecosystem, so I had Gemini CLI create the necessary files, which are:
- package.json
- tsconfig.json
- .gitignore
I adopted the basic folder structure: the source files go into src
, and transpiled JS files go into dist
.
Update manifest.json: entry_point
The example in the documentation uses plain JavaScript, but we want to use TypeScript, so the setup is a bit different. In particular, the entry point in the example is server/index.js
while ours is dist/index.js
.
I initially thought the directory server
had a special meaning, but it seems like the entry point can be any file in any directory.
Update manifest.json: user_config
WP RAG is a multi-tenant application, so the user should be able to pass the ID and the credentials to the WP RAG API server (through the MCP server) in order to access their data in WP RAG. The user_config
section in manifest.json
is for that kind of purpose. After installing a DXT with values in user_config
, the user will see the config dialog like the following:

I added two values to user_config
. The values entered by the user are passed to the program as environment variables, WP_RAG_SITE_ID
and WP_RAG_API_KEY
. Please see the source for the details.
Write code
My code is pretty simple and easy to understand. Only the code snippet below needs a bit of explanation:
const SearchPostsInputSchema = z.object({
q: z.string().describe("Search query"),
limit: z.number().optional().default(4).describe("Number of results"),
score_threshold: z.number().optional().default(0.2).describe("Threshold for score"),
});
server.registerTool(
"search_posts",
{
title: "Search WordPress posts from WP RAG vector database",
description: "Search posts from a specific site using a query and optional filters.",
inputSchema: SearchPostsInputSchema.shape,
},
async ({ q, limit, score_threshold }) => {
# (snip)
}
);
Look at the arguments to registerTool
. The first one is the name of the tool and the second one describes what this tool does. Also, SearchPostsInputSchema
is the list of the arguments that the tool takes. All the information will be used by MCP clients, so it’s important.
Package and test locally
Create a package
Now the development is almost done. Run the following command to create a .dxt
file:
npx @anthropic-ai/dxt pack
Install it
If there are no errors, double-click the generated file. Alternatively, drag and drop it into Claude Desktop’s Settings window.
Then, click on the “Install” button, fill in the config values, and click on the “Save” button. Also, don’t forget to enable it by clicking on the toggle button.
Test
Open a chat, and type in a question: “Search for WordPress posts about WP RAG, and summarize what the software can do in English.”
Claude thinks it needs to use the tool provided by WP RAG MCP Server Desktop Extension, and asks you for permission:

After you allow it, Claude calls the tool, receives the response, and generates an answer based on it:

As the documentation recommends, you should test it on both Windows and macOS.
Distribute
Once you’re satisfied with the extension, it’s time to distribute it. Actually, there are two ways:
- Distribute it by yourself
- Through Anthropic’s directory
As for the former, the easiest way would be using GitHub’s releases feature. Please see the following document for the details:
Managing releases in a repository – GitHub Docs
The latter requires a review by Anthropic. You can submit the extension on the following page:
Interest Form: Desktop Extensions
Conclusion
MCP Server Desktop Extension gives end-users, who are not necessarily developers, an easy way to install MCP servers. At the same time, it gives developers an easy way to package and distribute MCP servers.
This blog post walks through how to develop, test and distribute an MCP Server Desktop Extension written in TypeScript. Developing an extension in TypeScript isn’t much different from that using plain JavaScript, nor is it different from developing other types of programs in TypeScript.
If you have any questions etc., feel free to ask me via the channels shown below:
- The company’s inquiry form (It’s in Japanese, but you can use Google Translate etc.)
- DM to my X account
コメントを残す