You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature Request: Support for Generic/Custom Endpoints with API Key Authentication #3168
First of all, thank you for creating this promising tool. I'm writing to suggest a feature that I believe is critical for wider adoption and flexibility.
Currently, connecting to an AI model in OpenCode requires logging into a specific, pre-configured service provider (e.g., OpenAI, Azure, Google). This workflow is restrictive and doesn't support a large and growing number of use cases where developers only have an API endpoint and an API key.
This is in stark contrast to tools like Postman, Insomnia, or other API clients, where one can interact with any HTTP endpoint simply by providing the URL, headers (like Authorization: Bearer <API_KEY>), and a body.
Why This is a Major Limitation (The "Disaster")
The current provider-specific login model is a significant barrier for anyone using:
Self-Hosted Models: Developers using open-source models via frameworks like Ollama, vLLM, LocalAI, or custom inference servers. These services expose an OpenAI-compatible endpoint but have no "login with provider" flow.
Proxy Services: Many organizations and developers use proxy layers like LiteLLM, Cloudflare AI Gateway, or internal company gateways. These proxies manage routing, logging, and key management, providing a unified endpoint and key for various underlying models. OpenCode currently cannot connect to these.
Smaller or Niche Cloud Providers: The AI ecosystem is vast. Many smaller providers offer competitive services but aren't integrated into OpenCode's login list. They almost always provide a standard API key and endpoint.
Any OpenAI-Compatible API: Many new services and models are launching with an API that mirrors OpenAI's structure. The ability to simply point OpenCode to a new base URL and provide a key would make it instantly compatible with this entire ecosystem.
Proposed Solution
I propose adding a "Custom" or "Generic Provider" option to the model configuration.
When a user selects this option, the UI should simply ask for two main fields:
Endpoint Base URL: (e.g., https://api.example.com/v1)
API Key: (This would typically be sent in the Authorization: Bearer <API_KEY> header, as is standard practice).
This would provide the necessary flexibility to connect to virtually any RESTful AI service, dramatically increasing the utility of OpenCode.
This issue might be a duplicate of existing issues. Please check:
Make using any model with any provider easier #930: Make using any model with any provider easier - This issue specifically requests the ability to "add a provider: type in a name, OpenAI-compatible API endpoint, and API key, and start using opencode"
I agree, because our parent company has deployed Google Vertex, but it goes through network management and proxies. The way it's provided to subsidiaries is by accessing an internal endpoint using an API key, and the API key must be included in the HTTP headers. Below is an python example of the request code. Now, I'm unsure how to configure this in OpenCode:
importrequests
ENDPOINT="https://**********"API_KEY="**********"
headers= {
"Content-type": "application/json",
"api-key": API_KEY
}
messages= {
"contents": [
{
"role": "user",
"parts": [
{
"text": "What do you want to play today?"
}
]
}
]
## To use Thinking with the 2.5 Flash model, add the following parameters:# ,"generationConfig": {# "thinkingConfig": {# "thinkingBudget": 500, # Use up to 500 tokens for thinking.# "include_thoughts": True # Include thinking contents# }# }
}
response=requests.post(ENDPOINT, headers=headers, json=messages)
print(response.json())
Reacted by ShaoweiZhu, Gabor Körber and Laxsilence
@coreglass Please let me know if I didnt quite get your request, but from what I understand you want to be able to use Custom Models based on a custom endpoint and api key. This is currently supported on OpenCode by defining the provider and models in the opencode.json. https://opencode.ai/docs/models/#configure-models.
Here is an example where I am running a model on Ollama and adding to Opencode
@Laxsilence I am not sure if there is another way to pass in apikey creds as a different header but the Authorization: Bearer <API_KEY> one. Maybe @rekram1-node can answer if he has an idea, if not id be happy to make a pr to support it.
Judging from the logs, it appears we successfully reached our custom model's service endpoint. However, a request body validation failure occurred. Our hypothesis is that this is due to a mismatch: opencode.ai was sending a request formatted for the OpenAI API (as specified by "npm": "@ai-sdk/openai-compatible") to our endpoint, which expects a Gemini-native format.
To resolve this, we adjusted the configuration to use what we believed was the correct Google provider:
This change, however, resulted in more severe errors that seem to require additional, platform-specific parameters (likely for Google Cloud Vertex AI), which has left us confused.
Our objective is straightforward: we simply want opencode.ai to send requests in a format that our Gemini-based service can understand and process correctly. Is there a better or more direct way to configure this?
also does the url need to include the model and then the model needs to be sent in request body too? Unfamiliar with your system but that thing is sticking out to me as potentially a problem
Thank you both for your assistance. Here's my current progress:
I've written a Python service primarily designed to forward requests. Currently, the URL configured in Opencode is set to localhost:port. When a request is initiated from Opencode to my Python service, I forward it to an endpoint provided by the company. The logs confirm that my Python service does receive responses from the company's AI, but for some reason, these responses aren't being reflected on the Opencode interface. Below is my config.json from Opencode:
Are you sending that response all at once or does your proxy server correctly handle streams?
It's acceptable to call a non-streaming interface, and the session name can be properly returned and displayed on the interface. However, subsequent sessions use streaming calls. My Python code invokes the company's response stream interface and presumably receives all responses at once. Are you suggesting that, since OpenCode calls the response stream interface, I need to relay the content returned by the company's AI interface back to OpenCode in a streaming format within my Python code?
well the fact that the title generation actually works is a good sign, im kinda surprised that it would work and nothing else is? (unless you are authenticated to another provider)
all i was trying to say is to make sure that the data is being transmitted the exact same way google transmitts it because that google package is expecting a specific format
well the fact that the title generation actually works is a good sign, im kinda surprised that it would work and nothing else is? (unless you are authenticated to another provider)
all i was trying to say is to make sure that the data is being transmitted the exact same way google transmitts it because that google package is expecting a specific format
Okay, I need to check the differences in the data format returned compared to Google's data format. Our company documentation mentions that the AI deployment uses Google Vertex AI, but I can't obtain Google authentication and region details. The company only provided the API and key. So, when I set the provider to google-vertex, it directly throws an error. Now, using "npm": "@ai-sdk/google" might lead to potential inconsistencies in the data format.
wait just to confirm are you guys Coreglass and Laxsilence working on the same thing I saw "we" mentioned a few times, I think my recommendations may be conflicting between the two if these setups are different. I misunderstood and thought yall were doing same thing for whatever reason
If you are using google vertex you shouldn't use @ai-sdk/google you need to use the vertex one assuming you are sending requests back in vertex format.
Our parent company has deployed Google Vertex, but when we use @ai-sdk/google-vertex, we encounter an error indicating that we need to configure Google authentication and region information. Our subsidiary does not have the permissions to obtain these details. Currently, all we have is an internal network access endpoint and a personal API key—nothing else. Given only these two pieces of information, how can we configure google-vertex in opencode?
Currently, our progress is as follows: we have configured @ai-sdk/google. #3168 (comment)
Can you give me a bit more information about the errors you see? if the two of you are working on 1 thing why are the configs different? Also is it openai compatible like the original post says or is it google vertex compatible?
@rekram1-node@OpeOginni@palmamartin@Laxsilence
Thank you all very much for the discussion and suggestions. I want to express my sincere gratitude. I have now resolved the issue I was facing, and I am sharing the entire process in the hope that it will be helpful to others.
Integrating a Self-Hosted Gemini 2.5 Pro with OpenCode via a Custom Adapter
Here's a breakdown of the technical journey and the challenges I overcame while integrating a custom-hosted Gemini model with OpenCode.
My Environment:
Client: OpenCode running on Windows.
Model: A self-hosted instance of Gemini 2.5 Pro on Google Vertex AI, accessible only through a specific API key and an endpoint URL (likely due to a proxy).
The Initial Problem: Configuration Mismatch
Initially, I was unable to configure OpenCode using its built-in model providers. Even the "Vertex" option was not viable because it required a projectId and other credentials that I did not have; my access was limited to just an API key and an endpoint.
I then attempted to use the "Custom Provider" option, which allows for configuration with an API key and a baseUrl. However, this also failed. By inspecting the application logs, I discovered a crucial detail about OpenCode's behavior: for a single user prompt, it sends two distinct requests.
First Request (Non-streaming): To generate a title for the current chat session.
Second Request (Streaming): To get the actual response to the user's query.
Figure A:
The core issue, as illustrated in the attached "Figure A," was that OpenCode appends different sub-paths to the configured baseUrl for each of these requests. This meant the resulting URLs did not match the single, fixed endpoint I was required to use, causing all API calls to fail.
The Solution: A Java-based Adapter
To solve this, I decided to build an adapter using Java, which is my language of expertise. This adapter would act as a middleman:
It would receive the incoming requests from OpenCode.
It would then transform and forward these requests to the correct Google Vertex Gemini 2.5 Pro endpoint.
Finally, it would receive the response from Gemini and return it to OpenCode in the expected format.
This approach proved to be sound in principle, but it introduced a new challenge: handling streaming responses.
Implementing Streaming with Server-Sent Events (SSE)
How could I return a streaming response from my adapter back to OpenCode? By digging into OpenCode's source code, I found that it expects streaming data to be formatted as Server-Sent Events (SSE).
With this knowledge, I implemented the following logic in my Java adapter:
Receive the raw streaming response from the Gemini endpoint.
Parse each incoming JSON chunk to extract the content from the parts array.
Wrap this content in the SSE data: format and stream it back to OpenCode.
The moment of truth came, and it worked perfectly! The logs from my Java adapter confirmed that the entire request-response cycle was functioning correctly.
Pitfalls and Key Discoveries
Throughout this process, I encountered a couple of significant hurdles that are worth noting:
Incorrect NPM Package: I initially spent a lot of time trying to make the npm: "@ai-sdk/google-vertex" package work, without success. The solution was to switch to npm: "@ai-sdk/google". I suspect this is because the response structure from my proxied model endpoint aligns more closely with the standard Google AI API rather than the full Vertex AI SDK's expectations.
The finishReason "Aha!" Moment: Gemini's API has a peculiar behavior: it always returns finishReason: 'STOP', even when the response contains a tool call that needs to be executed. At first, I thought this was an issue with the model and I manually changed the finishReason to function_call within my adapter. This led to incorrect behavior where OpenCode would execute a single tool call and then halt, requiring me to manually prompt it to continue.
The breakthrough came when I revisited the source code. I discovered that OpenCode has special handling specifically for Gemini. It is designed to accept finishReason: 'STOP' and then internally inspects the response payload. If it finds tool call information, it correctly processes it as a function_call. Realizing this was the crucial insight that solved the final piece of the puzzle.
Conclusion
In the end, I successfully integrated my custom Gemini model with OpenCode. While it required building an intermediate adapter, the process of debugging and reverse-engineering the communication flow was an invaluable learning experience.
Activity
github-actions commentedon Oct 14, 2025
This issue might be a duplicate of existing issues. Please check:
Feel free to ignore if none of these address your specific case.
Laxsilence commentedon Oct 14, 2025
I agree, because our parent company has deployed Google Vertex, but it goes through network management and proxies. The way it's provided to subsidiaries is by accessing an internal endpoint using an API key, and the API key must be included in the HTTP headers. Below is an python example of the request code. Now, I'm unsure how to configure this in OpenCode:
OpeOginni commentedon Oct 14, 2025
@coreglass Please let me know if I didnt quite get your request, but from what I understand you want to be able to use Custom Models based on a custom endpoint and api key. This is currently supported on OpenCode by defining the provider and models in the
opencode.json. https://opencode.ai/docs/models/#configure-models.Here is an example where I am running a model on Ollama and adding to Opencode
{ "$schema": "https://opencode.ai/config.json", "provider": { "ollama": { "npm": "@ai-sdk/openai-compatible", "name": "Ollama (local)", "options": { "baseURL": "http://localhost:11434/v1", "apiKey": "<api-key>" }, "models": { "llama3.2:latest": { "name": "Llama 3.2" }, "another-supported-model": { "name": "Another Model" } } } } }For the
npmfield you need to pick a packe on the ai-sdk that works with the provider you are using AI-SDK ProvidersOpeOginni commentedon Oct 14, 2025
@Laxsilence I am not sure if there is another way to pass in apikey creds as a different header but the
Authorization: Bearer <API_KEY>one. Maybe @rekram1-node can answer if he has an idea, if not id be happy to make a pr to support it.rekram1-node commentedon Oct 14, 2025
You can pass any headers you want like so:
rekram1-node commentedon Oct 14, 2025
@coreglass I think this already exists?
It is called "Other" instead of "Custom" tho...
Laxsilence commentedon Oct 15, 2025
@rekram1-node Thank you for your reply. I tried using the method you provided, and here is my config.json:
{ "$schema": "https://opencode.ai/config.json", "theme": "tokyonight", "provider": { "my-custom-provider": { "name": "my AI", "options": { "baseURL": "https://xxx/ai-foundation/chat-ai/gemini/pro-thinking", "headers": { "Content-type": "application/json", "x-api-key": "EQxxxd" } }, "models": { "gemini-2.5-pro": { "name": "Gemini 2.5 Pro", "reasoning": true, "tool_call": true, "temperature": true } } } }, "model": "my AI/Gemini 2.5 Pro", "autoshare": false, "autoupdate": true }However, after switching to my model in the opencode, the following error occurred when making the call:
rekram1-node commentedon Oct 15, 2025
@coreglass your config is missing a few pieces, this guide may be helpful: https://opencode.ai/docs/providers/#custom-provider
What's primarily missing is that you aren't specifying the package to use for your provider, normally this would be the openai compatible one:
Here is an example config from the docs:
coreglass commentedon Oct 15, 2025
@rekram1-node
Following your guidance, we initially used the configuration below:
Judging from the logs, it appears we successfully reached our custom model's service endpoint. However, a request body validation failure occurred. Our hypothesis is that this is due to a mismatch: opencode.ai was sending a request formatted for the OpenAI API (as specified by "npm": "@ai-sdk/openai-compatible") to our endpoint, which expects a Gemini-native format.
To resolve this, we adjusted the configuration to use what we believed was the correct Google provider:
This change, however, resulted in more severe errors that seem to require additional, platform-specific parameters (likely for Google Cloud Vertex AI), which has left us confused.
Our objective is straightforward: we simply want opencode.ai to send requests in a format that our Gemini-based service can understand and process correctly. Is there a better or more direct way to configure this?
rekram1-node commentedon Oct 15, 2025
@coreglass
the one confusing thing here is there is a google vertext but there is also google ai studio
have you tried using:
@ai-sdk/google
instead of google vertex?
rekram1-node commentedon Oct 15, 2025
also does the url need to include the model and then the model needs to be sent in request body too? Unfamiliar with your system but that thing is sticking out to me as potentially a problem
Laxsilence commentedon Oct 15, 2025
@rekram1-node @coreglass
Thank you both for your assistance. Here's my current progress:
I've written a Python service primarily designed to forward requests. Currently, the URL configured in Opencode is set to
localhost:port. When a request is initiated from Opencode to my Python service, I forward it to an endpoint provided by the company. The logs confirm that my Python service does receive responses from the company's AI, but for some reason, these responses aren't being reflected on the Opencode interface. Below is myconfig.jsonfrom Opencode:{ "$schema": "https://opencode.ai/config.json", "theme": "tokyonight", "provider": { "myAI": { "npm": "@ai-sdk/google", "name": "myAI", "options": { "baseURL": "http://localhost:18080", "apiKey": "EQxxx" }, "models": { "gemini-2.5-pro": { "name": "Gemini 2.5 Pro", "reasoning": true, "tool_call": true, "temperature": true } } } }, "model": "myAI/Gemini 2.5 Pro", "autoshare": false, "autoupdate": true }Here's the log I receive when making a call through the Opencode interface:
And here's the content returned by my Python service in response:
rekram1-node commentedon Oct 15, 2025
Are you sending that response all at once or does your proxy server correctly handle streams?
Laxsilence commentedon Oct 15, 2025
It's acceptable to call a non-streaming interface, and the session name can be properly returned and displayed on the interface. However, subsequent sessions use streaming calls. My Python code invokes the company's response stream interface and presumably receives all responses at once. Are you suggesting that, since OpenCode calls the response stream interface, I need to relay the content returned by the company's AI interface back to OpenCode in a streaming format within my Python code?
rekram1-node commentedon Oct 15, 2025
well the fact that the title generation actually works is a good sign, im kinda surprised that it would work and nothing else is? (unless you are authenticated to another provider)
all i was trying to say is to make sure that the data is being transmitted the exact same way google transmitts it because that google package is expecting a specific format
Laxsilence commentedon Oct 15, 2025
Okay, I need to check the differences in the data format returned compared to Google's data format. Our company documentation mentions that the AI deployment uses Google Vertex AI, but I can't obtain Google authentication and region details. The company only provided the API and key. So, when I set the provider to google-vertex, it directly throws an error. Now, using "npm": "@ai-sdk/google" might lead to potential inconsistencies in the data format.
rekram1-node commentedon Oct 15, 2025
wait just to confirm are you guys Coreglass and Laxsilence working on the same thing I saw "we" mentioned a few times, I think my recommendations may be conflicting between the two if these setups are different. I misunderstood and thought yall were doing same thing for whatever reason
If you are using google vertex you shouldn't use @ai-sdk/google you need to use the vertex one assuming you are sending requests back in vertex format.
Maybe if you show error I can help better?
Laxsilence commentedon Oct 16, 2025
@rekram1-node Yes, we are working on one thing.
Our parent company has deployed Google Vertex, but when we use @ai-sdk/google-vertex, we encounter an error indicating that we need to configure Google authentication and region information. Our subsidiary does not have the permissions to obtain these details. Currently, all we have is an internal network access endpoint and a personal API key—nothing else. Given only these two pieces of information, how can we configure google-vertex in opencode?
Currently, our progress is as follows: we have configured @ai-sdk/google.
#3168 (comment)
rekram1-node commentedon Oct 16, 2025
Can you give me a bit more information about the errors you see? if the two of you are working on 1 thing why are the configs different? Also is it openai compatible like the original post says or is it google vertex compatible?
This resource may be useful: https://ai-sdk.dev/providers/ai-sdk-providers/google-vertex
If you are using vertex you prolly need
@ai-sdk/google-vertexif you are using vertex you will need to set these in your provider options:
ex:
It get's a bit funky here because vertex provider will try to cram those values (project, location) into a url like so (see here:https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/projects.locations.endpoints.chat/completions) :
endpoint: projects/{project}/locations/{location}/endpoints/{endpoint}
url: https://aiplatform.googleapis.com/v1/{endpoint}/chat/completions
coreglass commentedon Oct 17, 2025
@rekram1-node @OpeOginni @palmamartin @Laxsilence
Thank you all very much for the discussion and suggestions. I want to express my sincere gratitude. I have now resolved the issue I was facing, and I am sharing the entire process in the hope that it will be helpful to others.
Integrating a Self-Hosted Gemini 2.5 Pro with OpenCode via a Custom Adapter
Here's a breakdown of the technical journey and the challenges I overcame while integrating a custom-hosted Gemini model with OpenCode.
My Environment:
Client: OpenCode running on Windows.
Model: A self-hosted instance of Gemini 2.5 Pro on Google Vertex AI, accessible only through a specific API key and an endpoint URL (likely due to a proxy).
The Initial Problem: Configuration Mismatch
Initially, I was unable to configure OpenCode using its built-in model providers. Even the "Vertex" option was not viable because it required a projectId and other credentials that I did not have; my access was limited to just an API key and an endpoint.
I then attempted to use the "Custom Provider" option, which allows for configuration with an API key and a baseUrl. However, this also failed. By inspecting the application logs, I discovered a crucial detail about OpenCode's behavior: for a single user prompt, it sends two distinct requests.
First Request (Non-streaming): To generate a title for the current chat session.

Second Request (Streaming): To get the actual response to the user's query.
Figure A:
The core issue, as illustrated in the attached "Figure A," was that OpenCode appends different sub-paths to the configured baseUrl for each of these requests. This meant the resulting URLs did not match the single, fixed endpoint I was required to use, causing all API calls to fail.
The Solution: A Java-based Adapter
To solve this, I decided to build an adapter using Java, which is my language of expertise. This adapter would act as a middleman:
It would receive the incoming requests from OpenCode.
It would then transform and forward these requests to the correct Google Vertex Gemini 2.5 Pro endpoint.
Finally, it would receive the response from Gemini and return it to OpenCode in the expected format.
This approach proved to be sound in principle, but it introduced a new challenge: handling streaming responses.
Implementing Streaming with Server-Sent Events (SSE)
How could I return a streaming response from my adapter back to OpenCode? By digging into OpenCode's source code, I found that it expects streaming data to be formatted as Server-Sent Events (SSE).
With this knowledge, I implemented the following logic in my Java adapter:
Receive the raw streaming response from the Gemini endpoint.
Parse each incoming JSON chunk to extract the content from the parts array.
Wrap this content in the SSE data: format and stream it back to OpenCode.
The moment of truth came, and it worked perfectly! The logs from my Java adapter confirmed that the entire request-response cycle was functioning correctly.
Pitfalls and Key Discoveries
Throughout this process, I encountered a couple of significant hurdles that are worth noting:
Incorrect NPM Package: I initially spent a lot of time trying to make the npm: "@ai-sdk/google-vertex" package work, without success. The solution was to switch to npm: "@ai-sdk/google". I suspect this is because the response structure from my proxied model endpoint aligns more closely with the standard Google AI API rather than the full Vertex AI SDK's expectations.
The finishReason "Aha!" Moment: Gemini's API has a peculiar behavior: it always returns finishReason: 'STOP', even when the response contains a tool call that needs to be executed. At first, I thought this was an issue with the model and I manually changed the finishReason to function_call within my adapter. This led to incorrect behavior where OpenCode would execute a single tool call and then halt, requiring me to manually prompt it to continue.
The breakthrough came when I revisited the source code. I discovered that OpenCode has special handling specifically for Gemini. It is designed to accept finishReason: 'STOP' and then internally inspects the response payload. If it finds tool call information, it correctly processes it as a function_call. Realizing this was the crucial insight that solved the final piece of the puzzle.
Conclusion
In the end, I successfully integrated my custom Gemini model with OpenCode. While it required building an intermediate adapter, the process of debugging and reverse-engineering the communication flow was an invaluable learning experience.
rekram1-node commentedon Oct 17, 2025
lets go yay thats awesome
J0o1ey commentedon Jan 27, 2026
@rekram1-node hellorekram~,I meet the same issue.
If OpenCode can add self-hosted Google Vertex endpoint now?