@anyproto/anytype-mcp 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/bin/cli.mjs +1 -1
- package/package.json +1 -1
- package/src/init-server.ts +3 -2
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Anytype MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<a href="https://npmjs.org/package/@anyproto/anytype-mcp"><img src="https://img.shields.io/npm/v/@anyproto/anytype-mcp.svg" alt="NPM version" height="20" /></a>
|
|
4
|
+
<a href="https://cursor.com/install-mcp?name=anytype&config=JTdCJTIyY29tbWFuZCUyMiUzQSUyMm5weCUyMC15JTIwJTQwYW55cHJvdG8lMkZhbnl0eXBlLW1jcCUyMiUyQyUyMmVudiUyMiUzQSU3QiUyMk9QRU5BUElfTUNQX0hFQURFUlMlMjIlM0ElMjIlN0IlNUMlMjJBdXRob3JpemF0aW9uJTVDJTIyJTNBJTVDJTIyQmVhcmVyJTIwJTNDWU9VUl9BUElfS0VZJTNFJTVDJTIyJTJDJTIwJTVDJTIyQW55dHlwZS1WZXJzaW9uJTVDJTIyJTNBJTVDJTIyMjAyNS0wNS0yMCU1QyUyMiU3RCUyMiU3RCU3RA%3D%3D"><img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add anytype MCP server to Cursor" height="20" /></a>
|
|
5
|
+
<a href="https://lmstudio.ai/install-mcp?name=anytype&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBhbnlwcm90by9hbnl0eXBlLW1jcCJdLCJlbnYiOnsiT1BFTkFQSV9NQ1BfSEVBREVSUyI6IntcIkF1dGhvcml6YXRpb25cIjpcIkJlYXJlciA8WU9VUl9BUElfS0VZPlwiLCBcIkFueXR5cGUtVmVyc2lvblwiOlwiMjAyNS0wNS0yMFwifSJ9fQ%3D%3D"><img src="https://files.lmstudio.ai/deeplink/mcp-install-light.svg" alt="Add MCP Server anytype to LM Studio" height="20" /></a>
|
|
4
6
|
|
|
5
|
-
The Anytype MCP Server is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server
|
|
7
|
+
The Anytype MCP Server is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server enabling AI assistants to seamlessly interact with [Anytype's API](https://github.com/anyproto/anytype-api) through natural language.
|
|
6
8
|
|
|
7
9
|
It bridges the gap between AI and Anytype's powerful features by converting Anytype's OpenAPI specification into MCP tools, allowing you to manage your knowledge base through conversation.
|
|
8
10
|
|
|
@@ -19,9 +21,9 @@ It bridges the gap between AI and Anytype's powerful features by converting Anyt
|
|
|
19
21
|
### 1. Get Your API Key
|
|
20
22
|
|
|
21
23
|
1. Open Anytype
|
|
22
|
-
2. Go to Settings
|
|
23
|
-
3. Navigate to API Keys
|
|
24
|
-
4. Create
|
|
24
|
+
2. Go to App Settings
|
|
25
|
+
3. Navigate to API Keys section
|
|
26
|
+
4. Click on `Create new` button
|
|
25
27
|
|
|
26
28
|
<details>
|
|
27
29
|
<summary>Alternative: Get API key via CLI</summary>
|
|
@@ -52,6 +54,8 @@ Add the following configuration to your MCP client settings:
|
|
|
52
54
|
}
|
|
53
55
|
```
|
|
54
56
|
|
|
57
|
+
> **Tip:** After creating an API key in Anytype, you can copy a ready-to-use configuration snippet with your API key already filled in from the API Keys section.
|
|
58
|
+
|
|
55
59
|
<details>
|
|
56
60
|
<summary>Alternative: Global Installation</summary>
|
|
57
61
|
|
package/bin/cli.mjs
CHANGED
|
@@ -70,7 +70,7 @@ Add this to your MCP settings file as:`),console.log(`
|
|
|
70
70
|
`}var gr=class{constructor(a=r2.stdin,t=r2.stdout){this._stdin=a,this._stdout=t,this._readBuffer=new xr,this._started=!1,this._ondata=i=>{this._readBuffer.append(i),this.processReadBuffer()},this._onerror=i=>{var n;(n=this.onerror)===null||n===void 0||n.call(this,i)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(var a,t;;)try{let i=this._readBuffer.readMessage();if(i===null)break;(a=this.onmessage)===null||a===void 0||a.call(this,i)}catch(i){(t=this.onerror)===null||t===void 0||t.call(this,i)}}async close(){var a;this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),(a=this.onclose)===null||a===void 0||a.call(this)}send(a){return new Promise(t=>{let i=n2(a);this._stdout.write(i)?t():this._stdout.once("drain",t)})}};import Dg from"node:fs";import Pg from"node:path";var I8=6e4,br=class{constructor(a){this._options=a,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this.setNotificationHandler(lr,t=>{let i=this._requestHandlerAbortControllers.get(t.params.requestId);i?.abort(t.params.reason)}),this.setNotificationHandler(mr,t=>{this._onprogress(t)}),this.setRequestHandler(cr,t=>({}))}_setupTimeout(a,t,i,n){this._timeoutInfo.set(a,{timeoutId:setTimeout(n,t),startTime:Date.now(),timeout:t,maxTotalTimeout:i,onTimeout:n})}_resetTimeout(a){let t=this._timeoutInfo.get(a);if(!t)return!1;let i=Date.now()-t.startTime;if(t.maxTotalTimeout&&i>=t.maxTotalTimeout)throw this._timeoutInfo.delete(a),new Ot(Ma.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:t.maxTotalTimeout,totalElapsed:i});return clearTimeout(t.timeoutId),t.timeoutId=setTimeout(t.onTimeout,t.timeout),!0}_cleanupTimeout(a){let t=this._timeoutInfo.get(a);t&&(clearTimeout(t.timeoutId),this._timeoutInfo.delete(a))}async connect(a){this._transport=a,this._transport.onclose=()=>{this._onclose()},this._transport.onerror=t=>{this._onerror(t)},this._transport.onmessage=t=>{"method"in t?"id"in t?this._onrequest(t):this._onnotification(t):this._onresponse(t)},await this._transport.start()}_onclose(){var a;let t=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._transport=void 0,(a=this.onclose)===null||a===void 0||a.call(this);let i=new Ot(Ma.ConnectionClosed,"Connection closed");for(let n of t.values())n(i)}_onerror(a){var t;(t=this.onerror)===null||t===void 0||t.call(this,a)}_onnotification(a){var t;let i=(t=this._notificationHandlers.get(a.method))!==null&&t!==void 0?t:this.fallbackNotificationHandler;i!==void 0&&Promise.resolve().then(()=>i(a)).catch(n=>this._onerror(new Error(`Uncaught error in notification handler: ${n}`)))}_onrequest(a){var t,i,n;let r=(t=this._requestHandlers.get(a.method))!==null&&t!==void 0?t:this.fallbackRequestHandler;if(r===void 0){(i=this._transport)===null||i===void 0||i.send({jsonrpc:"2.0",id:a.id,error:{code:Ma.MethodNotFound,message:"Method not found"}}).catch(o=>this._onerror(new Error(`Failed to send an error response: ${o}`)));return}let p=new AbortController;this._requestHandlerAbortControllers.set(a.id,p);let s={signal:p.signal,sessionId:(n=this._transport)===null||n===void 0?void 0:n.sessionId};Promise.resolve().then(()=>r(a,s)).then(o=>{var d;if(!p.signal.aborted)return(d=this._transport)===null||d===void 0?void 0:d.send({result:o,jsonrpc:"2.0",id:a.id})},o=>{var d,l;if(!p.signal.aborted)return(d=this._transport)===null||d===void 0?void 0:d.send({jsonrpc:"2.0",id:a.id,error:{code:Number.isSafeInteger(o.code)?o.code:Ma.InternalError,message:(l=o.message)!==null&&l!==void 0?l:"Internal error"}})}).catch(o=>this._onerror(new Error(`Failed to send response: ${o}`))).finally(()=>{this._requestHandlerAbortControllers.delete(a.id)})}_onprogress(a){let{progressToken:t,...i}=a.params,n=Number(t),r=this._progressHandlers.get(n);if(!r){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(a)}`));return}let p=this._responseHandlers.get(n);if(this._timeoutInfo.has(n)&&p)try{this._resetTimeout(n)}catch(s){p(s);return}r(i)}_onresponse(a){let t=Number(a.id),i=this._responseHandlers.get(t);if(i===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(a)}`));return}if(this._responseHandlers.delete(t),this._progressHandlers.delete(t),this._cleanupTimeout(t),"result"in a)i(a);else{let n=new Ot(a.error.code,a.error.message,a.error.data);i(n)}}get transport(){return this._transport}async close(){var a;await((a=this._transport)===null||a===void 0?void 0:a.close())}request(a,t,i){return new Promise((n,r)=>{var p,s,o,d;if(!this._transport){r(new Error("Not connected"));return}((p=this._options)===null||p===void 0?void 0:p.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(a.method),(s=i?.signal)===null||s===void 0||s.throwIfAborted();let l=this._requestMessageId++,c={...a,jsonrpc:"2.0",id:l};i?.onprogress&&(this._progressHandlers.set(l,i.onprogress),c.params={...a.params,_meta:{progressToken:l}});let x=f=>{var h;this._responseHandlers.delete(l),this._progressHandlers.delete(l),this._cleanupTimeout(l),(h=this._transport)===null||h===void 0||h.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:l,reason:String(f)}}).catch(y=>this._onerror(new Error(`Failed to send cancellation: ${y}`))),r(f)};this._responseHandlers.set(l,f=>{var h;if(!(!((h=i?.signal)===null||h===void 0)&&h.aborted)){if(f instanceof Error)return r(f);try{let y=t.parse(f.result);n(y)}catch(y){r(y)}}}),(o=i?.signal)===null||o===void 0||o.addEventListener("abort",()=>{var f;x((f=i?.signal)===null||f===void 0?void 0:f.reason)});let g=(d=i?.timeout)!==null&&d!==void 0?d:I8,u=()=>x(new Ot(Ma.RequestTimeout,"Request timed out",{timeout:g}));this._setupTimeout(l,g,i?.maxTotalTimeout,u),this._transport.send(c).catch(f=>{this._cleanupTimeout(l),r(f)})})}async notification(a){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(a.method);let t={...a,jsonrpc:"2.0"};await this._transport.send(t)}setRequestHandler(a,t){let i=a.shape.method.value;this.assertRequestHandlerCapability(i),this._requestHandlers.set(i,(n,r)=>Promise.resolve(t(a.parse(n),r)))}removeRequestHandler(a){this._requestHandlers.delete(a)}assertCanSetRequestHandler(a){if(this._requestHandlers.has(a))throw new Error(`A request handler for ${a} already exists, which would be overridden`)}setNotificationHandler(a,t){this._notificationHandlers.set(a.shape.method.value,i=>Promise.resolve(t(a.parse(i))))}removeNotificationHandler(a){this._notificationHandlers.delete(a)}};function p2(e,a){return Object.entries(a).reduce((t,[i,n])=>(n&&typeof n=="object"?t[i]=t[i]?{...t[i],...n}:n:t[i]=n,t),{...e})}var yr=class extends br{constructor(a,t){var i;super(t),this._serverInfo=a,this._capabilities=(i=t?.capabilities)!==null&&i!==void 0?i:{},this._instructions=t?.instructions,this.setRequestHandler(Cs,n=>this._oninitialize(n)),this.setNotificationHandler(ks,()=>{var n;return(n=this.oninitialized)===null||n===void 0?void 0:n.call(this)})}registerCapabilities(a){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=p2(this._capabilities,a)}assertCapabilityForMethod(a){var t,i;switch(a){case"sampling/createMessage":if(!(!((t=this._clientCapabilities)===null||t===void 0)&&t.sampling))throw new Error(`Client does not support sampling (required for ${a})`);break;case"roots/list":if(!(!((i=this._clientCapabilities)===null||i===void 0)&&i.roots))throw new Error(`Client does not support listing roots (required for ${a})`);break;case"ping":break}}assertNotificationCapability(a){switch(a){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${a})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${a})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${a})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${a})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(a){switch(a){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Server does not support sampling (required for ${a})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${a})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${a})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${a})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${a})`);break;case"ping":case"initialize":break}}async _oninitialize(a){let t=a.params.protocolVersion;return this._clientCapabilities=a.params.capabilities,this._clientVersion=a.params.clientInfo,{protocolVersion:Zc.includes(t)?t:Rs,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},dr)}async createMessage(a,t){return this.request({method:"sampling/createMessage",params:a},js,t)}async listRoots(a,t){return this.request({method:"roots/list",params:a},Fs,t)}async sendLoggingMessage(a){return this.notification({method:"notifications/message",params:a})}async sendResourceUpdated(a){return this.notification({method:"notifications/resources/updated",params:a})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};var b0=qt(qn(),1),o1=qt($2(),1),d1=qt(x0(),1);import kg from"fs";function g0(e){let a=[];if(!e.requestBody)return a;let n=(e.requestBody.content||{})["multipart/form-data"];if(!n?.schema)return a;let r=n.schema;return r.type!=="object"||!r.properties||Object.entries(r.properties).forEach(([p,s])=>{let o=s;if(o.type==="string"&&o.format==="binary"&&a.push(p),o.type==="array"&&o.items){let d=o.items;d.type==="string"&&d.format==="binary"&&a.push(p)}}),a}var _n=class extends Error{constructor(t,i,n,r){super(`${i} ${t}`);this.status=i;this.data=n;this.headers=r;this.name="HttpClientError"}},rp=class{constructor(a,t){this.client=new(d1.default.default??d1.default)({definition:t,axiosConfigDefaults:{baseURL:a.baseUrl,headers:{"Content-Type":"application/json","User-Agent":"anytype-mcp-server",...a.headers}}}),this.api=this.client.init()}async prepareFileUpload(a,t){console.error("prepareFileUpload",{operation:a,params:t});let i=g0(a);if(i.length===0)return null;let n=new b0.default;for(let p of i){let o=function(d,l){try{let c=kg.createReadStream(l);n.append(d,c)}catch(c){throw new Error(`Failed to read file at ${l}: ${c}`)}};var r=o;console.error(`extracting ${p}`,{params:t});let s=t[p];if(!s)throw new Error(`File path must be provided for parameter: ${p}`);switch(typeof s){case"string":o(p,s);break;case"object":if(Array.isArray(s)){let d=0;for(let l of s)o(p,l),d++;break}default:throw new Error(`Unsupported file type: ${typeof s}`)}}for(let[p,s]of Object.entries(t))i.includes(p)||n.append(p,s);return n}async executeOperation(a,t={}){let i=await this.api,n=a.operationId;if(!n)throw new Error("Operation ID is required");let r=await this.prepareFileUpload(a,t),p={},s=r||{...t};if(a.parameters)for(let d of a.parameters)"name"in d&&d.name&&d.in&&(d.in==="path"||d.in==="query")&&t[d.name]!==void 0&&(p[d.name]=t[d.name],r||delete s[d.name]);if(!a.requestBody&&!r)for(let d in s)s[d]!==void 0&&(p[d]=s[d],delete s[d]);let o=i[n];if(!o)throw new Error(`Operation ${n} not found`);try{let d=Object.keys(s).length>0,c={headers:{...r?r.getHeaders():{...d?{"Content-Type":"application/json"}:{"Content-Type":null}}}};console.error("calling operation",{operationId:n,urlParameters:p,bodyParams:s,requestConfig:c});let x=await o(p,d?s:void 0,c);console.error("operation finished");let g=new o1.Headers;return Object.entries(x.headers).forEach(([u,f])=>{f&&g.append(u,f.toString())}),{data:x.data,status:x.status,headers:g}}catch(d){if(d.response){console.error("Error in http client",d);let l=new o1.Headers;throw Object.entries(d.response.headers).forEach(([c,x])=>{x&&l.append(c,x.toString())}),new _n(d.response.statusText||"Request failed",d.response.status,d.response.data,l)}throw d}}};var pp=class{constructor(a){this.openApiSpec=a;this.schemaCache={};this.nameCounter=0}internalResolveRef(a,t){if(!a.startsWith("#/")||t.has(a))return null;let i=a.replace(/^#\//,"").split("/"),n=this.openApiSpec;for(let r of i)if(n=n[r],!n)return null;return t.add(a),n}convertOpenApiSchemaToJsonSchema(a,t,i=!0){if("$ref"in a){let r=a.$ref;if(!i){if(r.startsWith("#/components/schemas/"))return{$ref:r.replace(/^#\/components\/schemas\//,"#/$defs/"),..."description"in a?{description:a.description}:{}};console.error(`Attempting to resolve ref ${r} not found in components collection.`)}let p={$ref:r};if("description"in a&&a.description&&(p.description=a.description),this.schemaCache[r])return this.schemaCache[r];let s=this.internalResolveRef(r,t);if(s){let o=this.convertOpenApiSchemaToJsonSchema(s,t,i);return this.schemaCache[r]=o,o}else return console.error(`Failed to resolve ref ${r}`),{$ref:r.replace(/^#\/components\/schemas\//,"#/$defs/"),description:"description"in a?a.description??"":""}}let n={};if(a.type&&(n.type=a.type),a.format==="binary"){n.format="uri-reference";let r="absolute paths to local files";n.description=a.description?`${a.description} (${r})`:r}else a.format&&(n.format=a.format),a.description&&(n.description=a.description);if(a.enum&&(n.enum=a.enum),a.default!==void 0&&(n.default=a.default),a.type==="object"){if(n.type="object",a.properties){n.properties={};for(let[r,p]of Object.entries(a.properties))n.properties[r]=this.convertOpenApiSchemaToJsonSchema(p,t,i)}a.required&&(n.required=a.required),a.additionalProperties===!0||a.additionalProperties===void 0?n.additionalProperties=!0:a.additionalProperties&&typeof a.additionalProperties=="object"?n.additionalProperties=this.convertOpenApiSchemaToJsonSchema(a.additionalProperties,t,i):n.additionalProperties=!1}if(a.type==="array"&&a.items&&(n.type="array",n.items=this.convertOpenApiSchemaToJsonSchema(a.items,t,i)),a.oneOf){if(a.oneOf.some(o=>typeof o=="object"&&"$ref"in o&&o.$ref==="#/components/schemas/apimodel.EmojiIcon"))return{type:"object",description:a.description,properties:{emoji:{type:"string",description:"The emoji of the icon"},format:{type:"string",description:"The format of the icon",enum:["emoji"]}},additionalProperties:!0};let p=a.oneOf.every(o=>typeof o=="object"&&"$ref"in o&&o.$ref.endsWith("PropertyValue")),s=a.oneOf.every(o=>typeof o=="object"&&"$ref"in o&&o.$ref.endsWith("PropertyLinkValue"));if(p||s)return{type:"object",properties:{...{...s?{key:{type:"string",description:"The key of the property",examples:["last_modified_date"]}}:{id:{type:"string",description:"The id of the property",examples:["last_modified_date"]},key:{type:"string",description:"The key of the property",examples:["last_modified_date"]},name:{type:"string",description:"The name of the property",examples:["Last modified date"]},object:{type:"string",description:"The data model of the object",examples:["property"]}}},text:{type:"string",description:"The text value, if applicable",examples:["Some text..."]},number:{type:"number",description:"The number value, if applicable",examples:[42]},select:{type:"string",description:"The selected tag id, if applicable",examples:["tag_id"]},multi_select:{type:"array",description:"The selected tag ids, if applicable",items:{type:"string"},examples:[["tag_id"]]},date:{type:"string",description:"The date value in ISO 8601 format, if applicable",examples:["2025-02-14T12:34:56Z"]},files:{type:"array",description:"The file ids, if applicable",items:{type:"string"},examples:[["['file_id']"]]},checkbox:{type:"boolean",description:"The checkbox value, if applicable",examples:[!0]},url:{type:"string",description:"The url value, if applicable",examples:["https://example.com"]},email:{type:"string",description:"The email value, if applicable",examples:["example@example.com"]},phone:{type:"string",description:"The phone number value, if applicable",examples:["+1234567890"]},objects:{type:"array",description:"The object ids, if applicable",items:{type:"string"},examples:[["['object_id']"]]}}}}return a.oneOf&&(n.oneOf=a.oneOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),a.anyOf&&(n.anyOf=a.anyOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),a.allOf&&(n.allOf=a.allOf.map(r=>this.convertOpenApiSchemaToJsonSchema(r,t,i))),n}convertToMCPTools(){let a="API",t={},i={[a]:{methods:[]}},n={};for(let[r,p]of Object.entries(this.openApiSpec.paths||{}))if(p)for(let[s,o]of Object.entries(p)){if(!this.isOperation(s,o)||o.tags?.includes("Auth")||s.toLowerCase()==="delete")continue;let d=this.convertOperationToMCPMethod(o,s,r);if(d){let l=this.ensureUniqueName(d.name).replaceAll("_","-");d.name=l,i[a].methods.push(d),t[a+"-"+l]={...o,method:s,path:r},n[a+"-"+l]={openApi:{...o,method:s,path:r},mcp:d}}}return{tools:i,openApiLookup:t,zip:n}}convertToOpenAITools(){let a=[];for(let[t,i]of Object.entries(this.openApiSpec.paths||{}))if(i)for(let[n,r]of Object.entries(i)){if(!this.isOperation(n,r)||r.tags?.includes("Auth")||n.toLowerCase()==="delete")continue;let p=this.convertOperationToJsonSchema(r,n,t),s={type:"function",function:{name:r.operationId,description:r.summary||r.description||"",parameters:p}};a.push(s)}return a}convertToAnthropicTools(){let a=[];for(let[t,i]of Object.entries(this.openApiSpec.paths||{}))if(i)for(let[n,r]of Object.entries(i)){if(!this.isOperation(n,r)||r.tags?.includes("Auth")||n.toLowerCase()==="delete")continue;let p=this.convertOperationToJsonSchema(r,n,t),s={name:r.operationId,description:r.summary||r.description||"",input_schema:p};a.push(s)}return a}convertComponentsToJsonSchema(){let a=this.openApiSpec.components||{},t={};for(let[i,n]of Object.entries(a.schemas||{}))t[i]=this.convertOpenApiSchemaToJsonSchema(n,new Set);return t}convertOperationToJsonSchema(a,t,i){let n={type:"object",properties:{},required:[],$defs:{}};if(a.parameters)for(let r of a.parameters){let p=this.resolveParameter(r);if(p&&p.schema){if(p.name==="Anytype-Version")continue;let s=this.convertOpenApiSchemaToJsonSchema(p.schema,new Set);p.description&&(s.description=p.description),n.properties[p.name]=s,p.required&&n.required.push(p.name)}}if(a.requestBody){let r=this.resolveRequestBody(a.requestBody);if(r?.content&&r.content["application/json"]?.schema){let p=this.convertOpenApiSchemaToJsonSchema(r.content["application/json"].schema,new Set);if(p.type==="object"&&p.properties){for(let[s,o]of Object.entries(p.properties))n.properties[s]=o;p.required&&n.required.push(...p.required)}}}return n}isOperation(a,t){return["get","post","put","delete","patch"].includes(a.toLowerCase())}isParameterObject(a){return!("$ref"in a)}isRequestBodyObject(a){return!("$ref"in a)}resolveParameter(a){if(this.isParameterObject(a))return a;{let t=this.internalResolveRef(a.$ref,new Set);if(t&&t.name)return t}return null}resolveRequestBody(a){if(this.isRequestBodyObject(a))return a;{let t=this.internalResolveRef(a.$ref,new Set);if(t)return t}return null}resolveResponse(a){if("$ref"in a){let t=this.internalResolveRef(a.$ref,new Set);return t||null}return a}convertOperationToMCPMethod(a,t,i){if(!a.operationId)return console.warn(`Operation without operationId at ${t} ${i}`),null;let n=a.operationId,r={$defs:{},type:"object",properties:{},required:[]};if(a.parameters)for(let o of a.parameters){let d=this.resolveParameter(o);if(d&&d.schema){if(d.name==="Anytype-Version")continue;let l=this.convertOpenApiSchemaToJsonSchema(d.schema,new Set,!0);d.description&&(l.description=d.description),r.properties[d.name]=l,d.required&&r.required.push(d.name)}}if(a.requestBody){let o=this.resolveRequestBody(a.requestBody);if(o?.content){if(o.content["multipart/form-data"]?.schema){let d=this.convertOpenApiSchemaToJsonSchema(o.content["multipart/form-data"].schema,new Set,!0);if(d.type==="object"&&d.properties){for(let[l,c]of Object.entries(d.properties))r.properties[l]=c;d.required&&r.required.push(...d.required)}}else if(o.content["application/json"]?.schema){let d=this.convertOpenApiSchemaToJsonSchema(o.content["application/json"].schema,new Set,!0);if(d.type==="object"&&d.properties){for(let[l,c]of Object.entries(d.properties))r.properties[l]=c;d.required&&r.required.push(...d.required)}else r.properties.body=d,r.required.push("body")}}}let p=a.summary||a.description||"";if(a.responses){let o=Object.entries(a.responses).filter(([d])=>d.startsWith("4")||d.startsWith("5")).map(([d,l])=>{let x=this.resolveResponse(l)?.description||"";return`${d}: ${x}`});o.length>0&&(p+=`
|
|
71
71
|
Error Responses:
|
|
72
72
|
`+o.join(`
|
|
73
|
-
`))}let s=this.extractResponseType(a.responses);try{return{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}catch(o){return console.warn(`Failed to generate Zod schema for ${n}:`,o),{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}}extractResponseType(a){let t=a?.["200"]||a?.["201"]||a?.["202"]||a?.["204"];if(!t)return null;let i=this.resolveResponse(t);if(!i||!i.content)return null;if(i.content["application/json"]?.schema){let n=this.convertOpenApiSchemaToJsonSchema(i.content["application/json"].schema,new Set,!0);return n.$defs={},i.description&&!n.description&&(n.description=i.description),n}return i.content["image/png"]||i.content["image/jpeg"]?{type:"string",format:"binary",description:i.description||""}:{type:"string",description:i.description||""}}ensureUniqueName(a){if(a.length<=64)return a;let t=a.slice(0,59),i=this.generateUniqueSuffix();return`${t}-${i}`}generateUniqueSuffix(){return this.nameCounter+=1,this.nameCounter.toString().padStart(4,"0")}};var sp=class{constructor(a,t){this.server=new yr({name:a,version:"1.0.0"},{capabilities:{tools:{}}});let i=t.servers?.[0].url||"http://127.0.0.1:31009";this.httpClient=new rp({baseUrl:i,headers:this.parseHeadersFromEnv()},t);let n=new pp(t),{tools:r,openApiLookup:p}=n.convertToMCPTools();this.tools=r,this.openApiLookup=p,this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(Ds,async()=>{let a=[];return Object.entries(this.tools).forEach(([t,i])=>{i.methods.forEach(n=>{let r=`${t}-${n.name}`,p=this.truncateToolName(r);a.push({name:p,description:n.description,inputSchema:n.inputSchema})})}),{tools:a}}),this.server.setRequestHandler(Ps,async a=>{console.error("calling tool",a.params);let{name:t,arguments:i}=a.params,n=this.findOperation(t);if(console.error("operations",this.openApiLookup),!n)throw new Error(`Method ${t} not found`);try{let r=await this.httpClient.executeOperation(n,i);return{content:[{type:"text",text:JSON.stringify(r.data)}]}}catch(r){if(console.error("Error in tool call",r),r instanceof _n){console.error("HttpClientError encountered, returning structured error",r);let p=r.data?.response?.data??r.data??{};return{content:[{type:"text",text:JSON.stringify({status:"error",...typeof p=="object"?p:{data:p}})}]}}throw r}})}findOperation(a){return this.openApiLookup[a]??null}parseHeadersFromEnv(){let a=process.env.OPENAPI_MCP_HEADERS;if(!a)return{};try{let t=JSON.parse(a);return typeof t!="object"||t===null?(console.warn("OPENAPI_MCP_HEADERS environment variable must be a JSON object, got:",typeof t),{}):t}catch(t){return console.warn("Failed to parse OPENAPI_MCP_HEADERS environment variable:",t),{}}}getContentType(a){let t=a.get("content-type");return t?t.includes("text")||t.includes("json")?"text":t.includes("image")?"image":"binary":"binary"}truncateToolName(a){return a.length<=64?a:a.slice(0,64)}async connect(a){await this.server.connect(a)}};var op=class extends Error{constructor(t){super("OpenAPI validation failed");this.errors=t;this.name="ValidationError"}};async function l1(e){let a=e||"http://127.0.0.1:31009/docs/openapi.json",t;if(a.startsWith("http://")||a.startsWith("https://"))try{let i=await ct.get(a);t=typeof i.data=="string"?i.data:JSON.stringify(i.data)}catch(i){i.code==="ECONNREFUSED"&&(console.error("Can't connect to API. Please ensure Anytype is running and reachable."),process.exit(1)),console.error("Failed to fetch OpenAPI specification from URL:",i.message),process.exit(1)}else{let i=Pg.resolve(process.cwd(),a);t=Dg.readFileSync(i,"utf-8")}try{return JSON.parse(t)}catch(i){console.error("Failed to parse OpenAPI specification:",i.message),process.exit(1)}}async function y0(e){let a=await l1(e)
|
|
73
|
+
`))}let s=this.extractResponseType(a.responses);try{return{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}catch(o){return console.warn(`Failed to generate Zod schema for ${n}:`,o),{name:n,description:p,inputSchema:r,...s?{outputSchema:s}:{}}}}extractResponseType(a){let t=a?.["200"]||a?.["201"]||a?.["202"]||a?.["204"];if(!t)return null;let i=this.resolveResponse(t);if(!i||!i.content)return null;if(i.content["application/json"]?.schema){let n=this.convertOpenApiSchemaToJsonSchema(i.content["application/json"].schema,new Set,!0);return n.$defs={},i.description&&!n.description&&(n.description=i.description),n}return i.content["image/png"]||i.content["image/jpeg"]?{type:"string",format:"binary",description:i.description||""}:{type:"string",description:i.description||""}}ensureUniqueName(a){if(a.length<=64)return a;let t=a.slice(0,59),i=this.generateUniqueSuffix();return`${t}-${i}`}generateUniqueSuffix(){return this.nameCounter+=1,this.nameCounter.toString().padStart(4,"0")}};var sp=class{constructor(a,t){this.server=new yr({name:a,version:"1.0.0"},{capabilities:{tools:{}}});let i=t.servers?.[0].url||"http://127.0.0.1:31009";this.httpClient=new rp({baseUrl:i,headers:this.parseHeadersFromEnv()},t);let n=new pp(t),{tools:r,openApiLookup:p}=n.convertToMCPTools();this.tools=r,this.openApiLookup=p,this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(Ds,async()=>{let a=[];return Object.entries(this.tools).forEach(([t,i])=>{i.methods.forEach(n=>{let r=`${t}-${n.name}`,p=this.truncateToolName(r);a.push({name:p,description:n.description,inputSchema:n.inputSchema})})}),{tools:a}}),this.server.setRequestHandler(Ps,async a=>{console.error("calling tool",a.params);let{name:t,arguments:i}=a.params,n=this.findOperation(t);if(console.error("operations",this.openApiLookup),!n)throw new Error(`Method ${t} not found`);try{let r=await this.httpClient.executeOperation(n,i);return{content:[{type:"text",text:JSON.stringify(r.data)}]}}catch(r){if(console.error("Error in tool call",r),r instanceof _n){console.error("HttpClientError encountered, returning structured error",r);let p=r.data?.response?.data??r.data??{};return{content:[{type:"text",text:JSON.stringify({status:"error",...typeof p=="object"?p:{data:p}})}]}}throw r}})}findOperation(a){return this.openApiLookup[a]??null}parseHeadersFromEnv(){let a=process.env.OPENAPI_MCP_HEADERS;if(!a)return{};try{let t=JSON.parse(a);return typeof t!="object"||t===null?(console.warn("OPENAPI_MCP_HEADERS environment variable must be a JSON object, got:",typeof t),{}):t}catch(t){return console.warn("Failed to parse OPENAPI_MCP_HEADERS environment variable:",t),{}}}getContentType(a){let t=a.get("content-type");return t?t.includes("text")||t.includes("json")?"text":t.includes("image")?"image":"binary":"binary"}truncateToolName(a){return a.length<=64?a:a.slice(0,64)}async connect(a){await this.server.connect(a)}};var op=class extends Error{constructor(t){super("OpenAPI validation failed");this.errors=t;this.name="ValidationError"}};async function l1(e){let a=e||"http://127.0.0.1:31009/docs/openapi.json",t;if(a.startsWith("http://")||a.startsWith("https://"))try{let i=await ct.get(a);t=typeof i.data=="string"?i.data:JSON.stringify(i.data)}catch(i){i.code==="ECONNREFUSED"&&(console.error("Can't connect to API. Please ensure Anytype is running and reachable."),process.exit(1)),console.error("Failed to fetch OpenAPI specification from URL:",i.message),process.exit(1)}else{let i=Pg.resolve(process.cwd(),a);t=Dg.readFileSync(i,"utf-8")}try{return JSON.parse(t)}catch(i){console.error("Failed to parse OpenAPI specification:",i.message),process.exit(1)}}async function y0(e){console.error("Initializing Anytype MCP Server...");let a=await l1(e);await new sp("Anytype API",a).connect(new gr),console.error("Anytype MCP Server running on stdio")}async function jg(e){let t=(await l1(e)).servers?.[0]?.url||"http://127.0.0.1:31009";await new er(t).generateAppKey()}async function Fg(e=process.argv.slice(2)){let[a,t]=e;!a||a==="run"?await y0(t):a==="get-key"?await jg(t):(console.error(`Error: Unknown command "${a}"`),process.exit(1))}Fg().catch(e=>{e instanceof op?(console.error("Invalid OpenAPI 3.1 specification:"),e.errors.forEach(a=>console.error(a))):console.error("Error:",e.message),process.exit(1)});export{Fg as main};
|
|
74
74
|
/*! Bundled license information:
|
|
75
75
|
|
|
76
76
|
mime-db/index.js:
|
package/package.json
CHANGED
package/src/init-server.ts
CHANGED
|
@@ -42,9 +42,10 @@ export async function loadOpenApiSpec(specPath?: string): Promise<OpenAPIV3.Docu
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export async function initProxy(specPath: string) {
|
|
45
|
+
console.error("Initializing Anytype MCP Server...");
|
|
45
46
|
const openApiSpec = await loadOpenApiSpec(specPath);
|
|
46
47
|
const proxy = new MCPProxy("Anytype API", openApiSpec);
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
await proxy.connect(new StdioServerTransport());
|
|
50
|
+
console.error("Anytype MCP Server running on stdio");
|
|
50
51
|
}
|